Emacs: Xah Fly Keys Customization

By Xah Lee. Date: . Last updated: .

This page shows how to customize Emacs: Xah Fly Keys.

Change Mode State Indicator

Emacs: Xah Fly Keys Mode Status Customization

Disable Change to Emacs Control Keybinding

By default, xah-fly-keys removes most of emacs control keybinding, and add a few standard ones like copy cut paste open, etc.

When disabled, no control binding will be changed by xah-fly-keys.

;; must come before loading xah-fly-keys
(setq xah-fly-use-control-key nil)

(require 'xah-fly-keys)

The advantage of removing lots emacs keybinding is that now you have lots key-spots for your own commands.

Disable Changes to Emacs Meta Keybinding

By default, xah-fly-keys disables most of emacs meta keybinding, and add 2 or so.

You can disable this by:

;; must come before loading xah-fly-keys
(setq xah-fly-use-meta-key nil)

(require 'xah-fly-keys)

Add a Global Key to Activate/Toggle Command/Insert Mode

You can add global keys to activate command mode or insert mode, or add a key to toggle.

Normally, i recommend setting CapsLock key position to send Home, and it will activate command mode. But depending on your keyboard, you can add any other key to activate command mode, activate insert mode, or toggle them.

Note that, activate command/insert is something you have to do few times a minute. So, the ease of the key is the utmost important. Also, if you are into mechanical keyboard, that key should have linear light activation force, such as Cherry MX Red switch.

The key choices to “Activate/Toggle Command/Insert Mode” can be anything not used by xah-fly-keys. The Ctrl+letter and Meta+letter spots are mostly empty. You can also use F1 to F24, and PageUp PageDown. Note, it should best be a single key press, not chord, because you'll need to call this command every few seconds.

Add a Global Key to Activate Command Mode

Here's a example of how to add a command mode activation key.

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

(global-set-key (kbd "<f4>") 'xah-fly-command-mode-activate)

Add a Global Key to Activate Insert Mode

Normally, you switch to command mode, then press a key to activate insert mode. But you can add a dedicated key to activate insert mode if you have extra thumb keys on your keyboard. [see Ergonomic Keyboard Reviews]

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

;; make End key to activate insertion mode
(global-set-key (kbd "<end>") 'xah-fly-insert-mode-activate)

Add Global Key to Toggle Command/Insert

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

;; make F4 toggle command/insert mode
(global-set-key (kbd "<f4>") 'xah-fly-mode-toggle)

Add Key to Insert Mode to Activate Command Mode

If you don't want to add a global key such as F4 to activate command mode, because they are too far, and you don't have a batman keyboard with extra thumb keys, but you want to use some easy to reach key such as backslash to activate command mode while you are in insert mode, here's how.

This is useful when you want a single key to switch back to command mode while in insert mode.

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

(define-key xah-fly-insert-map (kbd "\\") 'xah-fly-command-mode-activate)

note: if you set \ to do something while in insert mode, you won't be able to insert a backslash by the key \. To insert a backslash, press Ctrl+q first.

Emacs Keybinding Syntax

This is helpful in finding the emacs syntax for keys:

Emacs Keybinding Syntax

How to Make the CapsLock Key do Home Key

How to Make the CapsLock Key do Home Key

Add Keys to Command Mode Keymap

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

(define-key xah-fly-command-map (kbd "x") 'command-name-x)

Add Keys in Insert Mode Keymap

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

(define-key xah-fly-insert-map (kbd "x") 'command-name-x)

Make Escape Key Do Cancel (C-g)

You can make the Escape key do emacs's Ctrl+g. (for cancel. Usually bound to keyboard-quit )

(define-key key-translation-map (kbd "ESC") (kbd "C-g"))

Note: this will work 99% of time. When it doesn't work, just press Ctrl+g. (the only case i know it doesn't work is when you quit emacs, and emacs says there are unsaved file and if you still want to quit, and pressing Escape to cancel quit doesn't work, but Ctrl+g works.)

Note: for text terminal users, escape key is critical if you do not have Meta key setup. Because Meta+x can be typed by Escape x. So, if you remap Escape, you lose that.

Add a Global Leader Key

You can add a global leader key, so you don't have to switch to command mode first. This is especially useful if you have a foot pedal or extra thumb keys.

(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")

(global-set-key (kbd "<f10>") xah-fly-leader-key-map)

Creating a Whole Keymap to Leader Key

Here's a example of creating a whole keymap.

Let's say you want

and anything after 【leader 8】 would be your personal keys.

Here's the code:

(define-prefix-command 'my-keymap)

(define-key my-keymap (kbd "SPC") 'cmd1)
(define-key my-keymap (kbd "3") 'cmd2)
(define-key my-keymap (kbd "a") 'cmd3)

;; make xah-fly-keys 【leader 8】 as prefix for my-keymap
(define-key xah-fly-leader-key-map (kbd "8") my-keymap)

;; so now,
;; 【leader 8 space】 is cmd1
;; 【leader 8 3】 is cmd2
;; 【leader 8 a】 is cmd3
;; etc

If you want your letters to be translated according to xah-fly-keys-set-layout, then do it this way:

(xah-fly--define-keys
 ;; create a keymap my-keymap
 (define-prefix-command 'my-keymap)
 '(
   ("SPC" . cmd1)
   ("3" . cmd2)
   ("a" . cmd3)
   ;;
   ))

;; make xah-fly-keys 【leader 8】 as prefix for my-keymap
(xah-fly--define-keys
 (define-prefix-command 'xah-fly-leader-key-map)
 '(
   ("8" . my-keymap)
   ;;
   ))

;; all letters are dvorak. They get translated to whatever your xah-fly-keys-set-layout is set to

Add Hook

There are these hooks you can use:

xah-fly-command-mode-activate-hook
Hook variable. Value should be a list of function symbols. When command mode is activated, these functions are called after activation.
xah-fly-insert-mode-activate-hook
Hook variable. Value should be a list of function symbols. When insert mode is activated, these functions are called after activation.

Setup Major Mode Custom Keys

Here's the best way to create leader key set for any major mode, so you don't have to press Ctrl+c.

Get a list of the major mode's commands you want. You do this by first activate the major mode (or open a file that invoke the major mode), then, Alt+x describe-mode. It will list all commands of the mode.

Then, decide a leader key to call them. For example, if leader key is F9, you might have F9 a and F9 b and F9 c.

Find out what's the keymap name in the major mode. (look at its source code), then do as follows. You can do this for org mode, magit mode. Here's a example with go-mode.el.

;; example of adding a leader key map to golang mode
(when (fboundp 'go-mode)

  (defun xah-config-go-mode ()
    "config go-mode. Version 2021-01-15"
    (interactive)
    (progn
      ;; create a keymap
      (define-prefix-command 'xah-golang-leader-map)
      ;; add keys to it
      (define-key xah-golang-leader-map (kbd "c") 'xah-gofmt)
      (define-key xah-golang-leader-map (kbd "j") 'godef-jump)
      ;; add more of the major mode key/command here
      )
    ;; modify the major mode's key map, so that a key becomes your leader key
    (define-key go-mode-map (kbd "<f9>") xah-golang-leader-map)
    ;;
    )

  (add-hook 'go-mode-hook 'xah-config-go-mode))

Make a Key do x Depending on Major Mode

Emacs: Smart Key

Russian Layout Addon

Emacs: Xah Fly Keys for Russian Layout

Start in Command Mode When Emacs Daemon Starts

;; 2021-03-10 this fix the problem of: when emacs start as daemon, xah fly keys is not in command mode. thx to David Wilson (daviwil)

(defun my/server-fix-up()
  "Make sure 'xah-fly-keys' is starting in command-mode.

https://github.com/xahlee/xah-fly-keys/issues/103
https://github.com/daviwil/emacs-from-scratch/blob/master/show-notes/Emacs-Tips-08.org#configuring-the-ui-for-new-frames"
  (xah-fly-keys-set-layout "dvorak")
  (xah-fly-keys t))

(if (daemonp)
    (add-hook 'server-after-make-frame-hook 'my/server-fix-up))

Where to Add Personal Keys?

You can bind keys to any of the spots for personal commands.

You can create a whole leader key map sequence for all your personal keys. For example, start with

xtodo WORK IN PROGRESS. the following are originally written by Will Dey in 2020-04 when he did a major rewrite of xah-fly-keys key engine. It is in the process of editing and merged on this page.

Remapping

A very effective way to change what the command-mode keys do based on the major/minor mode is Remapping Commands. for example:

(define-key my-mode-map [remap command_name_1] 'command_name_2)

(info "(elisp) Remapping Commands")

Command remapping will work no matter which keyboard layout you choose to use, and allows you to make the customizations in the major/minor mode’s map rather than the global xah-fly-command-map. Emacs automatically looks up remappings after finding the command bound to a key. Xah Fly Keys defines no command remappings, so they will always be looked up in the normal major and minor mode maps.

To add a remapping, find the command that Xah Fly Keys binds to a key in command mode (e.g. through describe-key), then add a binding in the major/minor mode's map like this:

(define-key major-or-minor-mode-map [remap xah-fly-command-name] 'mode-specific-command-name)

For example, to make the “i j k l” keys scroll a PDF Tools page while in command mode:

(with-eval-after-load 'pdf-view
  (define-key pdf-view-mode-map [remap next-line] 'pdf-view-next-line-or-next-page)
  (define-key pdf-view-mode-map [remap previous-line] 'pdf-view-previous-line-or-previous-page))

Final Words

I recommend that you do not change much keys in xah-fly-keys. Just stick to it. Because, one thing about creating a keybinding system is that there's a lot habit to overcome. I've been changing keys every month for over 10 years. Each time, it's extremely painful, and with strong desire to go back. And, once you start to explore keys, you often become biased towards your CURRENT workflow or work. So, you get into a situation that you change every few months, when project changes, or your choice of major mode changes, and in particular, when your keyboard changes. Also, if you don't have a year or two dedicated study about keybinding system, you create a key system that you think must be logically flawless, but actually just to your habit, your hands, your current keyboard, and your workflow, not to someone else.

xah-fly-keys's keybinding choices is not scientifically the best, because that is basically an illusive concept, but is near optimal.

If you are interested in keybinding efficiency research, be sure to read:

back to Emacs: Xah Fly Keys

Xah Fly Keys