diff --git a/options-table.c b/options-table.c index 3d1b4f85..08efa6b2 100644 --- a/options-table.c +++ b/options-table.c @@ -405,7 +405,7 @@ const struct options_table_entry options_table[] = { .choices = options_table_popup_border_lines_list, .default_num = BOX_LINES_SINGLE, .text = "Type of characters used to draw menu border lines. Some of " - "these are only supported on terminals with UTF-8 support." + "these are only supported on terminals with UTF-8 support." }, { .name = "message-limit", @@ -425,7 +425,7 @@ const struct options_table_entry options_table[] = { .default_num = 0, .unit = "milliseconds", .text = "The timeout for the prefix key if no subsequent key is " - "pressed. Zero means disabled." + "pressed. Zero means disabled." }, { .name = "prompt-history-limit", @@ -462,7 +462,7 @@ const struct options_table_entry options_table[] = { .flags = OPTIONS_TABLE_IS_ARRAY, .default_str = "xterm*:clipboard:ccolour:cstyle:focus:title," "screen*:title," - "rxvt*:ignorefkeys", + "rxvt*:ignorefkeys", .separator = ",", .text = "List of terminal features, used if they cannot be " "automatically detected." @@ -479,6 +479,14 @@ const struct options_table_entry options_table[] = { "'User0', 'User1' and so on." }, + { .name = "variation-selector-always-wide", + .type = OPTIONS_TABLE_FLAG, + .scope = OPTIONS_TABLE_SERVER, + .default_num = 1, + .text = "If the Unicode VS16 codepoint should always be treated as a " + "wide character." + }, + /* Session options. */ { .name = "activity-action", .type = OPTIONS_TABLE_CHOICE, @@ -611,8 +619,8 @@ const struct options_table_entry options_table[] = { .default_num = 0, .unit = "milliseconds", .text = "Time to wait for a key binding to repeat the first time the " - "key is pressed, if it is bound with the '-r' flag. " - "Subsequent presses use the 'repeat-time' option." + "key is pressed, if it is bound with the '-r' flag. " + "Subsequent presses use the 'repeat-time' option." }, { .name = "key-table", @@ -1033,11 +1041,11 @@ const struct options_table_entry options_table[] = { .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, .default_str = "#[align=right]" - "#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}" - "[#{scroll_position}/#{history_size}]" - "#{?search_timed_out, (timed out)," - "#{?search_count, (#{search_count}" - "#{?search_count_partial,+,} results),}}", + "#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}" + "[#{scroll_position}/#{history_size}]" + "#{?search_timed_out, (timed out)," + "#{?search_count, (#{search_count}" + "#{?search_count_partial,+,} results),}}", .text = "Format of the position indicator in copy mode." }, @@ -1234,7 +1242,7 @@ const struct options_table_entry options_table[] = { .text = "Pane scrollbar position." }, - { .name = "popup-style", + { .name = "popup-style", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, .default_str = "default", @@ -1275,12 +1283,12 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, .default_str = "Pane is dead (" "#{?#{!=:#{pane_dead_status},}," - "status #{pane_dead_status},}" + "status #{pane_dead_status},}" "#{?#{!=:#{pane_dead_signal},}," - "signal #{pane_dead_signal},}, " + "signal #{pane_dead_signal},}, " "#{t:pane_dead_time})", .text = "Message shown after the program in a pane has exited, if " - "remain-on-exit is enabled." + "remain-on-exit is enabled." }, { .name = "scroll-on-clear", diff --git a/screen-write.c b/screen-write.c index bce56b8e..b980d0ee 100644 --- a/screen-write.c +++ b/screen-write.c @@ -2105,9 +2105,11 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc) */ if (utf8_is_zwj(ud)) zero_width = 1; - else if (utf8_is_vs(ud)) - zero_width = force_wide = 1; - else if (ud->width == 0) + else if (utf8_is_vs(ud)) { + zero_width = 1; + if (options_get_number(global_options, "variation-selector-always-wide")) + force_wide = 1; + } else if (ud->width == 0) zero_width = 1; /* Cannot combine empty character or at left. */ diff --git a/tmux.1 b/tmux.1 index 1d50ab29..58686732 100644 --- a/tmux.1 +++ b/tmux.1 @@ -4394,6 +4394,11 @@ For example: set -s user-keys[0] "\ee[5;30012\[ti]" bind User0 resize-pane -L 3 .Ed +.It Xo Ic variation-selector-always-wide +.Op Ic on | off +.Xc +Always treat Unicode variation selector 16 as marking a wide character. +This is a feature of some terminals as part of their Unicode 14 support. .El .Pp Available session options are: diff --git a/tty.c b/tty.c index ea2fa941..bfedb8ee 100644 --- a/tty.c +++ b/tty.c @@ -2882,15 +2882,23 @@ tty_check_fg(struct tty *tty, struct colour_palette *palette, /* Is this a 256-colour colour? */ if (gc->fg & COLOUR_FLAG_256) { /* And not a 256 colour mode? */ - if (colours < 256) { - gc->fg = colour_256to16(gc->fg); - if (gc->fg & 8) { - gc->fg &= 7; - if (colours >= 16) - gc->fg += 90; - else if (gc->fg == 0 && gc->bg == 0) - gc->fg = 7; - } + if (colours >= 256) + return; + gc->fg = colour_256to16(gc->fg); + if (~gc->fg & 8) + return; + gc->fg &= 7; + if (colours >= 16) + gc->fg += 90; + else { + /* + * Mapping to black-on-black or white-on-white is not + * much use, so change the foreground. + */ + if (gc->fg == 0 && gc->bg == 0) + gc->fg = 7; + else if (gc->fg == 7 && gc->bg == 7) + gc->fg = 0; } return; } @@ -2938,14 +2946,14 @@ tty_check_bg(struct tty *tty, struct colour_palette *palette, * palette. Bold background doesn't exist portably, so just * discard the bold bit if set. */ - if (colours < 256) { - gc->bg = colour_256to16(gc->bg); - if (gc->bg & 8) { - gc->bg &= 7; - if (colours >= 16) - gc->bg += 90; - } - } + if (colours >= 256) + return; + gc->bg = colour_256to16(gc->bg); + if (~gc->bg & 8) + return; + gc->bg &= 7; + if (colours >= 16) + gc->bg += 90; return; }