Czy istnieje w pełni automatyczny tryb wypełniania akapitów dla komentarzy do kodu?

18

Szukam mniejszego trybu, aby cały czas wypełniać akapity podczas pisania (podobnie jak w aggressive-indent-modeprzypadku wcięć). Musi być również wystarczająco inteligentny, aby wypełniać tylko komentarze (i być może ciągi znaków w zależności od języka).

Niektóre rzeczy, których próbowałem, to:

  • auto-fill-mode automatycznie wypełnia się podczas pisania nowych akapitów, ale nie wypełnia się podczas edycji akapitów.

  • refill-mode stale uzupełnia akapity, ale próbuje zawinąć kod w akapity oraz komentarze.

  • Próbowałem dodać fill-paragraphdo after-change-functionshaka, ale to psuje cofnięcie i wiele innych rzeczy (to prawdopodobnie wszystko można naprawić, ale wymagałoby to trochę wysiłku).

Jakieś lepsze pomysły?

dshepherd
źródło
6
Poza tym: rozdział 7 pisania GNU Emacsa przez Glicksteina opisuje, w jaki sposób możesz zaimplementować funkcjonalność, której szukasz. Może być świetną okazją do nauki / ćwiczenia z elisp.
Dan
Patrzę na autouzupełnianie akapitu (z włączoną funkcją autouzupełniania) org-mode, ale możesz spróbować rebox2
CodyChan

Odpowiedzi:

4

Wymyśliłem minimalny sposób implementacji tej funkcjonalności: po prostu spacja, aby zadzwonić (fill-paragraph)!

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

Do tej pory natknąłem się na kilka zastrzeżeń:

  1. elisp-mode(ewentualnie inni) wykonują jakiś fantazyjny kod, gdy dzwonisz fill-paragraph, może to być lub nie być to, czego chcesz. Prawdopodobnie można to naprawić, testując, czy punkt jest w komentarzu lub w dokumencie, ale nie jestem pewien, jak to zrobić.

  2. Czasami nie możesz łatwo wprowadzić wielu spacji (ponieważ fill-paragraphzabija wszelkie spacje końcowe). Ponieważ spacja działa teraz tak just-one-space, jakby zastąpienie tego wiązania prawdopodobnie było w porządku (insert " ").

Zrobiłem tryb drobny zawierający tę funkcjonalność, jest on dostępny na github lub w pakiecie melpa aggressive-fill-paragraph.

dshepherd
źródło
Uważam to za ironię, która aggressive-fill-paragraphjest o wiele mniej agresywna niż refill-mode, która jest agresywna aż do całkiem bezużytecznego (ponieważ nie możesz nawet cytować kogoś, kto > nie zmienia trybu ponownego napełniania: nawet jeśli używasz wyrażeń regularnych do wymiany) .
Cześć Angel
1

Jeśli podoba ci się zachowanie trybu napełniania (nie: p), ale nie, gdy się zachowuje, powinno być stosunkowo łatwo to naprawić, blokując go, gdy nie jesteś w odpowiednich warunkach

Na przykład

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

Zasadniczo usuwa funkcję wyzwalającą ponowne napełnianie after-change-functionsi zastępuje ją funkcją, która dodatkowo sprawdzi, czy mamy komentarz, zanim zrobimy dokładnie to samo.

Sigma
źródło
Wygląda na dobry początek, ale nadal nie do końca odpowiedni: jeśli podczas edytowania komentarza zostanie uruchomione uzupełnienie, wypełni cały akapit, w tym otaczający kod. Może to być wina trybu otaczającego, który nie zdefiniował poprawnie limitów akapitu, ale wątpię: próbowałem w trybie Emacsa Lispa, który, jak przypuszczam, robi z książki.
Gilles „SO- przestań być zły”
cóż, dlatego powiedziałem, że nie lubię refill-mode:) Problemem jest to, że refill-modeużywa fill-regionzamiast fill-paragraph, a zatem traci zdolność do honorowania fill-paragraph-functioni czyni rzeczy potencjalnie bałagan
Sigma