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 '18 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 '18 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...) – Vladimir Panteleev Feb 15 '18 at 1:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.