-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Vi-mode poor autosuggestion behavior / Invalid cursor placement and length in normal mode #10286
Comments
I'm disagreeing that this is a good first issue, it cuts to a fundamental issue with vi-mode: The cursor placement isn't the same as in emacs mode. That needs some careful consideration, because it would probably touch a lot more than the one bind function. See also #8189 or #3005, which both mention it as an issue with I'm going to close both of those and leave the issue at hand to be tracked here. |
Until this gets fixed fundamentally, is there any intermediary fish script conditional hack that could fix this specific pattern (normal mode |
It's not worth to add a hack. diff --git a/src/reader.rs b/src/reader.rs
index 45dbe69fd..5fd0425c1 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -1181,13 +1181,26 @@ impl ReaderData {
}
/// Update the cursor position.
- fn update_buff_pos(&mut self, elt: EditableLineTag, new_pos: Option<usize>) {
- if let Some(pos) = new_pos {
+ fn update_buff_pos(&mut self, elt: EditableLineTag, new_pos: Option<usize>) -> bool {
+ if let Some(mut pos) = new_pos {
+ if self
+ .vars()
+ .get_unless_empty(L!("fish_cursor_selection_mode"))
+ .is_some_and(|mode| mode.as_list()[0] == "inclusive")
+ {
+ let el = self.edit_line(elt);
+ if !el.is_empty() && pos == el.len() {
+ pos = el.len() - 1;
+ if el.position() == pos {
+ return false;
+ }
+ }
+ }
self.edit_line_mut(elt).set_position(pos);
}
if elt != EditableLineTag::Commandline {
- return;
+ return true;
}
let buff_pos = self.command_line.position();
let target_char = if self.cursor_selection_mode == CursorSelectionMode::Inclusive {
@@ -1196,7 +1209,7 @@ impl ReaderData {
0
};
let Some(selection) = self.selection.as_mut() else {
- return;
+ return true;
};
if selection.begin <= buff_pos {
selection.start = selection.begin;
@@ -1205,6 +1218,7 @@ impl ReaderData {
selection.start = buff_pos;
selection.stop = selection.begin + target_char;
}
+ true
}
}
@@ -2240,7 +2254,9 @@ impl ReaderData {
}
position
};
- self.update_buff_pos(self.active_edit_line_tag(), Some(position + 1));
+ if !self.update_buff_pos(self.active_edit_line_tag(), Some(position + 1)) {
+ break;
+ }
},
rl::BeginningOfBuffer => {
self.update_buff_pos(EditableLineTag::Commandline, Some(0));
@@ -2644,9 +2660,9 @@ impl ReaderData {
let (elt, el) = self.active_edit_line();
if self.is_navigating_pager_contents() {
self.select_completion_in_direction(SelectionMotion::East, false);
- } else if el.position() != el.len() {
- self.update_buff_pos(elt, Some(el.position() + 1));
- } else {
+ } else if el.position() == el.len()
+ || !self.update_buff_pos(elt, Some(el.position() + 1))
+ {
self.accept_autosuggestion(
/*full=*/ c != rl::ForwardSingleChar,
/*single=*/ c == rl::ForwardSingleChar, |
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
Today fish_cursor_selection_mode controls whether selection mode includes the cursor. Since it's by default only used for Vi mode, perhaps use it to also decide whether it should be allowed to select one-past the last character. Not allowing to select to select one-past the last character is much nicer in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select past end (using forward-single-char and such), so reset fish_cursor_selection_mode for the duration of the binding. Also fix other things like cursor placement after yank/yank-pop. Closes fish-shell#10286 Closes fish-shell#3299
fish, version 3.7.0
3.7.0
OS: Linux 6.6.14 NixOS (but happens on any OS)
Term: Kitty (but any terminal does this, over ssh, etc.)
In vi mode, I noticed an autocomplete issue, say you start here:
![image](https://private-user-images.githubusercontent.com/20625636/302369454-89b48cf5-a7b1-43c4-8ce7-13bb10b0cd6b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAzMzkxNjgsIm5iZiI6MTcyMDMzODg2OCwicGF0aCI6Ii8yMDYyNTYzNi8zMDIzNjk0NTQtODliNDhjZjUtYTdiMS00M2M0LThjZTctMTNiYjEwYjBjZDZiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzA3VDA3NTQyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTU3MDkzYWRiZTJhNjMzZGI1ZWQ0NWYyNGQwNjkyOWViYjBjMzg3NzgxOWU0MGU3YTA0MGEyYWI0MjRiNzA0OTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.lrSk5Fu1EePkGsr6ERvGasVZ1xBHLG1qjr1K1i6iwFY)
If you then press
ESC
to enter normal mode, thenl
to attempt to complete the autosuggestion, it doesn't work. You have to pressl
twice to complete.It seems that the reason for this issue with the autosuggestion or the fact that
ESC
moves you back, but that vi mode lets you move your normal mode cursor to after the last character, which isn't actually a valid vi place to put the cursor (or a "non-extant character").Then, when autosuggestion logic checks if you're at the last possible cursor position when you call
forward-char
withl
, it should consider you at the last possible normal mode position, but instead it thinks that there is that one extra place for the cursor to be.The text was updated successfully, but these errors were encountered: