2

I bind M-o to next-word, and want to use M-O to shift-select next word. M-O works well on Emacs GUI app on Mac, but not on Emacs in a terminal.

The reason is: In the terminal, up-arrow is encoded as M-O A (similar for other arrow keys), so M-O becomes a prefix key.

A solution is to use timeout, which was implemented by ergoemacs. However, I don't use ergoemacs keymap, so I don't wanna install it yet. Is there any other (smaller) package/function implemented the timeout solution?

  • Why just not use the default next-word (actually forward-word) keybinding defined to M-f? Are you talking about a different thing? – Manoel Vilela Nov 9 '17 at 9:03
  • Similar to ergoemacs, I re-map almost all shortcuts in my Emacs, e.g., my M-f is forward-char. – AhLeung Nov 9 '17 at 10:17
1

Codes adapted from https://gist.github.com/Pitometsu/f2f68d5e81862ceffb0d76d277376cf1

(defun my-tty-init-esc (frame)
  "Update `input-decode-map' in terminal with FRAME."
  (with-selected-frame frame
    (let ((term (frame-terminal frame)))
      (when (not (terminal-parameter term 'my-tty-esc-map))
        (let ((my-tty-esc-map (lookup-key input-decode-map [?\e])))
          (set-terminal-parameter term 'my-tty-esc-map my-tty-esc-map)
          (define-key input-decode-map [?\e]
            `(menu-item "" ,my-tty-esc-map :filter ,#'my-tty-esc))))
      (when (not (terminal-parameter term 'my-tty-M-O-map))
        (let ((my-tty-M-O-map (lookup-key input-decode-map "\eO")))  ; [?\eO] is not valid
          (set-terminal-parameter term 'my-tty-M-O-map my-tty-M-O-map)
          (define-key input-decode-map "\eO"
            `(menu-item "" ,my-tty-M-O-map :filter ,#'my-tty-M-O)))))))
(defun my-tty-esc (map)
  (if (and
       (let ((keys (this-single-command-keys)))
         (and (> (length keys) 0)
              (= (aref keys (1- (length keys))) ?\e)))
       (sit-for my-tty-prefix-timeout))
      (prog1 [escape]
        (when defining-kbd-macro
          (end-kbd-macro)
          (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
          (start-kbd-macro t t)))
    map))
(defun my-tty-M-O (map)
  (if (and
       (let ((keys (this-single-command-keys)))
         (> (length keys) 0))
       (sit-for my-tty-prefix-timeout))
      (progn
        (setq this-command-keys-shift-translated t)
        (handle-shift-selection)
        (next-word)
        )
    map))
(setq my-tty-prefix-timeout 0.01)
(add-hook 'after-make-frame-functions #'my-tty-init-esc)
(mapc #'my-tty-init-esc (frame-list))
)

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.