From e37e1b8f780a772bb79f26a858756049cf80cc77 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 10 Mar 2025 23:34:10 +0100 Subject: [PATCH] Fix regression causing glitches when prompt has control character MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 0627c9d9af (Render control characters as Unicode Control Pictures, 2020-08-29), we render control character in the commandline as "␇" etc. They can be inserted via either history search, or bindings such as bind ctrl-g "commandline -i \a" That commit incorrectly assumes that the prompt is rendered the same way as the command line (which goes through "ScreenData" etc). This is wrong -- prompt text is written to stdout as-is, and a prompt that outputs \t (tab) or \a (BEL) is valid. The wrong assumption means that we overestimate the width of prompts containing control characters. (For some reason, after switching from Vi insert to Vi normal mode, we seem to get the width right which means the command line jumps around) Let's revert to the old width computation for any prompt text. Closes #11252 (cherry picked from commit 4d81cf8af4fe0ba5a2cdce8931871f9df1c5f080) --- src/screen.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/screen.rs b/src/screen.rs index 479622198..ad6f43b2b 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -35,7 +35,7 @@ use crate::output::Outputter; use crate::termsize::{termsize_last, Termsize}; use crate::wchar::prelude::*; -use crate::wcstringutil::string_prefixes_string; +use crate::wcstringutil::{fish_wcwidth_visible, string_prefixes_string}; use crate::wutil::fstat; #[derive(Clone, Default)] @@ -1636,7 +1636,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_min_0(input.char_at(idx)); + width += usize::try_from(fish_wcwidth_visible(input.char_at(idx))).unwrap(); } idx += 1; } @@ -1682,7 +1682,7 @@ fn truncate_run( curr_width = measure_run_from(run, 0, None, cache); idx = 0; } else { - let char_width = wcwidth_rendered_min_0(c); + let char_width = usize::try_from(fish_wcwidth_visible(c)).unwrap(); curr_width -= std::cmp::min(curr_width, char_width); run.remove(idx); }