19

I'm looking for a minor mode to keep paragraphs filled at all times while typing (similar to what aggressive-indent-mode does for indentation). It also needs to be smart enough to only fill comments (and maybe strings depending on the language).

Some things that I've tried are:

  • auto-fill-mode automatically fills while you are typing new paragraphs but doesn't refill when you edit paragraphs.

  • refill-mode does constantly refill paragraphs but it tries to wrap code into paragraphs as well as comments.

  • I tried adding fill-paragraph to the after-change-functions hook but it screws up undo and plenty of other things (this is probably all fixable but would take some effort).

Any better ideas?

2
  • 6
    Aside: chapter 7 of Glickstein's Writing GNU Emacs Extensions walks through how you might implement the functionality you're after. Might be a great opportunity to learn/practice with elisp.
    – Dan
    Commented Nov 20, 2014 at 12:41
  • I'm looking the auto-fill-paragraph(with auto-fill enabled) in org-mode, but you may try rebox2
    – CodyChan
    Commented Jan 8, 2015 at 13:19

2 Answers 2

4

I came up with a minimal way of implementing this functionality: just bind space bar to also call (fill-paragraph)!

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

There are a couple of caveat's that I've stumbled across so far:

  1. elisp-mode (possibly others) does some fancy code filling when you call fill-paragraph, this may or may not be what you want. Can probably be fixed with by testing if point is in a comment or docstring but I'm not sure how to do that.

  2. You sometimes can't easily enter multiple spaces (because the fill-paragraph kills any trailing spaces). Since the space-bar now acts like just-one-space it's probably ok to replace that binding with (insert " ").

I made a minor-mode containing this functionality, it's available on github or in the melpa package aggressive-fill-paragraph.

1
  • 1
    I find it ironic that aggressive-fill-paragraph is far less aggressive than refill-mode, which is aggressive up to being pretty useless (as you can't even quote someone with > without refill-mode rearranging stuff: even if you use regexps for replacement).
    – Hi-Angel
    Commented Jul 27, 2019 at 19:53
1
+50

If you like how refill-mode behaves (I don't :p) but not when it behaves, it should be relatively easy to fix by inhibiting it whenever you're not in the right conditions

For example

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

Basically it removes the function that triggers the refill from after-change-functions and replaces it with one that will in addition check that we're in a comment before doing exactly the same thing.

2
  • Looks like a good start, but still not quite right: if a refill is triggered while editing a comment, it refills the whole paragraph, including the surrounding code. This may be the fault of the surrounding mode for not defining paragraph limits properly, but I doubt it: I tried in Emacs Lisp mode, which I presume does things by the book. Commented Jan 1, 2015 at 0:20
  • well, that's why I said I don't like refill-mode :) The problem is that refill-mode uses fill-region instead of fill-paragraph, thus losing the ability to honor fill-paragraph-function and making things potentially messy
    – Sigma
    Commented Jan 1, 2015 at 2:31

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.