Pollen publish is a powerful tool for publishing. It can preprocess any file with the racket language, so it gets rid of the ugly “template language” that other publishing tools have while retaining the simplicity.
Pollen preprocessor can proprecess any files ending .p and .pp. For example, pollen will preprocess my-file.css.pp to generate my-file.css file, and template.html for template.html.p. And in these files, you can always prefix symbol ◊ to call racket functions, or pollen tag functions, to preprocess text.
It would be useful to provide editing assistance via a minor mode in these files. To make an emacs minor mode for pollen preprocess files, it means to turn on the minor mode for any files that ends with .p and .pp.
It sounds like the minor mode needs to be global minor mode, but why should the pollen minor mode affect other unrelated buffers? Let’s not abuse global minor mode, and we can do better anyway, though the implementation is not that straightforward in Emacs.
So the challenge of creating an emacs minor mode for pollen preprocessor is to provide additional editing assistance, adding new keybindings for example, to all other emacs modes that preprocess files are original assocaited with.
To recap, let’s see what Emacs provides us for switching modes.
Emacs provides auto-mode-alist for calling a major mode function based on file suffix.
(add-to-list 'auto-mode-alist '("\\.pm$" . pollen-mode))
will turn on pollen-mode if file ends with .pm
- It can fall through the file suffix check if no match is found. That is, if we do nothing on file .pp, openning file my-file.css.pp will match the major mode for css suffix.
It can also fall through the file suffix check if auto-mode-alist has the form
(add-to-list 'auto-mode-alist '("\\.pp$" pollen-mode t))
In this example, pollen-mode will be called, but another major mode will be called after.
- To associate a minor mode with a major mode, emacs provides add-hook function.
During switching major modes, emacs will “tear down” what previous major mode has set up. So it does not work if we call pollen minor mode in pollen major mode and let emacs fall through to the other major mode. How to make it stick?
Emacs manual says little about this. You have to read the lines to get it right, especially if you just get started. Here is an example to show how to do it.
(defun pollen-minor-mode-on ()
(pollen-minor-mode 1))
(put 'pollen-minor-mode-on 'permanent-local-hook t)
(add-hook 'after-change-major-mode-hook 'pollen-minor-mode-on t t)
To see it in a glance,
- Define your own minor mode (read define-minor-mode).
- Add permanent-local-hook symbol property to your function that turns on your minor mode.
- Hook your function to after-change-major-mode-hook, so that the function is called every time major mode get changed.
add-hook is tricky, because the hook will be cleaned if you don’t pass the last argument. To fully understand how it actually works. You need to know symbol properties and buffer local variables before reading Emacs Manual.