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

feat(commands): shrink_selection #1340

Merged
merged 6 commits into from
Jan 6, 2022
Merged

feat(commands): shrink_selection #1340

merged 6 commits into from
Jan 6, 2022

Conversation

matoous
Copy link
Contributor

@matoous matoous commented Dec 23, 2021

Add shrink_selection command that can be used to shrink previously expanded selection.

To make shrink_selection work it was necessary to add selection history to the Document since we want to shrink the selection towards the syntax tree node that was initially selected.

Selection history is cleared any time the user changes selection other way than by expand_selection. This ensures that we don't get some funky edge cases when user calls shrink_selection.

Related: #1328

@matoous matoous changed the title feat(commands): shrink_selection PoC: feat(commands): shrink_selection Dec 23, 2021
@matoous matoous marked this pull request as draft December 23, 2021 10:13
@matoous
Copy link
Contributor Author

matoous commented Dec 23, 2021

Showcase:

Screen.Recording.2021-12-23.at.11.01.31.mov

helix-view/src/document.rs Outdated Show resolved Hide resolved
helix-view/src/document.rs Outdated Show resolved Hide resolved
helix-view/src/document.rs Outdated Show resolved Hide resolved
@matoous matoous changed the title PoC: feat(commands): shrink_selection feat(commands): shrink_selection Dec 23, 2021
@matoous
Copy link
Contributor Author

matoous commented Dec 23, 2021

@archseer I refactored the shrink_selection based on your suggestions, thanks a lot.

@matoous matoous marked this pull request as ready for review December 23, 2021 23:04
@matoous
Copy link
Contributor Author

matoous commented Dec 24, 2021

I am also wondering about the keybindings. @archseer suggested ]o and [o in #1328 (reply in thread). I personally would be more fond of modifier + key combo (such as A-]/A-[) that make it easier to hit it repeatedly to extend / shrink the selection further as this is the most common use case. Also, one more option: we could include extend/shrink selection in motions that can be repeated, extending would be then ]o..... which seems quick and easy too.

@archseer
Copy link
Member

I think I would prefer the latter (repeating with the dot). Similar to how >/< are used.

@sudormrfbin
Copy link
Member

sudormrfbin commented Dec 24, 2021

. repeats the last change, but changing selections is not a change. Perhaps another keybind ? Or we could special case here, but that would make it inconsistent.

@archseer
Copy link
Member

Oh sorry, I meant Alt-. which repeats the last movement

@matoous
Copy link
Contributor Author

matoous commented Dec 25, 2021

Added default key mapping to ]o and [o.


pub fn contains(&self, other: &Selection) -> bool {
self.iter()
.zip(other.iter())
Copy link
Member

Choose a reason for hiding this comment

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

Hmm. This won't work correctly if I have three selection ranges and then I call contains with two selection ranges that are a subset of the original selection

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, you are right. I reworked the method but I am still hesitant whether the check makes sense at all. I think just moving the cursor should disable the shrink_selection so that we are safe, but I guess we can adjust that later if there are any complaints?

Copy link
Member

@dead10ck dead10ck Dec 29, 2021

Choose a reason for hiding this comment

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

I was pondering this. I think just checking containment will do the right thing when the user flow is expand, expand, shrink, shrink, etc, but you could also have the following sequence

fn foo() {
    let a = 1;
    [a]
}

expand

fn foo() [{
    let a = 1;
    a
}]

move cursor around and back inside the function

fn foo() {
[]  let a = 1;
    a
}

select entire file

[
...
fn foo() {
    let a = 1;
    a
}
...
]

shrink selection

fn foo() {
    let a = 1;
    [a]
}

It might not matter much in practice. But I guess we just have to decide how strict we want to be.

@dead10ck
Copy link
Member

I think this shouldn't necessarily be a blocker, but one thing we could do if there haven't been any expands before shrinks is just select the first child node.

@archseer
Copy link
Member

just select the first child node.

I thought that was already the behavior? I proposed that before: when we run out of selections on the stack it should select the first child instead

@dead10ck
Copy link
Member

just select the first child node.

I thought that was already the behavior? I proposed that before: when we run out of selections on the stack it should select the first child instead

Well, if I'm not mistaken, the current PR does not do anything unless there was previously an expand to populate the selection history.

https://github.com/helix-editor/helix/pull/1340/files#diff-d782c07f22492bcae17333aba5dc5b840fb30317727e71267ebf4863f84787fdR5391

@matoous
Copy link
Contributor Author

matoous commented Dec 29, 2021

Well, if I'm not mistaken, the current PR does not do anything unless there was previously an expand to populate the selection history.

Yes, this is the case.

doc.set_selection(view.id, prev_selection);
} else {
// clear existing selection as they can't be shrinked to anyway
view.object_selections.clear()
Copy link
Member

Choose a reason for hiding this comment

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

Can you add that behavior in here? It should call object::shrink_selection and just look for the first descendant_for_byte_range

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, can you please check whether I understood the requirement correctly?

Copy link
Member

Choose a reason for hiding this comment

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

It looks right to me now 🙂

Add `shrink_selection` command that can be used to shrink
previously expanded selection.

To make `shrink_selection` work it was necessary to add
selection history to the Document since we want to shrink
the selection towards the syntax tree node that was initially
selected.

Selection history is cleared any time the user changes
selection other way than by `expand_selection`. This ensures
that we don't get some funky edge cases when user calls
`shrink_selection`.

Related: #1328
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.

4 participants