ISSUE: An overlay after-string at the end of a wrapped line is preventing the function previous-line
from moving the cursor directly upwards in a vertical line.
QUESTION: How to modify the following code snippet so that it essentially excludes the overlay after-string, when point is at the end of the line?
(cons (/ (float (car (posn-x-y (posn-at-point)))) (frame-char-width)) (window-hscroll))
DETAILS: I have a custom minor-mode that places an overlay after-string
at the end of the line, which generates a horizontal overlay stretching from the end of the line to the right edge of the window. That overlay after-string
is causing a conflict with line-move-visual
, which is used by previous-line
. When the cursor / point is at the end of the line, the function previous-line
should move the cursor directly upwards in a vertical motion when multiple wrapped lines exist. When the cursor is at the end of the line, it looks like it is a substantial horizontal distance from the right window edge -- however, the overlay after-string
causes the above-mentioned code to return a value for the cursor position at the far right window edge. Consequently, the cursor moves to the visual-end of the preceding wrapped line -- instead of moving directly upwards in a vertical motion aligned with the end of the line.
STEP ONE -- Beginning Position at End of Line:
STEP TWO -- UN-desired Effect:
Desire Effect -- After Step One
In the event that anyone would like to duplicate the overlay after-string
at the end of the line, here is a scaled down example of what is depicted in the screen-shots above. The code works just by pasting it into the *scratch*
buffer and typing M-x eval-buffer RET
(defvar my-eol-ruler nil
"A horizontal ruler stretching from eol (end of line) to the window edge.")
(make-variable-buffer-local 'my-eol-ruler)
(defvar my-eol-pilcrow nil
"A pilcrow symbol placed at the end of every line except the current line.")
(make-variable-buffer-local 'my-eol-pilcrow)
(defsubst col-at-eovl ()
(save-excursion
(let ((movement-indicator (vertical-motion 1)))
(when (= movement-indicator 1)
(backward-char 1)))
(- (current-column) (progn (vertical-motion 0) (current-column)))))
(defun my-eol-ruler-function ()
(let* (
(opoint (point))
(window-width (window-width))
(window-start (window-start))
(window-end (window-end nil t))
(col-eovl (col-at-eovl))
(my-current-line-length (- (- window-width col-eovl) 3))
(pilcrow
(propertize (char-to-string ?\u00B6)
'face '(:foreground "red")
'cursor t))
(pilcrow-underlined
(propertize (char-to-string ?\u00B6)
'face '(:foreground "white" :underline "blue")
'cursor t))
(underline (propertize (char-to-string ?\u2009)
'display `(space :width ,my-current-line-length)
'face '(:underline "blue")
'cursor t)))
(when (or my-eol-ruler my-eol-pilcrow)
(dolist (description `(
,my-eol-ruler
,my-eol-pilcrow ))
(remove-overlays (point-min) (point-max) 'after-string description)) )
(setq my-eol-ruler (concat pilcrow-underlined underline))
(setq my-eol-pilcrow pilcrow)
(save-excursion
(end-of-line)
(overlay-put (make-overlay (point) (point)) 'after-string my-eol-ruler ))
(save-excursion
(goto-char window-end)
(while (re-search-backward "\n" window-start t)
(let* (
(pbol (point-at-bol))
(peol (point))
(col-eovl (col-at-eovl)) )
(when
(or
(< opoint pbol)
(> opoint peol))
(overlay-put (make-overlay peol peol) 'after-string my-eol-pilcrow))))) ))
(add-hook 'post-command-hook 'my-eol-ruler-function)
after-string
property on the overlay. Yes, that's dirty, but there's probably no cleaner solution.