Apply autosuggestions from completions also if cursor is not at EOL

Before 1c4e5cadf2 (Autosuggestions in multi-line command lines,
2024-12-15), the completion code path in the autosuggestion performer
used to do something weird: it used to request completions for the
entire command line (with the implied cursor at end) but try to apply
the same completion at the actual cursor.

That commit changed this to request completions only up to the cursor
position, which could in theory make us produce valid completions even
if the cursor is not at end of the line.  However, that doesn't really
work since autosuggestions can only be rendered at the end of the line.
And the worst of it, that commit tries to compute

	line_at_cursor(&full_line, search_string_range.end)

which crashes as out-of-bounds if the completion needs to replace the token
(like a case-correcting completion does).

Let's apply completions to the end, matching how autosuggestions work
in general.
This commit is contained in:
Johannes Altmanninger 2025-01-03 12:15:55 +01:00
parent abaeb4af2a
commit d823444c6e
2 changed files with 18 additions and 4 deletions

View file

@ -4573,23 +4573,23 @@ fn get_autosuggestion_performer(
// Try normal completions.
let complete_flags = CompletionRequestOptions::autosuggest();
let mut would_be_cursor = search_string_range.end;
let (mut completions, needs_load) =
complete(&command_line[..cursor_pos], complete_flags, &ctx);
complete(&command_line[..would_be_cursor], complete_flags, &ctx);
let suggestion = if completions.is_empty() {
WString::new()
} else {
sort_and_prioritize(&mut completions, complete_flags);
let comp = &completions[0];
let mut cursor = cursor_pos;
let full_line = completion_apply_to_command_line(
&comp.completion,
comp.flags,
&command_line,
&mut cursor,
&mut would_be_cursor,
/*append_only=*/ true,
);
line_at_cursor(&full_line, search_string_range.end).to_owned()
line_at_cursor(&full_line, would_be_cursor).to_owned()
};
let mut result = AutosuggestionResult::new(
command_line,

View file

@ -9,3 +9,17 @@ isolated-tmux send-keys M-Right
isolated-tmux capture-pane -p
# CHECK: prompt 1> echo "foo bar baz"
tmux-sleep
touch COMPL
# Regression test.
isolated-tmux send-keys C-u C-l ': sometoken' M-b c
tmux-sleep
isolated-tmux capture-pane -p
# CHECK: prompt 1> : csometoken
# Test that we get completion autosuggestions also when the cursor is not at EOL.
isolated-tmux send-keys C-u 'complete nofilecomp -f' Enter C-l 'nofilecomp ./CO' C-a M-d :
tmux-sleep
isolated-tmux capture-pane -p
# CHECK: prompt 2> : ./COMPL