1

When I need a function to operate on a region I do, for example:

(defun myfunction (B E)
 (interactive "r")
 (let ((b (make-marker))
       (e (make-marker)))
   (set-marker b B)
   (set-marker e E)

   ;; DO SOMETHING THAT CHANGES THE BUFFER, THEN

   (comment-region b e)))

Is there a simpler way to have B and E as markers?

  • 1
    I seldom really need markers. If I really need a marker then usually only at one end. When I use markers I often do (let ((m (make-marker))) (unwind-protect (progn (set-marker m pos) ...) (set-marker m nil))) to avoid the dangling marker living on until the next garbage-collect. When you don't care about the dangling marker you can do (let ((m (set-marker (make-marker) pos))) ...). One sees that quite often in libraries. In some cases (save-restriction (narrow-to-region b e) ...) is an alternative to markers. – Tobias Feb 11 '18 at 12:01
  • Not caring about a dangling marker seems like a bad habit. – phils Feb 11 '18 at 14:52
  • 2
    I suspect the only way to make this simpler is by making a helper macro (like, with-markers) and reusing it. – wasamasa Feb 11 '18 at 17:59
  • 2
    @GabrieleNicolardi, buffer-has-markers-at can be used to confirm that the marker still exists after the let-bound variable goes out of scope. – phils Feb 11 '18 at 20:19
  • 1
    @GabrieleNicolardi, you need to use (set-marker MARKER nil) while you still have a handle on it (e.g. before the let-binding goes out of scope). That said, I did just confirm that the markers do get garbage-collected in that let-bound scenario (at some later point after they are out of scope); so although it's still best-practice to explicitly set them to nil when you are finished with them, they don't stick around forever. – phils Feb 11 '18 at 21:30
2

In the case given don't see a necessity for a marker:

(defun my-comment-region (start end)
  (interactive "*r")
  (comment-region start end))

A marker is needed, if the start/end positions are going to change during execution and should follow that change:

(defun my-change-of-region (start end)
  (interactive "*r")
  (let ((end (copy-marker end)))
    (delete-region start end)
    ;; start and end should be equal now
    (message "%s" start)
    (message "%s" end)))

As start doesn't change in example above, its marker would be useless. Only the end-marker has effect.

  • It's exactly what I needed. Indeed start/end positions are both going to change during execution (LaTeX typesetting). I didn't know about the "copy-marker" function. – Gabriele Nicolardi Feb 11 '18 at 16:43

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.