2

I want to insert an overlay at the beginning of every 40th or so visual/screen, to generate a WYSIWYG looking page-break overlay like so: enter image description here

At the moment this is done by font-locking the line-feed character (with overlays), which works but it edits the text and makes the overlay too concrete. Ideally I would have a minor-mode running which inserts overlays at the start of every nth visual line to prevent this.

While I found how to move x number of screen lines or get x number of screen lines in a certain region, https://www.gnu.org/software/emacs/manual/html_node/elisp/Screen-Lines.html, I have not been able to figure out how get that position so that I can use it in the declaration of the overlay. Maybe this is doable with some complicated compute-motion, but I am not exactly sure how that would work.

Any ideas?

This is a partial copy of Obtain points at beginning/ending of visual line without using vertical-motion, but that question specifically concerns obtaining the beginning/end of the current line, not any line. While I could iterate over the entire file and obtain those coordinates, that is obviously not very feasible.

3
  • I haven't used follow-mode, but perhaps that would be something that you might be interested in -- essentially there are two (2) windows and the divider between those windows could serve as a page break .... Commented Jun 14, 2021 at 15:43
  • I have used follow mode extensively and I like the concept, but it is not quite what I want because a) I want the text of the "page" to be somewhat window-size independent, to make it easier to semantically distinguish content (I find it very hard to keep track of things in large buffers) and b) follow-mode is extremely slow for me. This might be because I use a 4K display and have a lot of font-locking going on, but I do not really want to give either of those up. Commented Jun 14, 2021 at 15:48
  • Another idea might be to have a look at centered-cursor-mode and see what makes it tick. Instead of centering the cursor, you could place your overlays to achieve the desired visual effect. There may already be an adjustment built-in to that minor-mode to select a screen position other than dead center ... Commented Jun 14, 2021 at 20:26

1 Answer 1

1

I've figured it out! You can use save-excursion to get the position of the n-th visual line

(defun get-visual-line-start (n) "Get the character position of the 'nth' visual line, serving as the visual line number." (save-excursion (goto-line 1) (vertical-motion n) ; (end-of-visual-line) ; for the end of the line instead (point))) 

Then do something like

(let ((n 40)) (dotimes (line (round (/ (count-screen-lines) n)) (let* ((line-pos get-visual-line-start (* n (1+ line))) (ov (make-overlay line-pos line-pos))) ;;; do something with the overlay ))) 

Tada

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.