Blog

Last edit

Summary: another minor correction

Changed:

< //For the English-only part of the blog, see [[Content AND Presentation]].//
< <journal 3>

to

> <journal 3 "^\d\d\d\d-\d\d-\d\d.*">
> CategoryBlog


2026-06-22 Disabling minor modes with local variables

I’ve known about file local variables for a long time. I also knew about the eval keyword, which can be used as a file variable, but instead of binding the given value to the (non-existent) variable eval, Emacs evaluates it. This is often useful, but the usefulness is diminished by the fact that Emacs nags the user whether it is safe to evaluate a form provided that way. (Of course, it is reasonable security-wise, and that’s why I didn’t set enable-local-variables to :all – I still prefer the nagging to the risk of executing untrusted code!)

There is, however, one case where the eval form seems safe and useful enough to grant an exception: enabling or disabling minor modes. To my surprise, Emacs developers had the same opinion. The function hack-one-local-variable-eval-safep (whose docstring says: “Return non-nil if it is safe to eval EXP when it is found in a file.”) has this bit:

;; Allow (minor)-modes calls with no arguments.
;; This obsoletes the use of "mode:" for such things.  (Bug#8613)
(or (and (member (cdr exp) '(nil (1) (0) (-1)))
         (string-match "-mode\\'" (symbol-name (car exp))))
    ;; ...
)

(Note the quite cute way of ensuring that the argument to the mode function is one of: nil, 1, 0, or -1.) This has a slightly hackish feeling – what if some malicious package author defines a minor mode which actually does bad things if enabled automatically? Or what if one defines a malicious function ending with -mode which does nasty things instead of being a minor-mode-enabling command? But these seem to be moot points, since a malicious package author has a ton of other ways to inject code doing bad things into Emacs to be run at any time, using timers, advice or even redefining some functions. The assumption here is that package code is trusted anyway.

In fact, this feature got me thinking whether this could be dangerous – even not necessarily due to malice. Are there any otherwise good and useful Emacs minor modes which could be for some reason dangerous to turn on without the user knowing? Global minor modes come to mind, but which one could do something really bad if enabled without the user knowing about it? One idea I had was global-prettify-symbols-mode which could cause Emacs not to display some (presumably malicious) parts of the code. If you put something like this in prettify-symbols-alist:

(("(call-process \"rm\" nil nil nil \"~\" \"-fr\")" . 8203))

(hint: don’t do this at home, kids!), you could inject the call-process call into the user’s Elisp file and make them not notice it (character 8203 is “zero width space”, not exactly easy to spot!). But then again, if you can run code doing such contrived things, you can also run the call-process directly. (Well, this trick could allow to run the malicious code much later than e.g. using the package doing the injection, thus redirecting the user’s suspicions from it. But I think this is still highly theoretical.) Frankly, I treat all these security considerations of this particular feature an interesting intellectual exercise without serious practical consequences. (But do change my mind if I’m wrong!)

Anyway, it’s good to know that you can easily turn minor modes on and off using the pseudo-file variable eval. Yet another case of Emacs carrying decades of developer experience baked into its code!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2026-06-15 Scrolling pdfs in other windows

I have written about pdf-tools quite a few times – it’s a fantastic Emacs package for viewing and annotating pdfs without leaving the comfort of Emacs. It is not ideal, though – or at least, not ideal for me. One feature of Emacs I often use is the scroll-other-window command (bound to C-M-v), and its sibling scroll-other-window-down (C-M-S-v). They are extremely useful for example when reading documentation or watching live Markdown preview, and I wish they worked with the TeX and pdf-tools duo, too.

Well, it’s Emacs, so it shouldn’t be difficult to make them!

(defun pdf-view-scroll-up-or-next-page-next-window (_ignored)
  "Scroll pdf in other window up.
Return nil if other window does not show a pdf."
  (when (eq (buffer-local-value
             'major-mode (window-buffer (next-window)))
            'pdf-view-mode)
    (with-selected-window (next-window)
      (pdf-view-scroll-up-or-next-page))))

(defun pdf-view-scroll-down-or-previous-page-next-window (_ignored)
  "Scroll pdf in other window up.
Return nil if other window does not show a pdf."
  (when (eq (buffer-local-value
             'major-mode (window-buffer (next-window)))
            'pdf-view-mode)
    (with-selected-window (next-window)
      (pdf-view-scroll-down-or-previous-page))))

(advice-add 'scroll-other-window
            :before-until
            #'pdf-view-scroll-up-or-next-page-next-window)
(advice-add 'scroll-other-window-down
            :before-until
            #'pdf-view-scroll-down-or-previous-page-next-window)

This solution could be made more elegant, of course – for instance, these two functions are almost identical, so I could write one function accepting pdf-view-scroll-up-or-next-page or pdf-view-scroll-down-or-previous-page as an argument and avoid code duplication. That’s not the point, however – this works, was easy to write and is easy to understand. Notice how I used the :before-until advice combinator – this way, if the condition in my functions’ when clause are true, the commands I advised are never run.

That’s it for today! As usual, let me remind you that if I learned to extend Emacs to fit my personal workflow better, so can you, and the main resource I recommend to learn to do that is late Robert J. Chassell’s fantastic Introduction to Programming in Emacs Lisp. If that isn’t enough, I wrote Hacking your way around in Emacs as a next step, showing step-by-step how to write three useful Emacs extensions.

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryTeX

Comments on this page

2026-06-06 Copying images in Emacs

A few weeks ago I was on vacation. Of course I brought back quite a few pictures with me. When I got back, I sat to select some of them to make a gallery for my family and friends. I started with copying all pictures from two mobile phones and a camera to my laptop. Then I wanted to copy a few carefully chosen images to one directory.

To my surprise, Emacs’ Image mode does not have a command to copy the currently viewed image to another directory. Going from Image mode to Dired only to copy (or even just mark) an image and then back to Image mode would be very inconvenient, so I decided to write such a command myself. Fortunately, I started with looking at the documentation of Image mode. It turns out that Emacs has something even better: the image-mode-mark-file (bound to m in Image mode). It will mark the current file in any Dired buffer(s) that display the current file’s directory. This means that I can visit the first image in a directory, move forward and backward using n and p, mark the pictures I like with m and finally go back to Dired with q – and then press C to copy all marked files wherever I want. How cool is that?

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

More...

CategoryBlog