背景
我在 MacOS 和 Windows 上都使用 VIM,只有一个 vimrc 设置
这是我的一个轻量键映射绑定(bind):
map <leader>cmd:exec has("mac")==1? ':!open -a terminal' : ':!start cmd'
问题
但是,它并不像我想象的那样工作:按<leader>cmd
并且无需按回车键,就会弹出 cmd 或终端。
实际发生的是整个映射字符串
exec has("mac")==1? ':!open -a terminal' : ':!start cmd'
只是以 ex 模式出现并等待我按 Enter 键自行运行。
据我所知,如果您使用 exe "your cmd string"
在您的映射键设置中,您不需要放置 <cr>
在它之后,但是为什么当您使用三重运算符时,它的行为会有所不同?
尝试
所以我将其放入字符串中,例如
map <leader>cmd:exec has("mac")==1? ':!open -a terminal<cr>' : ':!start cmd<cr>'
vim 告诉我:
(另外,我不明白为什么<cr>
中的``
要转义,那``
中的字符串不仍然保持原来的含义吗?)
所以我修改如下:
map <leader>cmd:exec has("mac")==1? ':!open -a terminal\<cr\>' : ':!start cmd\<cr\>'
但它只是再次出现在 ex 模式中。
请问有什么解决办法吗?
最佳答案
首先,让我们稍微清理一下您的命令:
:nnoremap <leader>cmd :execute has("mac") ? "!open -a terminal" : "!start cmd"
-
nnoremap
优于map
因为它确保了非递归性并且明确了它所针对的模式, - 无需测试
has()
的值, - 缩写名称对于在命令行中输入很酷,但在脚本中毫无用处,
:
都是多余的。
但是这些都不能真正解决您的问题,即您的映射末尾没有回车符:
:nnoremap <leader>cmd :execute has("mac") ? "!open -a terminal" : "!start cmd"<CR>
你仍然需要按<CR>
无论如何都要第二次回到 Vim 所以…
:nnoremap <leader>cmd :execute has("mac") ? "!open -a terminal" : "!start cmd"<CR><CR>
现在,这是一种非常干净且通用的方法,可以根据平台以不同的方式执行操作:
" Define a global variable containing the current environment's name
" if it hasn't been already defined.
if !exists('g:env')
if has('win64') || has('win32') || has('win16')
let g:env = 'WINDOWS'
else
let g:env = toupper(substitute(system('uname'), '\n', '', ''))
endif
endif
以及映射的重新设计版本,其中添加了 open
的路径根据您的用例,您可能需要也可能不需要命令:
nnoremap <leader>cmd :execute g:env == "DARWIN" ? "!open -a terminal ." : "!start cmd"<CR><CR>
还有一种替代方法,只是为了好玩:
let cmds = { "DARWIN": "!open -a terminal .", "WINDOWS": "!start cmd" }
nnoremap <leader>cmd :execute cmds[g:env]<CR><CR>
关于vim - 根据操作系统映射 vim 键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50080963/