2.5 Remapped Keys

StumpWM may be configured to translate certain familiar top level keybindings to alternative key sequences that are understood by specific applications. For example, Emacs users are very familiar with C-n and C-p as keybindings for scrolling down and up one line at a time. However, most applications use these specific keybindings for other actions. The stumpwm:define-remapped-keys function may be used to define such application specific remapping of keybindings.

Function: define-remapped-keys specs

Define the keys to be remapped and their mappings. The SPECS argument needs to be of the following structure:

(regexp-or-function . (("key-to-remap" . <new-keycodes>) ...))

EXAMPLE: (define-remapped-keys ’(("Firefox" ("C-n" . "Down") ("C-p" . "Up") ("C-k" . ("C-S-End" "C-x")))))

The above form remaps Ctrl-n to Down arrow, and Ctrl-p to Up arrow keys. The Ctrl-k key is remapped to the sequence of keys Ctrl-Shift-End followed by Ctrl-x.

(define-remapped-keys
    '(("(Firefox|Chrome)"
       ("C-n"   . "Down")
       ("C-p"   . "Up")
       ("C-f"   . "Right")
       ("C-b"   . "Left")
       ("C-v"   . "Next")
       ("M-v"   . "Prior")
       ("M-w"   . "C-c")
       ("C-w"   . "C-x")
       ("C-y"   . "C-v")
       ("M-<"   . "Home")
       ("M->"   . "End")
       ("C-M-b" . "M-Left")
       ("C-M-f" . "M-Right")
       ("M-f"   . "C-Right")
       ("M-b"   . "C-Left")
       ("C-k"   . ("C-S-End" "C-x")))))

The above form adds Emacs like keybindings to windows whose window-class matches “Firefox” or “Chrome”. Additional application specific bindings may be included by using the specific X window-class values.

The window matching pattern can also be specified as a function which returns T if the focused window matches.

;; Match any window with a window-class matching "Firefox"
(define-remapped-keys
    `((,(lambda (win)
          (string-equal "Firefox" (window-class win)))
       ("C-n"   . "Down")
       ("C-p"   . "Up")
       ("C-f"   . "Right")
       ("C-b"   . "Left")
       ("C-v"   . "Next")
       ("M-v"   . "Prior")
       ("M-w"   . "C-c")
       ("C-w"   . "C-x")
       ("C-y"   . "C-v")
       ("M-<"   . "Home")
       ("M->"   . "End")
       ("C-M-b" . "M-Left")
       ("C-M-f" . "M-Right")
       ("M-f"   . "C-Right")
       ("M-b"   . "C-Left")
       ("C-k"   . ("C-S-End" "C-x")))))

2.5.1 Circumventing Remapped Keys

However, if the original key binding needs to be explictly applied the send-raw-key command may be used. It will prompt for a key which will be passed to the application as-is. For example, if the send-raw-key command were bound to C-t C-q as follows:

(define-key *root-map* (kbd "C-q") "send-raw-key")

Then, pressing C-t C-q, while the Firefox window has focus, would prompt asking for “Press a key to send”. Pressing C-n at the prompt will send the keystroke as-is to Firefox, causing it to open a new window.

If more than a single key needs to be passed to the application as-is, the variable *remapped-keys-enabled-p* may be used. Set to nil it will disable all remapped keys.

Command: send-raw-key

Prompts for a key and forwards it to the CURRENT-WINDOW.

Variable: *remapped-keys-enabled-p*

Bool to toggle remapped-keys on/off. Defaults to t