-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Added change_case command #441
Conversation
d006469
to
1223606
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks good! Note that we also want a command for uppercase and one for lowercase.
Kakoune uses these keybindings:
` to lower case
~ to upper case
<a-`> swap case
I kind of like having the swap case on ~
though.
Ok, I've implemented to_lowercase and to_uppercase, and placed the keymaps in a slightly more sensible manner. That said; I did notice a bug, but I'm not sure if this is the right place to solve it. When activating either case switch method on a selection > 1, the selection will grow with each press. However the same thing occurs with the replace command; it simple is less easy to trigger it. Can any-one confirm this behaviour? |
ddfe79a
to
ef52af3
Compare
Renamed change_case to switch_case.
ef52af3
to
e613403
Compare
.chars() | ||
.map(|ch| { | ||
if ch.is_lowercase() { | ||
ch.to_uppercase().collect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, these methods return an iterator, hmm. Maybe we can use flat_map
and directly process these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, good point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So with flat_map
you should be able to return these iterators directly without .collect()
. Might be a problem since all the branches return a different type though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must admit; this isn't my area of expertise, but I don't see much of an alternative. Or at-least no ones which also allocate.
With the exception of a custom enum combining the three branches, which also implements Iterator.
Any other suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the current implementation is fine for now :)
helix-term/src/commands.rs
Outdated
let (view, doc) = current!(cx.editor); | ||
let transaction = | ||
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { | ||
let text: Tendril = range.fragment(doc.text().slice(..)).to_lowercase().into(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're using to_lowercase in the uppercase method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, copy paste error; apologies.
Yeah I think this is a side-effect of the fact that ranges are end inclusive, but we |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { | ||
let text: Tendril = range.fragment(doc.text().slice(..)).to_lowercase().into(); | ||
|
||
(range.from(), range.to() + 1, Some(text)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(range.from(), range.to() + 1, Some(text)) | |
(range.from(), range.to(), Some(text)) |
I think this should fix the bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this does fix it when having a selection of >1 character, it causes it not to work when having a selection of 1 character. While this is solvable; the replace command has the exact same issue.
If I understand correctly, this behaviour is currently due to ranges being inclusive. archseer above suggested that this behaviour should be fixed later on in #376.
If so, should I work around the bug, or accept it for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine, you should accept it for now and we'll deal with it in #376
Sure, no problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, maybe can just leave the fix to another time.
Having taken a quick look, my suspicion is that #376 isn't necessary to solve the issue, but it will probably solve it kind of incidentally anyway...? Not totally sure. At the very least, it should make the issue easier to reason about. When I get back from vacation and resume work on the PR, I'll take a closer look. |
Thanks! 🎉 |
I'm back from vacation. I merged the changes into #376, and it does indeed fix the selection extending issue. |
In vim I use the chance case function quite a lot and found it missing here.
Here is my attempt at adding it.