Showing revision 7

Blog

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

2026-09-21 forward-paragraph in Magit

As I’ve mentioned many times, I am a heavy Magit user. Pretty often I do code reviews from within Magit. There was one thing that has bothered me for a long time.

While I know that Emacs has good support for moving by code units (like forward-sexp and backward-sexp), I am a lazy person and I often use just C-<down> and C-<up> (forward-paragraph and backward-paragraph). Functions I write (or read) are always separated by at least one empty line (and I consider it a bug when they aren’t), and long functions have parts separated by empty lines, too, so this is surprisingly useful. However, it doesn’t work in Magit when I look at diffs, for an obvious reason: most lines in the diff begin with a + or - and so they are considered one giant paragraph.

At first I thought that I could define my own versions of forward-paragraph and backward-paragraph, just for the Magit buffers which can show diffs. But then it occurred to me that I don’t have to – the only thing I have to do is to set the variables paragraph-start and paragraph-separate to suitable values. It’s still not that simple, though. For starters, the default value of paragraph-separate is huge and complicated regex I’d prefer not to analyze. That is easy, though – I can just say

(setq-local paragraph-separate (format "[+-]?\\(?:%s\\)" paragraph-separate))
(setq-local paragraph-start (format "[+-]?\\(?:%s\\)" paragraph-start))

The second problem I had to solve is that I need to so that only in the Magit buffers which can show a diff. Since I use use-package, this is easy:

(defun mbork-set-up-diff-aware-paragraphs ()
  "Make paragraph-moving commands work in a diff."
  (setq-local paragraph-separate (format "[+-]?\\(?:%s\\)" paragraph-separate))
  (setq-local paragraph-start (format "[+-]?\\(?:%s\\)" paragraph-start)))

(use-package magit
  ;; ...
  :hook (magit-mode . mbork-set-up-diff-aware-paragraphs))

And that’s pretty much it! It’s still not ideal – for example, it jumps over @@ lines which start hunks – but things like that are either easy to solve or not worth solving. And from now on, Magit is even more useful to me!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryGit

Comments on this page

2026-09-12 Duplicating lines and other Emacs miscellanea

A few weeks ago I wrote about how I remapped yank to my command which allows to transform the yanked text. The whole setup – where I press C-y twice to trigger the transformation transient – has one drawback: I sometimes legitimately want to call yank twice in a row. This happens when I need to copy the current line and modify the copy so that I have two similar lines in a row. (I often need this when editing Ledger transactions, for example.) What I sometimes do in such a situation is basically a dance of C-a C-1 C-k C-y C-y.

It turns out I don’t need to. There is a duplicate-line command which does exactly what is says on the tin. The only issue is that it is not bound to any key by default. There is, however, one key which is ideally suited for it - C-x C-d. It is normally bound to list-directory, which I find completely useless given that Dired (C-x d) exists.

Before binding duplicate-line to C-x C-d, let’s poke around a bit. This command is almost completely superseded by its cousin duplicate-dwim, which duplicates the current line if the region is inactive and the current region otherwise. Also, there are two options which allow to tweak both commands’ behavior. If you set duplicate-line-final-position to 0 (the default), duplicating the line leaves the point where it was. Setting it to +1 or -1 moves it to the first and last duplicated line, respectively (of course duplicate-line and duplicate-dwim accept a prefix argument!). The duplicate-region-final-position option works in a similar way.

(setq duplicate-line-final-position 1)
(setq duplicate-region-final-position 1)
(bind-key "C-x C-d" #'duplicate-dwim)

That’s not the end of the story, though. While looking around in the file where these commands are defined (lisp/misc.el), I found a few more interesting ones. One of them is copy-from-above-command. I’m not sure how useful it is (and what to bind it to in case I find a use for it), but it’s there if you need it. As its docstring says, it copies characters from the line above, starting above point and until the end of that line. (A prefix argument limits the maximum number of characters copied.) There is zap-up-to-char which works like zap-to-char but does not delete the character it zaps to. There are forward-to-word and backward-to-word, which work very similarly to forward-word and backward-word, but leave the point at the opposite end of the words they move to (so for example forward-to-word moves the point forward until it gets at the beginning of a word). There are a few more, but these I find the most interesting. Maybe I’ll bind them some day – but even if not, they might come in handy with M-x or in Elisp code one day.

That’s it for this time, see you next week!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2026-09-07 Pasting primary selection from keyboard

A few years ago I wrote about a setup I coded for myself for when I want to make paying my bills a tiny bit less painful. One thing I mentioned then was the primary selection. For those of you who don’t know it: under X.org, you can select a portion of text (for example by dragging the mouse over it) and then paste it in the same or another application with clicking the middle button. It is extremely useful for quick copy-and-paste operations where you do not have to issue a separate “copy” command (usually C-c, but often also found on mouse context menu). And by the way, Wayland also supports this.

Sometimes I find it useful to use it even without the mouse. Everybody knows how to select text using keyboard – one common way is by using movement keys with shift, but the Emacs way is to activate the mark with C-SPC and move the point using any of multiple ways Emacs gives us. The question is, however, how to paste the selected text without touching the mouse?

Well, it’s Emacs, so it’s enough to press C-h c and click the middle button to find out. It turns out that the command is mouse-yank-primary. Despite its name, it can be invoked without a mouse, either via M-x or by binding it to some key.

One important thing to mention here is that there is an option called mouse-yank-at-point. If it is nil (the default), the primary selection will be pasted in the place you clicked the mouse. I have it set to t, which means I can click anywhere in the Emacs frame and the primary selection will be pasted at point.

Of course, this is not going to be useful a lot of the time since the usual workflow with the primary selection is to both select and paste the text with the mouse, but if you need to do using your keyboard or from Elisp code, you know now how. (In fact, if you need to use the primary selection in Elisp code, you might want to check out the gui-get-primary-selection function, too.)

That’s it for today, see you next week!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

More...