tpope / vim-endwise

endwise.vim: Wisely add

Home Page:https://www.vim.org/scripts/script.php?script_id=2386

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!