Binding M-<up> / M-<down> in Emacs 23.1.1
Asked Answered
C

7

25

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.

Circumfuse answered 4/12, 2010 at 0:5 Comment(1)
nex-3.com/posts/45-efficient-window-switching-in-emacs#comments contains interesting tips in the commentsStilt
A
25

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.

Archival answered 5/12, 2010 at 19:19 Comment(2)
i've got a: Symbol's function definition is void: transpose-line-up messageHanse
@Hanse I followed the function names in the question. This isn't a standard command, presumably liam got it from some package or wrote it himself. Note that the standard command transpose-lines (C-x C-t) is pretty close.Gibbsite
E
9

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.)

Extenuate answered 4/12, 2010 at 2:19 Comment(6)
<M-up> doesn't work for me in the "screen" mode (I presume it wouldn't work for the OP's case either).Stilt
Same as J.F. Sebastian's answer above, I get the same error as reported in the original question.Circumfuse
Ah, I hadn't registered that part of the question. The "ugly workaround" makes much more sense now :)Extenuate
I've added some additional notes after further testing. The summary is that my original approach has worked for me in all situations: use describe-key to find out what to use with (kbd). It would be good if you could confirm whether or not you have done that?Extenuate
yes I have done that. (kbd "M-<up>") -> [M-up] . describe-key returns: ESC <up> (translated from ESC M-O A) is undefined. Using that sequence does not work either.Circumfuse
This is the single most useful emacs tip I have ever run across! Not only did I not know how to do this, it never occurred to me to ask how to do this. Fifty virtual upvotes for you! :)Agincourt
E
6
(global-set-key [M-up] 'beginning-of-buffer)
(global-set-key [M-down] 'end-of-buffer)

In my OSX, I have this definition to perform Alt-up/down to jump to top/bottom of buffer.

Ethbun answered 4/12, 2010 at 2:22 Comment(3)
[M-up] doesn't work for me in the "screen" mode (I presume it wouldn't work for the OP's case either).Stilt
Does not work for me. Still get the "ESC <up> is undefined" error.Circumfuse
Yes, I still have the same problem as @liam.Beaverbrook
S
4

ugly workaround:

I've typed C-q <M-up> it produced ^[[1;3A on the terminal inside screen inside emacs.

(global-set-key (kbd "<M-up>") 'transpose-line-up)
(global-set-key (kbd "^[[1;3A") 'transpose-line-up)

I've got Lisp error: (void-function transpose-line-up) so the key bindings work.

Note: C-q runs the command quoted-insert.

Stilt answered 4/12, 2010 at 1:3 Comment(2)
1st: ESC <up> is undefined 2nd: error: Key sequence ^ [ [ 1 ; 3 A starts with non-prefix key ^Circumfuse
@liam: Execute (format-kbd-macro (read-key-sequence "Key? " nil t)) and type <M-up> or <M-down>. What is the output?Stilt
A
2

The following lines work for me on macOS 10.11.6 and GNU Emacs 25.2.1:

(global-set-key (kbd "ESC <down>") 'end-of-buffer)
(global-set-key (kbd "ESC <up>") 'beginning-of-buffer)
Agitation answered 8/7, 2017 at 0:49 Comment(0)
S
0

Assuming you have the functions transpose-line-up and transpose-line-down already defined (as it seems to be from the example code in your original question):

(global-set-key [(meta up)] 'transpose-line-up)
(global-set-key [(meta down)] 'transpose-line-down)
Semitropical answered 5/12, 2010 at 17:24 Comment(0)
M
0

works on OSX Terminal:

(global-set-key (kbd "ESC <up>") 'transpose-line-up)
(global-set-key (kbd "ESC <down>") 'transpose-line-down)
Misrule answered 2/5, 2020 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.