PROBLEM: When point is at the end of a visually wrapped line (but not at the very end of the line), the cursor does not respect the cursor t
setting of the overlay after-string
-- i.e., the cursor appears at the beginning of the next visually wrapped line, instead of the very end of the current visually wrapped line.
In this example / question, let us assume that the variable word-wrap
is t
and the variable truncate-lines
is nil
. It does not have to be visual-line-mode
that is active, but it certainly could be. The goal is to extend a horizontal ruler from the end of the visual line to the right window edge, and fix the problem that occurs when point is at the end of the visually wrapped line (but not at the very end of the line).
The following code works in every situation except when the cursor is at the end of the visually wrapped line (but not at the very end of the line). Programmatically, how can the cursor remain visually located at the beginning of the overlay after-string
in this circumstance?
(defun example ()
(interactive)
(let* (
peovl
peovl+1
(col-eovl
(save-excursion
(let ((movement-indicator (vertical-motion 1)))
(when (= movement-indicator 1)
(backward-char 1)))
(setq peovl (point))
(setq peovl+1 (1+ peovl))
(- (current-column) (progn (vertical-motion 0) (current-column)))))
(current-underline-length (- (window-width) col-eovl))
(underline (propertize (char-to-string ?\u2009)
'display `(space :width ,current-underline-length)
'face '(:underline "blue")
'cursor t)))
(remove-overlays)
(unless (= peovl (point-at-eol))
(overlay-put (make-overlay peovl peovl+1) 'display ""))
(overlay-put (make-overlay peovl peovl) 'after-string underline)))
When adding an overlay with an 'after-string
property to a space character (i.e., the number 32 character code) at the last point of a visually wrapped line, the cursor will skip over the overlay entirely. The cursor t
property will be disregarded.
The solution/workaround is to use a 'display
property instead when attempting to achieve the visual effect described by the original poster.
(defun example ()
(interactive)
(remove-overlays)
(let* (
result
peovl
peovl+1
(opoint (point))
(peol (point-at-eol))
(underscore "_")
(col-eovl
(save-excursion
(let ((movement-indicator (vertical-motion 1)))
(when (= movement-indicator 1)
(backward-char 1)))
(setq peovl (point))
(setq peovl+1 (1+ peovl))
(- (current-column) (progn (vertical-motion 0) (current-column)))))
(current-underline-length (- (window-width) col-eovl))
(eol-underline (propertize (char-to-string ?\u2009)
'display `(space :width ,current-underline-length)
'face '(:underline "blue")
'cursor t))
(underscore-concatenated
(progn
(dotimes (i current-underline-length)
(setq result (concat underscore result))) result))
(wrapped-peovl-underline (propertize underscore-concatenated
'face '(:foreground "blue")
'cursor t)) )
(if
(and
(= opoint peovl)
(not (= peovl peol)))
(overlay-put (make-overlay peovl peovl+1) 'display wrapped-peovl-underline)
(unless (= peovl peol)
(overlay-put (make-overlay peovl peovl+1) 'display ""))
(overlay-put (make-overlay peovl peovl) 'after-string eol-underline))))