Last active
December 12, 2015 01:38
-
-
Save saitoha/4692491 to your computer and use it in GitHub Desktop.
Detect east-asian-ambiguous-width state of the terminal automatically (vim).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -cr vim.ba8835947b8b/runtime/doc/options.txt vim/runtime/doc/options.txt | |
*** vim.ba8835947b8b/runtime/doc/options.txt 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/runtime/doc/options.txt 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 699,704 **** | |
--- 699,709 ---- | |
when the system locale is set to one of CJK locales. See Unicode | |
Standard Annex #11 (http://www.unicode.org/reports/tr11). | |
+ Vim may set this option automatically at the startup time. | |
+ This only works when Vim is compiled with the |+termresponse| | |
+ feature and if |t_u7| is set to the sescape sequense to request | |
+ cursor position report. | |
+ | |
*'antialias'* *'anti'* *'noantialias'* *'noanti'* | |
'antialias' 'anti' boolean (default: off) | |
global | |
diff -cr vim.ba8835947b8b/runtime/doc/tags vim/runtime/doc/tags | |
*** vim.ba8835947b8b/runtime/doc/tags 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/runtime/doc/tags 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 964,969 **** | |
--- 964,970 ---- | |
't_te' term.txt /*'t_te'* | |
't_ti' term.txt /*'t_ti'* | |
't_ts' term.txt /*'t_ts'* | |
+ 't_u7' term.txt /*'t_u7'* | |
't_ue' term.txt /*'t_ue'* | |
't_us' term.txt /*'t_us'* | |
't_ut' term.txt /*'t_ut'* | |
*************** | |
*** 7972,7977 **** | |
--- 7973,7979 ---- | |
t_tp version4.txt /*t_tp* | |
t_ts term.txt /*t_ts* | |
t_ts_old version4.txt /*t_ts_old* | |
+ t_u7 term.txt /*t_u7* | |
t_ue term.txt /*t_ue* | |
t_undo version4.txt /*t_undo* | |
t_us term.txt /*t_us* | |
diff -cr vim.ba8835947b8b/runtime/doc/term.txt vim/runtime/doc/term.txt | |
*** vim.ba8835947b8b/runtime/doc/term.txt 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/runtime/doc/term.txt 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 294,299 **** | |
--- 294,301 ---- | |
|termcap-cursor-shape| | |
t_RV request terminal version string (for xterm) *t_RV* *'t_RV'* | |
|xterm-8bit| |v:termresponse| |'ttymouse'| |xterm-codes| | |
+ t_u7 request cursor position (for xterm) *t_u7* *'t_u7'* | |
+ |ambiwidth| | |
KEY CODES | |
Note: Use the <> form if possible | |
diff -cr vim.ba8835947b8b/src/main.c vim/src/main.c | |
*** vim.ba8835947b8b/src/main.c 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/src/main.c 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 804,809 **** | |
--- 804,812 ---- | |
starttermcap(); /* start termcap if not done by wait_return() */ | |
TIME_MSG("start termcap"); | |
+ #if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE) | |
+ may_req_ambiguous_character_width(); | |
+ #endif | |
#ifdef FEAT_MOUSE | |
setmouse(); /* may start using the mouse */ | |
diff -cr vim.ba8835947b8b/src/option.c vim/src/option.c | |
*** vim.ba8835947b8b/src/option.c 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/src/option.c 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 2900,2905 **** | |
--- 2900,2906 ---- | |
p_term("t_op", T_OP) | |
p_term("t_RI", T_CRI) | |
p_term("t_RV", T_CRV) | |
+ p_term("t_u7", T_U7) | |
p_term("t_Sb", T_CSB) | |
p_term("t_Sf", T_CSF) | |
p_term("t_se", T_SE) | |
diff -cr vim.ba8835947b8b/src/term.c vim/src/term.c | |
*** vim.ba8835947b8b/src/term.c 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/src/term.c 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 933,938 **** | |
--- 933,939 ---- | |
{(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")}, | |
# endif | |
{(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")}, | |
+ {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")}, | |
{K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, | |
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, | |
*************** | |
*** 1221,1226 **** | |
--- 1222,1228 ---- | |
{(int)KS_CWP, "[%dCWP%d]"}, | |
# endif | |
{(int)KS_CRV, "[CRV]"}, | |
+ {(int)KS_U7, "[U7]"}, | |
{K_UP, "[KU]"}, | |
{K_DOWN, "[KD]"}, | |
{K_LEFT, "[KL]"}, | |
*************** | |
*** 1596,1601 **** | |
--- 1598,1604 ---- | |
{KS_TS, "ts"}, {KS_FS, "fs"}, | |
{KS_CWP, "WP"}, {KS_CWS, "WS"}, | |
{KS_CSI, "SI"}, {KS_CEI, "EI"}, | |
+ {KS_U7, "u7"}, | |
{(enum SpecialKey)0, NULL} | |
}; | |
*************** | |
*** 3297,3302 **** | |
--- 3300,3344 ---- | |
(void)vpeekc_nomap(); | |
} | |
} | |
+ | |
+ # ifdef FEAT_MBYTE | |
+ /* Check how the terminal treats ambiguous character width. | |
+ * First, we move the cursor to (0, 0) and print a test ambiguous character | |
+ * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position. | |
+ * If the terminal treats \u25bd as single width, the position is (0, 1), | |
+ * or if it is treated as double width, that will be (0, 2). | |
+ * This function has the side effect that changes cursor position, so | |
+ * it must be called immediately after entering termcap mode. | |
+ */ | |
+ void | |
+ may_req_ambiguous_character_width() | |
+ { | |
+ if (crv_status == CRV_GET | |
+ && cur_tmode == TMODE_RAW | |
+ && termcap_active | |
+ && p_ek | |
+ # ifdef UNIX | |
+ && isatty(1) | |
+ && isatty(read_cmd_fd) | |
+ # endif | |
+ && *T_U7 != NUL | |
+ && !option_was_set("ambiwidth")) | |
+ { | |
+ char buf[16]; | |
+ term_windgoto(0, 0); | |
+ buf[mb_char2bytes(0x25bd, buf)] = 0; | |
+ out_str(buf); | |
+ out_str(T_U7); | |
+ term_windgoto(0, 0); | |
+ out_str(" "); | |
+ term_windgoto(0, 0); | |
+ /* check for the characters now, otherwise they might be eaten by | |
+ * get_keystroke() */ | |
+ out_flush(); | |
+ (void)vpeekc_nomap(); | |
+ } | |
+ } | |
+ # endif | |
#endif | |
/* | |
*************** | |
*** 4048,4060 **** | |
|| key_name[0] == KS_URXVT_MOUSE | |
|| key_name[0] == KS_SGR_MOUSE) | |
{ | |
! /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c". Also | |
! * eat other possible responses to t_RV, rxvt returns | |
! * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[. | |
! * mrxvt has been reported to have "+" in the version. Assume | |
! * the escape sequence ends with a letter or one of "{|}~". */ | |
! if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3) | |
! || (tp[0] == CSI && len >= 2))) | |
{ | |
j = 0; | |
extra = 0; | |
--- 4090,4102 ---- | |
|| key_name[0] == KS_URXVT_MOUSE | |
|| key_name[0] == KS_SGR_MOUSE) | |
{ | |
! /* Check for some termcodes start with "<Esc>[" or CSI. | |
! * - DA2(secondary device attributes): <Esc>[>{x};{vers};{y}c | |
! * - CPR(cursor position report) <Esc>[{row};{col}R | |
! */ | |
! if ((*T_CRV != NUL || *T_U7 != NUL) | |
! && (tp[0] == ESC && tp[1] == '[' && len >= 3) | |
! || (tp[0] == CSI && len >= 2)) | |
{ | |
j = 0; | |
extra = 0; | |
*************** | |
*** 4066,4073 **** | |
if (i == len) | |
return -1; /* not enough characters */ | |
/* eat it when at least one digit and ending in 'c' */ | |
! if (i > 2 + (tp[0] != CSI) && tp[i] == 'c') | |
{ | |
crv_status = CRV_GOT; | |
--- 4108,4135 ---- | |
if (i == len) | |
return -1; /* not enough characters */ | |
+ #ifdef FEAT_MBYTE | |
+ /* eat it when at least one digit and ending in 'R' */ | |
+ if (*T_U7 != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'R') | |
+ { | |
+ if (extra == 2) { | |
+ p_ambw = "single"; | |
+ } else if (extra == 3) { | |
+ p_ambw = "double"; | |
+ } | |
+ key_name[0] = (int)KS_EXTRA; | |
+ key_name[1] = (int)KE_IGNORE; | |
+ slen = i + 1; | |
+ } | |
+ else | |
+ #endif | |
+ /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c". Also | |
+ * eat other possible responses to t_RV, rxvt returns | |
+ * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[. | |
+ * mrxvt has been reported to have "+" in the version. Assume | |
+ * the escape sequence ends with a letter or one of "{|}~". */ | |
/* eat it when at least one digit and ending in 'c' */ | |
! if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') | |
{ | |
crv_status = CRV_GOT; | |
diff -cr vim.ba8835947b8b/src/term.h vim/src/term.h | |
*** vim.ba8835947b8b/src/term.h 2013-02-10 14:03:58.000000000 +0900 | |
--- vim/src/term.h 2013-02-10 14:03:58.000000000 +0900 | |
*************** | |
*** 83,92 **** | |
#ifdef FEAT_VERTSPLIT | |
KS_CSV, /* scroll region vertical */ | |
#endif | |
! KS_OP /* original color pair */ | |
}; | |
! #define KS_LAST KS_OP | |
/* | |
* the terminal capabilities are stored in this array | |
--- 83,93 ---- | |
#ifdef FEAT_VERTSPLIT | |
KS_CSV, /* scroll region vertical */ | |
#endif | |
! KS_OP, /* original color pair */ | |
! KS_U7 /* request cursor position */ | |
}; | |
! #define KS_LAST KS_U7 | |
/* | |
* the terminal capabilities are stored in this array | |
*************** | |
*** 158,163 **** | |
--- 159,165 ---- | |
#define T_CEI (term_str(KS_CEI)) /* end insert mode */ | |
#define T_CRV (term_str(KS_CRV)) /* request version string */ | |
#define T_OP (term_str(KS_OP)) /* original color pair */ | |
+ #define T_U7 (term_str(KS_U7)) /* request cursor position */ | |
#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */ | |
#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment