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 ....
    – lawlist
    Jun 14 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.
    – Wibbo
    Jun 14 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 ...
    – lawlist
    Jun 14 at 20:26
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.