What is the correct way to bind keys only for X frames? E.g. some key combinations are part of terminal escape sequences, but otherwise should be bindable when not running in a terminal.

Currently, I use an after-make-frame-functions hook:

(defun my-setup-nontty-bindings (frame)
  "Set up TTY-incompatible keybinds for FRAME, if it's not a TTY."
    (unless overriding-terminal-local-map
      (setq overriding-terminal-local-map (make-sparse-keymap)))
    (define-key overriding-terminal-local-map (kbd "M-[") 'cs/forward-or-backward-sexp)
    (define-key overriding-terminal-local-map (kbd "M-]") 'er/expand-region)))
(add-hook 'after-make-frame-functions 'my-setup-nontty-bindings)

This almost works, however:

  • A frame is not exactly the same as a terminal, and overriding-terminal-local-map is a per-terminal, not per-frame variable;
  • A non-nil overriding-terminal-local-map breaks international input, which is apparently by design.
  • 1
    Is it not possible to predicate the bindings on (display-graphic-p), e.g. (when (display-graphic-p) (define-key ...) ...)?
    – Basil
    Feb 14, 2018 at 21:48
  • I don't think you want to mess with overriding-terminal-local-map. It doesn't really have anything to do with terminal vs. graphical frames. You should probably just use global-set-key and display-graphic-p like @Basil suggested.
    – jpkotta
    Feb 14, 2018 at 21:59
  • No, that won't work because they are part of an escape sequence. Defining them in the global key map breaks all keys in the terminal whose sequence includes the ESC-[ sequence (i.e. arrow keys, F-keys...) Feb 15, 2018 at 1:37


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.