Search code examples
emacselisp

How do I navigate efficiently through emacs buffer modifying lines


I am an elisp (but not programming) beginner and have some questions about the best practice to implement a function. I have written an elisp function that reformats assembler source code according to certain rules; this function currently works for a single line. It basically uses navigation within the line, looking-at and replace-match calls on subexpressions to achieve the goal.

Now I'd like to apply it to a marked region, processing the region line by line. The behaviour will be similar to the indent-region function.

What is the recommended (and efficient) way to implement this? I consider using (line-number-at-pos ...) applied to (region-beginning) and (region-end) to count line numbers and then move from top to bottom, working through the buffer line by line, modifying these.

Also, what would I need to preserve through this operation? I though about (save-match-data ...) and am not sure how to handle mark and point. I guess they will be useless because the text extent changed.


Solution

  • Use save-excursion to save and restore point and mark and save-restriction to narrow to the region.

    The template would be something like this:

    (defun my-process-region (beg end)
      "Apply `my-process-line` to every line in region."
      (interactive "r")
      (save-restriction
        (widen)
        (save-excursion
          (narrow-to-region beg end)
          (goto-char (point-min))
          (while (not (eobp))
            (my-process-line)))))