Skip to content

Commit 2bc0275

Browse files
committed
New article on unsetting unwanted Emacs keybindings
1 parent e60abc9 commit 2bc0275

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#+OPTIONS: toc:nil num:nil
2+
#+STARTUP: showall indent
3+
#+STARTUP: hidestars
4+
#+OPTIONS: ^:{}
5+
#+BEGIN_EXPORT html
6+
---
7+
layout: blogpost
8+
title: "Emacs Quick Tip: Disable key bindings with global-unset-key"
9+
tags: emacs
10+
related_tags_count: 1
11+
---
12+
#+END_EXPORT
13+
14+
Do you also hate some of Emacs' default keybindings? Some of the default key bindings in Emacs don't really feel right for me, so I unset/remove them. Sometimes I override them with new operations. In this short article, I will show you how to yeet (remove) your unwanted keybindings.
15+
16+
* global-unset-key
17+
Emacs have a few global keybindings, like the navigation between open buffer windows (i.e, =C-x o=). Some can be quite useful, such as killing buffers with =C-x k=. Others are just a pain in my view. One example is =C-z=, which suspends Emacs. I have to admit I don't use Emacs as a terminal text editor. The few times I need it, I just use =M-x suspend-emacs=. (Suspending essentially stops the program temporarily, and let's us resume it once we want to). We can easily disable =C-z= with =global-unset-key=:
18+
19+
#+BEGIN_SRC lisp
20+
(global-unset-key (kbd "C-z"))
21+
#+END_SRC
22+
(=kbd= translates the string to an internal Emacs key binding representation)
23+
24+
25+
We can now either set a new operation for this keybinding, or let it do nothing (like I do!).
26+
27+
28+
* Unset keys in specific modes
29+
Sometimes, we may want to unset a keybinding for a specific mode instead. Maybe you want to remove the shift-up and shift-down bindings on org-mode headers? That will be the example going forward in the coming sections.
30+
31+
** Pre Emacs 29 (built-in)
32+
Before Emacs 29, we have the function =local-unset-key= available. The article you are reading does not seem to end here, so what is the issue? If this solution worked, we wouldn't need the alternative solutions presented next, right? =local-unset-key= only takes in the key binding and removes it from the local map that is currently used. That means the mode map you want to remove from have to be active, and you can't just remove it with a single line. It makes for easy usage in a hook though:
33+
34+
#+BEGIN_SRC emacs-lisp
35+
(add-hook 'org-mode-hook (lambda ()
36+
(local-unset-key (kbd "S-<down>"))))
37+
#+END_SRC
38+
39+
** Emacs 29 (built-in)
40+
The previous solution gets the job done, but it gets a bit clunky. We may want something that is more clear on which mode map we are removing from. Emacs 29 to the rescue; =keymap-unset= is available. It takes two arguments: a mode map and a string describing the keybinding.
41+
42+
*NOTE: This function takes in a STRING representation, not an internal key representation like the previous entries. This can cause some confusing if you suddenly try to wrap =kbd= around your keybinding arguments!*
43+
44+
Instead of needing a hook, we now have a more clear way of unsetting it!
45+
46+
#+BEGIN_SRC emacs-lisp
47+
(keymap-unset org-mode-map "S-<up>")
48+
#+END_SRC
49+
50+
*NOTE 2: The Emacs user guide (as well as eldoc) will probably tell you that an extra argument REMOVE exists. This is useful for mode maps that have a parent. Without the argument, the key binding is unset for all parents as well. If we want to use the binding in the parent map, we should use the remove argument. To my understanding it will take both ='remove= and =t=)*
51+
52+
** bind-key package which is also used in use-package (separate package version)
53+
The global variant had only one simple function to do our bidding; The same is obviously not the case for unsetting keys from local mode maps. Now I'm going to show you one more, which brings to mind the following quote:
54+
55+
#+BEGIN_QUOTE
56+
This is getting out of hand! Now, there are two of them!
57+
- Nute Gunray, Star Wars Episode I: The Phantom Menace
58+
#+END_QUOTE
59+
60+
The package bind-key, from use-package (but can be used standalone!), also provides some functionality for unsetting keys in local mode maps! It can unset both global and local bindings:
61+
62+
#+BEGIN_SRC emacs-lisp
63+
;; Unbind in global map
64+
(unbind-key "S-<up>")
65+
66+
;; Unbind in specific mode map
67+
(unbind-key "S-<down>" org-mode-map)
68+
#+END_SRC
69+
70+
(there will probably be one or two readers going full on "achcually!!!" on the use of the word functionality above. NOT saying they are functions. They are macros. The word functionality is used in the broad meaning here.)

0 commit comments

Comments
 (0)