如何使 vim 中的地图仅在我不写内引号时才起作用?

How to make map in vim to work only when I don't write inside quotes?

我加了

autocmd FileType rust inoremap {} {<CR>}<Esc>O

到我的 vimrc(应该可以使用 js 和其他带有花括号的语言)

所以如果我输入 {} 我会得到

{

}

光标在括号内

问题是 - 只有当我不写像 "{}"

这样的引号时我才需要它

Vim 知道我在引号内写,因为它突出显示它不同。那么如何在 vimrc 中获取条件映射?

您可以使用此命令(或网上流传已久的众多变体之一)获取当前高亮组:

:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')

在这种情况下,您应该得到如下所示的列表:

['rustString']

然后您可以编写一个函数来判断光标是否在字符串中:

function! IsString()
    return synstack(line('.'), col('.'))
           \ ->map('synIDattr(v:val, "name")')
           \ ->join(',')
           \ =~? 'String'
endfunction

一般情况下,“字符串”高亮组的名称如rustString,其中包含子字符串String,因此我们将列表中的所有组名连接起来并尝试匹配String .匹配 case-insensitive,以防万一。

参见 :help user-functions:help synstack():help line():help col():help map():help synIDattr():help join():help =~?.

下一步是将您的映射转换为“表达式映射”,其中 RHS 是在运行时计算以生成将实际执行的宏的表达式:

inoremap <expr> {} IsString() ? '{}' : '{<CR>}<Esc>O'

参见 :help <expr> 和奇怪的名字 :help trinary

请注意,该函数不假定特定的文件类型。因此,函数和映射都不需要限制为 rustjavascript,也不需要自动命令。