fir*_*dev 2 macos vim terminal keyboard-shortcuts iterm2
有没有办法Cmd在终端中使用Vim键?MacVim做的事情.
我已经重新映射Cmd+S到iTerm2发送Esc:w!<CR>以保存Vim中的文件,但这听起来有点弱.
有了iTerm和Vim的所有功能,应该有一些方法可以做到这一点吗?
这是可能的,但它需要一些做,并有一些缺点.
第一组问题是:
剩下的问题是Vim没有开箱即用的配置类似Mac的键绑定.幸运的是,MacVim在/Applications/MacVim.app/Contents/Resources/vim/runtime/macmap.vim中包含了大部分Mac风格的GUI绑定,而不是在Interface Builder或Objective-C源代码中对它们进行编码; 所以我能够复制它们并使它们适应终端.这是一个与MacVim(和其他Mac应用程序)非常接近的配置:
" Keybindings for terminal vim; mostly to emulate MacVim (somewhat)
" See /Applications/MacVim.app/Contents/Resources/vim/runtime/macmap.vim (from
" which many of the following are taken); and menu.vim in the same directory.
" Since these all have native (Cmd-modified) versions in MacVim, don't bother
" defining them there.
" A utility function to help cover our bases when mapping.
"
" Example of use:
" call NvicoMapMeta('n', ':new<CR>', 1)
" is equivalent to:
" exec "set <M-n>=\<Esc>n"
" nnoremap <special> <Esc>n :new<CR>
" vnoremap <special> <Esc>n <Esc><Esc>ngv
" inoremap <special> <Esc>n <C-o><Esc>n
" cnoremap <special> <Esc>n <C-c><Esc>n
" onoremap <special> <Esc>n <Esc><Esc>n
function! NvicoMapMeta(key, cmd, add_gv)
" TODO: Make this detect whether key is something that has a Meta
" equivalent.
let l:keycode = "<M-" . a:key . ">"
let l:set_line = "set " . l:keycode . "=\<Esc>" . a:key
let l:nmap_line = 'nmap <silent> <special> ' . l:keycode . ' ' . a:cmd
let l:vnoremap_line = 'vnoremap <silent> <special> ' . l:keycode . ' <Esc>' . l:keycode
if(a:add_gv)
let l:vnoremap_line.='gv'
endif
let l:inoremap_line = 'inoremap <silent> <special> ' . l:keycode . ' <C-o>' . l:keycode
let l:cnoremap_line = 'cnoremap <special> ' . l:keycode . ' <C-c>' . l:keycode
let l:onoremap_line = 'onoremap <silent> <special> ' . l:keycode . ' <Esc>' . l:keycode
exec l:set_line
exec l:nmap_line
exec l:vnoremap_line
exec l:inoremap_line
exec l:cnoremap_line
exec l:onoremap_line
endfunction
" I can't think of a good function to assign to Meta+n, since in MacVim Cmd+N
" opens a whole new editing session.
" Meta+Shift+N
" No equivalent to this in standard MacVim. Here " it just opens a window on a
" new buffer.
call NvicoMapMeta('N', ':new<CR>', 1)
" Meta+o
" Open netrw file browser
call NvicoMapMeta('o', ':split %:p:h<CR>', 1)
" Meta+w
" Close window
call NvicoMapMeta('w', ':confirm close<CR>', 1)
" Meta+s
" Save buffer
call NvicoMapMeta('s', ':confirm w<CR>', 1)
" Meta+Shift+S
" Save as
" TODO: This is silent, so you can't tell it's waiting for input. If anyone can
" fix this, please do!
call NvicoMapMeta('S', ':confirm saveas ', 1)
" Meta+z
" Undo
call NvicoMapMeta('z', 'u', 1)
" Meta+Shift+Z
" Redo
call NvicoMapMeta('Z', '<C-r>', 1)
" Meta+x
" Cut to system clipboard (requires register +")
exec "set <M-x>=\<Esc>x"
vnoremap <special> <M-x> "+x
" Meta+c
" Copy to system clipboard (requires register +")
exec "set <M-c>=\<Esc>c"
vnoremap <special> <M-c> "+y
" Meta+v
" Paste from system clipboard (requires register +")
exec "set <M-v>=\<Esc>v"
nnoremap <silent> <special> <M-v> "+gP
cnoremap <special> <M-v> <C-r>+
execute 'vnoremap <silent> <script> <special> <M-v>' paste#paste_cmd['v']
execute 'inoremap <silent> <script> <special> <M-v>' paste#paste_cmd['i']
" Meta+a
" Select all
call NvicoMapMeta('a', ':if &slm != ""<Bar>exe ":norm gggH<C-o>G"<Bar> else<Bar>exe ":norm ggVG"<Bar>endif<CR>', 0)
" Meta+f
" Find regexp. NOTE: MacVim's Cmd+f does a non-regexp search.
call NvicoMapMeta('f', '/', 0)
" Meta+g
" Find again
call NvicoMapMeta('g', 'n', 0)
" Meta+Shift+G
" Find again, reverse direction
call NvicoMapMeta('G', 'N', 0)
" Meta+q
" Quit Vim
" Not quite identical to MacVim default (which is actually coded in the app
" itself rather than in macmap.vim)
call NvicoMapMeta('q', ':confirm qa<CR>', 0)
" Meta+Shift+{
" Switch tab left
call NvicoMapMeta('{', ':tabN<CR>', 0)
" Meta+Shift+}
" Switch tab right
call NvicoMapMeta('}', ':tabn<CR>', 0)
" Meta+t
" Create new tab
call NvicoMapMeta('t', ':tabnew<CR>', 0)
" Meta+Shift+T
" Open netrw file browser in new tab
call NvicoMapMeta('T', ':tab split %:p:h<CR>', 0)
" Meta+b
" Call :make
call NvicoMapMeta('b', ':make<CR>', 1)
" Meta+l
" Open error list
call NvicoMapMeta('l', ':cl<CR>', 1)
" TODO: We need to configure iTerm2 to be able to send Cmd+Ctrl+arrow keys, so
" we can duplicate the :cnext/:cprevious/:colder/:cnewer bindings to those keys
" in MacVim.
" There may be a few others I've missed, too.
Run Code Online (Sandbox Code Playgroud)
该NvicoMakeMeta函数将传递给它的密钥的元密钥修改版本映射到指定的操作; "元键"这里只是Command- 或 - 修改的通用术语Option.名称中的"Nvico"表示它以普通,可视,插入,命令和操作员暂挂模式映射的事实.
由于Vim在解释ESC字符时的工作方式(这是所有元键序列的开头以及箭头键等),如果我们只是映射ESC加上另一个字符的序列,我们最终会得到Vim等待明显的接收到实际Esc按键后的时间量(例如,表示希望返回正常模式).我的函数避免这种情况的方法是使用:set设置密钥代码(请参阅参考资料:help :set-termcap).
总而言之,这是您需要做的:
iTerm菜单> Preferences…); 去Keys标签; 重新映射您想要用作修饰符的任何键,以便它发送Left Option或Right Option.按照建议允许iTerm2控制计算机; 它应该为您打开正确的首选项窗格.您必须先单击锁定并输入密码,然后才能选中iTerm旁边的复选框.Preferences在Profiles选项卡中的应用程序范围的对话框中打开它),并确保+Esc选中Left option key acts as(和/或Right option key acts as,取决于您是否已创建元键)发送Right Option).