vim: Add g?
convert to Rot13
/Rot47
(#27824)
Release Notes: - Added `g?` convert to `Rot13`/`Rot47` --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
7bc0dd1bf6
commit
57d7bc23ae
12 changed files with 252 additions and 23 deletions
|
@ -227,6 +227,8 @@
|
||||||
"g u": "vim::PushLowercase",
|
"g u": "vim::PushLowercase",
|
||||||
"g shift-u": "vim::PushUppercase",
|
"g shift-u": "vim::PushUppercase",
|
||||||
"g ~": "vim::PushOppositeCase",
|
"g ~": "vim::PushOppositeCase",
|
||||||
|
"g ?": "vim::PushRot13",
|
||||||
|
// "g ?": "vim::PushRot47",
|
||||||
"\"": "vim::PushRegister",
|
"\"": "vim::PushRegister",
|
||||||
"g w": "vim::PushRewrap",
|
"g w": "vim::PushRewrap",
|
||||||
"g q": "vim::PushRewrap",
|
"g q": "vim::PushRewrap",
|
||||||
|
@ -298,6 +300,8 @@
|
||||||
"g r": ["vim::Paste", { "preserve_clipboard": true }],
|
"g r": ["vim::Paste", { "preserve_clipboard": true }],
|
||||||
"g c": "vim::ToggleComments",
|
"g c": "vim::ToggleComments",
|
||||||
"g q": "vim::Rewrap",
|
"g q": "vim::Rewrap",
|
||||||
|
"g ?": "vim::ConvertToRot13",
|
||||||
|
// "g ?": "vim::ConvertToRot47",
|
||||||
"\"": "vim::PushRegister",
|
"\"": "vim::PushRegister",
|
||||||
// tree-sitter related commands
|
// tree-sitter related commands
|
||||||
"[ x": "editor::SelectLargerSyntaxNode",
|
"[ x": "editor::SelectLargerSyntaxNode",
|
||||||
|
@ -477,6 +481,13 @@
|
||||||
"~": "vim::CurrentLine"
|
"~": "vim::CurrentLine"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "vim_operator == g?",
|
||||||
|
"bindings": {
|
||||||
|
"g ?": "vim::CurrentLine",
|
||||||
|
"?": "vim::CurrentLine"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"context": "vim_operator == gq",
|
"context": "vim_operator == gq",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
|
|
|
@ -274,6 +274,8 @@ actions!(
|
||||||
ConvertToTitleCase,
|
ConvertToTitleCase,
|
||||||
ConvertToUpperCamelCase,
|
ConvertToUpperCamelCase,
|
||||||
ConvertToUpperCase,
|
ConvertToUpperCase,
|
||||||
|
ConvertToRot13,
|
||||||
|
ConvertToRot47,
|
||||||
Copy,
|
Copy,
|
||||||
CopyAndTrim,
|
CopyAndTrim,
|
||||||
CopyFileLocation,
|
CopyFileLocation,
|
||||||
|
|
|
@ -9168,6 +9168,42 @@ impl Editor {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_rot13(
|
||||||
|
&mut self,
|
||||||
|
_: &ConvertToRot13,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_text(window, cx, |text| {
|
||||||
|
text.chars()
|
||||||
|
.map(|c| match c {
|
||||||
|
'A'..='M' | 'a'..='m' => ((c as u8) + 13) as char,
|
||||||
|
'N'..='Z' | 'n'..='z' => ((c as u8) - 13) as char,
|
||||||
|
_ => c,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_rot47(
|
||||||
|
&mut self,
|
||||||
|
_: &ConvertToRot47,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_text(window, cx, |text| {
|
||||||
|
text.chars()
|
||||||
|
.map(|c| {
|
||||||
|
let code_point = c as u32;
|
||||||
|
if code_point >= 33 && code_point <= 126 {
|
||||||
|
return char::from_u32(33 + ((code_point + 14) % 94)).unwrap();
|
||||||
|
}
|
||||||
|
c
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn manipulate_text<Fn>(&mut self, window: &mut Window, cx: &mut Context<Self>, mut callback: Fn)
|
fn manipulate_text<Fn>(&mut self, window: &mut Window, cx: &mut Context<Self>, mut callback: Fn)
|
||||||
where
|
where
|
||||||
Fn: FnMut(&str) -> String,
|
Fn: FnMut(&str) -> String,
|
||||||
|
|
|
@ -223,6 +223,8 @@ impl EditorElement {
|
||||||
register_action(editor, window, Editor::convert_to_upper_camel_case);
|
register_action(editor, window, Editor::convert_to_upper_camel_case);
|
||||||
register_action(editor, window, Editor::convert_to_lower_camel_case);
|
register_action(editor, window, Editor::convert_to_lower_camel_case);
|
||||||
register_action(editor, window, Editor::convert_to_opposite_case);
|
register_action(editor, window, Editor::convert_to_opposite_case);
|
||||||
|
register_action(editor, window, Editor::convert_to_rot13);
|
||||||
|
register_action(editor, window, Editor::convert_to_rot47);
|
||||||
register_action(editor, window, Editor::delete_to_previous_word_start);
|
register_action(editor, window, Editor::delete_to_previous_word_start);
|
||||||
register_action(editor, window, Editor::delete_to_previous_subword_start);
|
register_action(editor, window, Editor::delete_to_previous_subword_start);
|
||||||
register_action(editor, window, Editor::delete_to_next_word_end);
|
register_action(editor, window, Editor::delete_to_next_word_end);
|
||||||
|
|
|
@ -412,7 +412,7 @@ fn is_identifier_char(c: char) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_vim_operator_char(c: char) -> bool {
|
fn is_vim_operator_char(c: char) -> bool {
|
||||||
c == '>' || c == '<' || c == '~' || c == '"'
|
c == '>' || c == '<' || c == '~' || c == '"' || c == '?'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_whitespace(source: &str) -> &str {
|
fn skip_whitespace(source: &str) -> &str {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod case;
|
|
||||||
mod change;
|
mod change;
|
||||||
|
mod convert;
|
||||||
mod delete;
|
mod delete;
|
||||||
mod increment;
|
mod increment;
|
||||||
pub(crate) mod mark;
|
pub(crate) mod mark;
|
||||||
|
@ -22,8 +22,8 @@ use crate::{
|
||||||
state::{Mark, Mode, Operator},
|
state::{Mark, Mode, Operator},
|
||||||
surrounds::SurroundsType,
|
surrounds::SurroundsType,
|
||||||
};
|
};
|
||||||
use case::CaseTarget;
|
|
||||||
use collections::BTreeSet;
|
use collections::BTreeSet;
|
||||||
|
use convert::ConvertTarget;
|
||||||
use editor::Anchor;
|
use editor::Anchor;
|
||||||
use editor::Bias;
|
use editor::Bias;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
|
@ -55,6 +55,8 @@ actions!(
|
||||||
ChangeCase,
|
ChangeCase,
|
||||||
ConvertToUpperCase,
|
ConvertToUpperCase,
|
||||||
ConvertToLowerCase,
|
ConvertToLowerCase,
|
||||||
|
ConvertToRot13,
|
||||||
|
ConvertToRot47,
|
||||||
ToggleComments,
|
ToggleComments,
|
||||||
ShowLocation,
|
ShowLocation,
|
||||||
Undo,
|
Undo,
|
||||||
|
@ -73,6 +75,8 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, Vim::change_case);
|
Vim::action(editor, cx, Vim::change_case);
|
||||||
Vim::action(editor, cx, Vim::convert_to_upper_case);
|
Vim::action(editor, cx, Vim::convert_to_upper_case);
|
||||||
Vim::action(editor, cx, Vim::convert_to_lower_case);
|
Vim::action(editor, cx, Vim::convert_to_lower_case);
|
||||||
|
Vim::action(editor, cx, Vim::convert_to_rot13);
|
||||||
|
Vim::action(editor, cx, Vim::convert_to_rot47);
|
||||||
Vim::action(editor, cx, Vim::yank_line);
|
Vim::action(editor, cx, Vim::yank_line);
|
||||||
Vim::action(editor, cx, Vim::toggle_comments);
|
Vim::action(editor, cx, Vim::toggle_comments);
|
||||||
Vim::action(editor, cx, Vim::paste);
|
Vim::action(editor, cx, Vim::paste);
|
||||||
|
@ -171,13 +175,19 @@ impl Vim {
|
||||||
}
|
}
|
||||||
Some(Operator::ShellCommand) => self.shell_command_motion(motion, times, window, cx),
|
Some(Operator::ShellCommand) => self.shell_command_motion(motion, times, window, cx),
|
||||||
Some(Operator::Lowercase) => {
|
Some(Operator::Lowercase) => {
|
||||||
self.change_case_motion(motion, times, CaseTarget::Lowercase, window, cx)
|
self.convert_motion(motion, times, ConvertTarget::LowerCase, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::Uppercase) => {
|
Some(Operator::Uppercase) => {
|
||||||
self.change_case_motion(motion, times, CaseTarget::Uppercase, window, cx)
|
self.convert_motion(motion, times, ConvertTarget::UpperCase, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::OppositeCase) => {
|
Some(Operator::OppositeCase) => {
|
||||||
self.change_case_motion(motion, times, CaseTarget::OppositeCase, window, cx)
|
self.convert_motion(motion, times, ConvertTarget::OppositeCase, window, cx)
|
||||||
|
}
|
||||||
|
Some(Operator::Rot13) => {
|
||||||
|
self.convert_motion(motion, times, ConvertTarget::Rot13, window, cx)
|
||||||
|
}
|
||||||
|
Some(Operator::Rot47) => {
|
||||||
|
self.convert_motion(motion, times, ConvertTarget::Rot47, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::ToggleComments) => {
|
Some(Operator::ToggleComments) => {
|
||||||
self.toggle_comments_motion(motion, times, window, cx)
|
self.toggle_comments_motion(motion, times, window, cx)
|
||||||
|
@ -216,13 +226,19 @@ impl Vim {
|
||||||
}
|
}
|
||||||
Some(Operator::Rewrap) => self.rewrap_object(object, around, window, cx),
|
Some(Operator::Rewrap) => self.rewrap_object(object, around, window, cx),
|
||||||
Some(Operator::Lowercase) => {
|
Some(Operator::Lowercase) => {
|
||||||
self.change_case_object(object, around, CaseTarget::Lowercase, window, cx)
|
self.convert_object(object, around, ConvertTarget::LowerCase, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::Uppercase) => {
|
Some(Operator::Uppercase) => {
|
||||||
self.change_case_object(object, around, CaseTarget::Uppercase, window, cx)
|
self.convert_object(object, around, ConvertTarget::UpperCase, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::OppositeCase) => {
|
Some(Operator::OppositeCase) => {
|
||||||
self.change_case_object(object, around, CaseTarget::OppositeCase, window, cx)
|
self.convert_object(object, around, ConvertTarget::OppositeCase, window, cx)
|
||||||
|
}
|
||||||
|
Some(Operator::Rot13) => {
|
||||||
|
self.convert_object(object, around, ConvertTarget::Rot13, window, cx)
|
||||||
|
}
|
||||||
|
Some(Operator::Rot47) => {
|
||||||
|
self.convert_object(object, around, ConvertTarget::Rot47, window, cx)
|
||||||
}
|
}
|
||||||
Some(Operator::AddSurrounds { target: None }) => {
|
Some(Operator::AddSurrounds { target: None }) => {
|
||||||
waiting_operator = Some(Operator::AddSurrounds {
|
waiting_operator = Some(Operator::AddSurrounds {
|
||||||
|
|
|
@ -7,23 +7,25 @@ use multi_buffer::MultiBufferRow;
|
||||||
use crate::{
|
use crate::{
|
||||||
Vim,
|
Vim,
|
||||||
motion::Motion,
|
motion::Motion,
|
||||||
normal::{ChangeCase, ConvertToLowerCase, ConvertToUpperCase},
|
normal::{ChangeCase, ConvertToLowerCase, ConvertToRot13, ConvertToRot47, ConvertToUpperCase},
|
||||||
object::Object,
|
object::Object,
|
||||||
state::Mode,
|
state::Mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum CaseTarget {
|
pub enum ConvertTarget {
|
||||||
Lowercase,
|
LowerCase,
|
||||||
Uppercase,
|
UpperCase,
|
||||||
OppositeCase,
|
OppositeCase,
|
||||||
|
Rot13,
|
||||||
|
Rot47,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vim {
|
impl Vim {
|
||||||
pub fn change_case_motion(
|
pub fn convert_motion(
|
||||||
&mut self,
|
&mut self,
|
||||||
motion: Motion,
|
motion: Motion,
|
||||||
times: Option<usize>,
|
times: Option<usize>,
|
||||||
mode: CaseTarget,
|
mode: ConvertTarget,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -41,15 +43,21 @@ impl Vim {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
match mode {
|
match mode {
|
||||||
CaseTarget::Lowercase => {
|
ConvertTarget::LowerCase => {
|
||||||
editor.convert_to_lower_case(&Default::default(), window, cx)
|
editor.convert_to_lower_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
CaseTarget::Uppercase => {
|
ConvertTarget::UpperCase => {
|
||||||
editor.convert_to_upper_case(&Default::default(), window, cx)
|
editor.convert_to_upper_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
CaseTarget::OppositeCase => {
|
ConvertTarget::OppositeCase => {
|
||||||
editor.convert_to_opposite_case(&Default::default(), window, cx)
|
editor.convert_to_opposite_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
|
ConvertTarget::Rot13 => {
|
||||||
|
editor.convert_to_rot13(&Default::default(), window, cx)
|
||||||
|
}
|
||||||
|
ConvertTarget::Rot47 => {
|
||||||
|
editor.convert_to_rot47(&Default::default(), window, cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
editor.change_selections(None, window, cx, |s| {
|
editor.change_selections(None, window, cx, |s| {
|
||||||
s.move_with(|map, selection| {
|
s.move_with(|map, selection| {
|
||||||
|
@ -62,11 +70,11 @@ impl Vim {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_case_object(
|
pub fn convert_object(
|
||||||
&mut self,
|
&mut self,
|
||||||
object: Object,
|
object: Object,
|
||||||
around: bool,
|
around: bool,
|
||||||
mode: CaseTarget,
|
mode: ConvertTarget,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -85,15 +93,21 @@ impl Vim {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
match mode {
|
match mode {
|
||||||
CaseTarget::Lowercase => {
|
ConvertTarget::LowerCase => {
|
||||||
editor.convert_to_lower_case(&Default::default(), window, cx)
|
editor.convert_to_lower_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
CaseTarget::Uppercase => {
|
ConvertTarget::UpperCase => {
|
||||||
editor.convert_to_upper_case(&Default::default(), window, cx)
|
editor.convert_to_upper_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
CaseTarget::OppositeCase => {
|
ConvertTarget::OppositeCase => {
|
||||||
editor.convert_to_opposite_case(&Default::default(), window, cx)
|
editor.convert_to_opposite_case(&Default::default(), window, cx)
|
||||||
}
|
}
|
||||||
|
ConvertTarget::Rot13 => {
|
||||||
|
editor.convert_to_rot13(&Default::default(), window, cx)
|
||||||
|
}
|
||||||
|
ConvertTarget::Rot47 => {
|
||||||
|
editor.convert_to_rot47(&Default::default(), window, cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
editor.change_selections(None, window, cx, |s| {
|
editor.change_selections(None, window, cx, |s| {
|
||||||
s.move_with(|map, selection| {
|
s.move_with(|map, selection| {
|
||||||
|
@ -134,6 +148,36 @@ impl Vim {
|
||||||
self.manipulate_text(window, cx, |c| c.to_lowercase().collect::<Vec<char>>())
|
self.manipulate_text(window, cx, |c| c.to_lowercase().collect::<Vec<char>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_rot13(
|
||||||
|
&mut self,
|
||||||
|
_: &ConvertToRot13,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_text(window, cx, |c| {
|
||||||
|
vec![match c {
|
||||||
|
'A'..='M' | 'a'..='m' => ((c as u8) + 13) as char,
|
||||||
|
'N'..='Z' | 'n'..='z' => ((c as u8) - 13) as char,
|
||||||
|
_ => c,
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_rot47(
|
||||||
|
&mut self,
|
||||||
|
_: &ConvertToRot47,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_text(window, cx, |c| {
|
||||||
|
let code_point = c as u32;
|
||||||
|
if code_point >= 33 && code_point <= 126 {
|
||||||
|
return vec![char::from_u32(33 + ((code_point + 14) % 94)).unwrap()];
|
||||||
|
}
|
||||||
|
vec![c]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn manipulate_text<F>(&mut self, window: &mut Window, cx: &mut Context<Self>, transform: F)
|
fn manipulate_text<F>(&mut self, window: &mut Window, cx: &mut Context<Self>, transform: F)
|
||||||
where
|
where
|
||||||
F: Fn(char) -> Vec<char> + Copy,
|
F: Fn(char) -> Vec<char> + Copy,
|
||||||
|
@ -308,4 +352,60 @@ mod test {
|
||||||
cx.simulate_shared_keystrokes("g shift-u i w").await;
|
cx.simulate_shared_keystrokes("g shift-u i w").await;
|
||||||
cx.shared_state().await.assert_eq("abc ˇDEF\n");
|
cx.shared_state().await.assert_eq("abc ˇDEF\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_convert_to_rot13(cx: &mut gpui::TestAppContext) {
|
||||||
|
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||||
|
// works in visual mode
|
||||||
|
cx.set_shared_state("a😀C«dÉ1*fˇ»\n").await;
|
||||||
|
cx.simulate_shared_keystrokes("g ?").await;
|
||||||
|
cx.shared_state().await.assert_eq("a😀CˇqÉ1*s\n");
|
||||||
|
|
||||||
|
// works with line selections
|
||||||
|
cx.set_shared_state("abˇC\n").await;
|
||||||
|
cx.simulate_shared_keystrokes("shift-v g ?").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇnoP\n");
|
||||||
|
|
||||||
|
// works in visual block mode
|
||||||
|
cx.set_shared_state("ˇaa\nbb\ncc").await;
|
||||||
|
cx.simulate_shared_keystrokes("ctrl-v j g ?").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇna\nob\ncc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_change_rot13_motion(cx: &mut gpui::TestAppContext) {
|
||||||
|
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||||
|
|
||||||
|
cx.set_shared_state("ˇabc def").await;
|
||||||
|
cx.simulate_shared_keystrokes("g ? w").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇnop def");
|
||||||
|
|
||||||
|
cx.simulate_shared_keystrokes("g ? w").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇabc def");
|
||||||
|
|
||||||
|
cx.simulate_shared_keystrokes(".").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇnop def");
|
||||||
|
|
||||||
|
cx.set_shared_state("abˇc def").await;
|
||||||
|
cx.simulate_shared_keystrokes("g ? i w").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇnop def");
|
||||||
|
|
||||||
|
cx.simulate_shared_keystrokes(".").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇabc def");
|
||||||
|
|
||||||
|
cx.simulate_shared_keystrokes("g ? $").await;
|
||||||
|
cx.shared_state().await.assert_eq("ˇnop qrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_change_rot13_object(cx: &mut gpui::TestAppContext) {
|
||||||
|
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||||
|
|
||||||
|
cx.set_shared_state("ˇabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
.await;
|
||||||
|
cx.simulate_shared_keystrokes("g ? i w").await;
|
||||||
|
cx.shared_state()
|
||||||
|
.await
|
||||||
|
.assert_eq("ˇnopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM");
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -116,6 +116,8 @@ pub enum Operator {
|
||||||
Lowercase,
|
Lowercase,
|
||||||
Uppercase,
|
Uppercase,
|
||||||
OppositeCase,
|
OppositeCase,
|
||||||
|
Rot13,
|
||||||
|
Rot47,
|
||||||
Digraph {
|
Digraph {
|
||||||
first_char: Option<char>,
|
first_char: Option<char>,
|
||||||
},
|
},
|
||||||
|
@ -958,6 +960,8 @@ impl Operator {
|
||||||
Operator::Uppercase => "gU",
|
Operator::Uppercase => "gU",
|
||||||
Operator::Lowercase => "gu",
|
Operator::Lowercase => "gu",
|
||||||
Operator::OppositeCase => "g~",
|
Operator::OppositeCase => "g~",
|
||||||
|
Operator::Rot13 => "g?",
|
||||||
|
Operator::Rot47 => "g?",
|
||||||
Operator::Register => "\"",
|
Operator::Register => "\"",
|
||||||
Operator::RecordRegister => "q",
|
Operator::RecordRegister => "q",
|
||||||
Operator::ReplayRegister => "@",
|
Operator::ReplayRegister => "@",
|
||||||
|
@ -1006,6 +1010,8 @@ impl Operator {
|
||||||
| Operator::ShellCommand
|
| Operator::ShellCommand
|
||||||
| Operator::Lowercase
|
| Operator::Lowercase
|
||||||
| Operator::Uppercase
|
| Operator::Uppercase
|
||||||
|
| Operator::Rot13
|
||||||
|
| Operator::Rot47
|
||||||
| Operator::ReplaceWithRegister
|
| Operator::ReplaceWithRegister
|
||||||
| Operator::Exchange
|
| Operator::Exchange
|
||||||
| Operator::Object { .. }
|
| Operator::Object { .. }
|
||||||
|
@ -1026,6 +1032,8 @@ impl Operator {
|
||||||
| Operator::Lowercase
|
| Operator::Lowercase
|
||||||
| Operator::Uppercase
|
| Operator::Uppercase
|
||||||
| Operator::OppositeCase
|
| Operator::OppositeCase
|
||||||
|
| Operator::Rot13
|
||||||
|
| Operator::Rot47
|
||||||
| Operator::ToggleComments
|
| Operator::ToggleComments
|
||||||
| Operator::ReplaceWithRegister
|
| Operator::ReplaceWithRegister
|
||||||
| Operator::Rewrap
|
| Operator::Rewrap
|
||||||
|
|
|
@ -153,6 +153,8 @@ actions!(
|
||||||
PushLowercase,
|
PushLowercase,
|
||||||
PushUppercase,
|
PushUppercase,
|
||||||
PushOppositeCase,
|
PushOppositeCase,
|
||||||
|
PushRot13,
|
||||||
|
PushRot47,
|
||||||
ToggleRegistersView,
|
ToggleRegistersView,
|
||||||
PushRegister,
|
PushRegister,
|
||||||
PushRecordRegister,
|
PushRecordRegister,
|
||||||
|
@ -619,6 +621,14 @@ impl Vim {
|
||||||
vim.push_operator(Operator::OppositeCase, window, cx)
|
vim.push_operator(Operator::OppositeCase, window, cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vim::action(editor, cx, |vim, _: &PushRot13, window, cx| {
|
||||||
|
vim.push_operator(Operator::Rot13, window, cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
Vim::action(editor, cx, |vim, _: &PushRot47, window, cx| {
|
||||||
|
vim.push_operator(Operator::Rot47, window, cx)
|
||||||
|
});
|
||||||
|
|
||||||
Vim::action(editor, cx, |vim, _: &PushRegister, window, cx| {
|
Vim::action(editor, cx, |vim, _: &PushRegister, window, cx| {
|
||||||
vim.push_operator(Operator::Register, window, cx)
|
vim.push_operator(Operator::Register, window, cx)
|
||||||
});
|
});
|
||||||
|
|
23
crates/vim/test_data/test_change_rot13_motion.json
Normal file
23
crates/vim/test_data/test_change_rot13_motion.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{"Put":{"state":"ˇabc def"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Key":"w"}
|
||||||
|
{"Get":{"state":"ˇnop def","mode":"Normal"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Key":"w"}
|
||||||
|
{"Get":{"state":"ˇabc def","mode":"Normal"}}
|
||||||
|
{"Key":"."}
|
||||||
|
{"Get":{"state":"ˇnop def","mode":"Normal"}}
|
||||||
|
{"Put":{"state":"abˇc def"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Key":"i"}
|
||||||
|
{"Key":"w"}
|
||||||
|
{"Get":{"state":"ˇnop def","mode":"Normal"}}
|
||||||
|
{"Key":"."}
|
||||||
|
{"Get":{"state":"ˇabc def","mode":"Normal"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Key":"$"}
|
||||||
|
{"Get":{"state":"ˇnop qrs","mode":"Normal"}}
|
6
crates/vim/test_data/test_change_rot13_object.json
Normal file
6
crates/vim/test_data/test_change_rot13_object.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{"Put":{"state":"ˇabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Key":"i"}
|
||||||
|
{"Key":"w"}
|
||||||
|
{"Get":{"state":"ˇnopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM","mode":"Normal"}}
|
15
crates/vim/test_data/test_convert_to_rot13.json
Normal file
15
crates/vim/test_data/test_convert_to_rot13.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{"Put":{"state":"a😀C«dÉ1*fˇ»\n"}}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Get":{"state":"a😀CˇqÉ1*s\n","mode":"Normal"}}
|
||||||
|
{"Put":{"state":"abˇC\n"}}
|
||||||
|
{"Key":"shift-v"}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Get":{"state":"ˇnoP\n","mode":"Normal"}}
|
||||||
|
{"Put":{"state":"ˇaa\nbb\ncc"}}
|
||||||
|
{"Key":"ctrl-v"}
|
||||||
|
{"Key":"j"}
|
||||||
|
{"Key":"g"}
|
||||||
|
{"Key":"?"}
|
||||||
|
{"Get":{"state":"ˇna\nob\ncc","mode":"Normal"}}
|
Loading…
Add table
Add a link
Reference in a new issue