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).
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.Sign up to join this community
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))