I recently saw this image on r/unixporn.
How can I recreate the 'notebook' effect: the broad line-height and underline of each line, but in Emacs (iiuc this is achieved using rxvt + pixmaps in Linux).
I recently saw this image on r/unixporn.
How can I recreate the 'notebook' effect: the broad line-height and underline of each line, but in Emacs (iiuc this is achieved using rxvt + pixmaps in Linux).
Edit: I've added some Elisp code at the end of the answer that performs all of the changes mentioned and then evaluates the buffer it is run in.
One way to get this effect is by making some simple modifications to Steve Purcell's page-break-lines.el
. (To future-proof this answer as much as possible, I am referring specifically to this version of the file from a March 4th 2020 commit). I can't post the code for this mode here since it is GPLv3. Fortunately, the changes necessary to get what you want are easy to make.
Note: before going any further, I highly recommend changing the names of all of these variables and functions so as they do not clash with those of the real page-break-lines
. My recommendation is to use the prefix my-ruled-lines
. This can be done by running (replace-string "page-break" "my-ruled")
. Note that this and all other replace-string
function calls in this answer should be run with the point at the top of the buffer containing the code. You should also change the minor-mode lighter too ((replace-string "PgLn" "Ruled")
).
This package causes Emacs to display a customizable character repeated enough times to fit the width of the window every time it sees a form-feed character (e.g. by using a line of dashes). The only changes we need to make are to:
Accomplishing the first part is very easy, and can be done by running the function (replace-string "^L" "^J")
. However, just making this change will make it so that Emacs doesn't display any newlines at all, which is not what we want.
Fortunately, all we have to do is to wrap our replacement characters with a newline on either side. This will put the put the replacement character line on a newline (but won't affect the line-numbering) and will put all future characters on the line after that. This can be done by modifying the following line in the function page-break-lines--update-display-table
(which should now be renamed to something like my-ruled-lines--update-display-table
). Note that this is line number 143 in Github's line numbering, but Emacs seems to eat an empty line when I paste it in:
(new-display-entry (vconcat (make-list width glyph))))
which should be changed to:
(new-display-entry (vconcat (list ?\^J) (make-list width glyph) (list ?\^J))))
Now you need to evaluate all of these functions (or save them to a .el
file and load them). Now run the command M-x my-ruled-lines-mode
(or whatever that command has been renamed to) in your desired buffer and it should work.
After you've done all of this you may want to tweak the face my-ruled-lines
to get your ruled lines to appear more to your liking.
One caveat: it appears these changes break the ability of this minor mode to remove the display changes from the buffer-display-table. You can use the following function to turn off the ruled lines if disabling the minor mode alone does not work:
(defun turn-off-my-ruled-lines-mode ()
(interactive)
(my-ruled-lines-mode -1)
(aset buffer-display-table ?\^J nil))
Script to make these changes
Since there are several individual steps to follow here, I've packaged all of the steps into a single Elisp function call. The code from page-break-lines.el
should be pasted into a buffer then this code should be evaluated (i.e. by using M-:
). This will make the changes and then define the minor mode.
(save-excursion
(goto-char (point-min))
(replace-string "page-break" "my-ruled")
(goto-char (point-min))
(replace-string "PgLn" "Ruled")
(goto-char (point-min))
(replace-string "^L" "^J")
(goto-char (point-min))
(replace-string "(new-display-entry (vconcat (make-list width glyph))))"
"(new-display-entry (vconcat (list ?\\^J) (make-list width glyph) (list ?\\^J))))")
(goto-char (point-max))
(newline)
(insert "(defun turn-off-my-ruled-lines-mode ()\n (interactive)\n (my-ruled-lines-mode -1)\n (aset buffer-display-table ?\\^J nil))")
(eval-buffer))
Here is what the results look like when run on default Emacs 26.3:
line-spacing
is set to 0
and doesn't seem to take negative values, so I looked at the default-height
parameter inside my-ruled-lines--update-display-table
but wasn't able to do anything meaningful with this
– Antony Woods
Jul 07 '20 at 08:38
C-h f beginning-of-buffer
: "This function is for interactive use only;
in Lisp code use `(goto-char (point-min))' instead."
– Drew
Jul 07 '20 at 15:11
end-of-buffer
).
– D. Gillis
Jul 07 '20 at 15:25
my-ruled-lines
face changes the size of the glyph's component characters, but not the spacing between lines. There may be a way around this though.
– D. Gillis
Jul 07 '20 at 17:07