Eclipse-like Line Commenting in Emacs

南笙酒味 提交于 2019-12-17 16:10:05

问题


In Eclipse, highlighting multiple rows and pressing Ctrl+/ comments each of the lines of the selection.

Emacs has a function comment-or-uncomment-region that is close what I want, but behaves differently if the region only partially covers the lines I'm trying to comment.

Is there any way I make a function similar to comment-or-uncomment-region, but have it comment each of the lines of the region regardless of how the region is selected?

In other words, I want the function to act as though the region occupies the whole line as long as the region includes that line, so it behaves as Eclipse's selection commenting does.

EDIT: I am actually using the comment-or-uncomment-region-or-line function mentioned as an answer instead of the function comment-or-uncomment-region that comes with Emacs.

I feel as though this is worth mentioning because the former seems to reflect how the line commenting works in Eclipse more. That is, the line the point is on is commented if no region exists.


回答1:


I ended up combining parts from juanleon's and Ehvince's answers to get something just a little more like Eclipse's commenting.

Here is the final product:

(defun comment-eclipse ()
  (interactive)
  (let ((start (line-beginning-position))
        (end (line-end-position)))
    (when (or (not transient-mark-mode) (region-active-p))
      (setq start (save-excursion
                    (goto-char (region-beginning))
                    (beginning-of-line)
                    (point))
            end (save-excursion
                  (goto-char (region-end))
                  (end-of-line)
                  (point))))
    (comment-or-uncomment-region start end)))

Please let me know if anything is wrong with it.




回答2:


Note that emacs 25 has a new function comment-line bound to C-x C-;.




回答3:


Here you have a function that do what you are describing:

(defun comment-or-uncomment-region-eclipse-style (beg end &optional arg)
  (interactive "*r\nP")
  (comment-or-uncomment-region
   (save-excursion
     (goto-char beg)
     (beginning-of-line)
     (point))
   (save-excursion
     (goto-char end)
     (end-of-line)
     (point)) arg))



回答4:


FWIW, I don't use comment-or-uncomment-region. I use comment-region instead. It's similar, but it lets you decide whether to uncomment or comment. It lets you nest comments, instead of automatically uncommenting the region if it is already commented out. With a numeric prefix arg it uses that many comment-start chars (e.g., ;, ;;, ;;;,... in Lisp). With a plain C-u prefix arg it uncomments. I bind it to C-x C-;.

Anyway, I think this does what you want, using comment-region (see that for the general behavior):

(defun comment-region-lines (beg end &optional arg)
  "Like `comment-region', but comment/uncomment whole lines."
  (interactive "*r\nP")
  (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
  (let ((bol  (save-excursion (goto-char beg) (line-beginning-position)))
        (eol  (save-excursion (goto-char end) (line-end-position))))
    (comment-region bol end arg)))

;; Suggested binding
(define-key ctl-x-map [(control ?\;)] 'comment-region-lines)

This saves and restores the region. And it works if only part of a single line is selected. I might even use it myself (which is saying quite a bit, since I have pretty set habits for this kind of thing).




回答5:


Compared to Juanleon's solution, mine adds the fact that if you don't select a region it will (un)comment the current line and go the next line (instead of doing something based on marks you don't see):

  (defun comment-or-uncomment-region-or-line ()
"Comments or uncomments the region or the current line if there's no active region."
(interactive)
(let (beg end)
    (if (region-active-p)
        (setq beg (region-beginning) end (region-end))
        (setq beg (line-beginning-position) end (line-end-position)))
    (comment-or-uncomment-region beg end)
    (next-line)))
;; bind it to F7:
(global-set-key (kbd "<f7>")'comment-or-uncomment-region-or-line)

taken from: Emacs comment/uncomment current line




回答6:


There is a file which provides the following

(defun ar-comment-or-uncomment-lor (&optional copy beg end)
  "Comment line or region, unless it's already commented:
uncomment then.

..." ...

Afterwards cursor is at next line, which permits repeated execution.

With C-u the current line is copied and inserted as comment above - thus reminding the previous state when editing.

Get it here:

https://github.com/andreas-roehler/werkstatt/blob/master/ar-comment-lor.el




回答7:


Here's a slight change to Ehvince's function which only advances to the next line if text was commented out. i.e., if uncommenting text, you usually want the cursor to remain.

(defun comment-or-uncomment-region-or-line ()
  "Comments or uncomments the region or the current line if there's no active region."
  (interactive)
  (let (beg end)
    (if (region-active-p)
        (setq beg (region-beginning) end (region-end))
      (setq beg (line-beginning-position) end (line-end-position)))
    (comment-or-uncomment-region beg end)
    (when (comment-only-p beg end)
        (next-logical-line))))


来源:https://stackoverflow.com/questions/20041904/eclipse-like-line-commenting-in-emacs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!