lifepillar / vim-mucomplete

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

Allow the user to choose the complete sequence of keys to exit Ctrl-X submode #41

Closed lacygoill closed 7 years ago

lacygoill commented 7 years ago

Hello,

Currently, by default, the plugin relies on the key sequence C-x C-b BS to exit the CTRL-X submode. I can't use it because I want to use the same key binding, C-b, to move the cursor backward in insert mode inside Vim, as the one I use inside the shell, or any program using the readline library.

Fortunately, the plugin also allows the user to choose a different key sequence thanks to the global variable g:mucomplete#exit_ctrlx_keys. However, it's only used as a suffix to <C-x>. I may have missed some, but the only other working key sequences beginning with C-x seem to be C-x C-g BS and C-x C-z BS.

So, one could probably write inside their vimrc:

let g:mucomplete#exit_ctrlx_keys = "\<c-g>\<bs>"

Or:

let g:mucomplete#exit_ctrlx_keys = "\<c-z>\<bs>"

The problem is I use the unicode.vim plugin, which installs mapping using the key sequences C-x C-g and C-x C-z.

I found another working key sequence C-g C-g. Besides, it fits the Vim idiom which puts various insert mode mappings behind the C-g prefix. And it's not used, which is confirmed by hitting :h i_^g then C-d, or by looking at the output of :echo map(taglist('^i_CTRL-G'), 'v:val.name').

I'm not asking to change the default value of C-x C-b BS. I know you don't want to, and I understand the reasoning. The help explicitly tells us that C-b is not mapped to anything in insert mode (as explained in :h i_^b). This makes C-b the perfect candidate for the trick which is needed by the plugin, and to make sure we are out of the CTRL-X submode before hitting the completion mapping of any given method.

What I'm asking is a way to use any exit key sequence, including ones which don't begin with C-x. Currently it's not possible because of this line:

let s:cnp = "\<c-x>" . get(g:, 'mucomplete#exit_ctrlx_keys', "\<c-b>\<bs>")

Would it be possible to let the user choose the whole key sequence, and not just the suffix?

Besides, if the user already mapped something to C-b in insert mode, what do you think about recommending them some alternative choices in the help?

Finally, what do you think about adding a warning message, in case the user already mapped something to C-b or C-x C-b. Maybe something like:

if !empty(mapcheck("\<c-x>\<c-b>", 'i')) || !empty(mapcheck("\<c-b>", 'i'))
    echohl WarningMsg
    let msg = "Warning: you have a mapping whose {lhs} is / begins with C-x C-b or C-b\n\n".
            \ "MUcomplete hits those keys before hitting the keys of some methods.\n".
            \ "It does this to make sure you are out of C-x submode before trying them.\n\n".
            \ "Your current mapping could lead to some unexpected behavior.\n".
            \ "Please remove/change it.".
            \ execute('verb imap <c-x><c-b>')."\n".
            \ execute('verb imap <c-b>')."\n\n"
    echo msg
    echohl None
endif

It's just a sketch, I'm sure you would find a better way to formulate the message. I could also try and submit a PR if you want. It uses execute() which would need to be replaced with :redir. Here, it's used to display the output of:

verb imap <c-x><c-b>
verb imap <c-b>

The :verbose modifier command would allow the user to see from which file the mapping was installed, which can help in case they have a lot of plugins and don't know which one is involved. From there, they could decide if they want/can disable the mapping to avoid any unexpected behavior from mucomplete, or keep it and change the value of g:mucomple#exit_ctrlx_keys.

Without a warning message, a user which doesn't read the documentation, and already mapped something to C-b, could get the wrong impression that the plugin doesn't work properly.

Thanks in advance for your help!

lifepillar commented 7 years ago

I have changed the default mapping to <c-g><c-g>, which seems to work well and it looks less like a hack. The new setting is called g:mucomplete#ctrlx_mode_out. The old variable g:mucomplete#ctrlx_exit_keys has been removed.

Thanks for the report!