Reputation: 3557
Can line completion Ctrl+X Ctrl+L be used to show line completions from a specific external file instead of "only" from the current buffer? Something like dictionaries, but for lines.
Update:
To test I did following:
tt.txt
with some test lines:set path+=D:\\t1\\tt.txt
:set complete ?
returns complete =.,w,b,u,t,i
:set path ?
returns path=.,,,D:\t1\tt.txt
checkpath
returns: All included files were foundWhat am I missing?
Upvotes: 4
Views: 821
Reputation: 196809
'path'
is supposed to be a list of directories so (assuming that's the correct syntax on Windows) :set path+=D:\\t1\\tt.txt
should be :set path+=D:\\t1\\
or :set path+=D:\\t1
.
The i
in 'complete'
means that the completion candidates are chosen from current and included files. You must include a file for completion to work: it won't if you don't explicitly include that file.
Say that you have created ~/test/testfile
with this single line:
lorem ipsum dolor sit amet
You add it to Vim's 'path'
with:
:set path+=~/test
To use it as completion source in a C++ file you would do:
#include <testfile>
and be able to do:
lore<C-x><C-f>
to get:
lorem ipsum dolor sit amet
As far as I know, it doesn't work with languages that don't have an include
mechanism like C or C++ so you can forget about it for Markdown, JavaScript, plain text or, if my tests are any indication, even PHP which does have include
.
If you want a more generic mechanism, just add that file to the arglist: it will automatically be used as a completion source:
:argadd ~/test/testfile
Upvotes: 1
Reputation: 15735
I think the only way to achieve what you want is with a custom complete-function. See help complete-functions
for the (very useful!) documentation. Here's my attempt at a solution:
First you need a separate function to silently grep a file for a string (if you just call the naked vimgrep
function you will get an ugly error if there are no matches).
function! SilentFileGrep( leader, file )
try
exe 'vimgrep /^\s*' . a:leader . '.*/j ' . a:file
catch /.*/
echo "no matches"
endtry
endfunction
Now, here's your completion function. Note that the path to the file you want to search is hard-coded in here, but you could change it to use a variable if you so wish. We call SilentFileGrep()
, which dumps the results in the quickfix list. Then we extract the results from the qflist (trimming the leading whitespace) and clear the qflist before returning the results.
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
To use this function, you need to set the completefunc
option to point at it:
set completefunc=LineCompleteFromFile
Then you can use <C-X><C-U>
to invoke the completion, which you could easily map to <C-X><C-L>
.
This seems to work pretty well for me, but it is not exhaustively tested.
Upvotes: 7
Reputation: 5756
As @black_wizard points out, the other file must be loaded in a buffer. With set hidden
, you can use the following to load another file and return to the previous buffer:
command! -nargs=? XL silent edit <args> | silent bprevious
To load tt.txt
into another buffer and return to the previous one:
:XL tt.txt
Upvotes: 0
Reputation: 5057
In Vim help for line completion it's written that it only works for loaded buffers. As a workaround, you may open your "dictionary" file in another buffer and Vim will suggest lines from this buffer.
Upvotes: 2
Reputation: 6258
If you do
:set dictionary=<some file>
then you can use ctrl + x followed by ctrl + k to complete from <some file
>
See
:help ins-completion
for more info.
Upvotes: 0