mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Add convert to {upper,lower} case
commands
Co-Authored-By: Julia <30666851+ForLoveOfCats@users.noreply.github.com>
This commit is contained in:
parent
d3c1966d96
commit
8c98b02e45
@ -231,6 +231,8 @@ actions!(
|
||||
SortLinesCaseInsensitive,
|
||||
ReverseLines,
|
||||
ShuffleLines,
|
||||
ConvertToUpperCase,
|
||||
ConvertToLowerCase,
|
||||
Transpose,
|
||||
Cut,
|
||||
Copy,
|
||||
@ -353,6 +355,8 @@ pub fn init(cx: &mut AppContext) {
|
||||
cx.add_action(Editor::sort_lines_case_insensitive);
|
||||
cx.add_action(Editor::reverse_lines);
|
||||
cx.add_action(Editor::shuffle_lines);
|
||||
cx.add_action(Editor::convert_to_upper_case);
|
||||
cx.add_action(Editor::convert_to_lower_case);
|
||||
cx.add_action(Editor::delete_to_previous_word_start);
|
||||
cx.add_action(Editor::delete_to_previous_subword_start);
|
||||
cx.add_action(Editor::delete_to_next_word_end);
|
||||
@ -4306,6 +4310,68 @@ impl Editor {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn convert_to_upper_case(&mut self, _: &ConvertToUpperCase, cx: &mut ViewContext<Self>) {
|
||||
self.manipulate_text(cx, |text| text.to_uppercase())
|
||||
}
|
||||
|
||||
pub fn convert_to_lower_case(&mut self, _: &ConvertToLowerCase, cx: &mut ViewContext<Self>) {
|
||||
self.manipulate_text(cx, |text| text.to_lowercase())
|
||||
}
|
||||
|
||||
fn manipulate_text<Fn>(&mut self, cx: &mut ViewContext<Self>, mut callback: Fn)
|
||||
where
|
||||
Fn: FnMut(&str) -> String,
|
||||
{
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
|
||||
let mut new_selections = Vec::new();
|
||||
let mut edits = Vec::new();
|
||||
for selection in self.selections.all::<usize>(cx) {
|
||||
let selection_is_empty = selection.is_empty();
|
||||
|
||||
let (start, end) = if selection_is_empty {
|
||||
let word_range = movement::surrounding_word(
|
||||
&display_map,
|
||||
selection.start.to_display_point(&display_map),
|
||||
);
|
||||
let start = word_range.start.to_offset(&display_map, Bias::Left);
|
||||
let end = word_range.end.to_offset(&display_map, Bias::Left);
|
||||
(start, end)
|
||||
} else {
|
||||
(selection.start, selection.end)
|
||||
};
|
||||
|
||||
let text = buffer.text_for_range(start..end).collect::<String>();
|
||||
let text = callback(&text);
|
||||
|
||||
if selection_is_empty {
|
||||
new_selections.push(selection);
|
||||
} else {
|
||||
new_selections.push(Selection {
|
||||
start,
|
||||
end: start + text.len(),
|
||||
goal: SelectionGoal::None,
|
||||
..selection
|
||||
});
|
||||
}
|
||||
|
||||
edits.push((start..end, text));
|
||||
}
|
||||
|
||||
self.transact(cx, |this, cx| {
|
||||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(edits, None, cx);
|
||||
});
|
||||
|
||||
this.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select(new_selections);
|
||||
});
|
||||
|
||||
this.request_autoscroll(Autoscroll::fit(), cx);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = &display_map.buffer_snapshot;
|
||||
|
@ -2695,6 +2695,65 @@ async fn test_manipulate_lines_with_multi_selection(cx: &mut TestAppContext) {
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_manipulate_text(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
// Test convert_to_upper_case()
|
||||
cx.set_state(indoc! {"
|
||||
«hello worldˇ»
|
||||
"});
|
||||
cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«HELLO WORLDˇ»
|
||||
"});
|
||||
|
||||
// Test convert_to_lower_case()
|
||||
cx.set_state(indoc! {"
|
||||
«HELLO WORLDˇ»
|
||||
"});
|
||||
cx.update_editor(|e, cx| e.convert_to_lower_case(&ConvertToLowerCase, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«hello worldˇ»
|
||||
"});
|
||||
|
||||
// From here on out, test more complex cases of manipulate_text() with a single driver method: convert_to_upper_case()
|
||||
|
||||
// Test no selection case - should affect words cursors are in
|
||||
// Cursor at beginning, middle, and end of word
|
||||
cx.set_state(indoc! {"
|
||||
ˇhello big beauˇtiful worldˇ
|
||||
"});
|
||||
cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
ˇHELLO big BEAUˇTIFUL WORLDˇ
|
||||
"});
|
||||
|
||||
// Test multiple selections on a single line and across multiple lines
|
||||
cx.set_state(indoc! {"
|
||||
«Theˇ» quick «brown
|
||||
foxˇ» jumps «overˇ»
|
||||
the «lazyˇ» dog
|
||||
"});
|
||||
cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«THEˇ» quick «BROWN
|
||||
FOXˇ» jumps «OVERˇ»
|
||||
the «LAZYˇ» dog
|
||||
"});
|
||||
|
||||
// Test case where text length grows
|
||||
cx.set_state(indoc! {"
|
||||
«tschüߡ»
|
||||
"});
|
||||
cx.update_editor(|e, cx| e.convert_to_upper_case(&ConvertToUpperCase, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«TSCHÜSSˇ»
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
Loading…
Reference in New Issue
Block a user