roxma / nvim-completion-manager

:warning: PLEASE USE https://github.com/ncm2/ncm2 INSTEAD
MIT License
917 stars 49 forks source link

Restoring default `CTRL-X CTRL-N` behavior #24

Closed rafaeln closed 7 years ago

rafaeln commented 7 years ago

This is a great plugin you wrote. Thanks for sharing!

Something I use frequently and which this plugin breaks a bit is this:

CTRL-X CTRL-N or CTRL-X CTRL-P Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will copy the words following the previous expansion in contexts unless a double CTRL-X is used.

With nvim-completion-manager, I have to type CTRL-X CTRL-N CTRL-N to get the same effect. Do you know any workarounds?

roxma commented 7 years ago

This is related to completeopt managed by this plugin

I don't have a neat workaround, but this might help:

inoremap <C-X><C-N> <C-X><C-N><C-N>
roxma commented 7 years ago

Maybe I could implement an auto popup completion source wiht this sort of behavior

rafaeln commented 7 years ago

Thanks. That's a pretty straightforward workaround. I'll give it a try. A completion source that had this sort of behavior would be even more awesome, and would be an improvement on vim's default behavior. The most awesome improvement, though, and I don't even know if this could be implemented, would be to allow this sort of ‘continue completing’ behavior with any source. You would be able, for instance, to complete a word from another tmux window, then keep copying the following words from the other tmux window with (or whatever mapping).

rafaeln commented 7 years ago

Just a quick update: for some reason, inoremap <C-X><C-N> <C-X><C-N><C-N> doesn't do what we thought it would.

roxma commented 7 years ago

@rafaeln

Hi, I've added a source for this.

Pick a key to map to <Plug>(cm_force_refresh)

imap <c-g> <Plug>(cm_force_refresh)

I also have tab mapping

      " smart tab for auto complete
      inoremap <expr> <silent> <Tab>  pumvisible()?"\<C-n>":"\<TAB>"
      inoremap <expr> <silent> <S-TAB>  pumvisible()?"\<C-p>":"\<S-TAB>"

<Tab> for selecting the popup item, <c-g> for refreshing the popup menu. So the key pressed in this screencast is <TAB><c-g><TAB><c-g>...

output

rafaeln commented 7 years ago

This is awesome! But it's unfortunately not working here.

I am running the latest dev version of neovim. My .config/nvim folder only contains the folders from nvim-completion-manager and the following minimal init.vim:

inoremap <expr> <silent> <Tab>  pumvisible()?"\<C-n>":"\<TAB>"
inoremap <expr> <silent> <S-TAB>  pumvisible()?"\<C-p>":"\<S-TAB>"
imap <c-g> <Plug>(cm_force_refresh)

In a buffer like the following (cursor is |)

something I would like to tell you gentlemen
some|

I get the popup, in pink, then press <tab> to complete some into something, which works, and makes the popup gray, and then I press <c-g>, but instead of getting the expected result, the only thing that happens is that the popup menu, still only containing the word something, changes color back pink. Keeping pressing <tab> and <c-g> will only keep changing the popup menu from gray to pink to gray to pink and so on.

Do you have any idea of what might be going on?

roxma commented 7 years ago

Try press a space, then <c-g> to force display of popup menu.

Your first popup comes from keyword of current buffer completion source.

The completion source added for this will be auto triggered after three mached word, then a space character. Or a single matched word, a space character, then <Plug>(cm_force_refresh) to force update.

It does not popup for a part of word without previous matched word, which does not make much sense, IMO.

roxma commented 7 years ago

<Plug>(cm_force_refresh) is not necessary for the auto triggered popup.

I've just pushed some refinement on the popup item, so it should look better.

output

roxma commented 7 years ago

I think It would be more convinent to have popup for the rest of line like this:

output

rafaeln commented 7 years ago

Oh, I see. I wasn't typing <space> between completing the first word and typing <c-g>. Thanks once more for sharing this plugin and putting together this source.

rafaeln commented 7 years ago

This completion source lacks one feature of vanilla <c-x><c-n> completion, namely, the ability to undestand other non-word characters besides <space>

Using vanilla vim, if my text is as follows (| is the cursor)

\tikzset{frontier/.style=\bold}

\tik|

I can <c-p><c-x><c-p><c-x><c-p><c-x><c-p><c-x><c-p> and get

\tikzset{frontier/.style=\bold}

\tikzset{frontier/.style=\bold}|

That is, the vanilla <c-x><c-n> completion mechanism understands {, /, = and so on as whitespace characters.

roxma commented 7 years ago

@rafaeln I've pushed an update.

By the way, there's difference between vim's builtin <c-p><c-x><c-p> and this completion source that I'm not gonna fix.

The builtin key is usually typed at the end of a word, and then the completions completes the next non-word sequence, and the next word.

But the source added here is usually triggered at the beginning of a word, then it completes the word, and the next non-word sequence. IMO, it's more consistent among NCM sources with this behavior.

rafaeln commented 7 years ago

I actually suspect that NCM's multi-word completion source is an improvement on vanilla vim's <c-x><c-p> completion mode. Indeed, very often, when I'm using the vanilla feature to complete only the beginning of some code, after I'm done <c-x><c-p>'ing, I end up having the press <c-w> once in order to delete the last word vim added and keep only the last whitespace character it added. Using NCM's multi-word completion source, that last step won't be required.

rafaeln commented 7 years ago

This last commit introduced a bug, though. The picture below shows what it is.

image

roxma commented 7 years ago

Sorry on that, I've pushed a new fix.

rafaeln commented 7 years ago

This fixed it!

roxma commented 7 years ago

Just an update, I disabled the auto popup of this feature by default, since the current implementation scans all openning buffer, at every completion calculation.

And the auto popup after 3 previous matching word seems not appropriate for programming languages.

This setting could be overrided, :help cm_sources_override and the auto_popup option of the source.

This change does not affect the behavior of <Plug>(cm_force_refresh)

rafaeln commented 7 years ago

Cool. So, talking about multi-word completion, let me report an inconsistency in behavior.

If in a line the last character before \n is a non-space non-word characters, such as }, multi-word completion wraps into the next line (which is also how vanilla vim's multi-word completion behaves). It the last characters before \n is a word character, multi-word completion is restricted to that single line.

Try it on this file:

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

something they would like to tell you gentlemen}

\tikzset{every node/.style=\it}
roxma commented 7 years ago

This is duplication filtering behavior of current implementation, it simply filters the duplicated word, which is they in this case. Normally the highest rank won't be filtered, which is determined by the number of previous match, but here, the two lines have the same rank.

If I change the line order into this, the } will be completed.

something they would like to tell you gentlemen}

\tikzset{every node/.style=\it}

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

output

rafaeln commented 7 years ago

I think I didn't explain well. Let me try again.

If you have the text (| is cursor)

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

something they would like to tell you gentlemen|

And you press <c-g>, you don't get any more suggestions, because you hit the end of the line.

But if you have the text (| is cursor)

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

\tikzset{every node/.style=\it}|

And you press <c-g>, you get other, from the next line down:

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

\tikzset{every node/.style=\it}other|
roxma commented 7 years ago

Now I understand what you mean.

This is kind of intended, becasuse I'm not sure how to refine it to a more proper behavior.

I need some advice.

By the way, It seems impossible for completion result to expand to the next line.

rafaeln commented 7 years ago

It's not really a bug. It's just inconsistent. I rarely find it useful to wrap completion into the next line, the default vim multi-word completion behavior. But sometimes it's useful. Like if you're completing into a multi-word expression, such as in the example below:

Given the context of the international solidarity
movement, I would state that ...

...

The international|

Where <c-x><c-p><c-x><c-p><c-x><c-p> would give you

Given the context of the international solidarity
movement, I would state that ...

...

The international solidarity movement|

This kind of line-wrapping completion is possible with vanilla vim multi-word completion, but it isn't possible with NCM's multi-word completion source.

roxma commented 7 years ago

A snippet engine like would be able to expand multiple lines. See this feature supported recently, https://github.com/roxma/nvim-completion-manager/issues/36

It is possible, to make the completion item expandable (snippet)

When ultisnips is triggered, it expands the whole line, then jump to the next line.

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

something they |

press <c-g> for completion:

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

something they would|

press ultisnips expand trigger:

something they would like to tell you gentlemen

\tikzset{every node/.style=\it}

other things

something they would like to tell you gentlemen
|

But this does not solve the inconsistent. Since the behavior of <c-g> is still the same.

rafaeln commented 7 years ago

I wasn't aware ultisnips was that flexible. I'll go read the documentation. I don't think the inconsistency is a real issue. There's always the workaround of resorting to vim's vanilla multiword completion mechanism whenever the rare occasion arises where I'd like to complete to wrap into the next line.