mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-31 12:21:19 -03:00
Soft-wrapped autosuggestion to hide right prompt for now
Prior to f417cbc981 (Show soft-wrapped portions in autosuggestions,
2025-12-11), we'd truncate autosuggestions before the right prompt.
We no longer do that for autosuggestions that soft-wrap, which means
we try to draw both right prompt and suggestion in the same space.
Make suggestion paint over right prompt for now, since this seems to
be a simple and robust solution. We can revisit this later.
Fixes #12255
This commit is contained in:
@@ -4,6 +4,7 @@ fish ?.?.? (released ???)
|
|||||||
This release fixes the following problems identified in fish 4.3.0:
|
This release fixes the following problems identified in fish 4.3.0:
|
||||||
|
|
||||||
- Selecting a completion could insert only part of the token (:issue:`12249`).
|
- Selecting a completion could insert only part of the token (:issue:`12249`).
|
||||||
|
- Glitch with soft-wrapped autosuggestions and :doc:`cmds/fish_right_prompt` (:issue:`12255`).
|
||||||
- The sample prompts and themes are correctly installed (:issue:`12241`).
|
- The sample prompts and themes are correctly installed (:issue:`12241`).
|
||||||
- Last line of command output could be hidden when missing newline (:issue:`12246`).
|
- Last line of command output could be hidden when missing newline (:issue:`12246`).
|
||||||
|
|
||||||
|
|||||||
@@ -1980,7 +1980,7 @@ fn compute_layout(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let left_prompt_width = left_prompt_layout.last_line_width;
|
let left_prompt_width = left_prompt_layout.last_line_width;
|
||||||
let mut right_prompt_width = right_prompt_layout.last_line_width;
|
let right_prompt_width = right_prompt_layout.last_line_width;
|
||||||
|
|
||||||
// Get the width of the first line, and if there is more than one line.
|
// Get the width of the first line, and if there is more than one line.
|
||||||
let first_command_line_width: usize = line_at_cursor(commandline_before_suggestion, 0)
|
let first_command_line_width: usize = line_at_cursor(commandline_before_suggestion, 0)
|
||||||
@@ -2016,24 +2016,14 @@ fn compute_layout(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide the right prompt if it doesn't fit on the first line.
|
|
||||||
if left_prompt_width + first_command_line_width + right_prompt_width < screen_width {
|
|
||||||
result.right_prompt = right_prompt;
|
|
||||||
} else {
|
|
||||||
right_prompt_width = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we should definitely fit.
|
|
||||||
assert!(left_prompt_width + right_prompt_width <= screen_width);
|
|
||||||
|
|
||||||
// Track each logical line from the autosuggestion so we can determine how much of it fits
|
// Track each logical line from the autosuggestion so we can determine how much of it fits
|
||||||
// on screen. We allow the lines to soft wrap naturally and we only truncate vertically if
|
// on screen. We allow the lines to soft wrap naturally and we only truncate vertically if
|
||||||
// we would exceed the screen height.
|
// we would exceed the screen height.
|
||||||
let cursor_y = left_prompt_layout.line_starts.len() - 1
|
let commandline_before_suggestion_lines = commandline_before_suggestion
|
||||||
+ commandline_before_suggestion
|
.chars()
|
||||||
.chars()
|
.filter(|&c| c == '\n')
|
||||||
.filter(|&c| c == '\n')
|
.count();
|
||||||
.count();
|
let cursor_y = left_prompt_layout.line_starts.len() - 1 + commandline_before_suggestion_lines;
|
||||||
|
|
||||||
let mut suggestion_lines = vec![];
|
let mut suggestion_lines = vec![];
|
||||||
|
|
||||||
@@ -2062,7 +2052,8 @@ fn compute_layout(
|
|||||||
+ commandline_before_suggestion
|
+ commandline_before_suggestion
|
||||||
.chars()
|
.chars()
|
||||||
.rposition(|c| c == '\n')
|
.rposition(|c| c == '\n')
|
||||||
.map_or(right_prompt_width, indent_width)
|
.map(indent_width)
|
||||||
|
.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
indent_width(suggestion_start - "\n".len())
|
indent_width(suggestion_start - "\n".len())
|
||||||
};
|
};
|
||||||
@@ -2122,6 +2113,24 @@ fn consumed_lines_or_truncated_suggestion(
|
|||||||
|
|
||||||
let mut autosuggestion = WString::new();
|
let mut autosuggestion = WString::new();
|
||||||
let mut displayed_len = 0;
|
let mut displayed_len = 0;
|
||||||
|
{
|
||||||
|
// Hide the right prompt if it doesn't fit on the first line.
|
||||||
|
let first_command_line_suggestion_width = if commandline_before_suggestion_lines == 0 {
|
||||||
|
suggestion_lines.first().map_or(0, |line| {
|
||||||
|
line.chars().map(wcwidth_rendered_min_0).sum::<usize>()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
if left_prompt_width
|
||||||
|
+ first_command_line_width
|
||||||
|
+ first_command_line_suggestion_width
|
||||||
|
+ right_prompt_width
|
||||||
|
<= screen_width
|
||||||
|
{
|
||||||
|
result.right_prompt = right_prompt;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (line_idx, autosuggestion_line) in suggestion_lines.iter().enumerate() {
|
for (line_idx, autosuggestion_line) in suggestion_lines.iter().enumerate() {
|
||||||
if line_idx != 0 {
|
if line_idx != 0 {
|
||||||
autosuggestion.push('\n');
|
autosuggestion.push('\n');
|
||||||
@@ -2421,20 +2430,19 @@ fn test_prompt_truncation() {
|
|||||||
fn test_compute_layout() {
|
fn test_compute_layout() {
|
||||||
macro_rules! validate {
|
macro_rules! validate {
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
$screen_width:expr,
|
$screen_width:expr,
|
||||||
$left_untrunc_prompt:literal,
|
$left_untrunc_prompt:literal,
|
||||||
$right_untrunc_prompt:literal,
|
$right_untrunc_prompt:literal,
|
||||||
$commandline_before_suggestion:literal,
|
$commandline_before_suggestion:literal,
|
||||||
$autosuggestion_str:literal,
|
$autosuggestion_str:literal,
|
||||||
$commandline_after_suggestion:literal
|
$commandline_after_suggestion:literal
|
||||||
)
|
) -> (
|
||||||
-> (
|
$left_prompt:literal,
|
||||||
$left_prompt:literal,
|
$left_prompt_space:expr,
|
||||||
$left_prompt_space:expr,
|
$right_prompt:literal,
|
||||||
$right_prompt:literal,
|
$autosuggestion:literal $(,)?
|
||||||
$autosuggestion:literal $(,)?
|
)
|
||||||
)
|
|
||||||
) => {{
|
) => {{
|
||||||
let full_commandline = L!($commandline_before_suggestion).to_owned()
|
let full_commandline = L!($commandline_before_suggestion).to_owned()
|
||||||
+ L!($autosuggestion_str)
|
+ L!($autosuggestion_str)
|
||||||
@@ -2482,7 +2490,7 @@ macro_rules! validate {
|
|||||||
) -> (
|
) -> (
|
||||||
"left>",
|
"left>",
|
||||||
5,
|
5,
|
||||||
"<right",
|
"",
|
||||||
" autosuggesTION",
|
" autosuggesTION",
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -2604,7 +2612,7 @@ macro_rules! validate {
|
|||||||
) -> (
|
) -> (
|
||||||
"left>",
|
"left>",
|
||||||
5,
|
5,
|
||||||
"",
|
"<RIGHT",
|
||||||
"and AUTOSUGGESTION",
|
"and AUTOSUGGESTION",
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -2614,7 +2622,7 @@ macro_rules! validate {
|
|||||||
) -> (
|
) -> (
|
||||||
"left>",
|
"left>",
|
||||||
5,
|
5,
|
||||||
"",
|
"<RIGHT",
|
||||||
"AUTOSUGGESTION",
|
"AUTOSUGGESTION",
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -2624,7 +2632,7 @@ macro_rules! validate {
|
|||||||
) -> (
|
) -> (
|
||||||
"left>",
|
"left>",
|
||||||
5,
|
5,
|
||||||
"",
|
"<RIGHT",
|
||||||
"utosuggestion sofT WRAP",
|
"utosuggestion sofT WRAP",
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
22
tests/checks/tmux-right-prompt.fish
Normal file
22
tests/checks/tmux-right-prompt.fish
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#RUN: %fish %s
|
||||||
|
#REQUIRES: command -v tmux
|
||||||
|
|
||||||
|
isolated-tmux-start -C '
|
||||||
|
function fish_right_prompt
|
||||||
|
echo RP
|
||||||
|
end
|
||||||
|
history append "echo $(string repeat 100 a)"
|
||||||
|
'
|
||||||
|
isolated-tmux send-keys Enter e
|
||||||
|
tmux-sleep
|
||||||
|
isolated-tmux capture-pane -p
|
||||||
|
# CHECK: prompt 0> {{ *}} RP
|
||||||
|
# CHECK: prompt 0> echo {{(a{65,})}}
|
||||||
|
# CHECK: {{(a{35,})}}
|
||||||
|
|
||||||
|
isolated-tmux send-keys C-h C-l "echo line1" M-Enter "e"
|
||||||
|
tmux-sleep
|
||||||
|
isolated-tmux capture-pane -p
|
||||||
|
# CHECK: prompt 0> echo line1 {{ *}} RP
|
||||||
|
# CHECK: echo {{(a{65,})}}
|
||||||
|
# CHECK: {{(a{35,})}}
|
||||||
Reference in New Issue
Block a user