如何避免在Vim中重新映射

时间:2019-01-10 16:18:00

标签: vim

我的.vimrc上有以下内容

au FileType ruby nnoremap <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')

这将在指定的行上执行rspec,并为我提供了在按Enter之前编辑该行的选项。但是我必须在测试文件上,才能正确获取文件名和行号。

在开发过程中,我手动运行nnoremap <leader>t :!rspec some/spec/file.rb:123以从代码中的任何位置运行我想要的测试。这样我就可以编写代码并触发测试,而无需访问测试文件。

问题是,如果我访问另一个ruby文件,则.vimrc中的映射将再次运行,并且我会松开之前使用的nnoremap命令。如果没有该序列的映射,是否有命令仅在正常模式下映射?

此致

2 个答案:

答案 0 :(得分:2)

这应该是本地缓冲区映射。使用<buffer>

au FileType ruby nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')

我们可以做得更好!

使用augroup并进行自我清理,以确保重新安全:source

augroup ruby_testing
    autocmd!
    autocmd FileType ruby nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')
augroup END

最好放弃autocmd并将此映射放在after目录中。将以下行添加到~/.vim/after/ftplugin/ruby.vim

nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')

有关更多帮助,请参见:

:h :map-local
:h :augroup
:h after-directory

答案 1 :(得分:1)

Vim具有:help :map-<unique>修饰符,如果该映射已经存在,则使映射失败。

au FileType ruby nnoremap <unique> <expr> <leader>t ...

您可以使用:silent!取消显示错误消息:

au FileType ruby silent! nnoremap <unique> <expr> <leader>t ...

或者(这会更好一点,因为它不会抑制映射定义中的任何其他错误,例如语法错误),您可以通过maparg()显式检查映射是否存在:

au FileType ruby if empty(maparg('<leader>t', 'n')) | nnoremap <expr> <leader>t ... | endif

请注意,这确实实现了您要的(我了解);即第一个Ruby文件将定义映射,而随后的所有Ruby文件都将被忽略;映射将始终使用第一个文件的名称和行号。如果您希望对同一映射使用不同的右侧,这取决于当前编辑的文件,则解决方案是根据@PeterRincker的答案进行的局部缓冲区映射。但是,这样一来,您必须在原始Ruby缓冲区内才能触发正确的映射。

对此的一种补救措施可能是从命令行历史记录中撤回已执行的命令行(对于不完整的映射,应自动发生,否则通过histadd()),以便您可以轻松地从另一个文件重新调用该命令。