Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
tmux: Fix a problems with displaying Ambiguous-width, Japanese Dakuten and Handakuten signs.
diff --git a/utf8.c b/utf8.c
index ad99edc..0d803d3 100644
--- a/utf8.c
+++ b/utf8.c
@@ -343,7 +343,200 @@ static struct utf8_width_entry utf8_width_table[] = {
{ 0xe0100, 0xe01ef, 0, NULL, NULL },
{ 0x100000, 0x10fffd, 0, NULL, NULL },
};
+
+/* Sorted, generated by 'uniset +WIDTH-A +WIDTH-F +WIDTH-W -cat=Me -cat=Mn -cat=Cf c'
+ * with Unicode 8.0.0 */
+static struct utf8_width_entry utf8_cjkwidth_table[] = {
+ { 0x000A1, 0x000A1, 2, NULL, NULL },
+ { 0x000A4, 0x000A4, 2, NULL, NULL },
+ { 0x000A7, 0x000A8, 2, NULL, NULL },
+ { 0x000AA, 0x000AA, 2, NULL, NULL },
+ { 0x000AE, 0x000AE, 2, NULL, NULL },
+ { 0x000B0, 0x000B4, 2, NULL, NULL },
+ { 0x000B6, 0x000BA, 2, NULL, NULL },
+ { 0x000BC, 0x000BF, 2, NULL, NULL },
+ { 0x000C6, 0x000C6, 2, NULL, NULL },
+ { 0x000D0, 0x000D0, 2, NULL, NULL },
+ { 0x000D7, 0x000D8, 2, NULL, NULL },
+ { 0x000DE, 0x000E1, 2, NULL, NULL },
+ { 0x000E6, 0x000E6, 2, NULL, NULL },
+ { 0x000E8, 0x000EA, 2, NULL, NULL },
+ { 0x000EC, 0x000ED, 2, NULL, NULL },
+ { 0x000F0, 0x000F0, 2, NULL, NULL },
+ { 0x000F2, 0x000F3, 2, NULL, NULL },
+ { 0x000F7, 0x000FA, 2, NULL, NULL },
+ { 0x000FC, 0x000FC, 2, NULL, NULL },
+ { 0x000FE, 0x000FE, 2, NULL, NULL },
+ { 0x00101, 0x00101, 2, NULL, NULL },
+ { 0x00111, 0x00111, 2, NULL, NULL },
+ { 0x00113, 0x00113, 2, NULL, NULL },
+ { 0x0011B, 0x0011B, 2, NULL, NULL },
+ { 0x00126, 0x00127, 2, NULL, NULL },
+ { 0x0012B, 0x0012B, 2, NULL, NULL },
+ { 0x00131, 0x00133, 2, NULL, NULL },
+ { 0x00138, 0x00138, 2, NULL, NULL },
+ { 0x0013F, 0x00142, 2, NULL, NULL },
+ { 0x00144, 0x00144, 2, NULL, NULL },
+ { 0x00148, 0x0014B, 2, NULL, NULL },
+ { 0x0014D, 0x0014D, 2, NULL, NULL },
+ { 0x00152, 0x00153, 2, NULL, NULL },
+ { 0x00166, 0x00167, 2, NULL, NULL },
+ { 0x0016B, 0x0016B, 2, NULL, NULL },
+ { 0x001CE, 0x001CE, 2, NULL, NULL },
+ { 0x001D0, 0x001D0, 2, NULL, NULL },
+ { 0x001D2, 0x001D2, 2, NULL, NULL },
+ { 0x001D4, 0x001D4, 2, NULL, NULL },
+ { 0x001D6, 0x001D6, 2, NULL, NULL },
+ { 0x001D8, 0x001D8, 2, NULL, NULL },
+ { 0x001DA, 0x001DA, 2, NULL, NULL },
+ { 0x001DC, 0x001DC, 2, NULL, NULL },
+ { 0x00251, 0x00251, 2, NULL, NULL },
+ { 0x00261, 0x00261, 2, NULL, NULL },
+ { 0x002C4, 0x002C4, 2, NULL, NULL },
+ { 0x002C7, 0x002C7, 2, NULL, NULL },
+ { 0x002C9, 0x002CB, 2, NULL, NULL },
+ { 0x002CD, 0x002CD, 2, NULL, NULL },
+ { 0x002D0, 0x002D0, 2, NULL, NULL },
+ { 0x002D8, 0x002DB, 2, NULL, NULL },
+ { 0x002DD, 0x002DD, 2, NULL, NULL },
+ { 0x002DF, 0x002DF, 2, NULL, NULL },
+ { 0x00391, 0x003A1, 2, NULL, NULL },
+ { 0x003A3, 0x003A9, 2, NULL, NULL },
+ { 0x003B1, 0x003C1, 2, NULL, NULL },
+ { 0x003C3, 0x003C9, 2, NULL, NULL },
+ { 0x00401, 0x00401, 2, NULL, NULL },
+ { 0x00410, 0x0044F, 2, NULL, NULL },
+ { 0x00451, 0x00451, 2, NULL, NULL },
+ { 0x01100, 0x01159, 2, NULL, NULL },
+ { 0x0115F, 0x0115F, 2, NULL, NULL },
+ { 0x02010, 0x02010, 2, NULL, NULL },
+ { 0x02013, 0x02016, 2, NULL, NULL },
+ { 0x02018, 0x02019, 2, NULL, NULL },
+ { 0x0201C, 0x0201D, 2, NULL, NULL },
+ { 0x02020, 0x02022, 2, NULL, NULL },
+ { 0x02024, 0x02027, 2, NULL, NULL },
+ { 0x02030, 0x02030, 2, NULL, NULL },
+ { 0x02032, 0x02033, 2, NULL, NULL },
+ { 0x02035, 0x02035, 2, NULL, NULL },
+ { 0x0203B, 0x0203B, 2, NULL, NULL },
+ { 0x0203E, 0x0203E, 2, NULL, NULL },
+ { 0x02074, 0x02074, 2, NULL, NULL },
+ { 0x0207F, 0x0207F, 2, NULL, NULL },
+ { 0x02081, 0x02084, 2, NULL, NULL },
+ { 0x020AC, 0x020AC, 2, NULL, NULL },
+ { 0x02103, 0x02103, 2, NULL, NULL },
+ { 0x02105, 0x02105, 2, NULL, NULL },
+ { 0x02109, 0x02109, 2, NULL, NULL },
+ { 0x02113, 0x02113, 2, NULL, NULL },
+ { 0x02116, 0x02116, 2, NULL, NULL },
+ { 0x02121, 0x02122, 2, NULL, NULL },
+ { 0x02126, 0x02126, 2, NULL, NULL },
+ { 0x0212B, 0x0212B, 2, NULL, NULL },
+ { 0x02153, 0x02154, 2, NULL, NULL },
+ { 0x0215B, 0x0215E, 2, NULL, NULL },
+ { 0x02160, 0x0216B, 2, NULL, NULL },
+ { 0x02170, 0x02179, 2, NULL, NULL },
+ { 0x02190, 0x02199, 2, NULL, NULL },
+ { 0x021B8, 0x021B9, 2, NULL, NULL },
+ { 0x021D2, 0x021D2, 2, NULL, NULL },
+ { 0x021D4, 0x021D4, 2, NULL, NULL },
+ { 0x021E7, 0x021E7, 2, NULL, NULL },
+ { 0x02200, 0x02200, 2, NULL, NULL },
+ { 0x02202, 0x02203, 2, NULL, NULL },
+ { 0x02207, 0x02208, 2, NULL, NULL },
+ { 0x0220B, 0x0220B, 2, NULL, NULL },
+ { 0x0220F, 0x0220F, 2, NULL, NULL },
+ { 0x02211, 0x02211, 2, NULL, NULL },
+ { 0x02215, 0x02215, 2, NULL, NULL },
+ { 0x0221A, 0x0221A, 2, NULL, NULL },
+ { 0x0221D, 0x02220, 2, NULL, NULL },
+ { 0x02223, 0x02223, 2, NULL, NULL },
+ { 0x02225, 0x02225, 2, NULL, NULL },
+ { 0x02227, 0x0222C, 2, NULL, NULL },
+ { 0x0222E, 0x0222E, 2, NULL, NULL },
+ { 0x02234, 0x02237, 2, NULL, NULL },
+ { 0x0223C, 0x0223D, 2, NULL, NULL },
+ { 0x02248, 0x02248, 2, NULL, NULL },
+ { 0x0224C, 0x0224C, 2, NULL, NULL },
+ { 0x02252, 0x02252, 2, NULL, NULL },
+ { 0x02260, 0x02261, 2, NULL, NULL },
+ { 0x02264, 0x02267, 2, NULL, NULL },
+ { 0x0226A, 0x0226B, 2, NULL, NULL },
+ { 0x0226E, 0x0226F, 2, NULL, NULL },
+ { 0x02282, 0x02283, 2, NULL, NULL },
+ { 0x02286, 0x02287, 2, NULL, NULL },
+ { 0x02295, 0x02295, 2, NULL, NULL },
+ { 0x02299, 0x02299, 2, NULL, NULL },
+ { 0x022A5, 0x022A5, 2, NULL, NULL },
+ { 0x022BF, 0x022BF, 2, NULL, NULL },
+ { 0x02312, 0x02312, 2, NULL, NULL },
+ { 0x02329, 0x0232A, 2, NULL, NULL },
+ { 0x02460, 0x024E9, 2, NULL, NULL },
+ { 0x024EB, 0x0254B, 2, NULL, NULL },
+ { 0x02550, 0x02573, 2, NULL, NULL },
+ { 0x02580, 0x0258F, 2, NULL, NULL },
+ { 0x02592, 0x02595, 2, NULL, NULL },
+ { 0x025A0, 0x025A1, 2, NULL, NULL },
+ { 0x025A3, 0x025A9, 2, NULL, NULL },
+ { 0x025B2, 0x025B3, 2, NULL, NULL },
+ { 0x025B6, 0x025B7, 2, NULL, NULL },
+ { 0x025BC, 0x025BD, 2, NULL, NULL },
+ { 0x025C0, 0x025C1, 2, NULL, NULL },
+ { 0x025C6, 0x025C8, 2, NULL, NULL },
+ { 0x025CB, 0x025CB, 2, NULL, NULL },
+ { 0x025CE, 0x025D1, 2, NULL, NULL },
+ { 0x025E2, 0x025E5, 2, NULL, NULL },
+ { 0x025EF, 0x025EF, 2, NULL, NULL },
+ { 0x02605, 0x02606, 2, NULL, NULL },
+ { 0x02609, 0x02609, 2, NULL, NULL },
+ { 0x0260E, 0x0260F, 2, NULL, NULL },
+ { 0x02614, 0x02615, 2, NULL, NULL },
+ { 0x0261C, 0x0261C, 2, NULL, NULL },
+ { 0x0261E, 0x0261E, 2, NULL, NULL },
+ { 0x02640, 0x02640, 2, NULL, NULL },
+ { 0x02642, 0x02642, 2, NULL, NULL },
+ { 0x02660, 0x02661, 2, NULL, NULL },
+ { 0x02663, 0x02665, 2, NULL, NULL },
+ { 0x02667, 0x0266A, 2, NULL, NULL },
+ { 0x0266C, 0x0266D, 2, NULL, NULL },
+ { 0x0266F, 0x0266F, 2, NULL, NULL },
+ { 0x0273D, 0x0273D, 2, NULL, NULL },
+ { 0x02776, 0x0277F, 2, NULL, NULL },
+ { 0x02E80, 0x02E99, 2, NULL, NULL },
+ { 0x02E9B, 0x02EF3, 2, NULL, NULL },
+ { 0x02F00, 0x02FD5, 2, NULL, NULL },
+ { 0x02FF0, 0x02FFB, 2, NULL, NULL },
+ { 0x03000, 0x03029, 2, NULL, NULL },
+ { 0x0302E, 0x0303E, 2, NULL, NULL },
+ { 0x03041, 0x03096, 2, NULL, NULL },
+ { 0x0309B, 0x030FF, 2, NULL, NULL },
+ { 0x03105, 0x0312C, 2, NULL, NULL },
+ { 0x03131, 0x0318E, 2, NULL, NULL },
+ { 0x03190, 0x031B7, 2, NULL, NULL },
+ { 0x031F0, 0x0321E, 2, NULL, NULL },
+ { 0x03220, 0x03243, 2, NULL, NULL },
+ { 0x03250, 0x0327D, 2, NULL, NULL },
+ { 0x0327F, 0x032FE, 2, NULL, NULL },
+ { 0x03300, 0x04DB5, 2, NULL, NULL },
+ { 0x04E00, 0x09FA5, 2, NULL, NULL },
+ { 0x0A000, 0x0A48C, 2, NULL, NULL },
+ { 0x0A490, 0x0A4C6, 2, NULL, NULL },
+ { 0x0AC00, 0x0D7A3, 2, NULL, NULL },
+ { 0x0E000, 0x0FA2D, 2, NULL, NULL },
+ { 0x0FA30, 0x0FA6A, 2, NULL, NULL },
+ { 0x0FE30, 0x0FE52, 2, NULL, NULL },
+ { 0x0FE54, 0x0FE66, 2, NULL, NULL },
+ { 0x0FE68, 0x0FE6B, 2, NULL, NULL },
+ { 0x0FF01, 0x0FF60, 2, NULL, NULL },
+ { 0x0FFE0, 0x0FFE6, 2, NULL, NULL },
+ { 0x0FFFD, 0x0FFFD, 2, NULL, NULL },
+ { 0x20000, 0x2FFFD, 2, NULL, NULL },
+ { 0x30000, 0x3FFFD, 2, NULL, NULL },
+ { 0xF0000, 0xFFFFD, 2, NULL, NULL },
+ { 0x100000, 0x10FFFD, 2, NULL, NULL }
+};
static struct utf8_width_entry *utf8_width_root = NULL;
+static struct utf8_width_entry *utf8_cjkwidth_root = NULL;
static void utf8_build(void);
@@ -440,6 +633,21 @@ utf8_build(void)
}
*ptr = item;
}
+
+ /* for cjk ambiguous width. */
+ for (i = 0; i < nitems(utf8_cjkwidth_table); i++) {
+ item = &utf8_cjkwidth_table[i];
+
+ ptr = &utf8_cjkwidth_root;
+ while (*ptr != NULL) {
+ node = *ptr;
+ if (item->last < node->first)
+ ptr = &node->left;
+ else if (item->first > node->last)
+ ptr = &node->right;
+ }
+ *ptr = item;
+ }
}
/* Lookup width of UTF-8 data in tree. */
@@ -451,6 +659,17 @@ utf8_width(u_int uc)
if (utf8_width_root == NULL)
utf8_build();
+ /* for cjk width */
+ item = utf8_cjkwidth_root;
+ while (item != NULL) {
+ if (uc < item->first)
+ item = item->left;
+ else if (uc > item->last)
+ item = item->right;
+ else
+ return (item->width);
+ }
+
item = utf8_width_root;
while (item != NULL) {
if (uc < item->first)
diff --git a/screen-write.c b/screen-write.c
index 53067ef..076a61d 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -929,6 +929,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* If the width is zero, combine onto the previous character, if
* there is space.
*/
+ /*
if (width == 0) {
if (screen_write_combine(ctx, &gc->data) == 0) {
screen_write_initctx(ctx, &ttyctx, 0);
@@ -936,6 +937,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
}
return;
}
+ */
/* Initialise the redraw context, saving the last cell. */
screen_write_initctx(ctx, &ttyctx, 1);
diff --git a/options-table.c b/options-table.c
index ab61ef7..a2bdd87 100644
--- a/options-table.c
+++ b/options-table.c
@@ -284,6 +284,12 @@ const struct options_table_entry options_table[] = {
.default_num = 0
},
+ { .name = "pane-border-ascii",
+ .type = OPTIONS_TABLE_FLAG,
+ .scope = OPTIONS_TABLE_SESSION,
+ .default_num = 0
+ },
+
{ .name = "prefix",
.type = OPTIONS_TABLE_KEY,
.scope = OPTIONS_TABLE_SESSION,
diff --git a/tty-acs.c b/tty-acs.c
index 5d03c3e..af2ce35 100644
--- a/tty-acs.c
+++ b/tty-acs.c
@@ -64,6 +64,41 @@ const struct tty_acs_entry tty_acs_table[] = {
{ '~', "\302\267" } /* bullet */
};
+const struct tty_acs_entry tty_acs_table_putty[] = {
+ { '+', "\342\206\222" },
+ { ',', "\342\206\220" },
+ { '-', "\342\206\221" },
+ { '.', "\342\206\223" },
+ { '0', "\342\226\256" },
+ { '`', "\342\227\206" },
+ { 'a', "\342\226\222" },
+ { 'f', "\302\260" },
+ { 'g', "\302\261" },
+ { 'h', "\342\226\222" },
+ { 'i', "\342\230\203" },
+ { 'j', "+" },
+ { 'k', "+" },
+ { 'l', "+" },
+ { 'm', "+" },
+ { 'n', "+" },
+ { 'o', "\342\216\272" },
+ { 'p', "\342\216\273" },
+ { 'q', "-" },
+ { 'r', "\342\216\274" },
+ { 's', "\342\216\275" },
+ { 't', "+" },
+ { 'u', "+" },
+ { 'v', "+" },
+ { 'w', "+" },
+ { 'x', "|" },
+ { 'y', "\342\211\244" },
+ { 'z', "\342\211\245" },
+ { '{', "\317\200" },
+ { '|', "\342\211\240" },
+ { '}', "\302\243" },
+ { '~', "*" }
+};
+
int
tty_acs_cmp(const void *key, const void *value)
{
@@ -89,7 +124,8 @@ tty_acs_get(struct tty *tty, u_char ch)
/* Otherwise look up the UTF-8 translation. */
entry = bsearch(&ch,
- tty_acs_table, nitems(tty_acs_table), sizeof tty_acs_table[0],
+ options_get_number(global_s_options, "pane-border-ascii") ? tty_acs_table_putty : tty_acs_table,
+ nitems(tty_acs_table), sizeof tty_acs_table[0],
tty_acs_cmp);
if (entry == NULL)
return (NULL);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment