mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-09 20:21:16 -03:00
Truncate autosuggestion lines only at screen edge
From each logical line in the autosuggestion, we show all or nothing. This means that we may truncate too early -- specifically 1 + the number of soft-wrappings in this line. Fix that. See also #12153
This commit is contained in:
@@ -2049,6 +2049,10 @@ fn compute_layout(
|
||||
.split(|&c| c == '\n')
|
||||
.enumerate()
|
||||
{
|
||||
if available_vertical_space == 0 {
|
||||
truncated_vertically = true;
|
||||
break;
|
||||
}
|
||||
let autosuggestion_line = wstr::from_char_slice(autosuggestion_line);
|
||||
|
||||
// Calculate space available for autosuggestion.
|
||||
@@ -2063,36 +2067,56 @@ fn compute_layout(
|
||||
} else {
|
||||
indent_width(suggestion_start - "\n".len())
|
||||
};
|
||||
available_vertical_space = available_vertical_space.saturating_sub(width / screen_width);
|
||||
if available_vertical_space == 0 {
|
||||
truncated_vertically = true;
|
||||
break;
|
||||
}
|
||||
let column = width % screen_width;
|
||||
let suggestion_line_height = {
|
||||
let mut column = column;
|
||||
fn consumed_lines_or_truncated_suggestion(
|
||||
screen_width: usize,
|
||||
available_vertical_space: usize,
|
||||
mut column: usize,
|
||||
autosuggestion_line: &wstr,
|
||||
) -> Result<usize, &wstr> {
|
||||
let mut lines = 1;
|
||||
for ch in autosuggestion_line.chars() {
|
||||
for (i, ch) in autosuggestion_line.char_indices() {
|
||||
let ch_width = wcwidth_rendered_min_0(ch);
|
||||
let new_column = column + ch_width;
|
||||
if new_column > screen_width {
|
||||
if new_column >= screen_width {
|
||||
column = 0;
|
||||
}
|
||||
if column == 0 && ch_width != 0 {
|
||||
lines += 1;
|
||||
}
|
||||
column = if new_column == screen_width {
|
||||
0
|
||||
} else {
|
||||
column + ch_width
|
||||
};
|
||||
let barely_softwrapped = new_column == screen_width;
|
||||
if !barely_softwrapped {
|
||||
column += ch_width;
|
||||
}
|
||||
if lines > available_vertical_space {
|
||||
return Err(autosuggestion_line.slice_to(i));
|
||||
}
|
||||
}
|
||||
lines
|
||||
};
|
||||
match available_vertical_space.checked_sub(suggestion_line_height) {
|
||||
Some(lines) => available_vertical_space = lines,
|
||||
None => {
|
||||
truncated_vertically = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
suggestion_lines.push(autosuggestion_line);
|
||||
Ok(lines)
|
||||
}
|
||||
suggestion_lines.push(
|
||||
match consumed_lines_or_truncated_suggestion(
|
||||
screen_width,
|
||||
available_vertical_space,
|
||||
column,
|
||||
autosuggestion_line,
|
||||
) {
|
||||
Ok(lines) => {
|
||||
available_vertical_space -= lines;
|
||||
autosuggestion_line
|
||||
}
|
||||
Err(truncated) => {
|
||||
truncated_vertically = true;
|
||||
truncated
|
||||
}
|
||||
},
|
||||
);
|
||||
if truncated_vertically {
|
||||
break;
|
||||
}
|
||||
|
||||
suggestion_start += autosuggestion_line.len() + "\n".len();
|
||||
}
|
||||
|
||||
@@ -49,22 +49,21 @@ isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^ echo 000000000000000000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^0000000000000000000000000000000000000…
|
||||
|
||||
# Currently, we take either all or nothing from soft-wrapped suggestion-lines.
|
||||
# The ellipsis means that we'll get more lines.
|
||||
isolated-tmux resize-window -y 3
|
||||
tmux-sleep
|
||||
isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^prompt> if true
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000…
|
||||
# CHECK: ^
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000000000000000…
|
||||
|
||||
# Test that truncation also works after the resize.
|
||||
isolated-tmux send-keys C-u if
|
||||
tmux-sleep
|
||||
isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^prompt> if true
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000…
|
||||
# CHECK: ^
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000000000000000…
|
||||
|
||||
# Test that we truncate such that the prompt is never pushed up.
|
||||
isolated-tmux resize-window -y 5 \; send-keys C-u Enter if
|
||||
@@ -83,8 +82,8 @@ isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^prompt>
|
||||
# CHECK: ^prompt>
|
||||
# CHECK: ^prompt> if true
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000…
|
||||
# CHECK: ^
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000000000000000…
|
||||
|
||||
# Now try with a multiline prompt.
|
||||
isolated-tmux send-keys C-u 'function fish_prompt; printf "prompt-line%d/2> \n" 1 2; end' Enter C-l Enter if
|
||||
@@ -103,8 +102,8 @@ isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^prompt-line2/2>
|
||||
# CHECK: ^prompt-line1/2>
|
||||
# CHECK: ^prompt-line2/2> if true
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000…
|
||||
# CHECK: ^
|
||||
# CHECK: ^ echo 00000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^ echo 000000000000000000000000000000000000000000000000000000…
|
||||
|
||||
isolated-tmux send-keys C-u \; resize-window -y 7 \; send-keys if
|
||||
tmux-sleep
|
||||
@@ -132,7 +131,7 @@ isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^prompt-line1
|
||||
# CHECK: ^> begin
|
||||
# CHECK: ^ : 000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
# CHECK: ^
|
||||
# CHECK: ^…
|
||||
|
||||
# Autosuggestions on a soft-wrapped commandline don't push the prompt.
|
||||
isolated-tmux resize-window -x 6 -y 4 \; send-keys C-u \
|
||||
@@ -159,4 +158,4 @@ isolated-tmux capture-pane -p | sed s/^/^/
|
||||
# CHECK: ^>
|
||||
# CHECK: ^>
|
||||
# CHECK: ^> echo
|
||||
# CHECK: ^
|
||||
# CHECK: ^ wrap…
|
||||
|
||||
Reference in New Issue
Block a user