mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-07 18:21:16 -03:00
Also use control pictures for pager prefix
The test case shows that the pager rendering is not quite right. It renders
'{\', leaving out the newline. This rendering is ambiguous.
Let's fix it by rendering \n as control picture, like we do for other control
characters in the pager.
This commit is contained in:
19
src/pager.rs
19
src/pager.rs
@@ -8,13 +8,12 @@
|
||||
};
|
||||
use crate::complete::Completion;
|
||||
use crate::editable_line::EditableLine;
|
||||
use crate::fallback::{fish_wcswidth, fish_wcwidth};
|
||||
#[allow(unused_imports)]
|
||||
use crate::future::IsSomeAnd;
|
||||
use crate::highlight::{highlight_shell, HighlightRole, HighlightSpec};
|
||||
use crate::libc::MB_CUR_MAX;
|
||||
use crate::operation_context::OperationContext;
|
||||
use crate::screen::{Line, ScreenData};
|
||||
use crate::screen::{wcswidth_rendered, wcwidth_rendered, Line, ScreenData};
|
||||
use crate::termsize::Termsize;
|
||||
use crate::wchar::prelude::*;
|
||||
use crate::wcstringutil::string_fuzzy_match_string;
|
||||
@@ -344,7 +343,7 @@ fn completion_try_print(
|
||||
}
|
||||
|
||||
fn measure_completion_infos(&mut self) {
|
||||
let prefix_len = usize::try_from(fish_wcswidth(&self.prefix));
|
||||
let prefix_len = wcswidth_rendered(&self.prefix);
|
||||
for comp in &mut self.unfiltered_completion_infos {
|
||||
let comp_strings = &mut comp.comp;
|
||||
|
||||
@@ -354,14 +353,14 @@ fn measure_completion_infos(&mut self) {
|
||||
comp.comp_width += 2;
|
||||
}
|
||||
|
||||
// fish_wcswidth() can return -1 if it can't calculate the width. So be cautious.
|
||||
let comp_width = fish_wcswidth(comp_string);
|
||||
comp.comp_width += prefix_len.unwrap_or_default();
|
||||
// This can return -1 if it can't calculate the width. So be cautious.
|
||||
let comp_width = wcswidth_rendered(comp_string);
|
||||
comp.comp_width += usize::try_from(prefix_len).unwrap_or_default();
|
||||
comp.comp_width += usize::try_from(comp_width).unwrap_or_default();
|
||||
}
|
||||
|
||||
// fish_wcswidth() can return -1 if it can't calculate the width. So be cautious.
|
||||
let desc_width = fish_wcswidth(&comp.desc);
|
||||
// This can return -1 if it can't calculate the width. So be cautious.
|
||||
let desc_width = wcswidth_rendered(&comp.desc);
|
||||
comp.desc_width = usize::try_from(desc_width).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
@@ -1071,7 +1070,7 @@ fn print_max_impl(
|
||||
) -> usize {
|
||||
let mut remaining = max;
|
||||
for (i, c) in s.chars().enumerate() {
|
||||
let iwidth_c = fish_wcwidth(c);
|
||||
let iwidth_c = wcwidth_rendered(c);
|
||||
let Ok(width_c) = usize::try_from(iwidth_c) else {
|
||||
// skip non-printable characters
|
||||
continue;
|
||||
@@ -1084,7 +1083,7 @@ fn print_max_impl(
|
||||
let ellipsis = get_ellipsis_char();
|
||||
if (width_c == remaining) && (has_more || i + 1 < s.len()) {
|
||||
line.append(ellipsis, color(i));
|
||||
let ellipsis_width = fish_wcwidth(ellipsis);
|
||||
let ellipsis_width = wcwidth_rendered(ellipsis);
|
||||
remaining = remaining.saturating_sub(usize::try_from(ellipsis_width).unwrap());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ pub fn append_line(&mut self, line: &Line) {
|
||||
pub fn wcswidth_min_0(&self, max: usize /* = usize::MAX */) -> usize {
|
||||
let mut result: usize = 0;
|
||||
for c in &self.text[..max.min(self.text.len())] {
|
||||
result += wcwidth_rendered(c.character);
|
||||
result += wcwidth_rendered_min_0(c.character);
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -327,7 +327,7 @@ pub fn write(
|
||||
colors[i],
|
||||
usize::try_from(indent[i]).unwrap(),
|
||||
first_line_prompt_space,
|
||||
wcwidth_rendered(effective_commandline.as_char_slice()[i]),
|
||||
wcwidth_rendered_min_0(effective_commandline.as_char_slice()[i]),
|
||||
);
|
||||
i += 1;
|
||||
}
|
||||
@@ -925,7 +925,7 @@ fn s_line(zelf: &Screen, i: usize) -> &Line {
|
||||
// Skip over skip_remaining width worth of characters.
|
||||
let mut j = 0;
|
||||
while j < o_line(&zelf, i).len() {
|
||||
let width = wcwidth_rendered(o_line(&zelf, i).char_at(j));
|
||||
let width = wcwidth_rendered_min_0(o_line(&zelf, i).char_at(j));
|
||||
if skip_remaining < width {
|
||||
break;
|
||||
}
|
||||
@@ -936,7 +936,7 @@ fn s_line(zelf: &Screen, i: usize) -> &Line {
|
||||
|
||||
// Skip over zero-width characters (e.g. combining marks at the end of the prompt).
|
||||
while j < o_line(&zelf, i).len() {
|
||||
let width = wcwidth_rendered(o_line(&zelf, i).char_at(j));
|
||||
let width = wcwidth_rendered_min_0(o_line(&zelf, i).char_at(j));
|
||||
if width > 0 {
|
||||
break;
|
||||
}
|
||||
@@ -969,7 +969,7 @@ fn s_line(zelf: &Screen, i: usize) -> &Line {
|
||||
let color = o_line(&zelf, i).color_at(j);
|
||||
set_color(&mut zelf, color);
|
||||
let ch = o_line(&zelf, i).char_at(j);
|
||||
let width = wcwidth_rendered(ch);
|
||||
let width = wcwidth_rendered_min_0(ch);
|
||||
zelf.write_char(ch, isize::try_from(width).unwrap());
|
||||
current_width += width;
|
||||
j += 1;
|
||||
@@ -1524,7 +1524,7 @@ fn measure_run_from(
|
||||
width = next_tab_stop(width);
|
||||
} else {
|
||||
// Ordinary char. Add its width with care to ignore control chars which have width -1.
|
||||
width += wcwidth_rendered(input.char_at(idx));
|
||||
width += wcwidth_rendered_min_0(input.char_at(idx));
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
@@ -1570,7 +1570,7 @@ fn truncate_run(
|
||||
curr_width = measure_run_from(run, 0, None, cache);
|
||||
idx = 0;
|
||||
} else {
|
||||
let char_width = wcwidth_rendered(c);
|
||||
let char_width = wcwidth_rendered_min_0(c);
|
||||
curr_width -= std::cmp::min(curr_width, char_width);
|
||||
run.remove(idx);
|
||||
}
|
||||
@@ -1719,7 +1719,7 @@ fn compute_layout(
|
||||
multiline = true;
|
||||
break;
|
||||
} else {
|
||||
first_line_width += wcwidth_rendered(c);
|
||||
first_line_width += wcwidth_rendered_min_0(c);
|
||||
}
|
||||
}
|
||||
let first_command_line_width = first_line_width;
|
||||
@@ -1734,7 +1734,7 @@ fn compute_layout(
|
||||
autosuggest_truncated_widths.reserve(1 + autosuggestion_str.len());
|
||||
for c in autosuggestion.chars() {
|
||||
autosuggest_truncated_widths.push(autosuggest_total_width);
|
||||
autosuggest_total_width += wcwidth_rendered(c);
|
||||
autosuggest_total_width += wcwidth_rendered_min_0(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1839,6 +1839,12 @@ fn rendered_character(c: char) -> char {
|
||||
}
|
||||
}
|
||||
|
||||
fn wcwidth_rendered(c: char) -> usize {
|
||||
usize::try_from(fish_wcwidth(rendered_character(c))).unwrap_or_default()
|
||||
fn wcwidth_rendered_min_0(c: char) -> usize {
|
||||
usize::try_from(wcwidth_rendered(c)).unwrap()
|
||||
}
|
||||
pub fn wcwidth_rendered(c: char) -> isize {
|
||||
fish_wcwidth(rendered_character(c))
|
||||
}
|
||||
pub fn wcswidth_rendered(s: &wstr) -> isize {
|
||||
s.chars().map(|c| fish_wcwidth(rendered_character(c))).sum()
|
||||
}
|
||||
|
||||
@@ -194,4 +194,15 @@ macro_rules! validate {
|
||||
validate!(&mut pager, 18, L!("abcdefghijklmnopq…"));
|
||||
validate!(&mut pager, 17, L!("abcdefghijklmnop…"));
|
||||
validate!(&mut pager, 16, L!("abcdefghijklmno…"));
|
||||
|
||||
// Newlines in prefix
|
||||
let c4s = vec![Completion::new(
|
||||
L!("Hello").to_owned(),
|
||||
L!("").to_owned(),
|
||||
StringFuzzyMatch::exact_match(),
|
||||
CompleteFlags::default(),
|
||||
)];
|
||||
pager.set_prefix(L!("{\\\n"), false); // }
|
||||
pager.set_completions(&c4s, true);
|
||||
validate!(&mut pager, 30, L!("{\\␊Hello")); // }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user