我在MacOS和Windows上都使用VIM,只有一个vimrc设置
这是我的轻量级键映射绑定之一:
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模式下,等待我按回车键自行运行。
据我所知,如果你在映射键设置中使用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模式中。
有任何解决方案吗?
答案 0 :(得分:3)
首先,让我们稍微清理一下你的命令:
: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>
答案 1 :(得分:0)
与@romainl的回答相反,您不需要在映射执行期间动态评估操作系统(Vim运行时,操作系统几乎无法更改;这是静态信息)。因此,有条件地定义映射要容易得多:
if has("mac")
nnoremap <leader>cmd :!open -a terminal<CR>
else
nnoremap <leader>cmd :!start cmd<CR>
endif
这让您摆脱:execute
,它速度更快,并且扩展或调整起来也容易得多。 (关于:noremap
的所有其他警告和@romainl的答案中缺少的<CR>
仍然适用。)