Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support <c-h> in g:AutoPairsMapBS (and ps, thanks!) #90

Closed
sodapopcan opened this issue Sep 10, 2024 · 7 comments
Closed

Support <c-h> in g:AutoPairsMapBS (and ps, thanks!) #90

sodapopcan opened this issue Sep 10, 2024 · 7 comments

Comments

@sodapopcan
Copy link

Hiya @LunarWatcher,

I just switched to this plugin after several years of using Kana's smartinput plugin. I knew I had to switch no matter what as soon as I read "1. Upgrade to Vim" in the README 🤣 So far it's working great and fixes an issue I always had with smartinput but never bothered reporting since it seemed largely unmaintained (i_<CR> did not work for square brackets).

One thing that did work in smartinput is using <c-h> as backspace (to delete closing pair) which I do all the time (less of a stretch!). I'm happy to make a PR but thought I'd ask first (also happy to let you do it if you'd prefer).

More controversially (and this is something that didn't work in smartinput either): I'm a user of rsi.vim so on top of <c-h> I also sometimes hit <c-w> hoping it will also delete the closing bracket. I'm totally onboard with being conservative and not checking for the presence of other plugins (especially since <c-w> conflicts with the default termkey) but I thought I would ask!

Thanks for the great plugin and the lolz :)

Andrew

@sodapopcan
Copy link
Author

PS, I just experienced it working with """ as well! I could cry 🥲 Even the way """ auto-pairs is nicer. I'm going to have to untrain my """<cr><esc>O muscle memory but that is nice problem to a very nice problem to have :)

@LunarWatcher
Copy link
Owner

Thanks for the great plugin and the lolz :)

You're welcome :) Always nice to hear it's being used ^^


I don't think I want to add <C-h> back, largely just because it's an extra two config options for minimal value for most people.

What you can do, however, is add this to your vimrc:

imap <C-h> <BS>

That'll recursively remap <C-h> to <BS> , so as long as you set g:AutoPairsBS = 1, it'll delete pairs. As an added bonus, it'll work as backspace everywhere, even if you eventually uninstall auto-pairs, and (in theory) work with anything else mapped to <BS>, if anything - as long as the <BS> maps are well-defined anyway, but that's a tangent.


As for <C-w>, this is more involved, but something I would be interested in supporting.

Not sure what <C-w> is for you (if it differs from the standard), but it's commonly used for word deletion, so preserving default behaviour would be nice here.

Right now, <BS> is hard-coded in AutoPairsDelete in multiple places:

return "\<BS>"
end
let [before, after, ig] = autopairs#Strings#getline(b:AutoPairsMultilineBackspace)
if b:AutoPairsBSIn == 1
for [open, close, opt] in b:AutoPairsList
if !opt["delete"] || close == ''
" Non-deletable pairs? Skip 'em
continue
endif
let rest_of_line = opt['multiline'] ? after : ig
let b = matchstr(before, autopairs#Utils#escape(open, opt) .. '\v\s?$')
let a = matchstr(rest_of_line, '^\v\s*' .. autopairs#Utils#escape(close, opt))
if b != '' && a != ''
if b[-1:-1] == ' '
if a[0] == ' '
return "\<BS>\<DELETE>"
else
return "\<BS>"
end
end
return autopairs#Strings#backspace(b) .. autopairs#Strings#delete(a)
end
endfor
endif
if b:AutoPairsBSAfter == 1
" delete the pair foo[]| <BS> to foo
for [open, close, opt] in b:AutoPairsList
if !opt["delete"]
continue
endif
if (close == '')
continue
endif
let m = autopairs#Strings#matchend(before, autopairs#Utils#escape(open, opt) .. '\v\s*' .. autopairs#Utils#escape(close, opt) .. '\v$', 0)
if len(m) > 0
return autopairs#Strings#backspace(m[2])
elseif opt["multiline"] && b:AutoPairsMultilineBackspace
let m = matchstr(before, '^\v\s*' .. autopairs#Utils#escape(close, opt))
if m != ''
let b = ""
let offset = 1
" a = m
while getline(line('.') - offset) =~ "^\s*$"
let b ..= getline(line('.') - offset) .. ' '
let offset += 1
if (line('.') - offset <= 0)
return "\<BS>"
endif
endwhile
let a = matchstr(getline(line('.') - offset), autopairs#Utils#escape(open, opt) .. '\v\s*$') .. ' '
if a != ' '
return autopairs#Strings#backspace(a) .. autopairs#Strings#backspace(b) .. autopairs#Strings#backspace(m)
endif
endif
end
endfor
endif
return "\<BS>"

Some, but not all, need to be replaced with a variable, and I'm not sure which (aside the ones on line 253 and 316 - I haven't looked at that code in ages, and most of it remains undocumented dark magic from jiangmiao's original code). That would let the function be defined for multiple different ways to delete text, but still handle pair deletion. I think the exact non-<BS> implementations are gonna have to be user config. The goal would be to allow this in the .vimrc:

inoremap <silent> <C-w> <C-R>=AutoPairsDelete("\<C-w>")<CR>

Though I'm not entirely sure if that can be a global map. Problem for later.

If you want to try implementing this, it shouldn't be too hard - it's mostly a matter of replacing the right instances of <BS> with an optional function parameter that defaults to <BS>. That should also mean none of the <BS> maps in the code or in the wild break.

If not, I'll implement it tomorrow. Out of capacity today unfortunately

@sodapopcan
Copy link
Author

sodapopcan commented Sep 10, 2024

Hey, thanks for the response!

I think I'm ok with remapping, I can't imagine it being a problem! I'm a little confused, though, because even Vim says <c-h> and <bs> are interchangeable (see :h i_CTRL-H)! I thought maybe it's because I'm using Kitty but I tried in another terminal with the same result. On the other hand, you can't map <cr> without affecting <c-m> nor can you remap <tab> without also affecting <c-i> but my knowledge of how terminal codes work is, well, I really know any knowledge there! But again, happy to reamap.

Yes, <c-w> is word deletion for me which is provided through rsi.vim--I'm very much a "vim motions in normal mode, readline everywhere else kinda-person, including my OS and Vim's insert and command modes. This of course means I have to use another termkey though I don't use :term much as shell prompt anyway, usually just for opening temporary programs (like REPLs) that ++close on exit. I mostly stick to terminal splits for additional command prompts.

I certainly won't have time tonight or the next few days to implement but if you haven't gotten to it by the weekend I may give it a shot!

Thanks again!

@LunarWatcher
Copy link
Owner

LunarWatcher commented Sep 11, 2024

I think I'm ok with remapping, I can't imagine it being a problem! I'm a little confused, though, because even Vim says and are interchangeable (see :h i_CTRL-H)! I thought maybe it's because I'm using Kitty but I tried in another terminal with the same result.

IIRC, it treats them the same internally, but they are still two different maps. Terminal code conversion is... complicated.

Yes, is word deletion for me which is provided through rsi.vim

Hm, that might add some complexity to the final map. Will have to look into that. Could've sworn <C-w> was a builtin, but /shrug

I checked. <C-W> is not overridden by rsi.vim, so it is using the builtin

@sodapopcan
Copy link
Author

Terminal code conversion is... complicated.

This was all I knew about them before! 🙃

I checked. <C-W> is not overridden by rsi.vim, so it is using the builtin

D'oh, my bad. It's been so long that I never remember what's what (and never use other peoples' vims).

@LunarWatcher
Copy link
Owner

D'oh, my bad. It's been so long that I never remember what's what (and never use other peoples' vims).

All good, I lose track of what's built-in regularly myself :p

@LunarWatcher
Copy link
Owner

Closing this up, if you update the plugin, you should be able to add

inoremap <silent><expr> <C-w> autopairs#AutoPairsDelete("\<C-w>")

to your vimrc, and <C-w> should now be able to delete pairs in addition to words. There's tests for it (and I've tested it manually), but let me know if anything breaks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants