artemave
artemave

Reputation: 6936

MacVim (iterm2/tmux) bind alt/meta

I have this nice set of vim mappings

" Drag Current Line/s Vertically
nnoremap <M-j> :m+<CR>
nnoremap <M-k> :m-2<CR>
inoremap <M-j> <Esc>:m+<CR>
inoremap <M-k> <Esc>:m-2<CR>
vnoremap <M-j> :m'>+<CR>gv

that I can't get to work on Mac/iTerm2/Tmux/vim combo. The problem I guess is in Alt key not getting mapped.

P.S. "Left option key acts as" is set to +Esc in iTerm session keys preferences

Upvotes: 2

Views: 4260

Answers (3)

Sebastian
Sebastian

Reputation: 483

People asking that question over SO tend to forget not everyone uses US keyboard layout. For 'Polski' I didn't find solution yet, and this is tricky. I had to set left Option key for esc+ otherwise left and right Options are used for diacritic characters and now sed -n l shows for option-j ^[j and for option-k ^[k BUT in vim no character is shown - it behaves simply like normal j and k. That being said in iTerm2 preferences window pressing option-j and option-k gives and Ż. so fields in settings respects system keyboard layout while content of the iTerm window is set for UTF-8. Not sure if that has anything to do with it but Alt/Option on Mac is used to insert characters using hexcodes.

Also, iTerm documentation explicitly states that sending <A- is not supported, only <M-. - but I tested both keybindings <A- and <M- in vim and keymapings simply don't work so @LMulvey solution is not valid in 2024.

But after struggling few hours (which indicates itself how bad idea is trying to use terminal editors on Mac - adding tmux to the mix is a nightmare) I accepted it won't work and I'll be using more VSC and Sublime Text where shortcut <ctrl-command-down> <ctrl-command-up> are set by default and work out of the box

Upvotes: 1

LMulvey
LMulvey

Reputation: 1670

I'm throwing this up here after scouring through tons of SO questions and answers. This solution worked for me with iTerm2 + Mojave.

  1. In iTerm2, go to Preferences -> Profile -> Keys. In the bottom right, change your left (or right) option key to fire off an Esc+ sequence instead of Meta/Normal.
  2. Put the following code in your .vimrc:
execute "set <A-j>=\ej"
execute "set <A-k>=\ek"

nnoremap <A-j> :m .+1<
nnoremap <A-k> :m .-2<
inoremap <A-j> <Esc>:m .+1<CR>==
inoremap <A-k> <Esc>:m .-2<CR>==
vnoremap <A-j> :m '>+1<CR>gv=
vnoremap <A-k> :m '<-2<CR>gv=gv

What is this doing?

Admittedly, my understanding is not great. When you send an ALT+j command to Terminal, iTerm will receive it as ^[j which is an Escape sequence. When mapping it to Vim, ^[ ends up as \e. If you want to double check what your ALT+j (or ALT+k) is firing as, type sed -n l in a Terminal window and then hit ALT+j – you should see this output: ^[j

The execute set commands are remapping <A-j> and <A-k> mappings for Vim to fire off ^[j/^[k respectively to match what's being fired by iTerm.

This fixed it for me and I can now move line blocks like a pro. Hopefully it helps some people (sorry for my lackluster explanation–still learning the Vim ecosystem).

Upvotes: 4

romainl
romainl

Reputation: 196516

I've already done some real life tests regarding this exact issue. My temporary and non-authoritative conclusion was/is that mappings using <M-> don't work in iTerm2 and that one should use alternative solutions instead.

I use <leader>.

Upvotes: 1

Related Questions