Patch 8.2.0936
Problem:    Some terminals misinterpret the code for getting cursor style.
Solution:   Send a sequence to the terminal and check the result. (IWAMOTO
            Kouichi, closes #2126)  Merged with current code.
Files:      src/main.c, src/term.c, src/proto/term.pro,
            src/testdir/term_util.vim, src/testdir/test_quickfix.vim,
            src/testdir/test_terminal.vim, src/testdir/test_startup_utf8.vim,
            src/testdir/dumps/Test_balloon_eval_term_01.dump,
            src/testdir/dumps/Test_balloon_eval_term_01a.dump,
            src/testdir/dumps/Test_balloon_eval_term_02.dump,
            src/testdir/dumps/Test_terminal_all_ansi_colors.dump


*** ../vim-8.2.0935/src/main.c  2020-06-06 15:57:59.083088326 +0200
--- src/main.c  2020-06-08 21:20:33.758644053 +0200
***************
*** 793,799 ****
  
  #if defined(FEAT_TERMRESPONSE)
      // Must be done before redrawing, puts a few characters on the screen.
!     may_req_ambiguous_char_width();
  #endif
  
      RedrawingDisabled = 0;
--- 793,799 ----
  
  #if defined(FEAT_TERMRESPONSE)
      // Must be done before redrawing, puts a few characters on the screen.
!     check_terminal_behavior();
  #endif
  
      RedrawingDisabled = 0;
*** ../vim-8.2.0935/src/term.c  2020-06-06 22:36:20.464116743 +0200
--- src/term.c  2020-06-09 15:51:23.453869117 +0200
***************
*** 126,131 ****
--- 126,134 ----
  // Request Cursor position report:
  static termrequest_T u7_status = TERMREQUEST_INIT;
  
+ // Request xterm compatibility check:
+ static termrequest_T xcc_status = TERMREQUEST_INIT;
+ 
  #  ifdef FEAT_TERMINAL
  // Request foreground color report:
  static termrequest_T rfg_status = TERMREQUEST_INIT;
***************
*** 152,157 ****
--- 155,161 ----
  static termrequest_T *all_termrequests[] = {
      &crv_status,
      &u7_status,
+     &xcc_status,
  #  ifdef FEAT_TERMINAL
      &rfg_status,
  #  endif
***************
*** 1428,1433 ****
--- 1432,1438 ----
  #ifdef FEAT_TERMRESPONSE
  static int    check_for_codes = FALSE;    // check for key code response
  static int    is_not_xterm = FALSE;       // recognized not-really-xterm
+ static int    xcc_test_failed = FALSE;    // xcc_status check failed
  #endif
  
      static struct builtin_term *
***************
*** 3605,3644 ****
  }
  
  /*
!  * Check how the terminal treats ambiguous character width (UAX #11).
!  * First, we move the cursor to (1, 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 (1, 1),
!  * or if it is treated as double width, that will be (1, 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_char_width(void)
  {
      if (u7_status.tr_progress == STATUS_GET
-           && can_get_termresponse()
-           && starting == 0
-           && *T_U7 != NUL
            && !option_was_set((char_u *)"ambiwidth"))
      {
        char_u  buf[16];
  
!       LOG_TR(("Sending U7 request"));
        // Do this in the second row.  In the first row the returned sequence
        // may be CSI 1;2R, which is the same as <S-F3>.
        term_windgoto(1, 0);
!       buf[mb_char2bytes(0x25bd, buf)] = 0;
        out_str(buf);
        out_str(T_U7);
        termrequest_sent(&u7_status);
        out_flush();
  
        // This overwrites a few characters on the screen, a redraw is needed
        // after this. Clear them out for now.
        screen_stop_highlight();
        term_windgoto(1, 0);
        out_str((char_u *)"  ");
        term_windgoto(0, 0);
  
        // Need to reset the known cursor position.
--- 3610,3689 ----
  }
  
  /*
!  * Send sequences to the terminal and check with t_u7 how the cursor moves, to
!  * find out properties of the terminal.
   */
      void
! check_terminal_behavior(void)
  {
+     int           did_send = FALSE;
+ 
+     if (!can_get_termresponse() || starting != 0 || *T_U7 == NUL)
+       return;
+ 
      if (u7_status.tr_progress == STATUS_GET
            && !option_was_set((char_u *)"ambiwidth"))
      {
        char_u  buf[16];
  
!       // Ambiguous width check.
!       // Check how the terminal treats ambiguous character width (UAX #11).
!       // First, we move the cursor to (1, 0) and print a test ambiguous
!       // character \u25bd (WHITE DOWN-POINTING TRIANGLE) and then query
!       // the current cursor position.  If the terminal treats \u25bd as
!       // single width, the position is (1, 1), or if it is treated as double
!       // width, that will be (1, 2).  This function has the side effect that
!       // changes cursor position, so it must be called immediately after
!       // entering termcap mode.
!       LOG_TR(("Sending request for ambiwidth check"));
        // Do this in the second row.  In the first row the returned sequence
        // may be CSI 1;2R, which is the same as <S-F3>.
        term_windgoto(1, 0);
!       buf[mb_char2bytes(0x25bd, buf)] = NUL;
        out_str(buf);
        out_str(T_U7);
        termrequest_sent(&u7_status);
        out_flush();
+       did_send = TRUE;
  
        // This overwrites a few characters on the screen, a redraw is needed
        // after this. Clear them out for now.
        screen_stop_highlight();
        term_windgoto(1, 0);
        out_str((char_u *)"  ");
+     }
+ 
+     if (xcc_status.tr_progress == STATUS_GET)
+     {
+       // 2. Check compatibility with xterm.
+       // We move the cursor to (2, 0), print a test sequence and then query
+       // the current cursor position.  If the terminal properly handles
+       // unknown DCS string and CSI sequence with intermediate byte, the test
+       // sequence is ignored and the cursor does not move.  If the terminal
+       // handles test sequence incorrectly, a garbage string is displayed and
+       // the cursor does move.
+       LOG_TR(("Sending xterm compatibility test sequence."));
+       // Do this in the third row.  Second row is used by ambiguous
+       // chararacter width check.
+       term_windgoto(2, 0);
+       // send the test DCS string.
+       out_str((char_u *)"\033Pzz\033\\");
+       // send the test CSI sequence with intermediate byte.
+       out_str((char_u *)"\033[0%m");
+       out_str(T_U7);
+       termrequest_sent(&xcc_status);
+       out_flush();
+       did_send = TRUE;
+ 
+       // If the terminal handles test sequence incorrectly, garbage text is
+       // displayed. Clear them out for now.
+       screen_stop_highlight();
+       term_windgoto(2, 0);
+       out_str((char_u *)"           ");
+     }
+ 
+     if (did_send)
+     {
        term_windgoto(0, 0);
  
        // Need to reset the known cursor position.
***************
*** 4680,4685 ****
--- 4725,4740 ----
  # endif
                        }
                    }
+                   else if (arg[0] == 3)
+                   {
+                       // Third row: xterm compatibility test.
+                       // If the cursor is not on the first column then the
+                       // terminal is not xterm compatible.
+                       if (arg[1] != 1)
+                           xcc_test_failed = TRUE;
+                       xcc_status.tr_progress = STATUS_GOT;
+                   }
+ 
                    key_name[0] = (int)KS_EXTRA;
                    key_name[1] = (int)KE_IGNORE;
                    slen = csi_len;
***************
*** 4814,4819 ****
--- 4869,4882 ----
                        else if (version == 115 && arg[0] == 0 && arg[2] == 0)
                            is_not_xterm = TRUE;
  
+                       // GNU screen sends 83;30600;0, 83;40500;0, etc.
+                       // 30600/40500 is a version number of GNU screen. DA2
+                       // support is added on 3.6.  DCS string has a special
+                       // meaning to GNU screen, but xterm compatibility
+                       // checking does not detect GNU screen.
+                       if (version >= 30600 && arg[0] == 83)
+                           xcc_test_failed = TRUE;
+ 
                        // Xterm first responded to this request at patch level
                        // 95, so assume anything below 95 is not xterm.
                        if (version < 95)
***************
*** 4827,4837 ****
                        // Only request the cursor style if t_SH and t_RS are
                        // set. Only supported properly by xterm since version
                        // 279 (otherwise it returns 0x18).
                        // Not for Terminal.app, it can't handle t_RS, it
                        // echoes the characters to the screen.
                        if (rcs_status.tr_progress == STATUS_GET
                                && version >= 279
-                               && !is_not_xterm
                                && *T_CSH != NUL
                                && *T_CRS != NUL)
                        {
--- 4890,4903 ----
                        // Only request the cursor style if t_SH and t_RS are
                        // set. Only supported properly by xterm since version
                        // 279 (otherwise it returns 0x18).
+                       // Only when the xcc_status was set, the test finished,
+                       // and xcc_test_failed is FALSE;
                        // Not for Terminal.app, it can't handle t_RS, it
                        // echoes the characters to the screen.
                        if (rcs_status.tr_progress == STATUS_GET
+                               && xcc_status.tr_progress == STATUS_GOT
+                               && !xcc_test_failed
                                && version >= 279
                                && *T_CSH != NUL
                                && *T_CRS != NUL)
                        {
***************
*** 4844,4851 ****
                        // Only request the cursor blink mode if t_RC set. Not
                        // for Gnome terminal, it can't handle t_RC, it
                        // echoes the characters to the screen.
                        if (rbm_status.tr_progress == STATUS_GET
!                               && !is_not_xterm
                                && *T_CRC != NUL)
                        {
                            LOG_TR(("Sending cursor blink mode request"));
--- 4910,4920 ----
                        // Only request the cursor blink mode if t_RC set. Not
                        // for Gnome terminal, it can't handle t_RC, it
                        // echoes the characters to the screen.
+                       // Only when the xcc_status was set, the test finished,
+                       // and xcc_test_failed is FALSE;
                        if (rbm_status.tr_progress == STATUS_GET
!                               && xcc_status.tr_progress == STATUS_GOT
!                               && !xcc_test_failed
                                && *T_CRC != NUL)
                        {
                            LOG_TR(("Sending cursor blink mode request"));
*** ../vim-8.2.0935/src/proto/term.pro  2020-06-06 22:36:20.464116743 +0200
--- src/proto/term.pro  2020-06-08 21:41:51.650251418 +0200
***************
*** 47,53 ****
  void starttermcap(void);
  void stoptermcap(void);
  void may_req_termresponse(void);
! void may_req_ambiguous_char_width(void);
  void may_req_bg_color(void);
  int swapping_screen(void);
  void scroll_start(void);
--- 47,53 ----
  void starttermcap(void);
  void stoptermcap(void);
  void may_req_termresponse(void);
! void check_terminal_behavior(void);
  void may_req_bg_color(void);
  int swapping_screen(void);
  void scroll_start(void);
*** ../vim-8.2.0935/src/testdir/term_util.vim   2020-05-11 22:04:46.928845435 
+0200
--- src/testdir/term_util.vim   2020-06-08 22:26:59.581244739 +0200
***************
*** 44,49 ****
--- 44,51 ----
  " Returns the buffer number of the terminal.
  "
  " Options is a dictionary, these items are recognized:
+ " "keep_t_u7" - when 1 do not make t_u7 empty (resetting t_u7 avoids clearing
+ "               parts of line 2 and 3 on the display)
  " "rows" - height of the terminal window (max. 20)
  " "cols" - width of the terminal window (max. 78)
  " "statusoff" - number of lines the status is offset from default
***************
*** 74,80 ****
    let cols = get(a:options, 'cols', 75)
    let statusoff = get(a:options, 'statusoff', 1)
  
!   let cmd = GetVimCommandCleanTerm() .. a:arguments
  
    let options = {
        \ 'curwin': 1,
--- 76,88 ----
    let cols = get(a:options, 'cols', 75)
    let statusoff = get(a:options, 'statusoff', 1)
  
!   if get(a:options, 'keep_t_u7', 0)
!     let reset_u7 = ''
!   else
!     let reset_u7 = ' --cmd "set t_u7=" '
!   endif
! 
!   let cmd = GetVimCommandCleanTerm() .. reset_u7 .. a:arguments
  
    let options = {
        \ 'curwin': 1,
*** ../vim-8.2.0935/src/testdir/test_quickfix.vim       2020-06-08 
19:35:55.781319897 +0200
--- src/testdir/test_quickfix.vim       2020-06-08 22:14:06.555443544 +0200
***************
*** 2710,2716 ****
    CheckScreendump
  
    let lines =<< trim END
-       set t_u7=
        call setline(1, ['some', 'text', 'with', 'matches'])
        write XCwindow
        vimgrep e XCwindow
--- 2710,2715 ----
*** ../vim-8.2.0935/src/testdir/test_terminal.vim       2020-05-31 
16:04:38.558053522 +0200
--- src/testdir/test_terminal.vim       2020-06-08 22:14:48.979337826 +0200
***************
*** 2465,2471 ****
    call writefile(text, 'Xtext')
    let cmd = GetVimCommandCleanTerm()
    let lines = [
-       \ 'set t_u7=',
        \ 'call setline(1, range(20))',
        \ 'hi PopTerm ctermbg=grey',
        \ 'func OpenTerm(setColor)',
--- 2465,2470 ----
***************
*** 2545,2551 ****
    END
    call writefile(text, 'Xtext')
    let lines = [
-       \ 'set t_u7=',
        \ 'call setline(1, range(20))',
        \ 'func OpenTerm()',
        \ "  let s:buf = term_start('cat Xtext', #{hidden: 1})",
--- 2544,2549 ----
***************
*** 2575,2581 ****
    CheckUnix
  
    let lines = [
-       \ 'set t_u7=',
        \ 'call setline(1, range(20))',
        \ 'func OpenTerm()',
        \ "  let s:buf = term_start('cat', #{hidden: 1, "
--- 2573,2578 ----
*** ../vim-8.2.0935/src/testdir/test_startup_utf8.vim   2020-05-31 
21:27:58.335221898 +0200
--- src/testdir/test_startup_utf8.vim   2020-06-08 22:29:44.224733553 +0200
***************
*** 1,5 ****
--- 1,6 ----
  " Tests for startup using utf-8.
  
+ source check.vim
  source shared.vim
  source screendump.vim
  
***************
*** 71,77 ****
        \ 'call test_option_not_set("ambiwidth")',
        \ 'redraw',
        \ ], 'Xscript')
!   let buf = RunVimInTerminal('-S Xscript', {})
    call TermWait(buf)
    call term_sendkeys(buf, "S\<C-R>=&ambiwidth\<CR>\<Esc>")
    call WaitForAssert({-> assert_match('single', term_getline(buf, 1))})
--- 72,78 ----
        \ 'call test_option_not_set("ambiwidth")',
        \ 'redraw',
        \ ], 'Xscript')
!   let buf = RunVimInTerminal('-S Xscript', #{keep_t_u7: 1})
    call TermWait(buf)
    call term_sendkeys(buf, "S\<C-R>=&ambiwidth\<CR>\<Esc>")
    call WaitForAssert({-> assert_match('single', term_getline(buf, 1))})
*** ../vim-8.2.0935/src/testdir/dumps/Test_balloon_eval_term_01.dump    
2019-11-09 16:45:21.000000000 +0100
--- src/testdir/dumps/Test_balloon_eval_term_01.dump    2020-06-08 
22:05:16.197071495 +0200
***************
*** 1,5 ****
  |o+0&#ffffff0|n>e| |o|n|e| |o|n|e| @38
! @2|o| |t|X|o| |t|w|o| @38
  |t|h|r|e| +0#0000001#ffd7ff255@17| +0#0000000#ffffff0@27
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255|l|i|n|e| |2| |c|o|l|u|m|n| |6|:| | 
+0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|t|X|o| @13| +0#4040ff13#ffffff0@27
--- 1,5 ----
  |o+0&#ffffff0|n>e| |o|n|e| |o|n|e| @38
! |t|w|o| |t|X|o| |t|w|o| @38
  |t|h|r|e| +0#0000001#ffd7ff255@17| +0#0000000#ffffff0@27
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255|l|i|n|e| |2| |c|o|l|u|m|n| |6|:| | 
+0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|t|X|o| @13| +0#4040ff13#ffffff0@27
*** ../vim-8.2.0935/src/testdir/dumps/Test_balloon_eval_term_01a.dump   
2019-11-09 16:46:23.000000000 +0100
--- src/testdir/dumps/Test_balloon_eval_term_01a.dump   2020-06-08 
22:09:19.352235966 +0200
***************
*** 1,5 ****
  |o+0&#ffffff0|n>e| |o|n|e| |o|n|e| @38
! @2|o| |t|X|o| |t|w|o| @38
  |t|h|r|e| +0#0000001#ffd7ff255@17| +0#0000000#ffffff0@27
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255|l|i|n|e| |2| |c|o|l|u|m|n| |6|:| | 
+0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|t|X|o| @13| +0#4040ff13#ffffff0@27
--- 1,5 ----
  |o+0&#ffffff0|n>e| |o|n|e| |o|n|e| @38
! |t|w|o| |t|X|o| |t|w|o| @38
  |t|h|r|e| +0#0000001#ffd7ff255@17| +0#0000000#ffffff0@27
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255|l|i|n|e| |2| |c|o|l|u|m|n| |6|:| | 
+0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|t|X|o| @13| +0#4040ff13#ffffff0@27
*** ../vim-8.2.0935/src/testdir/dumps/Test_balloon_eval_term_02.dump    
2019-11-09 16:45:27.000000000 +0100
--- src/testdir/dumps/Test_balloon_eval_term_02.dump    2020-06-08 
22:09:23.844220571 +0200
***************
*** 1,5 ****
  |o+0&#ffffff0|n|e| |o|n|e| |o|n|e| @38
! @2|o| |t|X|o| |t|w|o| @38
  |t|h|r|e|e+0&#e0e0e08| |t|h>r+0&#ffffff0|e@1| |t|h|r|e@1| @32
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|l|i|n|e| |3| |c|o|l|u|m|n| |5|:| | 
+0#4040ff13#ffffff0@27
--- 1,5 ----
  |o+0&#ffffff0|n|e| |o|n|e| |o|n|e| @38
! |t|w|o| |t|X|o| |t|w|o| @38
  |t|h|r|e|e+0&#e0e0e08| |t|h>r+0&#ffffff0|e@1| |t|h|r|e@1| @32
  |~+0#4040ff13&| @2| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@27
  |~| @2| +0#0000001#ffd7ff255|l|i|n|e| |3| |c|o|l|u|m|n| |5|:| | 
+0#4040ff13#ffffff0@27
*** ../vim-8.2.0935/src/testdir/dumps/Test_terminal_all_ansi_colors.dump        
2019-05-13 20:22:27.000000000 +0200
--- src/testdir/dumps/Test_terminal_all_ansi_colors.dump        2020-06-08 
22:11:43.519777958 +0200
***************
*** 1,5 ****
  
>A+0#0000001#8080809@1|B+0#e000002#ff404010@1|C+0#00e0003#40ff4011@1|D+0#e0e0004#ffff4012@1|E+0#0000e05#4040ff13@1|F+0#e000e06#ff40ff14@1|G+0#00e0e07#40ffff15@1|H+0#e0e0e08#ffffff16@1|I+0#8080809#0000001@1|J+0#ff404010#e000002@1|K+0#40ff4011#00e0003@1|L+0#ffff4012#e0e0004@1|M+0#4040ff13#0000e05@1|N+0#ff40ff14#e000e06@1|O+0#40ffff15#00e0e07@1|P+0#ffffff16#e0e0e08@1|
 +0#0000000#ffffff0|X+2#e000002&@1|Y+2#40ff4011&@1|Z+2#ff40ff14#e000e06@1| 
+0#0000000#ffffff0@35
! @2| +0#4040ff13&@72
  |~| @73
  |~| @73
  |~| @73
--- 1,5 ----
  
>A+0#0000001#8080809@1|B+0#e000002#ff404010@1|C+0#00e0003#40ff4011@1|D+0#e0e0004#ffff4012@1|E+0#0000e05#4040ff13@1|F+0#e000e06#ff40ff14@1|G+0#00e0e07#40ffff15@1|H+0#e0e0e08#ffffff16@1|I+0#8080809#0000001@1|J+0#ff404010#e000002@1|K+0#40ff4011#00e0003@1|L+0#ffff4012#e0e0004@1|M+0#4040ff13#0000e05@1|N+0#ff40ff14#e000e06@1|O+0#40ffff15#00e0e07@1|P+0#ffffff16#e0e0e08@1|
 +0#0000000#ffffff0|X+2#e000002&@1|Y+2#40ff4011&@1|Z+2#ff40ff14#e000e06@1| 
+0#0000000#ffffff0@35
! |~+0#4040ff13&| @73
  |~| @73
  |~| @73
  |~| @73
*** ../vim-8.2.0935/src/version.c       2020-06-08 20:50:23.432250668 +0200
--- src/version.c       2020-06-08 21:49:44.056381283 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     936,
  /**/

-- 
Not too long ago, unzipping in public was illegal...

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202006091358.059Dw6OF580084%40masaka.moolenaar.net.

Raspunde prin e-mail lui