diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 6be3d9575..f711b3b48 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -858,6 +858,8 @@ The user can change the settings of `fish` by changing the values of certain var - `fish_emoji_width` controls the computed width of certain characters, in particular emoji, whose rendered width varies across terminal emulators. This should be set to 1 if your terminal emulator renders emoji single-width, or 2 if double-width. Set this only if you see graphical glitching when printing emoji. +- `fish_ambiguous_width` controls the computed width of ambiguous East Asian characters. This should be set to 1 if your terminal emulator renders these characters as single-width (typical), or 2 if double-width. + - `fish_escape_delay_ms` overrides the default timeout of 300ms (default key bindings) or 10ms (vi key bindings) after seeing an escape character before giving up on matching a key binding. See the documentation for the bind builtin command. This delay facilitates using escape as a meta key. - `fish_greeting`, the greeting message printed on startup. diff --git a/src/env.cpp b/src/env.cpp index 5b57f7a1a..77f65b7bc 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -788,6 +788,16 @@ static void handle_change_emoji_width(const wcstring &op, const wcstring &var_na g_fish_emoji_width = std::max(0, new_width); } +static void handle_change_ambiguous_width(const wcstring &op, const wcstring &var_name) { + (void)op; + (void)var_name; + int new_width = 1; + if (auto width_str = env_get(L"fish_ambiguous_width")) { + new_width = fish_wcstol(width_str->as_string().c_str()); + } + g_fish_ambiguous_width = std::max(0, new_width); +} + static void handle_term_size_change(const wcstring &op, const wcstring &var_name) { UNUSED(op); UNUSED(var_name); @@ -860,6 +870,7 @@ static void setup_var_dispatch_table() { var_dispatch_table.emplace(L"fish_term24bit", handle_fish_term_change); var_dispatch_table.emplace(L"fish_escape_delay_ms", handle_escape_delay_change); var_dispatch_table.emplace(L"fish_emoji_width", handle_change_emoji_width); + var_dispatch_table.emplace(L"fish_ambiguous_width", handle_change_ambiguous_width); var_dispatch_table.emplace(L"LINES", handle_term_size_change); var_dispatch_table.emplace(L"COLUMNS", handle_term_size_change); var_dispatch_table.emplace(L"fish_complete_path", handle_complete_path_change); diff --git a/src/fallback.cpp b/src/fallback.cpp index bfccb7941..42a9d62d2 100644 --- a/src/fallback.cpp +++ b/src/fallback.cpp @@ -249,6 +249,10 @@ int killpg(int pgr, int sig) { } #endif +// Width of ambiguous characters. 1 is typical default. +int g_fish_ambiguous_width = 1; + +// Width of emoji characters. int g_fish_emoji_width = 0; // 1 is the typical emoji width in Unicode 8. @@ -289,8 +293,10 @@ int fish_wcwidth(wchar_t wc) { // Fall back to system wcwidth in this case. return wcwidth(wc); case widechar_ambiguous: + return g_fish_ambiguous_width; case widechar_private_use: - return 1; + // TR11: "All private-use characters are by default classified as Ambiguous". + return g_fish_ambiguous_width; case widechar_widened_in_9: return fish_get_emoji_width(wc); default: diff --git a/src/fallback.h b/src/fallback.h index 4647a6f67..44ddee398 100644 --- a/src/fallback.h +++ b/src/fallback.h @@ -16,6 +16,9 @@ // substitution if wchar.h is included after this header. #include // IWYU pragma: keep +/// The column width of ambiguous East Asian characters. +extern int g_fish_ambiguous_width; + /// The column width of emoji characters. This must be configurable because the value changed /// between Unicode 8 and Unicode 9, wcwidth() is emoji-ignorant, and terminal emulators do /// different things. See issues like #4539 and https://github.com/neovim/neovim/issues/4976 for how