From 1223606f21aed9e8f71e37eae6becc9b8d25c79e Mon Sep 17 00:00:00 2001 From: Cor Date: Tue, 13 Jul 2021 22:16:29 +0200 Subject: [PATCH 1/6] Added change_case command --- helix-term/src/commands.rs | 30 ++++++++++++++++++++++++++++++ helix-term/src/keymap.rs | 1 + 2 files changed, 31 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3b208ca8f55a..571449cc8e55 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -186,6 +186,7 @@ impl Command { extend_till_prev_char, extend_prev_char, replace, + change_case, page_up, page_down, half_page_up, @@ -780,6 +781,35 @@ fn replace(cx: &mut Context) { }) } +fn change_case(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + let transaction = + Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { + let max_to = rope_end_without_line_ending(&doc.text().slice(..)); + let to = std::cmp::min(max_to, range.to() + 1); + let text: String = RopeGraphemes::new(doc.text().slice(range.from()..to)) + .map(|g| { + let mut buffer: String = String::with_capacity(g.len_bytes()); + g.chars().for_each(|ch| { + if ch.is_lowercase() { + buffer.extend(ch.to_uppercase()); + } else if ch.is_uppercase() { + buffer.extend(ch.to_lowercase()); + } else { + buffer.push(ch); + } + }); + buffer + }) + .collect(); + + (range.from(), to, Some(text.into())) + }); + + doc.apply(&transaction, view.id); + doc.append_changes_to_history(view.id); +} + fn scroll(cx: &mut Context, offset: usize, direction: Direction) { use Direction::*; let (view, doc) = current!(cx.editor); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index d815e0064ebb..559c72b5e169 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -80,6 +80,7 @@ impl Default for Keymaps { // and matching set for select mode (extend) // key!('r') => Command::replace, + key!('~') => Command::change_case, key!('R') => Command::replace_with_yanked, key!(Home) => Command::goto_line_start, From 48df076fa18b8867294509d764920010ff22be86 Mon Sep 17 00:00:00 2001 From: Cor Date: Wed, 14 Jul 2021 13:49:35 +0200 Subject: [PATCH 2/6] Added switch_to_uppercase and switch_to_lowercase Renamed change_case to switch_case. --- helix-term/src/commands.rs | 61 +++++++++++++++++++++++++++----------- helix-term/src/keymap.rs | 5 +++- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 571449cc8e55..a5fc2a046355 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -186,7 +186,9 @@ impl Command { extend_till_prev_char, extend_prev_char, replace, - change_case, + switch_case, + switch_to_uppercase, + switch_to_lowercase, page_up, page_down, half_page_up, @@ -781,29 +783,52 @@ fn replace(cx: &mut Context) { }) } -fn change_case(cx: &mut Context) { +fn switch_case(cx: &mut Context) { let (view, doc) = current!(cx.editor); let transaction = Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { - let max_to = rope_end_without_line_ending(&doc.text().slice(..)); - let to = std::cmp::min(max_to, range.to() + 1); - let text: String = RopeGraphemes::new(doc.text().slice(range.from()..to)) - .map(|g| { - let mut buffer: String = String::with_capacity(g.len_bytes()); - g.chars().for_each(|ch| { - if ch.is_lowercase() { - buffer.extend(ch.to_uppercase()); - } else if ch.is_uppercase() { - buffer.extend(ch.to_lowercase()); - } else { - buffer.push(ch); - } - }); - buffer + let text: Tendril = range + .fragment(doc.text().slice(..)) + .chars() + .map(|ch| { + if ch.is_lowercase() { + ch.to_uppercase().collect() + } else if ch.is_uppercase() { + ch.to_lowercase().collect() + } else { + vec![ch] + } }) + .flatten() .collect(); - (range.from(), to, Some(text.into())) + (range.from(), range.to() + 1, Some(text)) + }); + + doc.apply(&transaction, view.id); + doc.append_changes_to_history(view.id); +} + +fn switch_to_uppercase(cx: &mut Context) { + 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(); + + (range.from(), range.to() + 1, Some(text)) + }); + + doc.apply(&transaction, view.id); + doc.append_changes_to_history(view.id); +} + +fn switch_to_lowercase(cx: &mut Context) { + 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(); + + (range.from(), range.to() + 1, Some(text)) }); doc.apply(&transaction, view.id); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 559c72b5e169..0731655e8de7 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -80,9 +80,12 @@ impl Default for Keymaps { // and matching set for select mode (extend) // key!('r') => Command::replace, - key!('~') => Command::change_case, key!('R') => Command::replace_with_yanked, + key!('~') => Command::switch_case, + key!('`') => Command::switch_to_uppercase, + alt!('`') => Command::switch_to_lowercase, + key!(Home) => Command::goto_line_start, key!(End) => Command::goto_line_end, From e613403f6a98f05afae000c3e6315bbe586d3b05 Mon Sep 17 00:00:00 2001 From: Cor Date: Wed, 14 Jul 2021 14:27:11 +0200 Subject: [PATCH 3/6] Updated the Keymap section of the Book --- book/src/keymap.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index c0c455d321a6..5d6e57956d84 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -41,26 +41,29 @@ ### Changes -| Key | Description | -| ----- | ----------- | -| `r` | Replace with a character | -| `R` | Replace with yanked text | -| `i` | Insert before selection | -| `a` | Insert after selection (append) | -| `I` | Insert at the start of the line | -| `A` | Insert at the end of the line | -| `o` | Open new line below selection | -| `o` | Open new line above selection | -| `u` | Undo change | -| `U` | Redo change | -| `y` | Yank selection | -| `p` | Paste after selection | -| `P` | Paste before selection | -| `>` | Indent selection | -| `<` | Unindent selection | -| `=` | Format selection | -| `d` | Delete selection | -| `c` | Change selection (delete and enter insert mode) | +| Key | Description | +| ----- | ----------- | +| `r` | Replace with a character | +| `R` | Replace with yanked text | +| `~` | Switch case of the selected text | +| `\`` | Set the selected text to upper case | +| `Alt-\`` | Set the selected text to lower case | +| `i` | Insert before selection | +| `a` | Insert after selection (append) | +| `I` | Insert at the start of the line | +| `A` | Insert at the end of the line | +| `o` | Open new line below selection | +| `o` | Open new line above selection | +| `u` | Undo change | +| `U` | Redo change | +| `y` | Yank selection | +| `p` | Paste after selection | +| `P` | Paste before selection | +| `>` | Indent selection | +| `<` | Unindent selection | +| `=` | Format selection | +| `d` | Delete selection | +| `c` | Change selection (delete and enter insert mode) | ### Selection manipulation From d8aacc0ae746e84c4ab42c637b62be0cb662468e Mon Sep 17 00:00:00 2001 From: Cor Date: Thu, 15 Jul 2021 08:55:06 +0200 Subject: [PATCH 4/6] Use flat_map instead of map + flatten --- helix-term/src/commands.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index a5fc2a046355..6ecce7656c6b 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -790,7 +790,7 @@ fn switch_case(cx: &mut Context) { let text: Tendril = range .fragment(doc.text().slice(..)) .chars() - .map(|ch| { + .flat_map(|ch| { if ch.is_lowercase() { ch.to_uppercase().collect() } else if ch.is_uppercase() { @@ -799,7 +799,6 @@ fn switch_case(cx: &mut Context) { vec![ch] } }) - .flatten() .collect(); (range.from(), range.to() + 1, Some(text)) From e0b0745f25b092a35b463d336d42bcbf4b5923f0 Mon Sep 17 00:00:00 2001 From: Cor Date: Thu, 15 Jul 2021 08:55:57 +0200 Subject: [PATCH 5/6] Fix switch_to_uppercase using to_lowercase --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 6ecce7656c6b..7e769f4e1dad 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -812,7 +812,7 @@ fn switch_to_uppercase(cx: &mut Context) { 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(); + let text: Tendril = range.fragment(doc.text().slice(..)).to_uppercase().into(); (range.from(), range.to() + 1, Some(text)) }); From e3beccdcc6a286d08835fc29bd84a8dd42341e17 Mon Sep 17 00:00:00 2001 From: Cor Date: Thu, 15 Jul 2021 13:38:48 +0200 Subject: [PATCH 6/6] Switched 'Alt-`' to uppercase and '`' to lowercase --- helix-term/src/keymap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 0731655e8de7..3ed34704866e 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -83,8 +83,8 @@ impl Default for Keymaps { key!('R') => Command::replace_with_yanked, key!('~') => Command::switch_case, - key!('`') => Command::switch_to_uppercase, - alt!('`') => Command::switch_to_lowercase, + alt!('`') => Command::switch_to_uppercase, + key!('`') => Command::switch_to_lowercase, key!(Home) => Command::goto_line_start, key!(End) => Command::goto_line_end,