Skip to content

feat(commands): shrink_selection - #1340

Merged
archseer merged 6 commits into
helix-editor:masterfrom
matoous:md/shrink_selection
Jan 6, 2022
Merged

feat(commands): shrink_selection#1340
archseer merged 6 commits into
helix-editor:masterfrom
matoous:md/shrink_selection

Conversation

@matoous

@matoous matoous commented Dec 23, 2021

Copy link
Copy Markdown
Contributor

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

matoous commented Dec 23, 2021

Copy link
Copy Markdown
Contributor Author

Showcase:

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

Comment thread helix-view/src/document.rs Outdated
Comment thread helix-view/src/document.rs Outdated
Comment thread helix-view/src/document.rs Outdated
@matoous matoous changed the title PoC: feat(commands): shrink_selection feat(commands): shrink_selection Dec 23, 2021
@matoous

matoous commented Dec 23, 2021

Copy link
Copy Markdown
Contributor Author

@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

matoous commented Dec 24, 2021

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
Member

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

@sudormrfbin

sudormrfbin commented Dec 24, 2021

Copy link
Copy Markdown
Member

. 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
Copy Markdown
Member

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

@matoous

matoous commented Dec 25, 2021

Copy link
Copy Markdown
Contributor Author

Added default key mapping to ]o and [o.

@matoous
matoous requested a review from archseer December 27, 2021 09:39
Comment thread helix-core/src/selection.rs Outdated

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

Copy link
Copy Markdown
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
Copy Markdown
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?

@dead10ck dead10ck Dec 29, 2021

Copy link
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

matoous commented Dec 29, 2021

Copy link
Copy Markdown
Contributor Author

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.

Comment thread helix-term/src/commands.rs Outdated
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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