设置Vim按键映射排除两类文件类型时报错求助
Vim多文件类型排除按键映射的问题解决
问题描述
我尝试设置如下Vim按键映射,实现排除两类文件类型的功能:
let LIN_VIM_NVIM_TREE='NvimTree' let LIN_VIM_FERN='fern' nnoremap <expr> <Leader>bn (&filetype ==# LIN_VIM_NVIM_TREE || &filetype ==# LIN_VIM_FERN ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
但执行时出现报错:E749 empty buffer, E488 Trailing characters when using &filetype?。仅设置排除单个文件类型的映射可以正常工作:
nnoremap <expr> <Leader>bn (&filetype ==# LIN_VIM_NVIM_TREE ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
问题原因
核心是Vimscript运算符优先级导致的表达式解析错误:
字符串连接符.的优先级高于三元运算符?:,而?:的优先级又高于逻辑或||。原表达式未加括号时,会被错误解析为:
&filetype ==# LIN_VIM_NVIM_TREE || ((&filetype ==# LIN_VIM_FERN ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>")
逻辑或的右侧变成了字符串拼接结果,Vim会将非空字符串视为布尔真,导致整个条件恒为真,最终生成的按键序列包含无效内容,触发报错。
解决方案
方案1:为条件判断加括号
给整个三元表达式的条件部分加上括号,确保Vim先执行完整的逻辑判断,再进行字符串拼接:
let LIN_VIM_NVIM_TREE='NvimTree' let LIN_VIM_FERN='fern' nnoremap <expr> <Leader>bn ((&filetype ==# LIN_VIM_NVIM_TREE || &filetype ==# LIN_VIM_FERN) ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
方案2:用index()简化条件判断
将需要排除的文件类型存入列表,通过index()函数判断当前文件类型是否在列表中,这种写法更简洁且易于扩展:
let LIN_VIM_EXCLUDE_FT = ['NvimTree', 'fern'] nnoremap <expr> <Leader>bn (index(LIN_VIM_EXCLUDE_FT, &filetype) != -1 ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
内容的提问来源于stack exchange,提问作者linrongbin
相关产品推荐
相关产品推荐

