0

I am using doom emacs on Mac OS. I would like to have an avy comment region and line command, where just as with for example avy-kill-region the region is selected. I've come up with the following function

(defun my-avy-comment-region ()
  (interactive)
  (save-excursion
     
    (let* ((eol (pos-eol))
           (beg (avy--line))
           (end (avy--line)))
(evilnc-comment-operator beg end )
      )))

which does exactly what I want except the endline seems to be one line off from the selected. How can I modify the code, so I am selecting the right line with avy--line for the end? Analogously I would like to implement my-avy-comment-line function where I struggle to parse the end of the line, so this would also be nice to full functionability.

1 Answer 1

1

You should prefer using Emacs native functions over evil functions, if possible.

Additionally, as you've mentioned, there is already avy-kill-region. I would reuse it with as little modification as possible. So you can just replace the cond clauses with the 'kill functions', with comment-region.

avy--line gives you the start position of the line, and it seems like comment-region and apparently also (evilnc-comment-operator beg end) don't include that line when commenting. So, then just try to take the start position of the next line. In summary, the following code (adapted from avi-kill-region, please diff the two functions to see the differences) should achieve what you want:

(defun avy-comment-region (arg)
  "Comment the region starting end ending with selected lines.

The window scope is determined by `avy-all-windows' or
`avy-all-windows-alt' when ARG is non-nil."
  (interactive "P")
  (let ((initial-window (selected-window)))
    (avy-with avy-kill-region
      (let* ((beg (save-selected-window
                    (list (avy--line arg) (selected-window))))
             (end (list
                   (save-excursion
                     (goto-char (avy--line arg))
                     (forward-line)
                     (point))
                     (selected-window))))
        (cond
          ((not (numberp (car beg)))
           (user-error "Fail to select the beginning of region"))
          ((not (numberp (car end)))
           (user-error "Fail to select the end of region"))
          ;; Restrict operation to same window. It's better if it can be
          ;; different windows but same buffer; however, then the cloned
          ;; buffers with different narrowed regions might cause problem.
          ((not (equal (cdr beg) (cdr end)))
           (user-error "Selected points are not in the same window"))
          (t
           (save-excursion
             (comment-region (car beg) (car end)))))))
    (select-window initial-window)))

Of course, instead of finding the next line, you could just remember to select the line after the region you'd like to comment (and keep the avi-kill-region functionality/definition that it acts on the region 'between the selected lines).

3
  • Why are emacs native functions preferable? Do they execute faster, or what are the main arguments? Could you also provide what should be different for avy-comment-line? I would accept the answer.
    – Rareform
    Commented Dec 20, 2023 at 13:50
  • Good question. Indeed, preferring Emacs functions is a personal rule, it makes code more portable, and you can generally be sure that the Emacs functions are well designed. If you find a problem with a function, you can report a bug directly to Emacs, instead of to some external package. But, for personal use, you can use any function that does the job (but obviously, personally, I prefer to follow my personal rule). Commented Dec 21, 2023 at 11:08
  • To modify the code to avy-comment-line you simply replace the (avy--line arg) in end with (cdr beg) (try to understand why this change works ;). Commented Dec 21, 2023 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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