Motivation: Why doesn’t
Emacs respond to
C-; and some other keys?
When you are running
Emacs occasionally you will notice that
Emacs does not respond to some keys. This is because the
Desktop enviornment-—if you are a
GNOME user, the
GNOME Desktop—steals those keys before it even reaches
For example, ever since the
embark package started recommending
C-. key binding for
embark-act, there have been reports of
Emacs users binding the
C-. key, only to find that it doesn’t work on
If you are one such user, who has his
C-; and possibly other keys snatched away from your
Emacs, read on …
Where does one find keyboard shortcuts used by the
GNOME Control Center
- You can find the keyboard shortcuts used by the
gnome-control-center. The keybindings used by the
Desktopare listed under
- You can find keyboard shortcuts used by various applications using the
dconf-editor; just search for
keyin the Search box.
To an experienced
Emacs user, both of these options are as good as looking for a needle in the haystack. What these
GUI tools report is piecemeal and you are left with a vague sense of unease.
- You can find the keyboard shortcuts using the
gsettingsshell command. For example, if the stolen key has a
Controlin there, you might try the following.
~$ gsettings list-recursively | grep -i 'Control' org.freedesktop.ibus.general.hotkey trigger ['Control+space', 'Zenkaku_Hankaku', 'Alt+Kanji', 'Alt+grave', 'Hangul', 'Alt+Release+Alt_R'] org.freedesktop.ibus.panel.emoji hotkey ['<Control>period', '<Control>semicolon'] org.freedesktop.ibus.panel.emoji unicode-hotkey ['<Control><Shift>u'] org.gnome.Terminal.Legacy.Keybindings close-tab '<Control><Shift>w' org.gnome.Terminal.Legacy.Keybindings close-window '<Control><Shift>q' org.gnome.Terminal.Legacy.Keybindings copy '<Control><Shift>c' ...
Is there a better way to hunt for the stolen keys which suits the temperament and outlook of an Emacs user?
As you all know, an
Emacs user is in a class of his own.
He doesn’t work with the best tools for a job at hand; instead he starts with a strongly-held belief-—often a mistaken belief-—that
Emacs is the best tool for the job, whatever the job may be; After exploring existing solutions that could be used within
Emacs, if he discovers that there is no such tool, he goes about creating one such tool.
- Copy the following
Emacs Lispsnippet to your
*scratch*buffer, and do
(require 'dash) (require 'rx) (require 'gsettings) (with-current-buffer (generate-new-buffer "*Gsettings*") (pop-to-buffer (current-buffer)) (org-mode) (let ((case-fold-search t)) (save-excursion (->> "list-recursively" gsettings--run gsettings--split-lines (--map (cond ((string-match (rx-to-string '(and (group (one-or-more (not " "))) (one-or-more " ") (group (one-or-more (not " "))) (one-or-more " ") (group (one-or-more any)))) it) (list (match-string 1 it) (match-string 2 it) (match-string 3 it))) (t (user-error "This shouldn't happen")))) (--select (and (let ((parsed (gvariant-parse (nth 2 it)))) (not (and (consp parsed) (eq (car parsed) 'parsec-error)))) (or (string-match-p (rx-to-string '(and "<" (one-or-more any) ">")) (nth 2 it)) (string-match-p (rx-to-string '(and "Keybindings")) (nth 0 it))))) (--map (let* ((bindings (gvariant-parse (nth 2 it)))) (cond ((vectorp bindings) (let ((prefix it)) (--map (append (list it) (butlast prefix)) bindings))) (t (list (append (list bindings) (butlast it))))))) (-flatten-n 1) (--map (cons (format "%s" (car it)) (cdr it))) (--tree-map (format "%s" it)) (--map (format "| %s |\n" (mapconcat #'identity it " | "))) (apply #'insert)))) (org-table-align) (sort-lines nil (point-min) (point-max)) (save-excursion (insert (format "|%s|%s|%s|\n" "Key Binding" "Schema" "Key")) (insert (format "|-\n"))) (org-table-align))
- You will be presented with the following
| Key Binding | Schema | Key | |-------------+----------------------------------------------+-----------------------| | | org.gnome.settings-daemon.plugins.media-keys | help | | 30 | org.gnome.gnome-flashback.keybindings | max-screencast-length | | <Alt>0 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-10 | | <Alt>1 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-1 | | <Alt>2 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-2 | | <Alt>3 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-3 | | <Alt>4 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-4 | | <Alt>5 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-5 | | <Alt>6 | org.gnome.Terminal.Legacy.Keybindings | switch-to-tab-6 | | ... | ... | ... |
M-x occur RET Control RETin the resulting buffer, followed by some eye-balling will help you identify the GNOME component.
For example, if you are looking for the
C-., then the entry of interest is
| <Control>period | org.freedesktop.ibus.panel.emoji | hotkey |
- Once you have identified the thief-—that is, the specific
Gsettingskey-—that needs to be re-configured, you can either use the
GNOME Control Center, the component-specific GUI or the
dconf-editorto re-configure or reset the keys. In the
C-;case , it is the
ibuspanel, which is the thief, and you could reset the keys as reclaim the stolen keys as shown below.
- If you disdain using GUI-—you should be, because you are a pre-historic beast (beest?)-—you can do
$ gsettings set org.freedesktop.ibus.panel.emoji hotkey "@as "
Bonus TIP: How to save and migrate your
GSettings to some other machine
If you are having multiple work machines, then you can use
$ dconf dump / > dconf-settings.in $ dconf load / < dconf-settings.in
$ dconf reset -f /
Emacs user, keyboard keys are a scarce resource; and having someone steal the already scarce set of keys is well-nigh a nightmare. So, it is good to know what to do in case
Emacs doesn’t respond to some keys. The solution outlined here targets
GNOME Desktop users. I will be happy to hear sob stories, and redemption options available for
Mac desktop users.
If you haven’t already noticed, the
Emacs Lisp snippet for probing the
GSettings for keybindings uses some heuristics for locating the keyboard shortcuts. Some heuristics in necessary; this is because the values in a
GSettings database does not have a unique type for values that are keyboard shortcuts; the keyboard shortcuts are just a string or an array of strings. I have a hunch that the heuristic used by
Emacs Lisp snippet could fall short, and fail to report an existing keyboard shortcut. So, be wary before you put full faith in the
Emacs Lisp snippet above to do what it claims to do.