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

Auto pair-removal #2940

Merged
merged 5 commits into from
Jul 22, 2022
Merged

Auto pair-removal #2940

merged 5 commits into from
Jul 22, 2022

Conversation

Houkime
Copy link
Contributor

@Houkime Houkime commented Jul 2, 2022

Fixes #1673
Supersedes #1379
No problems with multiple selections observed.
Putting match inside tuple would hurt readabilty - these tuples already take a while to comprehend.

Simple logic inspired by Godot 3.x stable branch:
https://github.com/godotengine/godot/blob/14f69acaa4ef80b235ef78f9caac1072daf8008b/scene/gui/text_edit.cpp#L2101
https://github.com/godotengine/godot/blob/14f69acaa4ef80b235ef78f9caac1072daf8008b/scene/gui/text_edit.cpp#L2054

helix-term/src/commands.rs Outdated Show resolved Hide resolved
helix-term/src/commands.rs Outdated Show resolved Hide resolved
@archseer
Copy link
Member

archseer commented Jul 2, 2022

\cc @dead10ck

@dead10ck
Copy link
Member

dead10ck commented Jul 2, 2022

This implementation is pretty much the same exact mechanism as #1379 (i.e. look ahead and behind one char and return a delete, see here) and so has exactly the same problem (which I've verified by pulling this branch locally and testing manually):

it does work, but only for one-width cursors. If it's in a selection, the head ends up moving back two characters, when it should only move back once, e.g. [word(]) -> [wor]d

The implementation of this should live in the auto_pairs module so that it can also reuse all the logic that ended up being necessary to handle computing the right selection. See here. The problem with this is as I described in #1379.

I would also want to see test coverage to verify that the intersection of all text edit cases works, as I described in this comment. I'm afraid the solution won't be this simple. It's why I've delayed trying until after we have an integration testing suite, which we have now. I plan on working on this after I finish up the write path fixes in #2267, if no one gets to it before me.

@archseer
Copy link
Member

archseer commented Jul 2, 2022

Yeah it doesn't fully fix it but the plan was to at least implement this for 1-width selections which should solve this for majority editing of cases.

@dead10ck
Copy link
Member

dead10ck commented Jul 2, 2022

Yeah it doesn't fully fix it but the plan was to at least implement this for 1-width selections which should solve this for majority editing of cases.

With respect, I don't think this is as uncommon as you may think. The test case above is going to happen any time the user enters append mode, or does a select all -> search for text, and then deletes chars and runs into a pair, e.g. empty strings, function calls with no arguments, slices, etc, etc. And it may not even be visible to them if it happens off screen.

@dead10ck
Copy link
Member

dead10ck commented Jul 2, 2022

On the other hand, I saw it suggested in the chat room that we could make this behavior only happen specifically when the range is single width, otherwise fall back to the regular single char delete. If that constraint were added, this would indeed be a good workaround until it can be fixed in a more general way for selections too.

@Houkime
Copy link
Contributor Author

Houkime commented Jul 2, 2022

On the other hand, I saw it suggested in the chat room that we could make this behavior only happen specifically when the range is single width, otherwise fall back to the regular single char delete. If that constraint were added, this would indeed be a good workaround until it can be fixed in a more general way for selections too.

done in 005f4c6

@Houkime Houkime requested a review from archseer July 2, 2022 17:05
Copy link
Member

@dead10ck dead10ck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me. A couple of minor comments, neither of which I'd consider blockers, but would be good changes to make. Integration tests would be even better.

Thanks for your contribution!

// delete both autopaired characters
{
(
graphemes::nth_prev_grapheme_boundary(text, pos, count),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might get a bit tricky with the count. If we just delete n chars in both directions, this will be wrong in some cases. e.g. presently with this case:

hello, "["], goodbye("")

If you hit backspace 3 times, you get

hello[,] goodbye("")

like you'd expect. But if you use the command with a count, e.g. if you bound backspace to this in normal mode and then hit 3<backspace>, you end up with:

hello[g]oodbye("")

Though, I don't know how many people bind this in normal mode and use the count with it, so I don't know if I'd consider this a blocker. It might be tricky to get the logic right.

auto_pairs,
) {
(Some(_x), Some(_y), Some(ap))
if range.len() == 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to use Range::is_single_grapheme so that it also works when the cursor is over a non-ASCII grapheme.

@dead10ck
Copy link
Member

dead10ck commented Jul 2, 2022

One minor issue I just noticed: if a pair is at the very beginning of the file, and the cursor is on the first char, it will delete the first char instead of doing nothing. This might be fixable by checking if the cursor is the first char in the document.

Copy link
Member

@dead10ck dead10ck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, tested locally, this looks good to me! Thanks for this fix! Can't wait to use it.

@archseer archseer merged commit 52bb110 into helix-editor:master Jul 22, 2022
thomasskk pushed a commit to thomasskk/helix that referenced this pull request Sep 9, 2022
* auto pair-removal

Fixes helix-editor#1673

* autopairs removal: use doc autopairs

* autopairs-removal: limit to one-char selections

* use single_grapheme() to check if range is one char

* fix errouneous deletes of " and other symmetric autopairs when at buffer start

Co-authored-by: Houkime <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

autopair: delete pair on backspace
3 participants