Closed Konfekt closed 7 years ago
In your example, when i hit /home/
and press tab until i select the user subfolder i already get a / at the end: /home/user/
. I can't hit tab nor / to try another nested folder, what i have been doing is /
and get the tab trigger when we hit /
like in the example bellow. I think that would be a good enhancement.
So we shouldn't get the latest /
MUcomplete uses Vim's default file completion, so that is not possible.
Yes, Vim uses a trailing slash / to indicate a Directory whereas YCM adds an extra column to indicate either directory or file. So the slash is already there.
With these mappings, Vim works like ZSH, for example, where a trailing slash indicates a Directory as well,but sill hitting / enters the selected subfolder.
The following setting may help, too:
let g:mucomplete#trigger_auto_pattern = { 'default' : g:mucomplete#pathsep . '$\|\k\k$' }
After completing part of a path, you may type any character followed by backspace to have the pop-up menu appear again with a list of subdirectories. Not ideal, but it works without any changes in µcomplete.
I've tried @Konfekt's idea and it seems a good compromise to me, well fit to the way Vim's file completion works (and it may be familiar to zsh users, too). I am a bit reluctant, though, to remap such a common character such as a (back)slash. It could be offered as an option.
On the other hand, it shouldn't be difficult to implement YCM's file completion in a function, which could be used as an additional completion method, similar to the way 'ulti'
is implemented. YCM does it in Python, I think, but it could be done in pure Vim, too. The tricky part would be making it portable and robust: the Dirvish plugin might be a source of inspiration. Pull requests are welcome :)
the Dirvish plugin might be a source of inspiration
On a second thought, this might not be a good idea, because µcomplete is in the public domain, while Dirvish is licensed through the GPL.
It would have to reimplement the completion list from scratch, by systemlist( has('win32') ? 'ls' : 'dir')
? Because Vim's file completion is robust, and mu-complete already supports it, it seems overkill to add another, untested, file completion to avoid mapping slash in insert mode.
But making it a documented option, is a good compromise.
It would have to reimplement the completion list from scratch
Yes, but I'd rather do something along these lines:
fun! PathCompleteDraft() abort
let l:prefix = matchstr(strpart(getline('.'), 0, col('.') - 1), '\f\+$')
if strlen(l:prefix) > 0
let l:candidates = map(glob(l:prefix.'*', 0, 1, 1),
\ '{
\ "word": v:val,
\ "menu": (isdirectory(v:val) ? "[dir]" : "[file]")
\ }')
if !empty(l:candidates)
call complete(col('.') - len(l:prefix), l:candidates)
endif
endif
return ''
endf
This is not devoid of its own difficulties, though: to make it work like YCM, some code should be executed at CompleteDone
, too. Complicating µcomplete only for this use case seems overkill for me, too.
@Konfekt @josefson Would you mind trying the path-completion
branch? I have added an experimental 'path'
method, which behaves similarly to what @josefson has suggested. The 'file'
method is unchanged for now.
As i see the branch is behaving like this:
I have added an experimental 'path' method, which behaves similarly to what @josefson has suggested.
I think you are being modest @Konfekt. From what i have tested so far, it behaves exactly like that.
Let me take this opportunity and thank you again for the work input you have been putting in this amazing plugin. A simplistic, yet fresh concept in autocomplete land for vim, which brought together some advantages that i didn't see put together before. I hope vimland get to test it, and maybe enjoy it like i am. I know you deserve some love for the great work you have been putting into it. Thanks man.
I have also implemented @Konfekt's suggestion, but a bit differently. Now 'file'
completion works as follows: when accepting a menu entry with <c-y>
, file completion is triggered again. Using <c-y>
is standard Vim's mapping, and there is no need to remap /
(of course, a user may still do it, if desired).
Please try the path-completion
branch and let me know how it works for you. I'd like feedback especially from Windows users, since I cannot test in Windows.
@josefson Thanks for the kind words. I've got much from Vim and the Vim community, giving something back is only fair. Plus, it's fun!
Just wondering: can YCM deal with paths containing spaces? Vim's file completion does not.
file
completion-method(path-completion branch) and it is also very satisfying. I could have lived with it.
file
or / on path
get out of the scope method. That should be a pain, for windows users mainly, i think most unix users avoid the use of spaces on filenaming. Good catch.@Konfekt @josefson Both the features you have requested have been implemented and are available in the current master, so I'm closing this. Please open new issues if you need to report bugs.
…and don't forget to read the docs!
Well done!
The documentation is off: The mapping of the thread is a différent one. The check if a file path is being completed is missing. Otherwise / ends completion in général. That's not intended.
I have updated the documentation: do you still find that there is something unclear?
Re the unintended behaviour, can you please elaborate?
Intended, no problem with indentation. The point was that
inoremap <expr> / pumvisible() ? "\<c-y>" : '/'
does not check if one is completing a file path. Thus, /
will always end completion. That's only intended, that is, wanted, when completing file paths.
The original mapping
let s:slash = has('win32') ? '\' : '/'
exec 'inoremap <expr> ' . s:slash . ' '
\ . '(pumvisible() && <SID>isBehindDir()) ?'
\ . '"<C-Y><C-X><C-F>" : "' . s:slash . '"'
let s:escaped_slash = escape(s:slash, '\')
function! s:isBehindDir()
return getline('.') =~# '\f\+` . s:escaped_slash . '$'
endfunction
makes this additional check. (Note that now <c-x><c-f>
is superfluous.)
Ah, right. I have updated the example in the documentation, adding your code (slightly modified to make it more general).
Perfect!
Perhaps this mapping is useful when completing file paths, and could become an option or make it into the docs:
When completing a file path (say
/home/
and hitting<tab>
) , and after having chosen a directory by iteratively hitting<tab>
(say/home/user
) , hitting/
allows you to continue completing the file names inside it (that is,/home/user/...
: