Emacs Markers

In a comment to my Emacs comment-box Revisited post, Aaron showed me a nice way to deal with the boundaries of expanding regions. Recall that in that post I wanted to pad the first line of a comment out to the fill column so that comment-box would draw the box across the whole width (more or less) of the window. The problem was that adding those blanks increased the size of the region so the character number of the end of the region was no longer correct. In my code that was easily fixed because I could use (point-max) to locate the end of the region since I had narrowed the buffer to the region.

Aaron’s way of handling this is nice because it feels less ad hoc and because it works for any position in the buffer not just the beginning or end. The idea is to use a marker to point at the end of the region. Conceptually, a marker is just like a position (that is a character index into the buffer) but it has the nice property that if you change the size of the buffer, the marker is adjusted when necessary. It’s as if you planted a flag at the position and the flag moves as the buffer expands or contracts.

Here’s what the revised code looks like

(defun jcs-comment-box (b e)
  "Draw a box comment around the region but arrange for the region
to extend to at least the fill column. Place the point after the
comment box."
  (interactive "r")
  (let ((e (copy-marker e t)))
    (goto-char b)
    (end-of-line)
    (insert-char ?  (- fill-column (current-column)))
    (comment-box b e 1)
    (goto-char e)
    (set-marker e nil)))

As you can see, I’ve replaced the with-region-or-buffer macro with the more sensible (interactive "r"). The copy-marker function will make a copy of an existing marker or if its first argument is a position it will make a marker with that offset. The (optional) second argument says that if text is added at the marker then move the marker ahead. A nil would say the leave the marker where it is. The (set-marker e nil) at the end of the function makes the marker point nowhere. It’s not strictly necessary but it lets Emacs stop worrying about keeping it updated as you further edit the buffer. As you can see, you can treat the marker just you would a position: you can use it as a position, move to it, and even do arithmetic on it.

Chapter 31 of the Emacs Lisp Manual explains markers further. It’s short and interesting so it’s worth a read if you like programming in Emacs Lisp.

This entry was posted in Programming and tagged . Bookmark the permalink.