Using both <expr> mappings on <cr> and endwise
christianrondeau opened this issue · comments
Hi!
I'm trying to use vim-endwise and keep the ability to undo single lines. I have this in my vimrc:
inoremap <expr> <silent> <CR> pumvisible() ? "<C-y>" : "<C-g>u<CR>"
When I press enter, it inserts:
pumvisible() ? "" : "
I tried my own mappings with:
let g:endwise_no_mappings = 1
imap <expr> <silent> <CR> pumvisible() ? "<C-y>" : "<C-g>u<CR><Plug>DiscretionaryEnd"
But as you might expect, I get an infinite loop and inoremap
won't call the plug-in!
I guess this is similar to #10 but I don't have any conflicting plugins.
Any idea how to get out of this conundrum?
For it to nest properly, you need to use a <C-R>=...<CR>
map rather than an <expr>
map, I believe.
I have same problem, following @tpope suggestions solve the problem.
@dhanifudin can you share the complete line you used? I never got to actually make it work :)
@christianrondeau you just need replace <expr>
with <C-R>=...
this is mine
imap <C-R>=...<CR> pumvisible() ?
\ deoplete#mappings#close_popup() : "\<CR>\<Plug>AutoPairsReturn"
just realize I made a mistake, after read the vim documentation about mapping http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_1).
imap <CR> <C-R>=pumvisible() ? deoplete#mappings#close_popup() : "\n"<CR>
For the life of me I can't make it work :)
Your last example does not call vim-endwise, and the one before either (see my my test below).
Here's a few things I have tried (I would REALLY love to undo individual lines and use vim-endwise)
imap <CR> <C-R>=Handlecr()<CR>
function! Handlecr() abort
if(pumvisible())
return "\<C-y>"
else
return "\<C-g>u\<CR>\<Plug>DiscretionaryEnd"
endif
endfunction
This outputs:
<t_ý>RDiscretionaryEnd
If I remove the \<Plug>DiscretionaryEnd
part, it works for undo per line, but not for vim-endwise.
I also have tried:
imap <CR> <C-R>="\n\<Plug>DiscretionaryEnd"<CR>
which does the same, and using \<CR>
instead of \n
gives me a E114: Missing quote: "\
.
It seems like <C-R>
will not resolve <Plug>
mappings.
I'm sure there is a simple way out that allows both undoing individual lines AND enabling vim-endwise. Yesterday I have lost a bunch of lines by working on the plane on my tiny tablet, but I can't accept that Vim cannot do this. That would be a first :)
@tpope what would you think of a PR that would allow executing <C-G>u
in line breaks? The idea is not fully fleshed out, but it would be something like:
execute "imap <CR> <CR><Plug>DiscretionaryEnd" . exists('g:endwise_undolinebreaks') ? "<C-G>u" : ""
Note that I tried adding a <C-G>u
before the actual line break too, so that when you press <CR>
, the first undo removes the endif
and the second removes the line break itself but it gets into an infinite loop. I didn't take the time yet to understand why.
But this works fine for me as-is; it allows me to undo every line break as expected... I could also use g:endwise_no_mappings
and do it just in my vimrc
, but I thought this might be a useful feature to have in vim-endwise
. What do you think?
I changed a similar <expr>
map for <CR>
to be a <C-R>=...<CR>
map and it works. However vim-endwise ignores my map's <silent>
when it re-maps the maps.
Would it be possible to add in a <silent>
in this case? Happy to attempt a pull request.
@christianrondeau I think if you inoremap <CR> <C-G>u<CR>
it before endwise loads it should do what you expect?
@airblade Off the top of my head I can't think of any reason we can't add <silent>
unconditionally.
@tpope this works... This sounds too simple to be true, but it looks like it is! I'll report back if I find something, but defining the mapping before vim-endwise seems to be the now obvious solution :) Thanks for looking into this!