Karsten Hopp 599fe6
To: vim_dev@googlegroups.com
Karsten Hopp 599fe6
Subject: Patch 7.3.859
Karsten Hopp 599fe6
Fcc: outbox
Karsten Hopp 599fe6
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 599fe6
Mime-Version: 1.0
Karsten Hopp 599fe6
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 599fe6
Content-Transfer-Encoding: 8bit
Karsten Hopp 599fe6
------------
Karsten Hopp 599fe6
Karsten Hopp 599fe6
Patch 7.3.859
Karsten Hopp 599fe6
Problem:    'ambiwidth' must be set by the user.
Karsten Hopp 599fe6
Solution:   Detects East Asian ambiguous width (UAX #11) state of the terminal
Karsten Hopp 599fe6
	    at the start-up time and 'ambiwidth' accordingly.  (Hayaki Saito)
Karsten Hopp 599fe6
Files:	    src/main.c, src/option.c, src/term.c, src/term.h,
Karsten Hopp 599fe6
	    src/proto/term.pro
Karsten Hopp 599fe6
Karsten Hopp 599fe6
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/main.c	2013-01-17 13:59:56.000000000 +0100
Karsten Hopp 599fe6
--- src/main.c	2013-03-13 19:09:03.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 804,809 ****
Karsten Hopp 599fe6
--- 804,812 ----
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
      starttermcap();	    /* start termcap if not done by wait_return() */
Karsten Hopp 599fe6
      TIME_MSG("start termcap");
Karsten Hopp 599fe6
+ #if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE)
Karsten Hopp 599fe6
+     may_req_ambiguous_character_width();
Karsten Hopp 599fe6
+ #endif
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  #ifdef FEAT_MOUSE
Karsten Hopp 599fe6
      setmouse();				/* may start using the mouse */
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/option.c	2013-02-13 15:44:22.000000000 +0100
Karsten Hopp 599fe6
--- src/option.c	2013-03-13 19:09:03.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 2900,2905 ****
Karsten Hopp 599fe6
--- 2900,2906 ----
Karsten Hopp 599fe6
      p_term("t_op", T_OP)
Karsten Hopp 599fe6
      p_term("t_RI", T_CRI)
Karsten Hopp 599fe6
      p_term("t_RV", T_CRV)
Karsten Hopp 599fe6
+     p_term("t_u7", T_U7)
Karsten Hopp 599fe6
      p_term("t_Sb", T_CSB)
Karsten Hopp 599fe6
      p_term("t_Sf", T_CSF)
Karsten Hopp 599fe6
      p_term("t_se", T_SE)
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/term.c	2013-02-26 14:56:24.000000000 +0100
Karsten Hopp 599fe6
--- src/term.c	2013-03-13 19:18:22.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 111,116 ****
Karsten Hopp 599fe6
--- 111,121 ----
Karsten Hopp 599fe6
  #  define CRV_SENT	2	/* did send T_CRV, waiting for answer */
Karsten Hopp 599fe6
  #  define CRV_GOT	3	/* received T_CRV response */
Karsten Hopp 599fe6
  static int crv_status = CRV_GET;
Karsten Hopp 599fe6
+ /* Request Cursor position report: */
Karsten Hopp 599fe6
+ #  define U7_GET	1	/* send T_U7 when switched to RAW mode */
Karsten Hopp 599fe6
+ #  define U7_SENT	2	/* did send T_U7, waiting for answer */
Karsten Hopp 599fe6
+ #  define U7_GOT	3	/* received T_U7 response */
Karsten Hopp 599fe6
+ static int u7_status = U7_GET;
Karsten Hopp 599fe6
  # endif
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  /*
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 933,938 ****
Karsten Hopp 599fe6
--- 938,944 ----
Karsten Hopp 599fe6
      {(int)KS_CWP,	IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
Karsten Hopp 599fe6
  #  endif
Karsten Hopp 599fe6
      {(int)KS_CRV,	IF_EB("\033[>c", ESC_STR "[>c")},
Karsten Hopp 599fe6
+     {(int)KS_U7,	IF_EB("\033[6n", ESC_STR "[6n")},
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
      {K_UP,		IF_EB("\033O*A", ESC_STR "O*A")},
Karsten Hopp 599fe6
      {K_DOWN,		IF_EB("\033O*B", ESC_STR "O*B")},
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 1221,1226 ****
Karsten Hopp 599fe6
--- 1227,1233 ----
Karsten Hopp 599fe6
      {(int)KS_CWP,	"[%dCWP%d]"},
Karsten Hopp 599fe6
  #  endif
Karsten Hopp 599fe6
      {(int)KS_CRV,	"[CRV]"},
Karsten Hopp 599fe6
+     {(int)KS_U7,	"[U7]"},
Karsten Hopp 599fe6
      {K_UP,		"[KU]"},
Karsten Hopp 599fe6
      {K_DOWN,		"[KD]"},
Karsten Hopp 599fe6
      {K_LEFT,		"[KL]"},
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 1596,1601 ****
Karsten Hopp 599fe6
--- 1603,1609 ----
Karsten Hopp 599fe6
  				{KS_TS, "ts"}, {KS_FS, "fs"},
Karsten Hopp 599fe6
  				{KS_CWP, "WP"}, {KS_CWS, "WS"},
Karsten Hopp 599fe6
  				{KS_CSI, "SI"}, {KS_CEI, "EI"},
Karsten Hopp 599fe6
+ 				{KS_U7, "u7"},
Karsten Hopp 599fe6
  				{(enum SpecialKey)0, NULL}
Karsten Hopp 599fe6
  			    };
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 3183,3189 ****
Karsten Hopp 599fe6
  		/* May need to check for T_CRV response and termcodes, it
Karsten Hopp 599fe6
  		 * doesn't work in Cooked mode, an external program may get
Karsten Hopp 599fe6
  		 * them. */
Karsten Hopp 599fe6
! 		if (tmode != TMODE_RAW && crv_status == CRV_SENT)
Karsten Hopp 599fe6
  		    (void)vpeekc_nomap();
Karsten Hopp 599fe6
  		check_for_codes_from_term();
Karsten Hopp 599fe6
  	    }
Karsten Hopp 599fe6
--- 3191,3198 ----
Karsten Hopp 599fe6
  		/* May need to check for T_CRV response and termcodes, it
Karsten Hopp 599fe6
  		 * doesn't work in Cooked mode, an external program may get
Karsten Hopp 599fe6
  		 * them. */
Karsten Hopp 599fe6
! 		if (tmode != TMODE_RAW && (crv_status == CRV_SENT
Karsten Hopp 599fe6
! 					 || u7_status == U7_SENT))
Karsten Hopp 599fe6
  		    (void)vpeekc_nomap();
Karsten Hopp 599fe6
  		check_for_codes_from_term();
Karsten Hopp 599fe6
  	    }
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 3245,3251 ****
Karsten Hopp 599fe6
  # endif
Karsten Hopp 599fe6
  	{
Karsten Hopp 599fe6
  	    /* May need to check for T_CRV response. */
Karsten Hopp 599fe6
! 	    if (crv_status == CRV_SENT)
Karsten Hopp 599fe6
  		(void)vpeekc_nomap();
Karsten Hopp 599fe6
  	    /* Check for termcodes first, otherwise an external program may
Karsten Hopp 599fe6
  	     * get them. */
Karsten Hopp 599fe6
--- 3254,3260 ----
Karsten Hopp 599fe6
  # endif
Karsten Hopp 599fe6
  	{
Karsten Hopp 599fe6
  	    /* May need to check for T_CRV response. */
Karsten Hopp 599fe6
! 	    if (crv_status == CRV_SENT || u7_status == U7_SENT)
Karsten Hopp 599fe6
  		(void)vpeekc_nomap();
Karsten Hopp 599fe6
  	    /* Check for termcodes first, otherwise an external program may
Karsten Hopp 599fe6
  	     * get them. */
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 3299,3304 ****
Karsten Hopp 599fe6
--- 3308,3355 ----
Karsten Hopp 599fe6
  	(void)vpeekc_nomap();
Karsten Hopp 599fe6
      }
Karsten Hopp 599fe6
  }
Karsten Hopp 599fe6
+ 
Karsten Hopp 599fe6
+ # if defined(FEAT_MBYTE) || defined(PROTO)
Karsten Hopp 599fe6
+ /*
Karsten Hopp 599fe6
+  * Check how the terminal treats ambiguous character width (UAX #11).
Karsten Hopp 599fe6
+  * First, we move the cursor to (0, 0) and print a test ambiguous character
Karsten Hopp 599fe6
+  * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
Karsten Hopp 599fe6
+  * If the terminal treats \u25bd as single width, the position is (0, 1),
Karsten Hopp 599fe6
+  * or if it is treated as double width, that will be (0, 2).
Karsten Hopp 599fe6
+  * This function has the side effect that changes cursor position, so
Karsten Hopp 599fe6
+  * it must be called immediately after entering termcap mode.
Karsten Hopp 599fe6
+  */
Karsten Hopp 599fe6
+     void
Karsten Hopp 599fe6
+ may_req_ambiguous_character_width()
Karsten Hopp 599fe6
+ {
Karsten Hopp 599fe6
+     if (u7_status == U7_GET
Karsten Hopp 599fe6
+ 	    && cur_tmode == TMODE_RAW
Karsten Hopp 599fe6
+ 	    && termcap_active
Karsten Hopp 599fe6
+ 	    && p_ek
Karsten Hopp 599fe6
+ #  ifdef UNIX
Karsten Hopp 599fe6
+ 	    && isatty(1)
Karsten Hopp 599fe6
+ 	    && isatty(read_cmd_fd)
Karsten Hopp 599fe6
+ #  endif
Karsten Hopp 599fe6
+ 	    && *T_U7 != NUL
Karsten Hopp 599fe6
+ 	    && !option_was_set((char_u *)"ambiwidth"))
Karsten Hopp 599fe6
+     {
Karsten Hopp 599fe6
+ 	 char_u	buf[16];
Karsten Hopp 599fe6
+ 
Karsten Hopp 599fe6
+ 	 term_windgoto(0, 0);
Karsten Hopp 599fe6
+ 	 buf[mb_char2bytes(0x25bd, buf)] = 0;
Karsten Hopp 599fe6
+ 	 out_str(buf);
Karsten Hopp 599fe6
+ 	 out_str(T_U7);
Karsten Hopp 599fe6
+ 	 u7_status = U7_SENT;
Karsten Hopp 599fe6
+ 	 term_windgoto(0, 0);
Karsten Hopp 599fe6
+ 	 out_str((char_u *)"  ");
Karsten Hopp 599fe6
+ 	 term_windgoto(0, 0);
Karsten Hopp 599fe6
+ 	 /* check for the characters now, otherwise they might be eaten by
Karsten Hopp 599fe6
+ 	  * get_keystroke() */
Karsten Hopp 599fe6
+ 	 out_flush();
Karsten Hopp 599fe6
+ 	 (void)vpeekc_nomap();
Karsten Hopp 599fe6
+     }
Karsten Hopp 599fe6
+ }
Karsten Hopp 599fe6
+ # endif
Karsten Hopp 599fe6
  #endif
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  /*
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 4049,4061 ****
Karsten Hopp 599fe6
  	    /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
Karsten Hopp 599fe6
  	    || key_name[0] == KS_URXVT_MOUSE)
Karsten Hopp 599fe6
  	{
Karsten Hopp 599fe6
! 	    /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c".  Also
Karsten Hopp 599fe6
! 	     * eat other possible responses to t_RV, rxvt returns
Karsten Hopp 599fe6
! 	     * "<Esc>[?1;2c".  Also accept CSI instead of <Esc>[.
Karsten Hopp 599fe6
! 	     * mrxvt has been reported to have "+" in the version. Assume
Karsten Hopp 599fe6
! 	     * the escape sequence ends with a letter or one of "{|}~". */
Karsten Hopp 599fe6
! 	    if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
Karsten Hopp 599fe6
! 					       || (tp[0] == CSI && len >= 2)))
Karsten Hopp 599fe6
  	    {
Karsten Hopp 599fe6
  		j = 0;
Karsten Hopp 599fe6
  		extra = 0;
Karsten Hopp 599fe6
--- 4100,4121 ----
Karsten Hopp 599fe6
  	    /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
Karsten Hopp 599fe6
  	    || key_name[0] == KS_URXVT_MOUSE)
Karsten Hopp 599fe6
  	{
Karsten Hopp 599fe6
! 	    /* Check for some responses from terminal start with "<Esc>[" or
Karsten Hopp 599fe6
! 	     * CSI.
Karsten Hopp 599fe6
! 	     *
Karsten Hopp 599fe6
! 	     * - xterm version string: <Esc>[>{x};{vers};{y}c
Karsten Hopp 599fe6
! 	     *   Also eat other possible responses to t_RV, rxvt returns
Karsten Hopp 599fe6
! 	     *   "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
Karsten Hopp 599fe6
! 	     *   mrxvt has been reported to have "+" in the version. Assume
Karsten Hopp 599fe6
! 	     *   the escape sequence ends with a letter or one of "{|}~".
Karsten Hopp 599fe6
! 	     *
Karsten Hopp 599fe6
! 	     * - cursor position report: <Esc>[{row};{col}R
Karsten Hopp 599fe6
! 	     *   The final byte is 'R'. now it is only used for checking for
Karsten Hopp 599fe6
! 	     *   ambiguous-width character state.
Karsten Hopp 599fe6
! 	     */
Karsten Hopp 599fe6
! 	    if ((*T_CRV != NUL || *T_U7 != NUL)
Karsten Hopp 599fe6
! 			&& ((tp[0] == ESC && tp[1] == '[' && len >= 3)
Karsten Hopp 599fe6
! 			    || (tp[0] == CSI && len >= 2)))
Karsten Hopp 599fe6
  	    {
Karsten Hopp 599fe6
  		j = 0;
Karsten Hopp 599fe6
  		extra = 0;
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 4067,4074 ****
Karsten Hopp 599fe6
  		if (i == len)
Karsten Hopp 599fe6
  		    return -1;		/* not enough characters */
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  		/* eat it when at least one digit and ending in 'c' */
Karsten Hopp 599fe6
! 		if (i > 2 + (tp[0] != CSI) && tp[i] == 'c')
Karsten Hopp 599fe6
  		{
Karsten Hopp 599fe6
  		    crv_status = CRV_GOT;
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
--- 4127,4153 ----
Karsten Hopp 599fe6
  		if (i == len)
Karsten Hopp 599fe6
  		    return -1;		/* not enough characters */
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
+ #ifdef FEAT_MBYTE
Karsten Hopp 599fe6
+ 		/* eat it when it has 2 arguments and ends in 'R' */
Karsten Hopp 599fe6
+ 		if (u7_status == U7_SENT && j == 1 && tp[i] == 'R')
Karsten Hopp 599fe6
+ 		{
Karsten Hopp 599fe6
+ 		    char *p = NULL;
Karsten Hopp 599fe6
+ 
Karsten Hopp 599fe6
+ 		    u7_status = U7_GOT;
Karsten Hopp 599fe6
+ 		    if (extra == 2)
Karsten Hopp 599fe6
+ 			p = "single";
Karsten Hopp 599fe6
+ 		    else if (extra == 3)
Karsten Hopp 599fe6
+ 			p = "double";
Karsten Hopp 599fe6
+ 		    if (p != NULL)
Karsten Hopp 599fe6
+ 			set_option_value((char_u *)"ambw", 0L, (char_u *)p, 0);
Karsten Hopp 599fe6
+ 		    key_name[0] = (int)KS_EXTRA;
Karsten Hopp 599fe6
+ 		    key_name[1] = (int)KE_IGNORE;
Karsten Hopp 599fe6
+ 		    slen = i + 1;
Karsten Hopp 599fe6
+ 		}
Karsten Hopp 599fe6
+ 		else
Karsten Hopp 599fe6
+ #endif
Karsten Hopp 599fe6
  		/* eat it when at least one digit and ending in 'c' */
Karsten Hopp 599fe6
! 		if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
Karsten Hopp 599fe6
  		{
Karsten Hopp 599fe6
  		    crv_status = CRV_GOT;
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/term.h	2010-08-15 21:57:25.000000000 +0200
Karsten Hopp 599fe6
--- src/term.h	2013-03-13 19:09:03.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 83,92 ****
Karsten Hopp 599fe6
  #ifdef FEAT_VERTSPLIT
Karsten Hopp 599fe6
      KS_CSV,	/* scroll region vertical */
Karsten Hopp 599fe6
  #endif
Karsten Hopp 599fe6
!     KS_OP	/* original color pair */
Karsten Hopp 599fe6
  };
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
! #define KS_LAST	    KS_OP
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  /*
Karsten Hopp 599fe6
   * the terminal capabilities are stored in this array
Karsten Hopp 599fe6
--- 83,93 ----
Karsten Hopp 599fe6
  #ifdef FEAT_VERTSPLIT
Karsten Hopp 599fe6
      KS_CSV,	/* scroll region vertical */
Karsten Hopp 599fe6
  #endif
Karsten Hopp 599fe6
!     KS_OP,	/* original color pair */
Karsten Hopp 599fe6
!     KS_U7	/* request cursor position */
Karsten Hopp 599fe6
  };
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
! #define KS_LAST	    KS_U7
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  /*
Karsten Hopp 599fe6
   * the terminal capabilities are stored in this array
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 158,163 ****
Karsten Hopp 599fe6
--- 159,165 ----
Karsten Hopp 599fe6
  #define T_CEI	(term_str(KS_CEI))	/* end insert mode */
Karsten Hopp 599fe6
  #define T_CRV	(term_str(KS_CRV))	/* request version string */
Karsten Hopp 599fe6
  #define T_OP	(term_str(KS_OP))	/* original color pair */
Karsten Hopp 599fe6
+ #define T_U7	(term_str(KS_U7))	/* request cursor position */
Karsten Hopp 599fe6
  
Karsten Hopp 599fe6
  #define TMODE_COOK  0	/* terminal mode for external cmds and Ex mode */
Karsten Hopp 599fe6
  #define TMODE_SLEEP 1	/* terminal mode for sleeping (cooked but no echo) */
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/proto/term.pro	2012-02-05 22:05:44.000000000 +0100
Karsten Hopp 599fe6
--- src/proto/term.pro	2013-03-13 19:09:54.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 34,39 ****
Karsten Hopp 599fe6
--- 34,40 ----
Karsten Hopp 599fe6
  void starttermcap __ARGS((void));
Karsten Hopp 599fe6
  void stoptermcap __ARGS((void));
Karsten Hopp 599fe6
  void may_req_termresponse __ARGS((void));
Karsten Hopp 599fe6
+ void may_req_ambiguous_character_width __ARGS((void));
Karsten Hopp 599fe6
  int swapping_screen __ARGS((void));
Karsten Hopp 599fe6
  void setmouse __ARGS((void));
Karsten Hopp 599fe6
  int mouse_has __ARGS((int c));
Karsten Hopp 599fe6
*** ../vim-7.3.858/src/version.c	2013-03-13 19:02:37.000000000 +0100
Karsten Hopp 599fe6
--- src/version.c	2013-03-13 19:27:31.000000000 +0100
Karsten Hopp 599fe6
***************
Karsten Hopp 599fe6
*** 730,731 ****
Karsten Hopp 599fe6
--- 730,733 ----
Karsten Hopp 599fe6
  {   /* Add new patch number below this line */
Karsten Hopp 599fe6
+ /**/
Karsten Hopp 599fe6
+     859,
Karsten Hopp 599fe6
  /**/
Karsten Hopp 599fe6
Karsten Hopp 599fe6
-- 
Karsten Hopp 599fe6
Microsoft is to software what McDonalds is to gourmet cooking
Karsten Hopp 599fe6
Karsten Hopp 599fe6
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 599fe6
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 599fe6
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 599fe6
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///