映射基于操作系统的vim键?

时间:2018-04-28 20:51:11

标签: vim

背景

我在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告诉我:

enter image description here

(另外,我无法弄清楚为什么<cr>中的``应该被转义,``中的字符串不是原始含义吗?)

所以我修改如下:

map <leader>cmd:exec has("mac")==1? ':!open -a terminal\<cr\>' : ':!start cmd\<cr\>'

但它只是再次出现在ex模式中。

有任何解决方案吗?

2 个答案:

答案 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>仍然适用。)