lifepillar / vim-mucomplete

Chained completion that works the way you want!
MIT License
913 stars 18 forks source link

Cycle from bottom to top #59

Closed vimeitor closed 7 years ago

vimeitor commented 7 years ago

Hi!

I'm very sorry if there's a setting that already does that, but I haven't seen it in the docs (which are very good, I must say), and everything I've tried hasn't worked. I would love to cycle from bottom to top (tab goes up, while shift-tab goes down). The issue with the following mappings is that when not in complete mode, pressing tab will decrease the indent level, while s-tab while increase it, which is not what I'm looking for.

imap <tab> <plug>(MUcompleteBwd)
imap <s-tab> <plug>(MUcompleteFwd)

Is there any way I can do this? Thank you :)

lifepillar commented 7 years ago

There is currently no way to do what you want. But, why don't you just define your completion chains backwards? E.g.:

let g:mucomplete#chains   {'vim': ['keyn', 'cmd', 'file'], 'default': ['dict', 'keyn', 'omni', 'file']}

will allow you to complete the default chains “from top to bottom”, as you say, without the need to redefine <tab> or <s-tab>.

lifepillar commented 7 years ago

Ah, sorry, I didn't get it. You are referring to the pop-up menu… I may add an option to switch the direction. Stay tuned!

vimeitor commented 7 years ago

Thank you very much for the answer. Sorry for any misunderstanding. The reason I'm interested in that is that the results are ordered by when they appear in the code (when talking about the local file complete; basically the classic c-n/c-p). supertab has a good description

Why does navigate the completion menu from bottom to top? [...] Now on to the reasoning behind this. When using or to start insert completion, both populate the completion popup with the same list of words in the same order, the only difference is that highlights the nearest matching word located above the current cursor position, which is the result at the bottom of the completion popup. Without supertab installed, continuing to hit will walk up the list to next nearest word above the cursor.

I think Bram chose to display the results like this so that

  • the completion logic is the same for and , only the first entry to highlight differs
  • so that the behavior of mode is consistent, always moving up the list and when starting mode you don't have to switch over to using to get the next nearest entry, just continue to hit .
  • So, with supertab I wanted to preserve the same behavior. If is your default completion method (supertab defaults to this being the case), then will start it and additional uses of will move up the list instead of down so that you don't have to suddenly switch to using to get the next nearest result.

Why is the supertab default? The original supertab author found (and I agree with his finding) that while coding, the keyword match you want is typically the closer of the matches above the cursor, which naturally provides.

I have also found that I like the bottom results more, so I think it would be very cool if we could do that :) I mean, it would be even better if we could choose the order the results are displayed in, but that would most likely require a patch in vim.

lifepillar commented 7 years ago

How would you expect <tab> to work with other completion types? For instance, should omni-completion also starts highlighting the bottom entry? Or should the switch of direction be applied only to keyword completion (<c-x><c-n>, <c-x><c-p>, <c-n>, <c-p>)?

vimeitor commented 7 years ago

That's a very good question that I have asked myself as well. I guess in the name of consistency we would have to cycle backwards for each of the completion methods; otherwise, I think it would be counter-intuitive. What's your opinion on this? It really is unfortunate that vim (as far as I know) doesn't allow you to invert the results for local file completion. Maybe I could open an issue in the vim repository and see if the would be willing to accept a patch.

lifepillar commented 7 years ago

I agree that uniform behaviour is more intuitive. I have a working implementation of this already, but I have realized that I need to decouple some state (currently, there is one variable tracking both the fwd/bwd direction of the traversal of the completion chain and the up/down direction of navigation in the pop-up menu). And I think that there is an opportunity to simplify some code, so I want to think more about it.

lifepillar commented 7 years ago

MUcomplete now follows the “natural” direction of each completion method. All Vim's completion methods start by selecting the topmost entry (assuming completeopt does not contains noselect), except for ctrl-p completions (<c-p> and <c-x><c-p>), which always select the last entry. Consequently, while in the pop-up menu, now <tab> moves from top to bottom in all cases, except for ctrlp-p completions, where it moves from bottom to top.

Such behaviour may be overridden on a per-completion type basis by setting a new variable called g:mucomplete#popup_direction. So, if you want 'file' completion to be bottom-to-top, you need to put this in your vimrc:

let g:mucomplete#popup_direction = { 'file' : -1 }

If you also wanted to invert, say, ctrl-p completion, you might write this:

let g:mucomplete#popup_direction = { 'file' : -1, 'c-p' : 1 }

where 1 means “select from top to bottom” and -1 means “select from bottom to top”.

Please try the current master and let me know how it works for you.

vimeitor commented 7 years ago

Thank you so much :) I have been playing with it for a bit and it works really well. It's really cool you made it so customizable. I found that the combination of using keyp instead of keyn and making tab cycle from bottom to top works best for my case. Thank you for taking your time to implement this. Very much appreciated.