From e33739a2f1149a476d971d87223d76daf1b63a05 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+nikitarevenco@users.noreply.github.com> Date: Sat, 9 Nov 2024 16:32:22 +0000 Subject: [PATCH 1/3] feat: add commands for working with different cases --- Cargo.lock | 7 ++++++ helix-term/Cargo.toml | 1 + helix-term/src/commands.rs | 40 +++++++++++++++++++++++++++++--- helix-term/src/keymap/default.rs | 13 ++++++++--- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8662c41e..1dd1c3de1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1197,6 +1197,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "helix-core" version = "24.7.0" @@ -1350,6 +1356,7 @@ dependencies = [ "futures-util", "grep-regex", "grep-searcher", + "heck", "helix-core", "helix-dap", "helix-event", diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index dc0e20b68..dccad0720 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -35,6 +35,7 @@ helix-loader = { path = "../helix-loader" } anyhow = "1" once_cell = "1.20" +heck = "0.5" tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"] } crossterm = { version = "0.28", features = ["event-stream"] } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ee2949fa0..5aef4a453 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -51,6 +51,7 @@ }; use anyhow::{anyhow, bail, ensure, Context as _}; +use heck::{ToKebabCase, ToLowerCamelCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase}; use insert::*; use movement::Movement; @@ -329,9 +330,14 @@ pub fn doc(&self) -> &str { extend_prev_char, "Extend to previous occurrence of char", repeat_last_motion, "Repeat last motion", replace, "Replace with new char", - switch_case, "Switch (toggle) case", - switch_to_uppercase, "Switch to uppercase", + switch_to_alternate_case, "Switch to aLTERNATE cASE", + switch_to_uppercase, "Switch to UPPERCASE", switch_to_lowercase, "Switch to lowercase", + switch_to_pascal_case, "Switch to PascalCase", + switch_to_camel_case, "Switch to camelCase", + switch_to_title_case, "Switch to Title Case", + switch_to_snake_case, "Switch to snake_case", + switch_to_kebab_case, "Switch to kebab-case", page_up, "Move page up", page_down, "Move page down", half_page_up, "Move half page up", @@ -1713,7 +1719,15 @@ fn switch_case_impl(cx: &mut Context, change_fn: F) exit_select_mode(cx); } -fn switch_case(cx: &mut Context) { +fn switch_heck_case_impl(cx: &mut Context, change_fn: impl Fn(Tendril) -> String) { + switch_case_impl(cx, |string| { + let stri = Tendril::from_iter(string.chars()); + let applied = change_fn(stri); + Tendril::from_iter(applied.chars()) + }); +} + +fn switch_to_alternate_case(cx: &mut Context) { switch_case_impl(cx, |string| { string .chars() @@ -1730,6 +1744,26 @@ fn switch_case(cx: &mut Context) { }); } +fn switch_to_pascal_case(cx: &mut Context) { + switch_heck_case_impl(cx, |str| str.to_upper_camel_case()) +} + +fn switch_to_camel_case(cx: &mut Context) { + switch_heck_case_impl(cx, |str| str.to_lower_camel_case()) +} + +fn switch_to_title_case(cx: &mut Context) { + switch_heck_case_impl(cx, |str| str.to_title_case()) +} + +fn switch_to_snake_case(cx: &mut Context) { + switch_heck_case_impl(cx, |str| str.to_snake_case()) +} + +fn switch_to_kebab_case(cx: &mut Context) { + switch_heck_case_impl(cx, |str| str.to_kebab_case()) +} + fn switch_to_uppercase(cx: &mut Context) { switch_case_impl(cx, |string| { string.chunks().map(|chunk| chunk.to_uppercase()).collect() diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index 5a3e8eed4..930f3d9b1 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -19,9 +19,16 @@ pub fn default() -> HashMap { "R" => replace_with_yanked, "A-." => repeat_last_motion, - "~" => switch_case, - "`" => switch_to_lowercase, - "A-`" => switch_to_uppercase, + "~" => switch_to_alternate_case, + "`" => { "Case" + "l" => switch_to_lowercase, + "u" => switch_to_uppercase, + "p" => switch_to_pascal_case, + "c" => switch_to_camel_case, + "t" => switch_to_title_case, + "s" => switch_to_snake_case, + "k" => switch_to_kebab_case, + }, "home" => goto_line_start, "end" => goto_line_end, From 105d4f997328c5f677192a7b12c039d20d26facf Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+nikitarevenco@users.noreply.github.com> Date: Sat, 9 Nov 2024 16:32:28 +0000 Subject: [PATCH 2/3] feat: add case-mode section --- book/src/keymap.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 71ae5e31f..f630bd31b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -11,6 +11,7 @@ ## Keymap - [Goto mode](#goto-mode) - [Match mode](#match-mode) - [Window mode](#window-mode) + - [Case Mode](#case-mode) - [Space mode](#space-mode) - [Popup](#popup) - [Completion Menu](#completion-menu) @@ -70,8 +71,6 @@ ### Changes | `r` | Replace with a character | `replace` | | `R` | Replace with yanked text | `replace_with_yanked` | | `~` | Switch case of the selected text | `switch_case` | -| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` | -| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` | | `i` | Insert before selection | `insert_mode` | | `a` | Insert after selection (append) | `append_mode` | | `I` | Insert at the start of the line | `insert_at_line_start` | @@ -169,6 +168,7 @@ ### Minor modes | ----- | ----------- | ------- | | `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` | | `g` | Enter [goto mode](#goto-mode) | N/A | +| ` ` ` | Enter [case mode](#case-mode) | N/A | | `m` | Enter [match mode](#match-mode) | N/A | | `:` | Enter command mode | `command_mode` | | `z` | Enter [view mode](#view-mode) | N/A | @@ -232,6 +232,32 @@ #### Goto mode | `k` | Move up textual (instead of visual) line | `move_line_up` | | `w` | Show labels at each word and select the word that belongs to the entered labels | `goto_word` | +#### Case mode + +Accessed by typing ` ` ` in [normal mode](#normal-mode). + +Various functions for changing case of text in different ways. + + "a" => switch_to_alternate_case, + "l" => switch_to_lowercase, + "u" => switch_to_uppercase, + "p" => switch_to_pascal_case, + "c" => switch_to_camel_case, + "t" => switch_to_title_case, + "s" => switch_to_snake_case, + "k" => switch_to_kebab_case, +| Key | Description | Command | +| ----- | ----------- | ------- | +| `l` | Switch all text to lowercase | `switch_to_lowercase` | +| `u` | Switch all text to UPPERCASE | `switch_to_uppercase` | +| `p` | Switch text to Pascal Case | `switch_to_pascal_case` | +| `c` | Switch text to camelCase | `switch_to_camel_case` | +| `t` | Switch text to Title Case | `switch_to_title_case` | +| `s` | Switch text to snake_case | `switch_to_snake_case` | +| `k` | Switch text to kebab-case | `switch_to_kebab_case` | + +TODO: Mappings for selecting syntax nodes (a superset of `[`). + #### Match mode Accessed by typing `m` in [normal mode](#normal-mode). From 007f6952a851f7521fa6d10215697a4afa0e1165 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+nikitarevenco@users.noreply.github.com> Date: Sat, 9 Nov 2024 16:34:44 +0000 Subject: [PATCH 3/3] docs: remove accidentally pasted code --- book/src/keymap.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index f630bd31b..c45edaf06 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -238,14 +238,6 @@ #### Case mode Various functions for changing case of text in different ways. - "a" => switch_to_alternate_case, - "l" => switch_to_lowercase, - "u" => switch_to_uppercase, - "p" => switch_to_pascal_case, - "c" => switch_to_camel_case, - "t" => switch_to_title_case, - "s" => switch_to_snake_case, - "k" => switch_to_kebab_case, | Key | Description | Command | | ----- | ----------- | ------- | | `l` | Switch all text to lowercase | `switch_to_lowercase` |