58

I'm trying to map Alt key in the following way:

:map <A-j> j
:map <A-k> k

but it doesn't work (bell is rang on Alt + j/Alt + k).

What am I missing?

I'm using Terminal on OSX, the same happens on remote Linux.


On Ctrl + v, Alt + j, I've got: ?~H~F ( when encoding=utf-8).

On Ctrl + v, Alt + k, I've got: ?~Z (˚ when encoding=utf-8).

Running vim without plugins (-u NONE) doesn't make any difference.

3
  • 1
    Does Alt (press, not hold) and then j work? With xterm at least I need to set metaSendsEscape to true to get these sequences to work... I don't know if you have the same problem, and I don't use OSX so I can't test... – Martin Tournoij Mar 3 '15 at 23:16
  • @Carpetsmoker Pressing Alt, release, then j or any other key works as normal. I've checked and found the option 'Use option as meta key', enabled it and it works now. So setting metaSendsEscape did the trick, thanks. – kenorb Mar 3 '15 at 23:41
  • 3
    This question was previously answered (with a better response) here: stackoverflow.com/questions/6778961/… – user3751385 Oct 5 '16 at 7:55
62

That's how I do it on Linux or Cygwin:

First check what chars are sent by your terminal when you press ALT+J:

In order to do this I go to console and run sed -n l (you can also use cat for it). Then I press ALT+J and see that the chars on the screen are ^[j .

I replace ^[ with \e (because that's what is sent by my terminal when I press esc) and the final string for me is \ej.

Then I write it to my .vimrc:

execute "set <M-j>=\ej"
nnoremap <M-j> j

And the mapping works.

8
  • 6
    I can't find the documentation for the :set <M-j>=\ej part. What should I search for? – Evgeni Sergeev Jun 3 '15 at 1:05
  • 1
    Thanks for the answer, this was the only solution that has worked for me w/ Iterm + vim – newUserNameHere Jun 22 '15 at 14:33
  • 1
    Nah, this doesn't work. Sometimes ESC-J will act as ALT-J – user3751385 Oct 4 '16 at 5:15
  • 2
    @EvgeniSergeev See :help :set-termcap – Rich Feb 15 '18 at 22:10
  • 1
    I like your "check what chars are sent by your terminal" part. Smart! – Bruce Feb 3 at 10:56
18

With help of Carpetsmoker, it seems that Terminal wasn't configured to 'Use Alt/option as meta key' (this is especially common for GUI Terminals).

For Terminal on OSX, it's in Preferences -> Settings -> Keyboard tab -> 'Use option as meta key'. Check: How can I change Terminal to use option as meta key? (Mavericks).

For XTerm, check: Configuring XTerm to Default to Meta Sends Escape which says:

Add this line anywhere in your personal .Xdefaults file (~/.Xdefaults):

xterm*metaSendsEscape: true

Then reload the config with xrdb. Without this step the changes in .Xdefaults won't take effect until the next X restart:

xrdb -l ~/.Xdefaults

Then standard mappings with Alt key like:

:map <A-j> j
:map <A-k> k

works fine.

For help, see: :h :map-alt-keys.

1
  • 4
    May also want to look at :h :map-alt-keys as another source of information – Peter Rincker Mar 4 '15 at 17:02
8

Similar to Kossak's answer but a bit simpler, by mapping literal key presses.

Either in normal mode after pressing :, or inserted into your .vimrc, map the input directly by starting the mapping:

nnoremap 

then hitting Ctrl + V then the keystroke to record, e.g. Alt + . This will show as something like this:

nnoremap ^[[1;3D

but each ^[ is a single, literal escape character and syntax highlighting should show this. Replace the literal escape(s) with the text <Esc>, and append the command you wish to use:

nnoremap <Esc>[1;3D <C-w>h

I know OP was mapping Alt + letters, but I used arrows to show how do it for something that may not be mapped by default.

4
  • Worked like a charm, thanks a lot! – aryndin Oct 24 '19 at 9:11
  • This is exactly what I was looking for. I didn't know exactly what vim was interpreting my desired key combo as, and this shows you. Thanks! – Jacob Evan Shreve Nov 25 '20 at 22:55
  • Doesn't work with my Danish layout. – Sebastian Nielsen Feb 15 at 21:06
  • @SebastianNielsen What, exactly "doesn't work"? This should be layout independent because you're mapping raw keypresses regardless of what they are. If you can't send SYN on a Danish keyboard, then first figure that out. – Walf Feb 16 at 0:07
3

If Control+V followed by ALT-x shows ^[x (type in terminal) you can fix it with this small script from vim.wikia.com:

for i in range(97,122)
  let c = nr2char(i)
  exec "map \e".c." <M-".c.">"
  exec "map! \e".c." <M-".c.">"
endfor

Add to .vimrc for all alt key mappings.

3

This works for me on Ubuntu 16.04 xfce terminal (and alacritty rust terminal)

Set ultisnip snippet trigger to Meta-/ (just like emacs snippet)

let g:UltiSnipsExpandTrigger="^[/"

Here's now I type ^[/ in vim

In insert mode Ctrl-V Alt-/

(Meta is the Alt key on my PC keyboard)

0

I'm using Terminal on OSX, the same happens on remote Linux.

I don't know about Terminal, but if you are on OSX, your mappings should work out of the box, provided that you use a recent Vim version, and a recent iTerm2 terminal.

You need at least the Vim patch 8.1.2134. Having the patch 8.1.2194 also helps, because it automatically enables the modifyOtherKeys feature on which Vim relies to let the user map various chords.

For iterm2, I think you need at least the version 3.4.0. From the changelog:

  • Modifier keys in vim should work better now. CSI u mode is no longer enabled by a control sequence. Instead, a "modifyOtherKeys" mode has been added which is compatible with xterm.

On Linux, xterm also supports the modifyOtherKeys feature.


You are not limited to meta chords. You can map many other chords, like <C-;> for example:

vim -Nu NONE +'nno <c-;> :echo "c-; was hit"<cr>'

For more info, see :h modifyOtherKeys.

1
  • I'm on 8.2.2300, and I couldn't make nnoremap <A-j> :echo "alt-j"<CR> work on macOS on either Terminal.app or Alacritty :( oh well, I don't tend to use those chords anyway – D. Ben Knoble Mar 7 at 17:53
0

You have another option. NeoVim works with M-x out of the box when you have terminal sending ESC + sequence, which mostly every terminal could.

As a summary for other answers, I think your two options are

  1. Turning using "opt as meta" off, using the actual sent code in mapping
  2. Turning using "opt as meta" on, using <esc>x type of sequence for mapping.

There are some answers stating that just turning on opt as meta would make <A-x>/<M-x> work. That is not true. At least, it will not work on macOS.

1
  • Welcome to Vi and Vim! I've edited your post for some formatting, and also edited out the opinion-based parts to focus on the core facts. – D. Ben Knoble Mar 7 at 17:46

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.