diff --git a/src/builtins/string.rs b/src/builtins/string.rs index 7cd42e4fb..994ca4aff 100644 --- a/src/builtins/string.rs +++ b/src/builtins/string.rs @@ -235,7 +235,7 @@ enum Direction { } fn width_without_escapes(ins: &wstr, start_pos: usize) -> usize { - let mut width: i32 = 0; + let mut width: isize = 0; for c in ins[start_pos..].chars() { let w = fish_wcwidth_visible(c); // We assume that this string is on its own line, diff --git a/src/builtins/string/shorten.rs b/src/builtins/string/shorten.rs index 85c42679a..c6f130a7a 100644 --- a/src/builtins/string/shorten.rs +++ b/src/builtins/string/shorten.rs @@ -191,7 +191,7 @@ impl<'args> StringSubCommand<'args> for Shorten<'args> { // This is somewhat easier. while max <= ourmax && pos < line.len() { pos += skip_escapes(&line, pos); - let w = fish_wcwidth_visible(line.char_at(pos)) as isize; + let w = fish_wcwidth_visible(line.char_at(pos)); if w <= 0 || max + w as usize + ell_width <= ourmax { // If it still fits, even if it is the last, we add it. max = max.saturating_add_signed(w); @@ -202,7 +202,7 @@ impl<'args> StringSubCommand<'args> for Shorten<'args> { let mut pos2 = pos + 1; while pos2 < line.len() { pos2 += skip_escapes(&line, pos2); - let w = fish_wcwidth_visible(line.char_at(pos2)) as isize; + let w = fish_wcwidth_visible(line.char_at(pos2)); max2 = max2.saturating_add_signed(w); pos2 += 1; } diff --git a/src/common.rs b/src/common.rs index 9292cfcf4..fe1ad7154 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1542,7 +1542,7 @@ pub fn reformat_for_screen(msg: &wstr, termsize: &Termsize) -> WString { while pos < msg.len() && ![' ', '\n', '\r', '\t'].contains(&msg.char_at(pos)) { // Check is token is wider than one line. If so we mark it as an overflow and break // the token. - let width = fish_wcwidth(msg.char_at(pos)) as isize; + let width = fish_wcwidth(msg.char_at(pos)); if (tok_width + width) > (screen_width - 1) { overflow = true; break; diff --git a/src/env_dispatch.rs b/src/env_dispatch.rs index 670253227..e859fde17 100644 --- a/src/env_dispatch.rs +++ b/src/env_dispatch.rs @@ -157,7 +157,7 @@ fn guess_emoji_width(vars: &EnvStack) { if let Some(width_str) = vars.get(L!("fish_emoji_width")) { // The only valid values are 1 or 2; we default to 1 if it was an invalid int. let new_width = fish_wcstoi(&width_str.as_string()).unwrap_or(1).clamp(1, 2); - FISH_EMOJI_WIDTH.store(new_width, Ordering::Relaxed); + FISH_EMOJI_WIDTH.store(isize::try_from(new_width).unwrap(), Ordering::Relaxed); FLOG!( term_support, "Overriding default fish_emoji_width w/", @@ -228,7 +228,8 @@ fn handle_change_ambiguous_width(vars: &EnvStack) { .unwrap_or(1) // Clamp in case of negative values. .max(0); - crate::fallback::FISH_AMBIGUOUS_WIDTH.store(new_width, Ordering::Relaxed); + crate::fallback::FISH_AMBIGUOUS_WIDTH + .store(isize::try_from(new_width).unwrap(), Ordering::Relaxed); } fn handle_term_size_change(vars: &EnvStack) { diff --git a/src/fallback.rs b/src/fallback.rs index 896ce2dcd..ff898c8ce 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -7,12 +7,12 @@ use crate::widecharwidth::{WcLookupTable, WcWidth}; use crate::{common::is_console_session, wchar::prelude::*}; use once_cell::sync::Lazy; use std::cmp; -use std::sync::atomic::{AtomicI32, Ordering}; +use std::sync::atomic::{AtomicIsize, Ordering}; use std::{ffi::CString, mem, os::fd::RawFd}; /// Width of ambiguous East Asian characters and, as of TR11, all private-use characters. /// 1 is the typical default, but we accept any non-negative override via `$fish_ambiguous_width`. -pub static FISH_AMBIGUOUS_WIDTH: AtomicI32 = AtomicI32::new(1); +pub static FISH_AMBIGUOUS_WIDTH: AtomicIsize = AtomicIsize::new(1); /// Width of emoji characters. /// @@ -24,23 +24,24 @@ pub static FISH_AMBIGUOUS_WIDTH: AtomicI32 = AtomicI32::new(1); /// Valid values are 1, and 2. 1 is the typical emoji width used in Unicode 8 while some newer /// terminals use a width of 2 since Unicode 9. // For some reason, this is declared here and exposed here, but is set in `env_dispatch`. -pub static FISH_EMOJI_WIDTH: AtomicI32 = AtomicI32::new(1); +pub static FISH_EMOJI_WIDTH: AtomicIsize = AtomicIsize::new(1); static WC_LOOKUP_TABLE: Lazy = Lazy::new(WcLookupTable::new); /// A safe wrapper around the system `wcwidth()` function -pub fn wcwidth(c: char) -> i32 { +pub fn wcwidth(c: char) -> isize { extern "C" { pub fn wcwidth(c: libc::wchar_t) -> libc::c_int; } const _: () = assert!(mem::size_of::() >= mem::size_of::()); - unsafe { wcwidth(c as libc::wchar_t) } + let width = unsafe { wcwidth(c as libc::wchar_t) }; + isize::try_from(width).unwrap() } // Big hack to use our versions of wcswidth where we know them to be broken, which is // EVERYWHERE (https://github.com/fish-shell/fish-shell/issues/2199) -pub fn fish_wcwidth(c: char) -> i32 { +pub fn fish_wcwidth(c: char) -> isize { // The system version of wcwidth should accurately reflect the ability to represent characters // in the console session, but knows nothing about the capabilities of other terminal emulators // or ttys. Use it from the start only if we are logged in to the physical console. @@ -84,7 +85,7 @@ pub fn fish_wcwidth(c: char) -> i32 { /// fish's internal versions of wcwidth and wcswidth, which can use an internal implementation if /// the system one is busted. -pub fn fish_wcswidth(s: &wstr) -> i32 { +pub fn fish_wcswidth(s: &wstr) -> isize { let mut result = 0; for c in s.chars() { let w = fish_wcwidth(c); diff --git a/src/screen.rs b/src/screen.rs index 42cd44abf..8bea459fc 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -99,14 +99,12 @@ impl Line { /// This follows fish_wcswidth() semantics, except that characters whose width would be -1 are /// treated as 0. pub fn wcswidth_min_0(&self, max: usize /* = usize::MAX */) -> usize { - let mut result = 0; + let mut result: usize = 0; for c in &self.text[..max.min(self.text.len())] { let w = fish_wcwidth_visible(c.character); // A backspace at the start of the line does nothing. if w > 0 || result > 0 { - result = - usize::try_from(isize::try_from(result).unwrap() + isize::try_from(w).unwrap()) - .unwrap(); + result = result.checked_add_signed(w).unwrap(); } } result @@ -1530,9 +1528,7 @@ fn measure_run_from( let w = fish_wcwidth_visible(input.char_at(idx)); // A backspace at the start of the line does nothing. if w != -1 || width > 0 { - width = - usize::try_from(isize::try_from(width).unwrap() + isize::try_from(w).unwrap()) - .unwrap(); + width = width.checked_add_signed(w).unwrap(); } } idx += 1; diff --git a/src/wcstringutil.rs b/src/wcstringutil.rs index 4f0e8ad21..d072b9ef4 100644 --- a/src/wcstringutil.rs +++ b/src/wcstringutil.rs @@ -538,7 +538,7 @@ impl<'a> Iterator for LineIterator<'a> { } /// Like fish_wcwidth, but returns 0 for characters with no real width instead of -1. -pub fn fish_wcwidth_visible(c: char) -> i32 { +pub fn fish_wcwidth_visible(c: char) -> isize { if c == '\x08' { return -1; } diff --git a/src/wutil/mod.rs b/src/wutil/mod.rs index 70331ea9e..89c1402bd 100644 --- a/src/wutil/mod.rs +++ b/src/wutil/mod.rs @@ -498,7 +498,7 @@ pub fn fish_iswgraph(c: char) -> bool { !fish_reserved_codepoint(c) && (fish_is_pua(c) || unsafe { iswgraph(c as libc::wchar_t) } != 0) } -pub fn fish_wcswidth(s: &wstr) -> libc::c_int { +pub fn fish_wcswidth(s: &wstr) -> isize { fallback::fish_wcswidth(s) }