Eclipse-подобное комментирование строк в Emacs

В Eclipse выделение нескольких строк и нажатие Ctrl+/ комментирует каждую из строк выделения.

Emacs имеет функцию comment-or-uncomment-region это близко к тому, что я хочу, но ведет себя по-другому, если регион только частично покрывает строки, которые я пытаюсь комментировать.

Есть ли способ сделать функцию, аналогичную comment-or-uncomment-region, но прокомментирует ли он каждую из строк региона независимо от того, как выбран регион?

Другими словами, я хочу, чтобы функция действовала так, как если бы область занимала всю строку, пока область включает в себя эту строку, поэтому она ведет себя так же, как комментирование выбора Eclipse.

РЕДАКТИРОВАТЬ: я на самом деле использую comment-or-uncomment-region-or-line функция упоминается как ответ вместо функции comment-or-uncomment-region это идет с Emacs.

Я чувствую, что это стоит упомянуть, потому что первое, кажется, отражает, как комментирование строк работает в Eclipse больше. То есть строка, на которой находится точка, комментируется, если не существует региона.

7 ответов

Решение

Я закончил тем, что соединил части из ответов Джуанлеона и Эвинса, чтобы получить что-то более похожее на комментарии "Затмения".

Вот конечный продукт:

(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)))

Пожалуйста, дайте мне знать, если что-то не так с этим.

Обратите внимание, что в emacs 25 появилась новая функция comment-line связан с C-x C-;,

FWIW, я не использую comment-or-uncomment-region, я использую comment-region вместо. Это похоже, но это позволяет вам решить, раскомментировать или комментировать. Это позволяет вам вкладывать комментарии, вместо того, чтобы автоматически раскомментировать регион, если он уже закомментирован. С числовым префиксом arg он использует столько начальных символов комментария (например, ;, ;;, ;;;... в Лиспе). С равниной C-u префикс аргументируется. Я связываю это с C-x C-;,

Во всяком случае, я думаю, что это делает то, что вы хотите, используя comment-region (см. это для общего поведения):

(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)

Это сохраняет и восстанавливает регион. И это работает, если выбрана только часть одной строки. Я мог бы даже использовать это сам (что говорит довольно много, так как у меня есть довольно определенные привычки для такого рода вещей).

Здесь у вас есть функция, которая делает то, что вы описываете:

(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))

По сравнению с решением Хуанлеона мой добавляет тот факт, что если вы не выберете регион, он (не) закомментирует текущую строку и перейдет к следующей (вместо того, чтобы делать что-то на основе отметок, которых вы не видите):

  (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)

взято из: Emacs комментарий / раскомментировать текущую строку

Существует файл, который обеспечивает следующее

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

... "...

После этого курсор находится на следующей строке, что разрешает повторное выполнение.

С Cu текущая строка копируется и вставляется как комментарий выше - таким образом, напоминая предыдущее состояние при редактировании.

Получи это здесь:

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

Вот небольшое изменение в функции Эхвинса, которая переходит на следующую строку, только если текст был закомментирован. то есть, если раскомментировать текст, вы обычно хотите, чтобы курсор оставался.

(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))))
Другие вопросы по тегам