emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Unbalanced change hooks (part 2)


From: Phillip Lord
Subject: Re: Unbalanced change hooks (part 2)
Date: Tue, 30 Aug 2016 15:34:19 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>>  (or
>>                 ;; previously this was not skewed if no region, but actually,
>>                 ;; if there is no region we need to copy everything, we can
>>                 ;; also do by declaring skew -- this is important for the
>>                 ;; multi-lentic situation
>>                 (not (or start stop length-before))
>>                 ;; skews only occur in insertions which result in a positive
>>                 ;; length-before. This also picks up no-insertion changes
>>                 (and (< 0 length-before)
>>                      ;; = start stop means we have a deletion because
>>                      ;; there is no range after. Deletions seem to be
>>                      ;; safe.
>>                      (not (= start stop))))
>
> I don't understand what this is doing.


That's a shame. I don't understand what it is doing either, and I was
hoping that you might do.


> It seems to be looking for indirect clues rather than checking
> directly for the properties on which the code relies.

Perhaps. At the moment, the only thing function that I know definately
causes me problems is subst-char-in-region.

> Why not do something like:
>
>     (defun lentic--b-c-f (start end)
>       (setq-local lentic--b-c-pos (cons start end))
>       ...)
>
>     (defun lentic--a-c-f (start end length)
>       (if (prog1 (not (and (eq start (car lentic--b-c-pos))
>                            (eq (+ start length) (cdr lentic--b-c-pos))))
>             (setq lentic--b-c-pos nil))
>           ;; This a-c-f is not properly paired with the previous b-c-f.
>           <do-the-skewed-thing>
>         ;; Proper pairing
>         <do-the-non-skew-thing>))

I will try and test this to see.


> If the performance issue is serious enough, you can of course try to "do
> it right" with something like:
>
>     (defun lentic--b-c-f (start end)
>       (setq-local lentic--b-c-data
>                   (cons start (buffer-substring start end)))
>       ...)
>
>     (defun lentic--a-c-f (start end length)
>       ;; Get the before-change content of start..end.
>       (let ((old-text (substring (cdr lentic--b-c-data)
>                                  (- start (car lentic--b-c-data))
>                                  (- end length (car lentic--b-c-data)))))
>         ;; Update lentic--b-c-data for possible subsequent other a-c-f calls.
>         (setcdr lentic--b-c-data
>                 (concat (substring (cdr lentic--b-c-data)
>                                    0 (- start (car lentic--b-c-data)))
>                         (buffer-substring start end)
>                         (substring (cdr lentic--b-c-data)
>                                    (- end length (car lentic--b-c-data)))))
>       <now-do-what-we-have-to-do>))
>
> But it can admittedly be cumbersome since the old-text is now in a string
> rather than being inside the buffer.

Because, I am not using the before and after positions just to recognise
the string that has changed. I am have to calculate the equivalent
positions in the other "lentic" buffer; and this can only be done before
the change, since the two buffers are them in a consistent state.

In the case that they are skewed, I have to throw all my knowledge away,
since the converted positions are not unreliable. So I copy the whole
buffer, and apply the general (unoptimized) transformation.

>> 1) being able to know when b-c-f and a-c-f are not paired or consistent
>> would be useful
>
> Does the above lentic--b-c-pos give the needed info?
>
>> 2) decreasing the number of times these occurs would be useful, even if
>> it cannot be removed entirely.
>
> Note that in the subst-char-in-region you could "make it pairup"
> yourself by hand: if you have (< (+ start length) (cdr lentic--b-c-pos)),
> then you can just
>
>     (let ((diff (- (cdr lentic--b-c-pos) (+ start length))))
>       (cl-incf length diff)
>       (cl-incf end diff))
>
> such that (eq (+ start length) (cdr lentic--b-c-pos)).


So, this works because subst-char-in-region is guaranteed not to change
the size of the region right? But, how do I know that
subst-char-in-region has been called? I discovered this problem first,
when fill-paragraph broke lentic. It just so happens that
subst-char-in-region was the culprit; it wasn't the command though.

Phil




reply via email to

[Prev in Thread] Current Thread [Next in Thread]