Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding M-<up> / M-<down> in Emacs 23.1.1

Tags:

I'm trying to put in a feature that I miss from Eclipse, where Alt+[Up/Down] transposes the lines up or down, but can not for the life of me figure out how to assign to these keys properly. I am using it in -nw mode (so just in a shell window), and typically run in a screen session.

Using a global key binding, I can get it to work with letter combinations, like (kbd "M-m"), but every combination I have tried for the arrow keys just gives me a message that doesn't make sense, I always get:

"ESC <up> is undefined" 

What I have tried:

(global-set-key (kbd "M-<up>") 'transpose-line-up)     (global-set-key (kbd "<escape>-<up>") 'transpose-line-up) (global-set-key [M-up] 'transpose-line-up) (global-set-key [\e \M-O A] 'transpose-line-up) 

And C-h c just returns:

ESC <up> (translated from ESC M-O A) is undefined 

None of these work, either using ESC or Alt.

Any idea how I can make this work? I would prefer to have these as Alt+[Up/Down] just because that is what I am used to.

Edit

From the comments:

  • C-q Up prints ^[OA.

  • C-q M-Up prints ^[ and moves the cursor up a line.

  • C-h k (Alt+Up) prints ESC <up> (translated from ESC M-O A) is undefined.

Thanks for the suggestions, but they all turned out the same.

like image 726
liam Avatar asked Dec 04 '10 00:12

liam


People also ask

How do you bind commands in Emacs?

Keys can be bound to commands either interactively or in your . emacs file. To interactively bind keys for all modes, type M-x global-set-key RET key cmd RET . To bind a key just in the current major mode, type M-x local-set-key RET key cmd RET .


2 Answers

Emacs has a complex mechanism to handle the vicissitudes of function key and modifier encodings on various terminal types. It doesn't work out of the box in all cases. The following settings should work on your terminal:

(define-key input-decode-map "\e\eOA" [(meta up)]) (define-key input-decode-map "\e\eOB" [(meta down)]) (global-set-key [(meta up)] 'transpose-line-up) (global-set-key [(meta down)] 'transpose-line-down) 

You should be able to use (kbd "<M-up>") and (kbd "<M-down>") in place of [(meta up)] and [(meta down)], as long as you've done the step of telling Emacs (via input-decode-map) about the escape sequences that your terminal uses to encode these key combinations.

like image 154
Gilles 'SO- stop being evil' Avatar answered Sep 29 '22 13:09

Gilles 'SO- stop being evil'


I always use C-h k (key) (i.e. describe-key) to find out how Emacs refers to (key), and then use (kbd) with that same string to utilise it.

In this case, describe-key returns <M-up>, so I would use (global-set-key (kbd "<M-up>") 'transpose-line-up) (exactly as J.F. Sebastian has done).

Edit:

Running emacs -nw (but not through screen), describe-key reports ESC <up> (translated from ESC M-[ A), and (kbd "ESC <up>") is successful for binding it.

Running screen emacs -nw, describe-key reports ESC <up> (translated from ESC M-O A), which seems to match what you see, and the binding for (kbd "ESC <up>") still works for me.

(n.b. Tested under Cygwin with screen 4.00.03, and Emacs 23.2.1.)

like image 22
phils Avatar answered Sep 29 '22 12:09

phils