Fix text transformation commands for multiple line, single selection cases (#3060)

If you highlight the following block of text (with a single selection):

```
The quick brown
fox jumps over
the lazy dog
```

and run `editor: convert to upper camel case`, you'll get:

```
TheQuickBrown
foxJumpsOver
theLazyDog
```

instead of:

```
TheQuickBrown
FoxJumpsOver
TheLazyDog
```

The same thing happens for `editor: convert to title case`. This happens
because [`to_case` crate](https://crates.io/crates/convert_case) doesn't
allow the user to define '\n' as a boundary. I wanted to fix this at the
lib level, so I filled [an
issue](https://github.com/rutrum/convert-case/issues/16) but I never
heard back. What's strange is VS Code and Sublime I think both exhibit
the same output as we do currently, but I don't personally think this
feels right (happy to hear opposing opinions). I'm just doing the naive
thing to hack around this limitation of the `to_case` crate.

I did some testing and it seems I only need to adjust `editor: convert
to title case` and `editor: convert to upper camel case`. The way the
other transformations are implemented in `to_case` don't seem to have
this issue.

Release Notes:

- Fixed a bug where running certain text transfomration commands on a
single selection covering multiple lines would not transform all
selected lines as expected.
This commit is contained in:
Joseph T. Lyons 2023-09-28 14:04:17 -04:00 committed by GitHub
parent a8188a2f33
commit 3cf7164a54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 2 deletions

View file

@ -4653,7 +4653,13 @@ impl Editor {
}
pub fn convert_to_title_case(&mut self, _: &ConvertToTitleCase, cx: &mut ViewContext<Self>) {
self.manipulate_text(cx, |text| text.to_case(Case::Title))
self.manipulate_text(cx, |text| {
// Hack to get around the fact that to_case crate doesn't support '\n' as a word boundary
// https://github.com/rutrum/convert-case/issues/16
text.split("\n")
.map(|line| line.to_case(Case::Title))
.join("\n")
})
}
pub fn convert_to_snake_case(&mut self, _: &ConvertToSnakeCase, cx: &mut ViewContext<Self>) {
@ -4669,7 +4675,13 @@ impl Editor {
_: &ConvertToUpperCamelCase,
cx: &mut ViewContext<Self>,
) {
self.manipulate_text(cx, |text| text.to_case(Case::UpperCamel))
self.manipulate_text(cx, |text| {
// Hack to get around the fact that to_case crate doesn't support '\n' as a word boundary
// https://github.com/rutrum/convert-case/issues/16
text.split("\n")
.map(|line| line.to_case(Case::UpperCamel))
.join("\n")
})
}
pub fn convert_to_lower_camel_case(

View file

@ -2792,6 +2792,34 @@ async fn test_manipulate_text(cx: &mut TestAppContext) {
«hello worldˇ»
"});
// Test multiple line, single selection case
// Test code hack that covers the fact that to_case crate doesn't support '\n' as a word boundary
cx.set_state(indoc! {"
«The quick brown
fox jumps over
the lazy dogˇ»
"});
cx.update_editor(|e, cx| e.convert_to_title_case(&ConvertToTitleCase, cx));
cx.assert_editor_state(indoc! {"
«The Quick Brown
Fox Jumps Over
The Lazy Dogˇ»
"});
// Test multiple line, single selection case
// Test code hack that covers the fact that to_case crate doesn't support '\n' as a word boundary
cx.set_state(indoc! {"
«The quick brown
fox jumps over
the lazy dogˇ»
"});
cx.update_editor(|e, cx| e.convert_to_upper_camel_case(&ConvertToUpperCamelCase, cx));
cx.assert_editor_state(indoc! {"
«TheQuickBrown
FoxJumpsOver
TheLazyDogˇ»
"});
// From here on out, test more complex cases of manipulate_text()
// Test no selection case - should affect words cursors are in