bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#41513: `compute-motion' can miscount buffer positions in the presenc


From: Stephen Bach
Subject: bug#41513: `compute-motion' can miscount buffer positions in the presence of 'before-string/'after-string overlays
Date: Sun, 24 May 2020 14:30:13 -0400

Hi,

Please see the attached demonstration code, runnable with `emacs -Q' and `eval-buffer'.

When `compute-motion' scans along a buffer range that covers an overlay with a 'buffer-string or 'after-string property [*] having as its content a sort-of tricky but not too tricky propertized string (described below), `compute-motion' can/will return an incorrect POS value.

E.g. an overlay with this plist:

  '(before-string #("AAA" 0 3 (display ""))

This overlay is effectively a no-op for redisplay - the "AAA" string that would have been printed at the start of the overlay interval is not printed because its presentation is suppressed by the string's 'display property. This is right and proper.

However, `compute-motion' appears to interpret this overlay as having an effective visible length of -3 rather than 0. Ditto if the overlay had instead had an 'after-string property with the same content. [*] The effective length being negative suggests to me an overcorrection rather than missing logic.

([*] Aside: I believe `compute-motion' sometimes also miscalculates 'display as an overlay property for cases where one might reasonably expect it to work- but I limit this report to 'before-string and 'after-string.)

Popular packages such as flycheck and git-gutter use this pattern of overlay to annotate the margin and the fringe. The pattern is increasingly common which in turn increasingly limits the application of `compute-motion' as a reliable exposed function.

The miscounting appears to exist at least as far back as Emacs 24. Might there be a mitigation/workaround? I like `compute-motion' despite its complicated signature and complicated return value (and despite its apparently rare use in the extended ecosystem) - it's fast and it involves no cursor movement to perform its measurements.

Thanks for reading.


Testcase output:
=======================================

-------------------------------------
Without overlay:
- ‘point’ at col 30: <31>
- buffer content on and after col 30: <30   35   40   45   50>
- posn coord at col 30: <(30 . 0)>
- buffer pos of col 30 according to ‘compute-motion’: <31>     [ok]
- coord of col 30 according to ‘compute-motion’: <(30 . 0)>
-------------------------------------
With ’before-string overlay:
- ‘point’ at col 30: <31>
- buffer content on and after col 30: <30   35   40   45   50>
- posn coord at col 30: <(30 . 0)>
- buffer pos of col 30 according to ‘compute-motion’: <28>     <<< INCONSISTENT
- coord of col 30 according to ‘compute-motion’: <(30 . 0)>
-------------------------------------
With ’after-string overlay:
- ‘point’ at col 30: <31>
- buffer content on and after col 30: <30   35   40   45   50>
- posn coord at col 30: <(30 . 0)>
- buffer pos of col 30 according to ‘compute-motion’: <28>     <<< INCONSISTENT
- coord of col 30 according to ‘compute-motion’: <(30 . 0)>

Attachment: compute-motion-testcase.el
Description: Binary data


reply via email to

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