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

Add command to merge consecutive ranges in selection #5047

Conversation

DylanBulfin
Copy link
Contributor

My attempt at #4914

Adds command that will merge consecutive ranges in the selection, bound to Alt-_ for now.

@kirawi
Copy link
Member

kirawi commented Dec 7, 2022

I think you can use dedup_by instead, assuming that ranges are in order. I'll check if they are.

@pascalkuthe pascalkuthe added the S-waiting-on-review Status: Awaiting review from a maintainer. label Dec 7, 2022
@DylanBulfin DylanBulfin force-pushed the dylanbulfin/merge_consecutive_ranges branch from 0aa44ff to a08d407 Compare December 8, 2022 22:21
@kirawi kirawi added the A-helix-term Area: Helix term improvements label Dec 9, 2022
@DylanBulfin
Copy link
Contributor Author

I think you can use dedup_by instead, assuming that ranges are in order. I'll check if they are.

I couldn't find a way to use dedup_by, but @austinletson helped me with a way to do it in a more elegant way using a fold. Is this more along the lines of what you were thinking?

@pascalkuthe
Copy link
Member

pascalkuthe commented Dec 9, 2022

I think you can use dedup_by instead, assuming that ranges are in order. I'll check if they are.

I couldn't find a way to use dedup_by, but @austinletson helped me with a way to do it in a more elegant way using a fold. Is this more along the lines of what you were thinking?

The problem with this version is that you are potentially allocating a vector and copying all data. It might not be super critical but it is pretty easy to avoid here by using dedup_by which also is easier to read/clearer to understand (this use-case is exactly what that function is for). dedup_by iterates the vec in order and passes a pair of elements to your function. If your function returns true the first element is removed and only the second one is kept, otherwise both are kept. Furthermore you receive a mutable reference so you can modify both elements. I would use something along the following lines (it didn't test this and might have messed something up but it should point you in the right direction).

self.ranges.deadup_by(|prev_range, curr_range|{
      if prev_range.to() == curr_range.from()  {
          *curr_range = curr_range.merge(curr_range);
          // prev_range will be removed
          true
      } else {
          false
      }
})

@DylanBulfin
Copy link
Contributor Author

The problem with this version is that you are potentially allocating a vector and copying all data. It might not be super critical but it is pretty easy to avoid here by using dedup_by which also is easier to read/clearer to understand (this use-case is exactly what that function is for). dedup_by iterates the vec in order and passes a pair of elements to your function. If your function returns true the first element is removed and only the second one is kept, otherwise both are kept. Furthermore you receive a mutable reference so you can modify both elements. I would use something along the following lines (it didn't test this and might have messed something up but it should point you in the right direction).

self.ranges.deadup_by(|prev_range, curr_range|{
      if prev_range.to() == curr_range.from()  {
          *curr_range = curr_range.merge(curr_range);
          // prev_range will be removed
          true
      } else {
          false
      }
})

Thanks for the help! I had missed the fact that dedup_by gives mutable refs; reimplemented the command.

@archseer
Copy link
Member

Oh this is a nice implementation and we could simplify normalize in a similar way. The only difference is the conditional: if prev_range.to() == curr_range.from() vs if prev_range.overlaps(curr_range)

@DylanBulfin DylanBulfin force-pushed the dylanbulfin/merge_consecutive_ranges branch from b60e9c7 to 7b0e8d3 Compare December 13, 2022 15:11
Rewrote command, added test

Moved keymap

Refactoring command, added test coverage

Added primary index calculation

Moving primary_index calculation

Refactored code to use fold instead of loop

Changed to use dedup_by

Removed duplicate merge call

Fix primary index calculation
@DylanBulfin DylanBulfin force-pushed the dylanbulfin/merge_consecutive_ranges branch from 7b0e8d3 to a0b7fd7 Compare December 13, 2022 18:49
@DylanBulfin
Copy link
Contributor Author

Oh this is a nice implementation and we could simplify normalize in a similar way. The only difference is the conditional: if prev_range.to() == curr_range.from() vs if prev_range.overlaps(curr_range)

Simplified normalize the same way, happy to move it to a different PR if that would be better.

@the-mikedavis
Copy link
Member

Could you add a line for the new command to the book? Somewhere in this section would be good:

### Selection manipulation

@DylanBulfin
Copy link
Contributor Author

Added command to book, and renamed it to merge_consecutive_selections to fit better with the nomenclature used in other commands.

@the-mikedavis the-mikedavis merged commit 1107296 into helix-editor:master Dec 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants