Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support swtiching the case of a char with ~ in vi #452

Merged
merged 1 commit into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/core_editor/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl Editor {
EditCommand::PasteCutBufferAfter => self.insert_cut_buffer_after(),
EditCommand::UppercaseWord => self.line_buffer.uppercase_word(),
EditCommand::LowercaseWord => self.line_buffer.lowercase_word(),
EditCommand::SwitchcaseChar => self.line_buffer.switchcase_char(),
EditCommand::CapitalizeChar => self.line_buffer.capitalize_char(),
EditCommand::SwapWords => self.line_buffer.swap_words(),
EditCommand::SwapGraphemes => self.line_buffer.swap_graphemes(),
Expand Down
48 changes: 48 additions & 0 deletions src/core_editor/line_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,28 @@ impl LineBuffer {
self.move_word_right();
}

/// Switches the ASCII case of the current char
pub fn switchcase_char(&mut self) {
let insertion_offset = self.insertion_point();
let right_index = self.grapheme_right_index();

if right_index > insertion_offset {
let change_range = insertion_offset..right_index;
let swapped = self.get_buffer()[change_range.clone()]
.chars()
.map(|c| {
if c.is_ascii_uppercase() {
c.to_ascii_lowercase()
} else {
c.to_ascii_uppercase()
}
})
.collect::<String>();
self.replace_range(change_range, &swapped);
self.move_right();
}
}

/// Counts the number of words in the buffer
pub fn word_count(&self) -> usize {
self.lines.split_whitespace().count()
Expand Down Expand Up @@ -957,6 +979,32 @@ mod test {
line_buffer.assert_valid();
}

#[rstest]
#[case("", 0, "", 0)]
#[case("a test", 2, "a Test", 3)]
#[case("a Test", 2, "a test", 3)]
#[case("test", 0, "Test", 1)]
#[case("Test", 0, "test", 1)]
#[case("test", 3, "tesT", 4)]
#[case("tesT", 3, "test", 4)]
#[case("ß", 0, "ß", 2)]
fn switchcase_char(
#[case] input: &str,
#[case] in_location: usize,
#[case] output: &str,
#[case] out_location: usize,
) {
let mut line_buffer = buffer_with(input);
line_buffer.set_insertion_point(in_location);
line_buffer.switchcase_char();

let mut expected = buffer_with(output);
expected.set_insertion_point(out_location);

assert_eq!(expected, line_buffer);
line_buffer.assert_valid();
}

#[rstest]
#[case("This is a test", 13, "This is a tets", 14)]
#[case("This is a test", 14, "This is a tets", 14)] // NOTE: Swaping works in opposite direction at last index
Expand Down
6 changes: 6 additions & 0 deletions src/edit_mode/vi/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ where
.as_ref()
.map(|to_till| Command::ReverseToTill(to_till.clone()))
}
Some('~') => {
let _ = input.next();
Some(Command::Switchcase)
}
_ => None,
}
}
Expand Down Expand Up @@ -203,6 +207,7 @@ pub enum Command {
ReplayToTill(ViToTill),
ReverseToTill(ViToTill),
HistorySearch,
Switchcase,
}

impl Command {
Expand Down Expand Up @@ -260,6 +265,7 @@ impl Command {
}
Self::SubstituteCharWithInsert => vec![ReedlineOption::Edit(EditCommand::CutChar)],
Self::HistorySearch => vec![ReedlineOption::Event(ReedlineEvent::SearchHistory)],
Self::Switchcase => vec![ReedlineOption::Edit(EditCommand::SwitchcaseChar)],
// Mark a command as incomplete whenever a motion is required to finish the command
Self::Delete | Self::Change | Self::Incomplete => vec![ReedlineOption::Incomplete],
}
Expand Down
5 changes: 5 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ pub enum EditCommand {
/// Capitalize the current character
CapitalizeChar,

/// Switch the case of the current character
SwitchcaseChar,

/// Swap the current word with the word to the right
SwapWords,

Expand Down Expand Up @@ -228,6 +231,7 @@ impl Display for EditCommand {
EditCommand::PasteCutBufferAfter => write!(f, "PasteCutBufferAfter"),
EditCommand::UppercaseWord => write!(f, "UppercaseWord"),
EditCommand::LowercaseWord => write!(f, "LowercaseWord"),
EditCommand::SwitchcaseChar => write!(f, "SwitchcaseChar"),
EditCommand::CapitalizeChar => write!(f, "CapitalizeChar"),
EditCommand::SwapWords => write!(f, "SwapWords"),
EditCommand::SwapGraphemes => write!(f, "SwapGraphemes"),
Expand Down Expand Up @@ -300,6 +304,7 @@ impl EditCommand {
| EditCommand::PasteCutBufferAfter
| EditCommand::UppercaseWord
| EditCommand::LowercaseWord
| EditCommand::SwitchcaseChar
| EditCommand::CapitalizeChar
| EditCommand::SwapWords
| EditCommand::SwapGraphemes
Expand Down