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: Stefan Monnier
Subject: Re: Unbalanced change hooks (part 2)
Date: Mon, 29 Aug 2016 21:15:52 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

>  (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.  It seems to be looking for
indirect clues rather than checking directly for the properties on which
the code relies.

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>))

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.

> 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)).


        Stefan




reply via email to

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