Blog

For the English part of the blog, see Content AND Presentation.

2026-01-12 Making fill-paragraph more flexible

I wrote recently about fill-paragraph-semlf and how I moved to it entirely with M-q. It quickly turned out that it wasn’t the best idea. Sometimes I want to be able to fill the paragraph in the old way, too. I figured that the best way to do it is to make M-q do that when pressed for the second time.

Now, there is the unfill package maintained by Steve Purcell, which introduces the unfill-toggle function. Binding it to M-q makes it alternate between filling and “unfilling” the paragraph (that is, turning it to one long line) when pressed more than one time. What I want is something even better – to have three options, semantic filling, unfilling and filling “normally”.

I think the simplest way to to achieve that is to introduce a global variable to keep the last operation performed by M-q in, much like what C-l (recenter-top-bottom) does.

(require 'cl-lib)

(defvar fill-paragraph-state nil
  "The way the paragraph was filled the last time.")

;; From https://github.com/purcell/unfill/blob/master/unfill.el#L39
(defun unfill-paragraph ()
  "Replace newline chars in current paragraph by single spaces.
This command does the inverse of `fill-paragraph'."
  (interactive)
  (let ((fill-column most-positive-fixnum))
    (call-interactively 'fill-paragraph)))

(defun fill-paragraph-rotate ()
  "Fill the current paragraph in one of three ways.
First, it fills the paragraph semantically, then, unfills it, and
finally, fills it in the traditional way."
  (interactive)
  (unless (eq last-command this-command)
    (setq fill-paragraph-state nil))
  (let (deactivate-mark)
    (cl-case fill-paragraph-state
      ('fill-paragraph-semlf
       (call-interactively 'unfill-paragraph)
       (setq fill-paragraph-state 'unfill-paragraph))
      ('unfill-paragraph
       (call-interactively 'fill-paragraph)
       (setq fill-paragraph-state 'fill-paragraph))
      (t
       (call-interactively 'fill-paragraph-semlf)
       (setq fill-paragraph-state 'fill-paragraph-semlf)))))

As you can see, the code is pretty simple. If the last command is not fill-paragraph-rotate, the state of the three-way toggle is reset, and then we perform the fill depending on how it was performed the last time.

One minor problem with this function is that in some modes, semantic filling just doesn’t work. For example, as I mentioned before, AUCTeX sets fill-paragraph-function to LaTeX-fill-paragraph, which apparently overrides fill-region-as-paragraph-function. This means that “traditional” and “semantic” filling does exactly the same thing in AUCTeX buffers. I could utilize fill-paragraph-function instead of fill-region-as-paragraph-function, but I don’t see the point. I don’t write in (La)TeX that often nowadays, and I can live without semantic filling in (La)TeX buffers. On the other hand, if I were still doing a lot of (La)TeX, I would probably do something about it. Semantic filling is especially valuable in LaTeX, where many people may collaborate on a plain text document written (mostly) in a natural language. Thing is, LaTeX-fill-paragraph seems extremely complex, and I don’t really want to invest a lot of time in a feature I would hardly ever need. Instead, I decided to suggest such a feature to AUCTeX developers.

Anyway, that’s it for today. Happy writing in Emacs!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryTeX

Comments on this page

2026-01-05 Magit and new branch length

Like many Emacsers, I am a heavy Magit user. If you use Magit, I don’t need to tell you how great it is; if you don’t, I suggest you do yourself a favor and try it out.

That doesn’t mean that Magit is ideal, though. It has some issues, though usually very minor ones. Today I’d like to write about something which is definitely not a “Magit issue”, but rather something I personally miss in it.

When I start working on a feature, I create a branch for it. Usually this means pressing b c (magit-branch-and-checkout). Magit then asks me for the branch’s name. I like my branches to have short names (not more than 32 characters). When I see that the name I’ve typed seems long, I can press C-x h M-= (that is, mark-whole-buffer and count-words-region) and see how many characters I’ve typed. I’d prefer, however, to be shown that length while I type.

This turned out to be a bit more complex than I thought it would be. First of all, when you make a mistake while working on functions you have put into post-command-hook, you might make your Emacs unresponsive. (This is exactly what happened to me while working on this very feature. From then on, I experimented with this code in a separate Emacs instance.) Second, it is easy to write a function which shows the length of the minibuffer, suitable to include in post-command-hook, but it’s less obvious how to include it there. My first idea was to add an :around advice to magit-read-string to add that function before calling magit-read-string and remove it afterwards – but this didn’t help when I pressed C-g while typing the new branch name and the code after the invocation of magit-read-string was skipped. After some experiments (and a short chat with an LLM, I have to admit) I think I found a working (though not exactly elegant) solution. Emacs has two hooks which can help with minibuffer shenanigans: minibuffer-setup-hook and minibuffer-exit-hook. They are run when entering and exiting the minibuffer, and the crucial part is that minibuffer-exit-hook is run even when the user exits the minibuffer via C-g.

So, what I decided to do was to set up hooks within hooks. First of all, I defined a simple function which echoes the number of characters in the minibuffer, using the minibuffer-contents function. Then, I created two functions, magit-branch-length--minibuffer-setup-length and magit-branch-length--minibuffer-exit-length, which (respectively) adds and removes the previously defined echoing function from post-command-hook. These functions are supposed to be added to the minibuffer hooks I mentioned above. Then I advised the magit-read-string function so that before it’s run, my hook-adding-hooks are added where they should be. In my previous attempt, I used an :around advice combinator so that these hooks would be removed after exiting magit-read-string, but that didn’t work – the removing code was skipped when I pressed C-g while entering the branch name. So, I defined one more function, whose sole purpose is to remove all minibuffer hooks, and put it in the minibuffer-exit-hook, too. (Of course, it also removes itself from that hooks.) That way, all my code gets properly removed from all hooks when I exit the minibuffer (in any way).

And that was quite a mouthful, right? I suspect there is some easier method to achieve my goal, so if you know one, please do let me know. In the meantime, I’m using this code (and I’m quite happy about having it!), and remembering the hook trickery I devised for this feature in case I need it again some day.

(defun minibuffer-show-length ()
  "Show the length of minibuffer contents using `minibuffer-message'."
  (minibuffer-message "%d characters" (length (minibuffer-contents))))

(defun magit-branch-length--magit-read-string-before (&rest args)
  "Setup the minibuffer so that its length will be shown.
Make it so only the next time the minibuffer is used."
  (add-hook 'minibuffer-setup-hook
            #'magit-branch-length--minibuffer-setup-length)
  (add-hook 'minibuffer-exit-hook
            #'magit-branch-length--minibuffer-exit-length)
  (add-hook 'minibuffer-exit-hook
            #'magit-branch-length--remove-minibuffer-hooks))

(defun magit-branch-length--minibuffer-setup-length ()
  "Add `minibuffer-show-length' to `post-command-hook'."
  (add-hook 'post-command-hook #'minibuffer-show-length nil t))

(defun magit-branch-length--minibuffer-exit-length ()
  "Remove `minibuffer-show-length' from `post-command-hook'."
  (remove-hook 'post-command-hook #'minibuffer-show-length))

(defun magit-branch-length--remove-minibuffer-hooks ()
  "Remove functions added to the minibuffer setup and exit hooks."
  (remove-hook 'minibuffer-setup-hook
               #'magit-branch-length--minibuffer-setup-length)
  (remove-hook 'minibuffer-exit-hook
               #'magit-branch-length--minibuffer-exit-length)
  (remove-hook 'minibuffer-exit-hook
               #'magit-branch-length--remove-minibuffer-hooks))

(advice-add 'magit-read-string
            :before
            #'magit-branch-length--magit-read-string-before)

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2025-12-25 Christmas 2025

This time my Christmas wishes to the readers are short but sincere – after some family visits I’m pretty tired. Still, as usual, I will pray a decade of Rosary for all of you. Merry Christmas!

CategoryEnglish, CategoryBlog, CategoryFaith

Comments on this page

More...