114

I tried to map <Alt+D> to <Ctrl+D> by adding the below line to .vimrc, but it doesn't work. I checked the .vimrc is loaded by Vim.

map <Alt-D> <C-D>

Is there any error in this mapping?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Thomson
  • 20,586
  • 28
  • 90
  • 134
  • Are you using vim in a terminal, or a gui version (gvim, macvim)? – Nick Knowlson Sep 28 '11 at 18:52
  • Also note that if your `encoding` changes after the mapping runs, what you get out of your Alt keys may not match what you initially set. – dash-tom-bang Feb 15 '16 at 23:35
  • In insert mode, press `control+v`, then your key combo `alt+d` & it should insert `^[d`. So you end up with `map ^[d ` or what have you. Note that TYPING `^[d` does not do the same thing. – Reed Feb 05 '21 at 16:56
  • Your Operating system or Terminal Emulator (or maybe both) has intercepted your `Alt-d` keystroke and performed an action that produced no visible change (New-Bookmark?). Find your OS `system settings->keymaps` tool and remove all keymaps associated with `Alt-d`. Again do this with keybindings defined in your Terminal `settings->keymaps`. Now vim is able to receive your `Alt-d`. – Eric Leschinski Jun 05 '22 at 01:47

10 Answers10

176

To Mac users out there: for mapping ALT+hjkl, use instead the real character generated (find out which character using the combination while in INSERT mode), for example with my keyboard I get:

<ALT+j> ==> ª
<ALT+k> ==> º

and so on. Solution found here on StackOverflow.

I used this to move lines up and down with ALT+k\j, using this on my .vimrc:

nnoremap ª :m .+1<CR>==
nnoremap º :m .-2<CR>==

inoremap ª <Esc>:m .+1<CR>==gi
inoremap º <Esc>:m .-2<CR>==gi

vnoremap ª :m '>+1<CR>gv=gv
vnoremap º :m '<-2<CR>gv=gv

as explained here.

Hope it's useful, enjoy Vim :)

ADDENDUM BY Dylan_Larkin (2019): For this to work on a Mac, "Use Option as Meta Key" must be turned OFF in Terminal->Preferences->Keyboard

UPDATE 09/2021

I recently switched from a "British" keyboard to "ABC - Extended" and noticed this configuration doesn't work as expected. As an alternative, I mapped the <up> and <down> keys to do the same operation (which, I guess, also solves most of the complexity explained in other answers of this very question):

nnoremap <down> :m .+1<CR>==
nnoremap <up> :m .-2<CR>==

inoremap <down> <Esc>:m .+1<CR>==gi
inoremap <up> <Esc>:m .-2<CR>==gi

vnoremap <down> :m '>+1<CR>gv=gv
vnoremap <up> :m '<-2<CR>gv=gv

This is also a great way for beginners to rewire the habit of using the arrows and instead learn the much more efficient Vim motion way to move around the code. ;)

You can complete your transition mapping <left> and <right> to quickly move between tabs with:

nnoremap <left> gT
nnoremap <right> gt

Or whatever you fancy (even a brutal <NOP>, like I did at the beginning of my journey).

Bruno Belotti
  • 2,414
  • 1
  • 31
  • 28
  • 12
    This is just what I came here for (Alt+HJKL to move splits)! Thanks! – Jamie Schembri Jun 14 '13 at 13:17
  • 6
    A easy way to find out which character it is, is by using `cat`. Simply type `cat` and inside the cat window the key combination you want. Found out that alt + brackets is ‘ and “ on my mac. – patchrail Jul 22 '14 at 21:25
  • 4
    this works great as Alt+HJKL to move between splits, my fingers love it!! `nmap ˙ nmap ¬ nmap ˚ nmap ∆ ` – John Morales Dec 10 '14 at 01:54
  • 2
    As wacky as it sounds, this is actually correct. Thanks bunches! – Fomentia Jun 30 '15 at 14:29
  • 1
    The question has nothing specified as having to do with Mac, so why is this Mac-specific answer so up-voted and accepted? The original question is an important one that affects many OSs and terminals, so a more generic answer like that from @pablox should be favored. – Micah Elliott Aug 20 '15 at 18:54
  • 2
    @MicahElliott: I actually agree with you, but bare in mind that his question is almost 2 years younger and mine was actually just an addendum for Mac users: the question was already answered, I don't know why it's now accepted. Anyway, the nice thing about SO is that pablox's answer is here, everybody can read it, and if somebody find it relevant can up-vote it (as I just did, BTW). At the end of the day, the only thing that really count is to help each other. :) – Bruno Belotti Aug 20 '15 at 22:45
  • 4
    These exact mappings may not work as expected in future versions of OSX. Use `sed -n l` to see the output of and before you configure the mapping. In my case is `∆` and is `˚` – luk3thomas Jan 13 '16 at 14:31
  • This only seems to work on MacVim. It does not seem to work from terminal Vim on OS X. – f1lt3r Sep 30 '16 at 15:42
  • @AlistairMacDonald : although I am using MacVim, I just tested on my terminal (iTerm and Terminal, just to be sure) and it seems to work fine.... ¯_(ツ)_/¯ – Bruno Belotti Sep 30 '16 at 15:57
  • ¯_(ツ)_/¯ foobar – f1lt3r Sep 30 '16 at 15:59
  • So @AlistairMacDonald did you find a solution in the end? :) – Bruno Belotti Sep 30 '16 at 20:56
  • 1
    I did. Use the CTL key. – f1lt3r Oct 03 '16 at 20:08
  • proper way in macvim: `set macmeta` in `.vimrc` enables mapping the alt key – rfabbri May 15 '18 at 00:11
  • Alt j is ∆ and alt k is ˚ for me, When I save this in my .vimrc I get a conversion error. I have a set encoding=utf-8 in my .vimrc and it doesnt help. I was able to save doing this `:w ++enc=utf-8` but when i reopen the symbol changes to an upside down question mark :( – av4625 Aug 21 '18 at 19:22
  • I'm not sure what's happening @av4625, encoding always confuse me! Check if your encoding is actually set with `:set encoding?` (sometime a typo can mess your life!), then try with a new fresh .vimrc, adding only the relevant lines, so you can be assured no other command of plugin is messing up your configuration mid-way. Also, take a look at your terminal emulator configuration and make sure everything is set as it should be (I found this not to be the case, sometimes). Hope this helps, let me know and good luck! :) – Bruno Belotti Aug 22 '18 at 08:12
  • 6
    On macOS, when setting `Use Option as Meta Key` or on iTerm profile `⌥ key to Esc+` will behave as the traditionally way (like on Linux/Unix). So you don't need to set on Vim the map to `<^[j>`, just map it to `` or `` and it works. – goetz Feb 02 '19 at 19:07
  • Thank you @goetzc, somebody edited my answer adding the last sentence: I didn't check the functionality and trusted the user, but he was probably wrong. I'm going to remove it from my answer and add it as a comment (for reference) – Bruno Belotti Feb 05 '19 at 13:20
  • 1
    QUESTION BY @Dylan_Larkin: For this to work on a Mac, "Use Option as Meta Key" must be turned OFF in Terminal->Preferences->Keyboard Note that with this option ON, on more recent Mac OS', Alt+j is ^[j. However, and YMMV, but trying to map ^[j doesn't work for me. So, it's a trade-off, as I prefer Option as Meta Key=ON. If someone can find an updated solution (2017-19), that would be great. – Bruno Belotti Feb 05 '19 at 13:23
  • Quick note, unless I'm missing something, doing this would make it harder to find a mapping much later when using `:verbose nmap ` etc. – Sri Kadimisetty Jan 14 '20 at 02:35
  • 1
    FYI 'ª' if you paste it into vim, and press 'ga' it will show the character code as 170 or 0xaa. You can express it in vim as `` or `` This allows you to map unusual keystrokes easily either by telling VIM which character represents down ( `set =`) or direct mapping (`map ....`). Also, If you have UTF characters in your `.vimrc`, consider adding `scriptencoding utf8` at the beginning. – Dave Sep 11 '21 at 06:31
52

:help key-notation describes what format needs to be used to map different keys. In the case of alt, you can use either <A- or <M-. So your mapping would be

map <M-d> <C-d>

I'd also recommend using the nore variant of :map (e.g., noremap) unless you explicitly want to allow the right-hand side to be re-evaluated for mappings.

jamessan
  • 41,569
  • 8
  • 85
  • 85
  • 2
    This still doesn't have any effect. Alt+D input still inputs some strange character to Vim. – Thomson Sep 21 '11 at 14:16
  • 13
    That's a separate issue. Your terminal is sending a multi-byte character to Vim and Vim doesn't know to interpret that as ``. You probably need to change your terminal's settings so it sends `` as `d`. – jamessan Sep 21 '11 at 14:19
  • 3
    @jamessan how to do it on iterm2? – Finn Nov 09 '18 at 04:22
  • @jamessan Thanks. this key notation `` works well in idea vim on Mac. – Richard Aug 15 '23 at 07:37
45

I'm not sure is "possible" anymore. Please read the update below.

Yes, you can even in terminal vim, but there's no real catch all answer. You basically have to follow two steps:

  1. Make sure the <M-d> notation exists, and map exactly what your terminal inputs (^[ is the escape character):

    $ cat
    ^[d
    $
    
    " in your .vimrc
    execute "set <M-d>=\ed"
    " you have to use double quotes!
    
  2. Map something to your newly "created" combination:

    noremap <M-d> :echo "m-d works!"<cr>
    

Understanding how it works, you can expand this "trick" to other "strange" combinations, for instance, I'm using termite, and vim doesn't recognize <S-F1>, using cat I get ^[[1;2P. Then, in my vimrc I do: execute "set <S-F1>=\e[1;2P", and then I can map it to anything.

Note: I don't know why, but for some people using \<Esc> works instead of \e.


Update (february 2016)

Depending on the terminfo your terminal runs, maybe you could... in most terminals, "alt + h", for example, is mapped to ^[h, which is: "escape + h". So it could overwrite keys. I've just tried (again) and it seems to work, but I believe it's a very buggy and error prone implementation.

Nevertheless, for the brave enough, here's an experimental plugin:

  • 1
    Instead of the `execute "set...` stuff, you can just directly use `set =^[d`. The `^[` is actually an escape character entered with `C-v-Esc`. This was necessary in rxvt/urxvt, but xterm shouldn’t need the special treatment. More info on this topic in the [vim wiki](http://vim.wikia.com/wiki/Get_Alt_key_to_work_in_terminal). – Micah Elliott Aug 20 '15 at 18:48
  • Is there an analogous approach to this that would work with tmux so that i.e., M-d could be binded? – George Feb 11 '16 at 16:08
  • 3
    For me, `` then `d` now does the same thing as ``+`d`. Also, you can just do this in one line with `Ctrl-v`, `` as per [here](http://stackoverflow.com/a/16600458/1944384). – Sparhawk Jan 18 '17 at 04:58
  • I've had issues with vim-move [1], but this finally fixed it -- thanks!! [1] https://github.com/matze/vim-move/issues/15 – Kipras Melnikovas Jan 20 '21 at 17:29
29

Map Alt Key in Vim on Mac OSx:

Start by viewing the key code your terminal is sending to vim:

$ sed -n l
^[[1;9D 

In the above example, I ran the command and pressed Alt + Left.

The ^[[1;9D is the escaped sequence being sent to vim, so we can user that for our mapping.

map <Esc>[1;9D 
random-forest-cat
  • 33,652
  • 11
  • 120
  • 99
  • 4
    If you are using iTerm2 app, it is good to check how the keys are mapped in the Profile > Keys. – fikovnik Feb 13 '17 at 01:12
  • 1
    With left **`Option`** key (**`⌥`**) configured as `Esc+` in iTerm2, I could map **`alt+q`** to quit vim: **`nnoremap q :qa!`** – ryenus Nov 21 '18 at 03:18
  • You can also setup iTerm2 to work with that remap if you go to Preferences > Profiles, select your current profile, go to the "keys" tab for that profile and change the option that says "Left ⌥ Key" to "Esc+" (available options are "Normal", "Meta", and "Esc+"). – Giovanni Benussi Apr 04 '19 at 11:54
17

Use:

map <A-D> <C-D>

See :help key-notation.

Benoit
  • 76,634
  • 23
  • 210
  • 236
  • 1
    It seems this still doesn't work. Alt+d will input an strange character to Vim, which is the same with the unmap case. – Thomson Sep 21 '11 at 14:12
  • Works for me (I'm using `gvim` on Windows) – Deqing Sep 02 '13 at 07:29
  • @Thomson Your terminal/konsole GUI has intercepted your Alt-d and relayed a different keystroke that can be found by going to terminal->settings->keymaps. Your vim command is working perfectly, it's the keystroke that isn't getting past your terminal window. – Eric Leschinski Jun 04 '22 at 05:26
11

My Terminal would produce ^[x commands (e.g. for alt-x). What got it to work inside Vim was 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 to fix all alt key mappings.

laktak
  • 57,064
  • 17
  • 134
  • 164
10

as a follow up to Bruno's answer for Mac users, try making sure your option key is mapped to Esc+.

This will give you the "normal" behavior of the option (A) key in Vim.

For example, in iterm2, this option can be found under Preferences > Profiles > Keys:

iterm2 preferences screenshot

axelyung
  • 463
  • 4
  • 9
9

Your terminal might not transmit "properly" the Alt-D. You can use C-V to actually get the actual escape sequence send to Vim and use it to create your mapping. Ie, edit your .vimrc and replace the actual by typing the following sequence "C-V Alt-D" so you'll have the correct escape sequence in your vimrc. That won't work if your terminal doesn't send anything to vim.

mb14
  • 22,276
  • 7
  • 60
  • 102
3

Find out key mapping by putting following command in your vim editor

:help key-notation

It will display all the key mapping.

enter image description here

In my ubuntu system for Alt it is <M-...>. It is possible for your version mapping might be different. If you too have same mapping then following should work.

map <M-D> <C-D>
ABN
  • 1,024
  • 13
  • 26
0

Hello after no good solution after years of testing all the above on mac, I kept searching.

Here is my solution:

To create a combination keystroke including Alt you have to declare the combination in the preference > keyboard and use that combination in the vim setup file (check use option as meta key).

The output must be an unusual character (no a for example) so that you're not overriding a regular character.

In the example below you should be able to quite vim with ALT-Up.

vim setting: vim setting

mac setting: mac setting

Aksen P
  • 4,564
  • 3
  • 14
  • 27
MC F
  • 1