diff --git a/assets/keymaps/linux/jetbrains.json b/assets/keymaps/linux/jetbrains.json index 43937701cf..dbf50b0fce 100644 --- a/assets/keymaps/linux/jetbrains.json +++ b/assets/keymaps/linux/jetbrains.json @@ -58,7 +58,8 @@ "ctrl-shift-home": "editor::SelectToBeginning", "ctrl-shift-end": "editor::SelectToEnd", "ctrl-f8": "editor::ToggleBreakpoint", - "ctrl-shift-f8": "editor::EditLogBreakpoint" + "ctrl-shift-f8": "editor::EditLogBreakpoint", + "ctrl-shift-u": "editor::ToggleCase" } }, { diff --git a/assets/keymaps/macos/jetbrains.json b/assets/keymaps/macos/jetbrains.json index 355e860908..22c6f18383 100644 --- a/assets/keymaps/macos/jetbrains.json +++ b/assets/keymaps/macos/jetbrains.json @@ -55,7 +55,8 @@ "cmd-shift-home": "editor::SelectToBeginning", "cmd-shift-end": "editor::SelectToEnd", "ctrl-f8": "editor::ToggleBreakpoint", - "ctrl-shift-f8": "editor::EditLogBreakpoint" + "ctrl-shift-f8": "editor::EditLogBreakpoint", + "cmd-shift-u": "editor::ToggleCase" } }, { diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 3ac7825993..670d21478f 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -420,6 +420,7 @@ actions!( Tab, Backtab, ToggleBreakpoint, + ToggleCase, DisableBreakpoint, EnableBreakpoint, EditLogBreakpoint, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 5539cea460..6290a0606a 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -9143,6 +9143,17 @@ impl Editor { }); } + pub fn toggle_case(&mut self, _: &ToggleCase, window: &mut Window, cx: &mut Context) { + self.manipulate_text(window, cx, |text| { + let has_upper_case_characters = text.chars().any(|c| c.is_uppercase()); + if has_upper_case_characters { + text.to_lowercase() + } else { + text.to_uppercase() + } + }) + } + pub fn convert_to_upper_case( &mut self, _: &ConvertToUpperCase, diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 915edc237f..761add2715 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -3875,6 +3875,41 @@ async fn test_manipulate_lines_with_multi_selection(cx: &mut TestAppContext) { "}); } +#[gpui::test] +async fn test_toggle_case(cx: &mut TestAppContext) { + init_test(cx, |_| {}); + + let mut cx = EditorTestContext::new(cx).await; + + // If all lower case -> upper case + cx.set_state(indoc! {" + «hello worldˇ» + "}); + cx.update_editor(|e, window, cx| e.toggle_case(&ToggleCase, window, cx)); + cx.assert_editor_state(indoc! {" + «HELLO WORLDˇ» + "}); + + // If all upper case -> lower case + cx.set_state(indoc! {" + «HELLO WORLDˇ» + "}); + cx.update_editor(|e, window, cx| e.toggle_case(&ToggleCase, window, cx)); + cx.assert_editor_state(indoc! {" + «hello worldˇ» + "}); + + // If any upper case characters are identified -> lower case + // This matches JetBrains IDEs + cx.set_state(indoc! {" + «hEllo worldˇ» + "}); + cx.update_editor(|e, window, cx| e.toggle_case(&ToggleCase, window, cx)); + cx.assert_editor_state(indoc! {" + «hello worldˇ» + "}); +} + #[gpui::test] async fn test_manipulate_text(cx: &mut TestAppContext) { init_test(cx, |_| {}); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index e9719b6a1f..54c65f05e6 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -211,6 +211,7 @@ impl EditorElement { register_action(editor, window, Editor::sort_lines_case_insensitive); register_action(editor, window, Editor::reverse_lines); register_action(editor, window, Editor::shuffle_lines); + register_action(editor, window, Editor::toggle_case); register_action(editor, window, Editor::convert_to_upper_case); register_action(editor, window, Editor::convert_to_lower_case); register_action(editor, window, Editor::convert_to_title_case);