0

The accepted answer of this question provides a way in terminal Emacs to get command(super) key bindings worked as M-*. The solution should work for every terminal.

How to get Command + Control + */Command + Option + */... like key bindings translate to C-M-*/C-S-*/... in terminal Emacs in Kitty on macOS then?

Saddle Point
  • 486
  • 8
  • 24

1 Answers1

0
  1. Start kitty
  2. Do emacs -nw
  3. Copy the snippet to *scratch* buffer and then do M-x eval-buffer
(require 'dash)

(defvar kitty--char-and-shifted-char) (setq kitty--char-and-shifted-char (mapcar (lambda (it) (cons (string-to-char (car it)) (string-to-char (cdr it)))) (append (mapcar (lambda (c) (cons (char-to-string c) (char-to-string (upcase c)))) (number-sequence ?a ?z)) '( ("`" . "~") ("1" . "!") ("2" . "@") ("3" . "#") ("4" . "$") ("5" . "%") ("6" . "^") ("7" . "&") ("8" . "*") ("9" . "(") ("0" . ")") ("-" . "_") ("=" . "+") ("[" . "{") ("]" . "}") ("\" . "|") (";" . ":") ("'" . "&quot;") ("," . "<") ("." . ">") ("/" . "?")))))

(defun kitty--modifiers->value (modifiers) (cl-loop with modifiers->value = '( (shift . 1) (alt . 2) (ctrl . 4) (super . 8) (hyper . 16) (meta . 32) (caps_lock . 64) (num_lock . 128)) for modifier in modifiers summing (alist-get modifier modifiers->value) into n finally return (1+ n)))

(defun kitty-modifiers->emacs-keys (keys) (apply #'concat (cl-loop with alist = `((shift . "S-") (super . "s-") (alt . "M-") (ctrl . "C-")) for x in keys collect (cond ((numberp x) (char-to-string x)) ((stringp x) x) ((symbolp x) (alist-get x alist))))))

(defvar kitty--info) (setq kitty--info (cl-loop for (base-char . shifted-char) in kitty--char-and-shifted-char ;; M-char1 collect (list base-char nil (list (char-to-string base-char))) ;; M-S-char1 collect (list base-char (list 'shift) (list (char-to-string shifted-char)))))

(defun kitty-configure--Command-key (CommandKey) (interactive (list ;; When we press Command' key, what do we want to seeM-' or s-'. ;; ;; SinceOption' key sends M-', it is preferable to chooses-' (let* ((choices '(("super" . super) ("alt" . alt))) (option (completing-read "Treat Command key as " choices nil t))) (assoc-default option choices)))) (cl-loop with format-spec = "%-32s\t%s" ;; When we press Command, Kitty sends a super modifier along with the ;; key with kitty--prefix = 'super with modifier-set = '(ctrl ;; hyper ) initially (let* ((header (format format-spec "What Emacs Sees" "What Kitty Sends"))) (message "When you press `Command' key ....") (message "%s" header) (message "%s" (make-string (length header) ?-))) for new-modifiers in (-powerset modifier-set) do (cl-loop for (base-char modifiers emacs-keys) in kitty--info for what-emacs-should-see = (kitty-modifiers->emacs-keys (cons CommandKey (append new-modifiers emacs-keys))) for what-kitty-sends = (format "M-[ %s ; %s u" (key-description (format "%s" base-char)) (key-description (format "%s" (kitty--modifiers->value (cons kitty--prefix (append new-modifiers modifiers)))))) do (message format-spec what-emacs-should-see what-kitty-sends) (define-key input-decode-map (kbd what-kitty-sends) (kbd what-emacs-should-see)))))

  1. Do M-x kitty-configure--Command-key
  2. You will be prompted for how you want the Command key to behave. Choose super or alt. I suggest you pick super. Since Option key can be configured to send M (or is it ESC?)
  3. You will see following *Messages*. They give an indication of what keys Emacs sees.

When you press ‘Command’ key ....
What Emacs Sees                     What Kitty Sends
-------------------------------------------------
s-C-a                               M-[ 9 7 ; 1 3 u
s-C-A                               M-[ 9 7 ; 1 4 u
s-C-b                               M-[ 9 8 ; 1 3 u
s-C-B                               M-[ 9 8 ; 1 4 u
s-C-c                               M-[ 9 9 ; 1 3 u
s-C-C                               M-[ 9 9 ; 1 4 u
s-C-d                               M-[ 1 0 0 ; 1 3 u
s-C-D                               M-[ 1 0 0 ; 1 4 u
s-C-e                               M-[ 1 0 1 ; 1 3 u
s-C-E                               M-[ 1 0 1 ; 1 4 u
....
s-a                                 M-[ 9 7 ; 9 u
s-A                                 M-[ 9 7 ; 1 0 u
s-b                                 M-[ 9 8 ; 9 u
s-B                                 M-[ 9 8 ; 1 0 u
s-c                                 M-[ 9 9 ; 9 u
s-C                                 M-[ 9 9 ; 1 0 u
s-d                                 M-[ 1 0 0 ; 9 u
s-D                                 M-[ 1 0 0 ; 1 0 u
s-e                                 M-[ 1 0 1 ; 9 u
s-E                                 M-[ 1 0 1 ; 1 0 u
  1. Do C-h k Command+x and see what sees
  2. Do Command+x and see what Emacs sees
  3. Do C-Command+% and see what Emacs sees.
  4. Do M-x kitty-configure--Command-key, and for a change pick alt and repeat the previous steps.

Above snippet doesn't handle any key not seen in *Messages* specifically it does NOT handle Functional key definition and any other .

Setting up of the keys that are NOT configured by this snippet, is left as an exercise to the reader.


FWIW, on Debian/Windows Keyboard,emacs running within kitty doesn't respond to LeftWinKey. (LeftWinKey is usually s- (=super) on GTK Emacs).

So, the snippet shared above not only can be used on Macs to configure the Command key, but also can be used to configure LeftWin on Debian/Windows machines.

I--the author of this snippet--use Debian/Windows laptop btw. This is a a en:us keyboard with qwerty layout.

~$ setxkbmap -print -verbose 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc105
layout:     us,mn,us
variant:    ,,
options:    numpad:microsoft,keypad:pointerkeys,compose:menu,caps:shiftlock
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete+numpad(microsoft)
compat:     complete+ledcaps(shift_lock)
symbols:    pc+us+mn:2+us:3+inet(evdev)+capslock(shiftlock)+compose(menu)+keypad(pointerkeys)
geometry:   pc(pc105)
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete+numpad(microsoft)"    };
    xkb_compat    { include "complete+ledcaps(shift_lock)"  };
    xkb_symbols   { include "pc+us+mn:2+us:3+inet(evdev)+capslock(shiftlock)+compose(menu)+keypad(pointerkeys)" };
    xkb_geometry  { include "pc(pc105)" };
};