The Problem
The problem here is that there’s no face to control the appearance of
the margins. You can display text in the margin using overlays (that’s
what linum-mode
does) but, like any text in Emacs, it’s constrained
to the limits of the buffer. So you can’t have any control over the
margin display beyond the last line of the buffer.
What you can do, is fix those faulty lines in-between.
What to put there
This variable controls what you want to display on those visual lines
“between” two logical lines. The important part is the 'face 'linum
,
which ensures these lines will follow the appearance of linum-mode
.
The "-----"
part is demonstrative, you can change it to spaces or
whatever you wish.
(defvar endless/margin-display
`((margin left-margin) ,(propertize "-----" 'face 'linum))
"String used on the margin.")
How to do it
The following code goes through the buffer and places overlays
(similar to the ones linum-mode
uses) on each line which isn’t
“real”.
(defvar-local endless/margin-overlays nil
"List of overlays in current buffer.")
(defun endless/setup-margin-overlays ()
"Put overlays on each line which is visually wrapped."
(interactive)
(let ((ww (- (window-width)
(if (= 0 (or (cdr fringe-mode) 1)) 1 0)))
ov)
(mapc #'delete-overlay endless/margin-overlays)
(save-excursion
(goto-char (point-min))
(while (null (eobp))
;; On each logical line
(forward-line 1)
(save-excursion
(forward-char -1)
;; Check if it has multiple visual lines.
(while (>= (current-column) ww)
(endles/make-overlay-at (point))
(forward-char (- ww))))))))
(defun endles/make-overlay-at (p)
"Create a margin overlay at position P."
(push (make-overlay p (1+ p)) endless/margin-overlays)
(overlay-put
(car endless/margin-overlays) 'before-string
(propertize " " 'display endless/margin-display)))
And we want to it run whenever linum-mode
updates the line numbers.
(add-hook 'linum-before-numbering-hook #'endless/setup-margin-overlays)