Clean up the accept-autosuggestion code path a little bit

It's still a bit too complex unfortunately.
This commit is contained in:
Johannes Altmanninger 2024-11-14 12:20:47 +01:00
parent 2b19e1a09b
commit ca21872d14
3 changed files with 53 additions and 43 deletions

0
foo bar baz Normal file
View file

View file

@ -2275,7 +2275,7 @@ impl<'a> Reader<'a> {
rl::EndOfLine => { rl::EndOfLine => {
let (_elt, el) = self.active_edit_line(); let (_elt, el) = self.active_edit_line();
if self.is_at_end(el) { if self.is_at_end(el) {
self.accept_autosuggestion(true, false, MoveWordStyle::Punctuation); self.accept_autosuggestion(AutosuggestionPortion::Count(usize::MAX));
} else { } else {
loop { loop {
let position = { let position = {
@ -2774,11 +2774,13 @@ impl<'a> Reader<'a> {
if self.is_navigating_pager_contents() { if self.is_navigating_pager_contents() {
self.select_completion_in_direction(SelectionMotion::East, false); self.select_completion_in_direction(SelectionMotion::East, false);
} else if self.is_at_end(el) { } else if self.is_at_end(el) {
self.accept_autosuggestion( self.accept_autosuggestion(AutosuggestionPortion::Count(
/*full=*/ c != rl::ForwardSingleChar, if c == rl::ForwardSingleChar {
/*single=*/ c == rl::ForwardSingleChar, 1
MoveWordStyle::Punctuation, } else {
); usize::MAX
},
));
} else { } else {
self.update_buff_pos(elt, Some(el.position() + 1)); self.update_buff_pos(elt, Some(el.position() + 1));
} }
@ -2919,7 +2921,7 @@ impl<'a> Reader<'a> {
}; };
let (elt, el) = self.active_edit_line(); let (elt, el) = self.active_edit_line();
if self.is_at_end(el) { if self.is_at_end(el) {
self.accept_autosuggestion(false, false, style); self.accept_autosuggestion(AutosuggestionPortion::PerMoveWordStyle(style));
} else { } else {
self.move_word(elt, MoveWordDir::Right, /*erase=*/ false, style, false); self.move_word(elt, MoveWordDir::Right, /*erase=*/ false, style, false);
} }
@ -3021,7 +3023,7 @@ impl<'a> Reader<'a> {
} }
rl::AcceptAutosuggestion => { rl::AcceptAutosuggestion => {
let success = !self.autosuggestion.is_empty(); let success = !self.autosuggestion.is_empty();
self.accept_autosuggestion(true, false, MoveWordStyle::Punctuation); self.accept_autosuggestion(AutosuggestionPortion::Count(usize::MAX));
self.input_data.function_set_status(success); self.input_data.function_set_status(success);
} }
rl::TransposeChars => { rl::TransposeChars => {
@ -4317,6 +4319,11 @@ fn get_autosuggestion_performer(
} }
} }
enum AutosuggestionPortion {
Count(usize),
PerMoveWordStyle(MoveWordStyle),
}
impl<'a> Reader<'a> { impl<'a> Reader<'a> {
fn can_autosuggest(&self) -> bool { fn can_autosuggest(&self) -> bool {
// We autosuggest if suppress_autosuggestion is not set, if we're not doing a history search, // We autosuggest if suppress_autosuggestion is not set, if we're not doing a history search,
@ -4428,12 +4435,7 @@ impl<'a> Reader<'a> {
// Accept any autosuggestion by replacing the command line with it. If full is true, take the whole // Accept any autosuggestion by replacing the command line with it. If full is true, take the whole
// thing; if it's false, then respect the passed in style. // thing; if it's false, then respect the passed in style.
fn accept_autosuggestion( fn accept_autosuggestion(&mut self, amount: AutosuggestionPortion) {
&mut self,
full: bool,
single: bool, /* = false */
style: MoveWordStyle, /* = Punctuation */
) {
if self.autosuggestion.is_empty() { if self.autosuggestion.is_empty() {
return; return;
} }
@ -4441,39 +4443,36 @@ impl<'a> Reader<'a> {
self.clear_pager(); self.clear_pager();
// Accept the autosuggestion. // Accept the autosuggestion.
if full { match amount {
// Just take the whole thing. AutosuggestionPortion::Count(count) => {
self.data.replace_substring( let pos = self.command_line.len();
EditableLineTag::Commandline, let count = count.min(self.autosuggestion.text.len() - pos);
0..self.command_line.len(), if count != 0 {
self.autosuggestion.text.clone(), self.data.replace_substring(
); EditableLineTag::Commandline,
} else if single { pos..pos,
let pos = self.command_line.len(); self.autosuggestion.text[pos..pos + count].to_owned(),
if pos + 1 < self.autosuggestion.text.len() { );
}
}
AutosuggestionPortion::PerMoveWordStyle(style) => {
// Accept characters according to the specified style.
let mut state = MoveWordStateMachine::new(style);
let mut want = self.command_line.len();
while want < self.autosuggestion.text.len() {
let wc = self.autosuggestion.text.as_char_slice()[want];
if !state.consume_char(wc) {
break;
}
want += 1;
}
let have = self.command_line.len();
self.data.replace_substring( self.data.replace_substring(
EditableLineTag::Commandline, EditableLineTag::Commandline,
pos..pos, have..have,
self.autosuggestion.text[pos..pos + 1].to_owned(), self.autosuggestion.text[have..want].to_owned(),
); );
} }
} else {
// Accept characters according to the specified style.
let mut state = MoveWordStateMachine::new(style);
let mut want = self.command_line.len();
while want < self.autosuggestion.text.len() {
let wc = self.autosuggestion.text.as_char_slice()[want];
if !state.consume_char(wc) {
break;
}
want += 1;
}
let have = self.command_line.len();
self.data.replace_substring(
EditableLineTag::Commandline,
have..have,
self.autosuggestion.text[have..want].to_owned(),
);
} }
} }
} }

View file

@ -0,0 +1,11 @@
#RUN: %fish %s
#REQUIRES: command -v tmux
isolated-tmux-start
isolated-tmux send-keys 'echo "foo bar baz"' Enter C-l
isolated-tmux send-keys 'echo '
tmux-sleep
isolated-tmux send-keys M-Right
isolated-tmux capture-pane -p
# CHECK: prompt 1> echo "foo bar baz"
tmux-sleep