Skip to content

Commit

Permalink
Buf fix for cut-related commands: 's', 'd', 'c' and 'x': they should …
Browse files Browse the repository at this point in the history
…behave consistently with Vim:

- 'x' should cut selection like d under visual mode but it only cut one char under cursor right now
- 'c' cut selection correctly but it does not enter insert mode
- get_selection bug fix: Vi mode should be inclusive: include the last char
  • Loading branch information
deephbz committed Dec 31, 2024
1 parent bd30103 commit bd443f4
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/core_editor/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,9 @@ impl Editor {
pub fn get_selection(&self) -> Option<(usize, usize)> {
self.selection_anchor.map(|selection_anchor| {
if self.insertion_point() > selection_anchor {
(selection_anchor, self.insertion_point())
(selection_anchor, self.insertion_point() + 1)
} else {
(self.insertion_point(), selection_anchor)
(self.insertion_point(), selection_anchor + 1)
}
})
}
Expand Down
19 changes: 16 additions & 3 deletions src/edit_mode/vi/command.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{motion::Motion, motion::ViCharSearch, parser::ReedlineOption};
use super::{motion::Motion, motion::ViCharSearch, parser::ReedlineOption, ViMode};
use crate::{EditCommand, ReedlineEvent, Vi};
use std::iter::Peekable;

Expand Down Expand Up @@ -166,11 +166,24 @@ impl Command {
select: false,
})],
Self::RewriteCurrentLine => vec![ReedlineOption::Edit(EditCommand::CutCurrentLine)],
Self::DeleteChar => vec![ReedlineOption::Edit(EditCommand::CutChar)],
Self::DeleteChar => {
if vi_state.mode == ViMode::Visual {
vec![ReedlineOption::Edit(EditCommand::CutSelection)]
} else {
vec![ReedlineOption::Edit(EditCommand::CutChar)]
}
}
Self::ReplaceChar(c) => {
vec![ReedlineOption::Edit(EditCommand::ReplaceChar(*c))]
}
Self::SubstituteCharWithInsert => vec![ReedlineOption::Edit(EditCommand::CutChar)],
Self::SubstituteCharWithInsert => {
let result = if vi_state.mode == ViMode::Visual {
vec![ReedlineOption::Edit(EditCommand::CutSelection)]
} else {
vec![ReedlineOption::Edit(EditCommand::CutChar)]
};
result
}
Self::HistorySearch => vec![ReedlineOption::Event(ReedlineEvent::SearchHistory)],
Self::Switchcase => vec![ReedlineOption::Edit(EditCommand::SwitchcaseChar)],
// Whenever a motion is required to finish the command we must be in visual mode
Expand Down
3 changes: 1 addition & 2 deletions src/edit_mode/vi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,10 @@ impl EditMode for Vi {
self.cache.clear();
ReedlineEvent::None
} else if res.is_complete(self.mode) {
let event = res.to_reedline_event(self);
if let Some(mode) = res.changes_mode() {
self.mode = mode;
}

let event = res.to_reedline_event(self);
self.cache.clear();
event
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/edit_mode/vi/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ impl ParsedViSequence {
| (Some(Command::RewriteCurrentLine), ParseResult::Incomplete)
| (Some(Command::SubstituteCharWithInsert), ParseResult::Incomplete)
| (Some(Command::HistorySearch), ParseResult::Incomplete)
| (Some(Command::Change), ParseResult::Valid(_)) => Some(ViMode::Insert),
| (Some(Command::Change), ParseResult::Valid(_))
| (Some(Command::Change), ParseResult::Incomplete) => Some(ViMode::Insert),
(Some(Command::ChangeInside(char)), ParseResult::Incomplete)
if is_valid_change_inside_left(char) || is_valid_change_inside_right(char) =>
{
Expand Down

0 comments on commit bd443f4

Please sign in to comment.