ervandew / supertab

Perform all your vim insert mode completions with Tab
3.17k stars 216 forks source link

Only reverse completion menu when completion has been invoked by SuperTab (`<C-n>`) #113

Open blueyed opened 10 years ago

blueyed commented 10 years ago

When the completion has been invoked by e.g. YouCompleteMe or manually somehow, <Tab> should not cycle the completion menu in reverse, if the mode being used is <C-p> (as explained in the FAQ ("Why does navigate the completion menu from bottom to top?" ref).

SuperTab could maybe set an internal variable, if it triggered the completion and then behave accordingly.

TEST CASE:

  1. Trigger completion manually using <c-n>
  2. Press <Tab>

After initially the first element has been selected, after tab, the last one is.

For some reason it works when using omni completion (<C-x><C-o>), and b:complType is being set to` in that case.

This appears to get triggered through: imap =ManualCompletionEnter()

Maybe <c-n> should get mapped to get informed about the mode being used, too? I could not find the place where this gets done though - SuperTab seems to be the only plugin/place which controls this variable.

ervandew commented 10 years ago

The only way I can think to reliably solve this would be to go back to mapping <c-n> and <c-p> , but one of the main reasons I removed those mappings was to provide a means to completely bypass supertab if you want and go back to using the stock vim behavior (that and the philosophy that fewer mappings are better).

So, I think I'm of the opinion that YCM should delegate to supertab (if available) for keyword completion like several of the snippet plugins do, but I'm not all that familiar with YCM and more specifically the use case that is triggering this issue.

blueyed commented 10 years ago

My current use case is to call YouCompleteMe via SuperTab's chaining, which appears to work as expected, since it sets b:complType to ^X^U.

let g:SuperTabDefaultCompletionType = "<c-p>"
autocmd FileType *
  \ if &omnifunc != '' |
  \   call SuperTabChain('youcompleteme#OmniComplete', "<c-p>") |
  \   call SuperTabSetDefaultCompletionType("<c-x><c-u>") |
  \ elseif &completefunc != '' |
  \   call SuperTabChain(&completefunc, "<c-p>") |
  \   call SuperTabSetDefaultCompletionType("<c-x><c-u>") |
  \ endif

The problem I've described above only happens when the chaining is not being setup.

FWIW, it's good enough to keep using <c-n> if you've initiated completion this way.

But maybe SuperTab could just notice/remember when it was called via its mapping, check if the mode is <c-p> and only reverse the direction in this case?

blueyed commented 10 years ago

YouCompleteMe is making sure to stay in completion mode to always refresh its completions. Therefore it's by the design that it does not forward on empty results.

I wonder if that would be feasible for SuperTab's chaining, too, where it could call the defined function again on every cursor move, but that's probably out of scope given that the chaining triggers Vim's internal completion in the end. I assume there's no way to get the completions <c-p> would provide and handle them internally?

ervandew commented 10 years ago

I created a new branch (supertab_tracking) which now tracks when supertab initiates the completion mode and decicdes which direction <tab>/<s-tab> should advance in. I have a feeling there are going to be some really subtle, hard to track down issues that this won't catch or will cause, so let me know if you run into problems with it. I should also note that this change effective breaks the <tab>/<s-tab> behavior when initiating completion with <c-p>, since supertab still won't know how the completion was initiated, just that it didn't initiate it.