mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-21 11:31:15 -03:00
Unconditionally default emoji width to 2
"Emoji width" refers to the width of emoji codepoints. Since Unicode 9, they're classified as "wide" according to TR11 (https://www.unicode.org/reports/tr11/). Unicode 9 was released in 2016, and this slowly percolated into C libraries and terminals. Glibc updated its default in 2.26, released in August 2017. Until now, we'd guess support for unicode 9 by checking the system wcwidth function for an emoji - if it returned 2, we'd set our emoji width to 2 as well. However, that's a problem in the common case of using ssh to connect to an old server - modern desktop OS, old server LTS OS, boom. So now we instead just figure you've got a system that's *displaying* the emoji that has been updated in the last 9 years. In effect we're putting the burden on those who run old RHEL et al as their client OS. They need to set $fish_emoji_width to 1. Fixes #12500 Part of #12562
This commit is contained in:
committed by
Johannes Altmanninger
parent
88d01f7eb8
commit
8561008513
@@ -25,7 +25,7 @@
|
|||||||
/// Valid values are 1, and 2. 1 is the typical emoji width used in Unicode 8 while some newer
|
/// 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.
|
/// 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`.
|
// For some reason, this is declared here and exposed here, but is set in `env_dispatch`.
|
||||||
pub static FISH_EMOJI_WIDTH: AtomicIsize = AtomicIsize::new(1);
|
pub static FISH_EMOJI_WIDTH: AtomicIsize = AtomicIsize::new(2);
|
||||||
|
|
||||||
static WC_LOOKUP_TABLE: LazyLock<WcLookupTable> = LazyLock::new(WcLookupTable::new);
|
static WC_LOOKUP_TABLE: LazyLock<WcLookupTable> = LazyLock::new(WcLookupTable::new);
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
};
|
};
|
||||||
use crate::screen::{IS_DUMB, ONLY_GRAYSCALE, screen_set_midnight_commander_hack};
|
use crate::screen::{IS_DUMB, ONLY_GRAYSCALE, screen_set_midnight_commander_hack};
|
||||||
use crate::terminal::ColorSupport;
|
use crate::terminal::ColorSupport;
|
||||||
use crate::tty_handoff::xtversion;
|
|
||||||
use crate::wutil::fish_wcstoi;
|
use crate::wutil::fish_wcstoi;
|
||||||
use fish_wcstringutil::{bool_from_string, string_prefixes_string};
|
use fish_wcstringutil::{bool_from_string, string_prefixes_string};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -61,7 +60,7 @@ macro_rules! vars {
|
|||||||
L!("fish_sequence_key_delay_ms"),
|
L!("fish_sequence_key_delay_ms"),
|
||||||
vars!(update_wait_on_sequence_key_ms),
|
vars!(update_wait_on_sequence_key_ms),
|
||||||
);
|
);
|
||||||
table.add_anon(L!("fish_emoji_width"), vars!(guess_emoji_width));
|
table.add_anon(L!("fish_emoji_width"), vars!(handle_emoji_width));
|
||||||
table.add_anon(
|
table.add_anon(
|
||||||
L!("fish_ambiguous_width"),
|
L!("fish_ambiguous_width"),
|
||||||
vars!(handle_change_ambiguous_width),
|
vars!(handle_change_ambiguous_width),
|
||||||
@@ -159,7 +158,7 @@ fn handle_timezone(var_name: &wstr, vars: &EnvStack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update the value of [`FISH_EMOJI_WIDTH`](fish_fallback::FISH_EMOJI_WIDTH).
|
/// Update the value of [`FISH_EMOJI_WIDTH`](fish_fallback::FISH_EMOJI_WIDTH).
|
||||||
pub fn guess_emoji_width(vars: &EnvStack) {
|
pub fn handle_emoji_width(vars: &EnvStack) {
|
||||||
use fish_fallback::FISH_EMOJI_WIDTH;
|
use fish_fallback::FISH_EMOJI_WIDTH;
|
||||||
|
|
||||||
if let Some(width_str) = vars.get(L!("fish_emoji_width")) {
|
if let Some(width_str) = vars.get(L!("fish_emoji_width")) {
|
||||||
@@ -171,38 +170,7 @@ pub fn guess_emoji_width(vars: &EnvStack) {
|
|||||||
"Overriding default fish_emoji_width w/",
|
"Overriding default fish_emoji_width w/",
|
||||||
new_width
|
new_width
|
||||||
);
|
);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let term_program = vars
|
|
||||||
.get(L!("TERM_PROGRAM"))
|
|
||||||
.map_or_else(WString::new, |v| v.as_string());
|
|
||||||
|
|
||||||
// TODO(term-workaround)
|
|
||||||
if xtversion().unwrap_or(L!("")).starts_with(L!("iTerm2 ")) {
|
|
||||||
// iTerm2 now defaults to Unicode 9 sizes for anything after macOS 10.12
|
|
||||||
FISH_EMOJI_WIDTH.store(2, Ordering::Relaxed);
|
|
||||||
flog!(term_support, "default emoji width 2 for iTerm2");
|
|
||||||
} else if term_program == "Apple_Terminal" && {
|
|
||||||
let version = vars
|
|
||||||
.get(L!("TERM_PROGRAM_VERSION"))
|
|
||||||
.map(|v| v.as_string())
|
|
||||||
.and_then(|v| {
|
|
||||||
let mut consumed = 0;
|
|
||||||
crate::wutil::wcstod::wcstod(&v, '.', &mut consumed).ok()
|
|
||||||
})
|
|
||||||
.unwrap_or(0.0);
|
|
||||||
version as i32 >= 400
|
|
||||||
} {
|
|
||||||
// Apple Terminal on High Sierra
|
|
||||||
FISH_EMOJI_WIDTH.store(2, Ordering::Relaxed);
|
|
||||||
flog!(term_support, "default emoji width: 2 for", term_program);
|
|
||||||
} else {
|
} else {
|
||||||
// Default to whatever the system's wcwidth gives for U+1F603, but only if it's at least
|
|
||||||
// 1 and at most 2.
|
|
||||||
#[cfg(not(cygwin))]
|
|
||||||
let width = fish_fallback::wcwidth('😃').clamp(1, 2);
|
|
||||||
#[cfg(cygwin)]
|
|
||||||
let width = 2_isize;
|
let width = 2_isize;
|
||||||
FISH_EMOJI_WIDTH.store(width, Ordering::Relaxed);
|
FISH_EMOJI_WIDTH.store(width, Ordering::Relaxed);
|
||||||
flog!(term_support, "default emoji width:", width);
|
flog!(term_support, "default emoji width:", width);
|
||||||
@@ -325,7 +293,6 @@ fn handle_locale_change(vars: &EnvStack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_term_change(vars: &EnvStack, suppress_repaint: bool) {
|
fn handle_term_change(vars: &EnvStack, suppress_repaint: bool) {
|
||||||
guess_emoji_width(vars);
|
|
||||||
init_terminal(vars);
|
init_terminal(vars);
|
||||||
if !suppress_repaint {
|
if !suppress_repaint {
|
||||||
reader_schedule_prompt_repaint();
|
reader_schedule_prompt_repaint();
|
||||||
@@ -393,7 +360,7 @@ fn run_inits(vars: &EnvStack) {
|
|||||||
init_locale(vars);
|
init_locale(vars);
|
||||||
init_special_chars_once();
|
init_special_chars_once();
|
||||||
init_terminal(vars);
|
init_terminal(vars);
|
||||||
guess_emoji_width(vars);
|
handle_emoji_width(vars);
|
||||||
update_wait_on_escape_ms(vars);
|
update_wait_on_escape_ms(vars);
|
||||||
update_wait_on_sequence_key_ms(vars);
|
update_wait_on_sequence_key_ms(vars);
|
||||||
handle_read_limit_change(vars);
|
handle_read_limit_change(vars);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
use crate::env::EnvStack;
|
use crate::env::EnvStack;
|
||||||
use crate::env::{EnvMode, Environment, Statuses};
|
use crate::env::{EnvMode, Environment, Statuses};
|
||||||
use crate::env_dispatch::MIDNIGHT_COMMANDER_SID;
|
use crate::env_dispatch::MIDNIGHT_COMMANDER_SID;
|
||||||
use crate::env_dispatch::guess_emoji_width;
|
use crate::env_dispatch::handle_emoji_width;
|
||||||
use crate::exec::exec_subshell;
|
use crate::exec::exec_subshell;
|
||||||
use crate::expand::expand_one;
|
use crate::expand::expand_one;
|
||||||
use crate::expand::{ExpandFlags, ExpandResultCode, expand_string, expand_tilde};
|
use crate::expand::{ExpandFlags, ExpandResultCode, expand_string, expand_tilde};
|
||||||
@@ -386,7 +386,7 @@ pub fn reader_push<'a>(parser: &'a Parser, history_name: &wstr, conf: ReaderConf
|
|||||||
background_color,
|
background_color,
|
||||||
} = terminal_init(parser.vars(), inputfd);
|
} = terminal_init(parser.vars(), inputfd);
|
||||||
let input_data = input_queue.get_input_data_mut();
|
let input_data = input_queue.get_input_data_mut();
|
||||||
guess_emoji_width(parser.vars());
|
handle_emoji_width(parser.vars());
|
||||||
|
|
||||||
// Provide value for `status current-command`
|
// Provide value for `status current-command`
|
||||||
parser.libdata_mut().status_vars.command = L!("fish").to_owned();
|
parser.libdata_mut().status_vars.command = L!("fish").to_owned();
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ def makeenv(script_path: Path, home: Path) -> Dict[str, str]:
|
|||||||
"STY",
|
"STY",
|
||||||
"TERM", # Erase this since we still respect TERM=dumb etc.
|
"TERM", # Erase this since we still respect TERM=dumb etc.
|
||||||
"TERM_PROGRAM",
|
"TERM_PROGRAM",
|
||||||
"TERM_PROGRAM_VERSION",
|
|
||||||
]:
|
]:
|
||||||
if var in env:
|
if var in env:
|
||||||
del env[var]
|
del env[var]
|
||||||
|
|||||||
Reference in New Issue
Block a user