Существует ли полностью автоматический режим заполнения абзаца для комментариев кода?

18

Я ищу второстепенный режим, чтобы абзацы всегда были заполнены во время набора текста (аналогично тому, что aggressive-indent-modeделает для отступа). Он также должен быть достаточно умным, чтобы заполнять только комментарии (и, возможно, строки в зависимости от языка).

Вот некоторые вещи, которые я пробовал:

  • auto-fill-mode автоматически заполняется при вводе новых абзацев, но не заполняется при редактировании абзацев.

  • refill-mode постоянно пополняет абзацы, но пытается обернуть код в абзацы и комментарии.

  • Я попытался добавить fill-paragraphк after-change-functionsкрючку, но он облажался и многое другое (это, вероятно, все поправимо, но потребует некоторых усилий).

Есть идеи получше?

dshepherd
источник
6
Кроме того: в главе 7 Glickstein Writing GNU Emacs Extensions рассказывается, как реализовать функциональность, к которой вы стремитесь. Может быть отличная возможность учиться / практиковаться с elisp.
Дан
Я ищу автозаполнение абзаца (с включенным автозаполнением) org-mode, но вы можете попробовать rebox2
CodyChan

Ответы:

4

Я придумал минимальный способ реализации этой функциональности: просто связать пробел, чтобы также позвонить (fill-paragraph)!

(defun fill-then-insert-space ()
  (interactive)
  (fill-paragraph)
  (insert " "))
(global-set-key (kbd "SPC") #'fill-then-insert-space)

Есть несколько предостережений, с которыми я столкнулся:

  1. elisp-mode(возможно, другие) выполняет некоторую причудливую кодовую заливку, когда вы звоните fill-paragraph, это может или не может быть тем, что вы хотите. Вероятно, это можно исправить с помощью тестирования, если точка находится в комментарии или строке документации, но я не уверен, как это сделать.

  2. Иногда вы не можете легко ввести несколько пробелов (потому что fill-paragraphубивает любые пробелы). Поскольку пробел теперь работает так, just-one-spaceчто, вероятно, можно заменить эту привязку на (insert " ").

Я сделал вспомогательный режим, содержащий эту функциональность, он доступен на github или в пакете melpa aggressive-fill-paragraph.

dshepherd
источник
Я нахожу ироничным, что aggressive-fill-paragraphон гораздо менее агрессивен, чем refill-modeагрессивен, вплоть до того, что он довольно бесполезен (поскольку вы даже не можете цитировать кого-то > без перестановки в режиме пополнения баланса: даже если вы используете регулярные выражения для замены) .
Привет-ангел
1

Если вам нравится, как ведет себя режим пополнения (а не: p), но не когда он ведет себя, его будет относительно легко исправить, подавив его, когда вы находитесь в неподходящих условиях.

Например

(defvar plop/refill-enabler-function nil)

(defun plop/region-in-comment (beg end)
  ;; should really be comment-only-p, but that seems really broken for me
  (not
   (loop for c from beg to end
      if (not (eq 'font-lock-comment-face (get-char-property c 'face)))
      return t)))

(defun plop/refill-after-change-function (beg end len)
  (unless undo-in-progress
    (when (and plop/refill-enabler-function
               (funcall plop/refill-enabler-function beg end))
      (setq refill-doit end))))

(defun plop/install-refill-hack ()
  (if refill-mode
      (progn
        (add-hook 'after-change-functions 'plop/refill-after-change-function nil t)
        (remove-hook 'after-change-functions 'refill-after-change-function t))
    (progn
      (remove-hook 'after-change-functions 'plop/refill-after-change-function t))))

(defun plop/refill-hook ()
  (set (make-local-variable 'plop/refill-enabler-function)
       #'plop/region-in-comment)
  (add-hook 'refill-mode-hook 'plop/install-refill-hack t t)
  (refill-mode))

(add-hook 'some-hook 'plop/refill-hook)

По сути, она удаляет функцию, которая запускает пополнение, after-change-functionsи заменяет ее на функцию, которая дополнительно проверяет, что мы находимся в комментарии, прежде чем делать то же самое.

Сигма
источник
Выглядит как хорошее начало, но все же не совсем правильно: если при редактировании комментария происходит повторное заполнение, оно заполняет весь абзац, включая окружающий код. Это может быть ошибка окружающего режима в неправильном определении пределов абзаца, но я сомневаюсь в этом: я пробовал в режиме Emacs Lisp, который, как я предполагаю, делает вещи по книге.
Жиль "ТАК - перестань быть злым"
ну, вот почему я сказал, что мне не нравится refill-mode:) Проблема в том, что refill-modeиспользует fill-regionвместо этого fill-paragraph, теряя таким образом способность чтить fill-paragraph-functionи делая вещи потенциально грязными
Sigma