使用外部文件进行Vim行自动补全

4
Ctrl+X Ctrl+L 可以用于显示来自特定外部文件的行完成,而不仅仅是当前缓冲区中的内容。就像字典一样,但是适用于行。

更新:

为了测试,我执行以下操作:

  • 创建一个名为tt.txt的文件,并添加一些测试行
  • 将文件放置在D:\t1\中(我在windows上)
  • 使用命令:set path+=D:\\t1\\tt.txt将文件包含进来
  • :set complete ?返回complete =.,w,b,u,t,i
  • :set path ?返回path=.,,,D:\t1\tt.txt
  • checkpath返回:找到了所有包含的文件
  • 按下Ctrl+X Ctrl+L应该会自动匹配tt.txt中的内容,但是返回“未找到模式”

我错过了什么?


3
你尝试过阅读:help ins-completion吗? - Hauleth
5个回答

7

我认为实现你想要的唯一方法是使用自定义的 complete-function。请参阅 help complete-functions,查看(非常有用!)文档。这是我的解决方案:

首先,您需要一个单独的函数来静默地在文件中搜索字符串(如果您只调用裸的 vimgrep 函数,则如果没有匹配项,将会出现难看的错误)。

function! SilentFileGrep( leader, file )
    try
        exe 'vimgrep /^\s*' . a:leader . '.*/j ' . a:file
    catch /.*/
        echo "no matches"
    endtry
endfunction

现在,这是您的完成函数。请注意,您要搜索的文件的路径在此处是硬编码的,但如果您希望,可以更改为使用变量。我们调用 SilentFileGrep(),将结果转储到快速修复列表中。然后,我们从 qflist 中提取结果(修剪前导空格),清除 qflist 并返回结果。

function! LineCompleteFromFile(findstart,base)
    if a:findstart
        " column to begin searching from (first non-whitespace column):
        return match(getline("."),'\S')
    else
        " grep the file and build list of results:
        let path = <path_to_file>
        call SilentFileGrep( a:base, path )
        let matches = []
        for thismatch in getqflist()
            " trim leading whitespace
            call add(matches, matchstr(thismatch.text,'\S.*'))
        endfor
        call setqflist([])
        return matches
    endif
endfunction

为了使用这个函数,你需要将completefunc选项设置为指向它的位置。
set completefunc=LineCompleteFromFile

然后你可以使用<C-X><C-U>来调用补全,你可以很容易地将它映射到<C-X><C-L>

对我来说,这似乎运行得非常好,但没有完全测试。


我将这个插件进行了重写(并在我看来进行了改进),使其成为一个独立的插件,并且也可以作为标准的vim插件在https://gitlab.com/mcepl/vim-files-complete上使用。 - mcepl

2
在Vim的行自动完成帮助文档中写道,它只能在已加载的缓冲区中工作。为了解决这个问题,您可以在另一个缓冲区中打开您的“字典”文件,然后Vim将从该缓冲区中建议行。

1
  • 'path' 应该是一个目录列表,因此(假设在Windows上这是正确的语法):set path+=D:\\t1\\tt.txt 应该是 :set path+=D:\\t1\\ 或者 :set path+=D:\\t1

  • 'complete' 中的 i 表示补全候选项是从 当前和包含的文件中选择的。要使补全工作,必须包含一个文件:如果您没有显式地包含该文件,则无法进行补全。

    假设您创建了 ~/test/testfile,其中只有一行:

    lorem ipsum dolor sit amet
    

    您可以使用以下命令将其添加到 Vim 的 'path' 中:

    :set path+=~/test
    

    要在 C++ 文件中使用它作为补全源,您需要执行以下操作:

    #include <testfile>
    

    然后就可以执行:

    lore<C-x><C-f>
    

    以获得:

    lorem ipsum dolor sit amet
    
据我所知,它不能与像C或C++这样没有“include”机制的语言一起使用,因此您可以忘记将其用于Markdown、JavaScript、纯文本或者如果我的测试有任何指示,甚至是具有“include”的PHP。 如果您想要一个更通用的机制,只需将该文件添加到arglist中:它会自动用作完成源。
:argadd ~/test/testfile

0

如果你这样做

:set dictionary=<some file>

然后您可以使用ctrl + x,然后再使用ctrl + k来从<some file>中完成。

请参阅。

:help ins-completion

更多信息请查看。


1
问题是关于整行补全(CTRL-X CTRL-L)。“字典”是用来补全单词的,这不是问题所涉及的。 - glts

0
正如@black_wizard所指出的那样,另一个文件必须在缓冲区中加载。使用set hidden,您可以使用以下命令加载另一个文件并返回到先前的缓冲区:
command! -nargs=? XL silent edit <args> | silent bprevious

tt.txt加载到另一个缓冲区并返回到先前的缓冲区:

:XL tt.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接