mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-29 06:13:20 +00:00
Make wcwidth an isize
Seems more consistent with the rest of our code.
This commit is contained in:
parent
8545b5debe
commit
a1ed63fd83
8 changed files with 20 additions and 22 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<WcLookupTable> = 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::<libc::wchar_t>() >= mem::size_of::<char>());
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue