Content AND Presentation

2019-04-21 Easter 2019

This is the night,
when once you led our forebears, Israel’s children,
from slavery in Egypt
and made them pass dry-shod through the Red Sea.

This is the night
that with a pillar of fire
banished the darkness of sin.

This is the night
that even now throughout the world,
sets Christian believers apart from worldly vices
and from the gloom of sin,
leading them to grace
and joining them to his holy ones.

This is the night
when Christ broke the prison-bars of death
and rose victorious from the underworld.

[…]

O truly blessed night,
worthy alone to know the time and hour
when Christ rose from the underworld!

This is the night
of which it is written:
The night shall be as bright as day,
dazzling is the night for me, and full of gladness.

The sanctifying power of this night
dispels wickedness, washes faults away,
restores innocence to the fallen, and joy to mourners,
drives out hatred, fosters concord, and brings down the mighty.

[…]

Therefore, O Lord,
we pray you that this candle,
hallowed to the honour of your name,
may persevere undimmed,
to overcome the darkness of this night.
Receive it as a pleasing fragrance,
and let it mingle with the lights of heaven.
May this flame be found still burning
by the Morning Star:
the one Morning Star who never sets,
Christ your Son,
who, coming back from death’s domain,
has shed his peaceful light on humanity,
and lives and reigns for ever and ever.
Amen.

Continuing the tradition, let me wish all of my readers a Happy Easter!

CategoryEnglish, CategoryBlog, CategoryFaith

Comments on this page

2019-04-15 How to make a menu in Emacs

As we all know, Emacs is so much more than just a text editor. There are quite a few serious applications written on top of it, like Org-mode or mu4e. And many applications – including those two – contain menus (the mu4e main menu or Org-mode’s exporting menu).

Since I am in the (slow) process of writing my own application in Emacs (an in-house tool, so probably of little interest to the general public – but I might be tempted to blog about parts of it one day), I got interested in the problem of coding my own menu.

One of the easiest ways to do that is to display a menu in a temporary buffer and then use read-key or its ilk. This is probably not the best idea most of the time. One of the reasons Emacs is so brilliant is that it (almost) doesn’t have modal dialog windows. So this blocks the user from doing anything else, for instance.

Conisder how Emacs’ own VC works. If you decide to commit something, and even pop up the *vc-log* buffer (the one you type your commit message in), and then change your mind, the manual advises you explicitly not to kill that buffer:
To abort a commit, just type ‘C-c C-c’ in that buffer. You can switch buffers and do other editing. As long as you don’t try to make another commit, the entry you were editing remains in the ‘vc-log’ buffer, and you can go back to that buffer at any time to complete the commit.

The Emacs way has always been to use dedicated buffer with a major mode binding keys from your menu to the actions you want to launch from the menu. (This is how mu4e menu works, for instance.) Of course, there is always the “official” drop-down menu, bound to F10 by default – but I’m less interested in drop-down menus here.

Some Emacs packages deviate from this convention. For instance, Org-mode’s exporting menu is effectively a dialog window. This has all the drawbacks a dialog has, like non-searchability etc., but since I usually spend very little time there, it is rarely a problem. (Many people, however, do not know that you can easily scroll in that window, which is one of the reasons it might benefit from a redesign.)

Interestingly, one of the modern approaches to a menu in Emacs – Oleh Krehel’s hydra – is at first glance very similar to a modal dialog. You fire a hydra, it is displayed at the bottom of the screen, and any key you press is handled by it. And there are lots of hydra users who apparently do like this behavior. What is going on here?

Well, apparently Emacs has an analog of modal dialog windows: key sequences. Even in vanilla Emacs, if you press C-x, anything you press next is catched and interpreted by the C-x prefix keymap. Hydra is just an extension of this mechanism (and not the only one: guide-key and which-key are popular alternatives).

The bottom line of what I have said until now is this: if I wanted to make a menu for my Emacs app, hydra is a light-weight solution, probably wort considering. But what if I want something more traditional? (I might not want an external dependency - hydra is not part of Emacs. I might want clickable items or drop-downs etc. The reasons may vary.)

Well, we then want to have a dedicated buffer with the menu. Displaying the menu is the easy part – it’s basically a bunch of insert calls. The important part (though not much harder) is the association of keybindings with the menu items.

Let’s start with something simple. For the sake of example, let me create a menu which will enable me to save all files, exit Emacs or start another instance of Emacs (this is really a contrived example, but you can easily imagine more useful actions).

(defun emacs-start-menu ()
  "Make Emacs like MS Windows."
  (interactive)
  (switch-to-buffer " *Start Menu*")
  (erase-buffer)
  (insert
   "Emacs Start Menu\n"
   "\n"
   "* [S]ave all files\n"
   "* E[x]it Emacs\n"
   "* Start another [E]macs")
  (start-menu-mode))

Let’s see what happens here. First we switch to a buffer called " *Start-menu*". The convention is to surround the names of “special” buffers (I’m not sure whether this is their “official” name, but I couldn’t find it in the Emacs manual). The space at the beginning signals to Emacs that this is an “ephemeral” buffer – it does not save undo information and does not appear in the buffer list. Of course, you might or might not want to start your menu buffer name with a space, depending on the context. My rule of thumb is to start it with a space if there is some easy way to get to this buffer (like if I bound emacs-start-menu to some global keybinding, for instance). We then erase anything which might have been previously in the buffer – most probably the very same menu we want to enter, but clearing it and inserting again is easier than checking whether the contents are what they should be, and we have no control over what the user did to our buffer in the meantime.

Then we insert a bunch of text (basically, our menu, or whatever makes sense in our case). Last but not least, we start the start-menu-mode, which will make our menu actually work.

So, let’s define this now.

(define-derived-mode start-menu-mode special-mode "Emacs Start Menu"
  "A major mode for a buffer with the Emacs Start Menu.")

(define-key start-menu-mode-map (kbd "S") #'save-some-buffers)
(define-key start-menu-mode-map (kbd "x") #'save-buffers-kill-emacs)
(define-key start-menu-mode-map (kbd "E")
  (lambda ()
    (interactive)
    (start-process "another-emacs" " *another-emacs-buffer*" "emacs")))

What we do here is we define a new mode, derived from special-mode. It is a very, well, special mode, which does two things: first, it makes the buffer read-only (which makes sense in the case of menus), and then, it has some default bindings, like scrolling with SPC and +DEL=, quitting with q and digits (without C- or M-) working as numeric prefix keys. To learn more, say C-h f special-mode RET.

When we have our mode, the rest is very easy – we just add a few keybindings to it. The only thing that is non-trivial here is the lambda expression. I didn’t bother with defining a named command to start another Emacs instance, so I used an anonymous one (not forgetting about the interactive form).

Is that all for today? Yes. Is that all about menus? No. We could add colors, dynamic elements, clickable options and probably lots of other features. However, this will have to wait.

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2019-04-08 Adding an empty file to Git

As a follow-up to the previous post, let me mention another Git trick. I often stage files in chunks (or even line by line), using Magit’s equivalent of git add --patch. It is not obvious, however, what to do if I want to stage some part of a file which is not yet tracked by Git – if I just git add it, it is staged as a whole.

It turns out, however, that there is a way – this is Git, after all. If you say git add -N some-file, Git stages some-file as an empty file, and you can git add --patch parts of it.

You’re welcome. ;-)

CategoryEnglish, CategoryBlog, CategoryGit

Comments on this page

More...

CategoryEnglish, CategoryBlog