As ansi-term doku tells us: any key which is not in use by emacs will be passed down to shell running inside term-mode.

As an example - I have a screen session running inside ansi-term and configured to respond to "C-o" (escape ^Oo in ~/.screenrc).

The "C-o" is not in-use by emacs, at least not in term-raw-map, so I have no trouble controlling my screen inside ansi-term.

On the other hand - <M-(arrow keys)> are in use by emacs and I want to not have those defined in term-raw-map only, otherwise I would like to keep the original mapping, even in term-line-map.

So, my thinking went - Let's undefine the offending key in term-raw-map, so that it could be passed down to whatever is running inside ansi-term.

Hence, the little piece of code, that demonstrates my conundrum.

First, I tried to define-key to nil, then tried to use a built-in local-unset-key, neither of those methods helped.

On the other hand, if I just redefine the keys to anything else, they work as expected.

My knowledge of emacs is currently insufficient to understand how to proceed to get the desired behavior.

;; For expediency I'm using only <M-left> and not all the arrow keys
;; to test - comment out one of the lines:
(defun my-local/term-hook ()
;; This does NOT work:
  (define-key term-raw-map (kbd "<M-left>") nil)
  ;; Neither does this:
  (local-unset-key (kbd "<M-left>"))

  ;; It does work flawlessly if redefined:
  (define-key term-raw-map (kbd "<M-left>") 'left-word))

(add-hook 'term-mode-hook 'my-local/term-hook)

So, to recap the question: How to change the term-raw-map in such a way, that keys already defined in other maps would be undefined in term-raw-map?

For instance, in my particular case, I'm trying to have <M-(arrow keys)> uninterpreted by emacs current active keymap and passed down to shell, as is the case with "C-o".

  • 1
    I think your question could use some clarification. What do you mean by "pass M-left?" If you can define that keybinding as desired, then what are you still missing? Are you perhaps looking for term-send-raw?
    – nispio
    Apr 13 '16 at 16:44
  • I tried to refine my question as best as possible. Hope it helps.
    – voobscout
    Apr 13 '16 at 20:15
  • voobscout: I think this is a duplicate of emacs.stackexchange.com/q/17085 ? Please confirm.
    – phils
    Apr 13 '16 at 23:30
  • FWIW, you seem to be a bit confused about how the keymaps are working. It is not true that "any key which is not in use by emacs will be passed down to [the] shell". term-raw-map is simply set up to explicitly bind most keys to send the appropriate input to the process running in the terminal. The likes of <M-(arrow keys)> are not present in term-raw-map and therefore they are being processed by some lower-priority keymap in Emacs, and consequently nothing is being sent to the terminal. To solve this you must add new bindings to term-raw-map.
    – phils
    Apr 13 '16 at 23:41
  • phils: and nispio: Thank you! I was indeed confused about how keymaps work in emacs and was infact looking for term-send-raw-string! I cannot confirm it to be a duplicate of 17085, although very similar.
    – voobscout
    Apr 14 '16 at 8:46

So, after reading excellent commentary for the original question, I was able to solve my problem in this way:

(defun my-term-hook ()
  (define-key term-raw-map (kbd "<M-left>")
    (lambda () (interactive) (term-send-raw-string "\e[1;3D")))
  (define-key term-raw-map (kbd "<M-right>")
    (lambda () (interactive) (term-send-raw-string "\e[1;3C")))
  (define-key term-raw-map (kbd "<M-up>")
    (lambda () (interactive) (term-send-raw-string "\e[1;3A")))
  (define-key term-raw-map (kbd "<M-down>")
    (lambda () (interactive) (term-send-raw-string "\e[1;3B")))

(add-hook 'term-mode-hook 'my-term-hook)

If someone knows of a better/cleaner way, please let everyone know!

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.