Remap <C-(Left|Right|Up|Down)> for Neovim on OSX - macos

I'm trying to remap C-any arrow key in Neovim on my Mac to switch windows.
My .config/nvim/init.vim has the following:
" Basic key mappings and controls
" -------------------------------
" Simpler pane moving.
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
nnoremap <C-Down> <C-W><C-J>
nnoremap <C-Up> <C-W><C-K>
nnoremap <C-Right> <C-W><C-L>
nnoremap <C-Left> <C-W><C-H>
However when I restart nvim, the C-J/K/L/H combos work but the C-arrow key combos do not work. What else do I have to do on my Mac to get such remappings to work when I'm working in OSX's default terminal app, or tmux using zsh?

Related

Ctrl-h mapping in Neovim's terminal emulator

I've enabled the following mappings in my init.vim:
tnoremap <Esc> <C-\><C-n>
tnoremap <C-h> <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
These greatly improve windows navigation in Vim.
However, I've noticed that C-h does not work as expected when executed in terminal buffer. Trying this on a usual terminal session results in Backspace action. So probably it seems to be one of these alternative key combinations, like C-i for Tab or C-[ for Esc. But is there any way to make C-h work in Neovim's terminal session as per my bindings?
Thanks!
This issue has already been extensively debated here. Original Vim does not rely on terminfo and includes its own patch for correct handling of C-h sequences. Neovim does look at terminfo though.
Briefly, the fix is executing these commands in the shell:
infocmp $TERM | sed 's/kbs=^[hH]/kbs=\\177/' > $TERM.ti
tic $TERM.ti

How to make ALT works in gvim as in vim?

I'm trying to adapt to vim, again, I'm doing pretty well for now but unfortunately Gvim and Vim doesn't handle the same way the alt key.
In Vim, pressing ALT+ any other key) is the same to press (ESC + any other key). Even in bash's prompt using the vi mode (set -o vi).
If I use the same shortcuts in Gvim, estranges UTF-8 characters are printed.
How can I disable
In Vim, pressing (ALT + any other key) is the same to press (ESC + any other key). Even in bash's prompt using the vi mode (set -o vi).
Vim doesn't do that, your terminal does -- which is why you see the same behavior in other programs in that terminal, like bash. Instead of removing behavior from gvim, you need to add behavior to gvim that matches the terminal behavior you expect.
Depending on your window manager, you may be able to map to do what you want:
# in .vimrc, or without guards in .gvimrc
if has("gui_running")
map <m-j> (something)
endif
Use map, nmap, imap, ... depending on which modes you want.
As mentioned by #fred-nurk the difference in key mappings between terminal based vim and gvim is based on the key mappings and capabilities of your GUI environment (window manager) and your terminal emulator(s).
I'm assuming also that your question is referring to 'insert mode' issues so I'm answering accordingly.
One way to map the gvim keys to behave more closely to vim would be remap each offending key and also disable menu keys. Honestly, this is pretty much all you probably need in your .vimrc somewhere (near the bottom[?]):
[edited to add menubar toggles]:
" vim.gtk/gvim: map alt+[hjkl] to normal terminal behaivior
if has("gui_running")
" inoremap == 'ignore any other mappings'
inoremap <M-h> <ESC>h
inoremap <M-j> <ESC>j
inoremap <M-k> <ESC>k
inoremap <M-l> <ESC>l
" uncomment to disable Alt+[menukey] menu keys (i.e. Alt+h for help)
set winaltkeys=no " same as `:set wak=no`
" uncomment to disable menubar
set guioptions -=m
" uncomment to disable icon menubar
set guioptions -=T
" macro to toggle window menu keys
noremap ,wm :call ToggleWindowMenu()<CR>
" function to toggle window menu keys
function ToggleWindowMenu()
if (&winaltkeys == 'yes')
set winaltkeys=no "turn off menu keys
set guioptions -=m "turn off menubar
" uncomment to remove icon menubar
"set guioptions -=T
else
set winaltkeys=yes "turn on menu keys
set guioptions +=m "turn on menubar
" uncomment to add icon menubar
"set guioptions +=T
endif
endfunction
endif

How to use abbrev in MacVim

I'm new to mvim and I'm not sure how to use commands that have been saved in my vimrc file like the following:
"Load the current buffer in Chrome - Mac specific.
abbrev chrome :! open -a Google\ Chrome %:p<cr>
(note: This was originally:
"Load the current buffer in Chrome - Mac specific.
abbrev ff :! open -a FireFox.app %:p<cr>
)
I'm just confused as how this abbrev works all together and couldn't find an answer on google :\ Maybe someone here could help?
These lines create an abbreviation for a commonly used command. In this case, it is creating an abbreviation for opening the current buffer in a particular application. For instance if you were working on a file called index.html and you entered the command :chrome in vim, it would open index.html in Chrome.
For the three major Mac browsers, use the following lines in your .vimrc file:
" Open the current buffer in a web browser
abbrev ff :!open -a Firefox.app %:p
abbrev chrome :!open -a Google\ Chrome.app %:p
abbrev sf :!open -a Safari.app %:p
This works because the :! at the beginning of each abbreviation definition tells vim to execute a shell command. In these cases, the shell command is open -a [WHICHEVER_BROSWER].app using the current buffer %:p.
Here is some further reading:
Vim Wiki article on Abbreviations
Blog Post about Opening Buffers in External Apps
While using abbrev works in this scenario it's normally used for saving typing or fixing common spelling mistake:
iabbrev mmm myultRalonganDrandomlycapiTAlizedemailadDress#example.com
iabbrev teh the
If you want to execute a command, I think normal mappings are conceptually better suited. Here is what I have in my ~/.vimrc:
let os=substitute(system('uname'), "\n", "", "")
if os == "Darwin" || os == "Mac"
nnoremap <F12>f :exe ':silent !open -a firefox %'<CR>
nnoremap <F12>c :exe ':silent !open -a "google chrome" %'<CR>
nnoremap <F12>o :exe ':silent !open -a opera %'<CR>
nnoremap <F12>s :exe ':silent !open -a safari %'<CR>
elseif os == "Linux"
nnoremap <F12>f :exe ':silent !firefox %'<CR>
nnoremap <F12>c :exe ':silent !chromium-browser %'<CR>
nnoremap <F12>o :exe ':silent !opera %'<CR>
endif

Can't Map <S-CR> in Vim

Got my first Mac over the weekend, and I'm trying to get adjusted. This line in my vimrc, which worked on my windows, won't work with vim through iTerm
inoremap <S-CR> <Esc>
I'm wanting Shift-Enter to act as Escape in insert mode. I've tried using Enter and Return, but that requires me to use the Fn key on my Macbook, which is just as annoying as the escape key.
I Appreciate the help!
The problem here is with the terminal emulation. Most terminals cannot distinguish between non-printing keys [1] and those keys combined with modifier keys.
However, you can still make the desired combination work if your terminal application has the ability to remap key combinations (as iTerm2, for example, does). Map the terminal application's combination to some Unicode character you'll never use, then map that key in Vim to the desired effect, and you can get around this limitation.
For this example, in iTerm2, open the Keys Preferences pane, add a Global Shortcut key, input shift and return, give it an action of Set Text, and then put ✠ (a Maltese Cross, but you could use any random unlikely-to-be-used Unicode character) as its value. In your .vimrc, add these lines:
" Map ✠ (U+2720) to <Esc> as <S-CR> is mapped to ✠ in iTerm2.
inoremap ✠ <Esc>
Or:
inoremap <S-CR> <Esc>
" Map ✠ (U+2720) to <S-CR>, so we have <S-CR> mapped to ✠ in iTerm2 and
" ✠ mapped back to <S-CR> in Vim.
imap ✠ <S-CR>
Entering <S-CR> in Vim in iTerm2 will now ultimately result in <Esc> in Vim as desired.
[1]: E.g. space, tab, enter, delete, control, alt, escape.
That's because for iTerm <S-CR> is the same as <CR>, type Ctrl+V Return then Ctrl+V Shift+Return and you'll see that the same character is inserted in both cases.
So, when you type <S-CR> Vim gets <CR> and your mapping is not triggered.
MacVim is the equivalent of GVim: a GUI for Vim. You don't run MacVim through iTerm. You either run the GUI version (MacVim.app) OR the CLI version ($ vim).
You can launch the GUI from the CLI but iTerm's settings won't interfere in any way with MacVim's settings.
In MacVim your mapping works perfectly.
As far as I know all or most "terminals" treat ⇧↩ the same as ↩. Maybe you should try another sequence like jj?

Mac terminal Vim will only use backspace when at the end of a line

I seem to have something odd with either my Mac 10.6 terminal or my .vimrc.
When I type backspace on my laptop's keyboard, it only works when the cursor is at the end of the line. Trying to delete from within a line does nothing. MacVim operates normally. Google hasn't helped because I can't even figure out what to call this behavior.
All other backspace commands in my Terminal work as expected, so I am leaning towards it being Vim specific.
Here's the output of my ~/.vimrc 's mappings, I can't see anything that would make Vim in the terminal operate this way:
cflewis#coral-reef ~> egrep ".*map.*" ~/.vimrc
"inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
let mapleader = ","
map Q gq
nmap <silent> <leader>s :set nolist!<CR>
" extended '%' mapping for if/then/else/end etc
map <S-Insert> <MiddleMouse>
map! <S-Insert> <MiddleMouse>
nmap <silent> <C-N> :silent noh<CR>
nmap <C-E> :b#<CR>
nmap <C-P> :NERDTreeToggle<CR>
nmap <leader>p :NERDTreeFind<CR>
nmap <leader>/ :call NERDComment(0, "invert")<cr>
vmap <leader>/ :call NERDComment(0, "invert")<cr>
nmap <leader>t :TlistToggle<CR>
nmap <leader>e :e **/
nmap <Leader>b :MiniBufExplorer<cr>
nmap <Leader>sh :ConqueSplit bash<cr>
nmap <Leader>r :ConqueSplit
" map ,y to show the yankring
nmap <leader>y :YRShow<cr>
imap <silent> <Down> <C-o>gj
imap <silent> <Up> <C-o>gk
nmap <silent> <Down> gj
nmap <silent> <Up> gk
cmap w!! %!sudo tee > /dev/null %
inoremap jj <Esc>
nnoremap JJJJ <Nop>
Any ideas would be appreciated. I tried flipping the delete key to send ^H or ^?, to no difference.
Most likely, the "problem" you're seeing is that you can't delete anything that was not typed during your current insert mode session. This is due to the default setting for the 'backspace' option. Adding set backspace=indent,eol,start to your ~/.vimrc is the behavior that you probably want.
This is the only explicit backspace mapping I have in my config. I do not know if it will help for your problem, but it might be worth a try?
" allow backspacing over everything in insert mode
set backspace=indent,eol,start

Resources