Vim自动补全优化需求:显示非当前文件补全项的来源路径
解决Vim自动补全的两个需求
一、让非当前文件的补全建议显示来源路径
默认的^n关键字补全会混合当前文件和其他文件的补全建议,但不会标注来源。我们可以通过自定义补全函数来实现这个需求,步骤如下:
- 在你的
.vimrc(或Neovim的init.vim)中添加以下自定义补全函数:
function! MyKeywordComplete(findstart, base) if a:findstart " 定位当前单词的起始位置 let line = getline('.') let start = col('.') - 1 while start > 0 && line[start-1] =~ '\k' let start -= 1 endwhile return start else " 收集当前缓冲区和其他来源的关键字 let current_buf = bufnr('%') let items = [] " 添加当前文件的补全项,标记为[当前文件] for word in getcompletion(a:base, 'keyword', {'bufnr': current_buf}) call add(items, {'word': word, 'menu': '[当前文件]'}) endfor " 添加其他已加载缓冲区的补全项,显示相对路径 for buf in getbufinfo({'buflisted': 1}) if buf.bufnr != current_buf && buf.name != '' let short_path = fnamemodify(buf.name, ':~:.') for word in getcompletion(a:base, 'keyword', {'bufnr': buf.bufnr}) call add(items, {'word': word, 'menu': '[' . short_path . ']'}) endfor endif endfor " 添加标签文件中的补全项,显示来源路径 for word in getcompletion(a:base, 'tag') let tag_info = gettaglist(word)[0] if tag_info != {} let short_path = fnamemodify(tag_info.filename, ':~:.') call add(items, {'word': word, 'menu': '[' . short_path . ']'}) endif endfor " 去重,避免相同关键字重复显示 let seen = {} let unique_items = [] for item in items if !has_key(seen, item.word) call add(unique_items, item) let seen[item.word] = 1 endif endfor return unique_items endif endfunction
- 把
^n绑定到这个自定义补全函数:
set completefunc=MyKeywordComplete imap <C-n> <C-x><C-u>
现在按^n触发补全时,当前文件的建议会显示[当前文件],其他文件或标签的建议会显示对应的相对路径,一眼就能区分来源。
二、查看补全项的来源文件路径
如果只是临时查询某个补全项的来源,有两种实用方法:
方法1:借助自定义补全的菜单信息
上面的自定义补全已经把来源路径直接显示在补全菜单右侧了,选中补全项时就能直接看到,非常直观。
方法2:用原生Vim命令查询
如果你用的是默认的^n补全,可以按以下步骤操作:
- 输入部分关键字,触发补全后选中你想查询的项
- 在命令行输入
:echo v:completed_item,如果补全项来自其他缓冲区,结果里会有bufnr字段,再执行:echo bufname(v:completed_item.bufnr)就能得到对应的文件路径 - 对于来自标签的补全项,执行
:echo gettaglist('你的关键字')会返回标签的详细信息,其中filename字段就是来源文件路径
内容的提问来源于stack exchange,提问作者BiBi
相关产品推荐
相关产品推荐

