Patch 8.1.1125
Problem:    Libvterm does not handle the window position report.
Solution:   Let libvterm call the fallback CSI handler when not handling CSI
            sequence.  Handle the window position report in Vim.
Files:      src/libvterm/src/state.c, src/terminal.c, src/ui.c,
            src/proto/ui.pro, src/evalfunc.c, src/testdir/test_terminal.vim


*** ../vim-8.1.1124/src/libvterm/src/state.c    2018-12-24 21:38:40.814173687 
+0100
--- src/libvterm/src/state.c    2019-04-06 14:44:25.847900874 +0200
***************
*** 905,910 ****
--- 905,911 ----
    int leader_byte = 0;
    int intermed_byte = 0;
    VTermPos oldpos = state->pos;
+   int handled = 1;
  
    /* Some temporaries for later code */
    int count, val;
***************
*** 1416,1421 ****
--- 1417,1426 ----
        case 8: /* CSI 8 ; rows ; cols t  set size */
        if (argcount == 3)
          on_resize(CSI_ARG(args[1]), CSI_ARG(args[2]), state);
+       break;
+       default:
+       handled = 0;
+       break;
      }
      break;
  
***************
*** 1450,1455 ****
--- 1455,1465 ----
      break;
  
    default:
+     handled = 0;
+     break;
+   }
+ 
+   if (!handled) {
      if(state->fallbacks && state->fallbacks->csi)
        if((*state->fallbacks->csi)(leader, args, argcount, intermed, command, 
state->fbdata))
          return 1;
*** ../vim-8.1.1124/src/terminal.c      2019-03-30 18:46:57.360077328 +0100
--- src/terminal.c      2019-04-06 15:25:12.799197577 +0200
***************
*** 3842,3855 ****
      return 1;
  }
  
  static VTermParserCallbacks parser_fallbacks = {
!   NULL,               /* text */
!   NULL,               /* control */
!   NULL,               /* escape */
!   NULL,               /* csi */
!   parse_osc,  /* osc */
!   NULL,               /* dcs */
!   NULL                /* resize */
  };
  
  /*
--- 3842,3909 ----
      return 1;
  }
  
+ /*
+  * Called by libvterm when it cannot recognize a CSI sequence.
+  * We recognize the window position report.
+  */
+     static int
+ parse_csi(
+       const char  *leader UNUSED,
+       const long  args[],
+       int         argcount,
+       const char  *intermed UNUSED,
+       char        command,
+       void        *user)
+ {
+     term_T    *term = (term_T *)user;
+     char      buf[100];
+     int               len;
+     int               x = 0;
+     int               y = 0;
+     win_T     *wp;
+ 
+     // We recognize only CSI 13 t
+     if (command != 't' || argcount != 1 || args[0] != 13)
+       return 0; // not handled
+ 
+     // When getting the window position fails it results in zero/zero.
+     (void)ui_get_winpos(&x, &y, (varnumber_T)100);
+ 
+     FOR_ALL_WINDOWS(wp)
+       if (wp->w_buffer == term->tl_buffer)
+           break;
+     if (wp != NULL)
+     {
+ #ifdef FEAT_GUI
+       if (gui.in_use)
+       {
+           x += wp->w_wincol * gui.char_width;
+           y += W_WINROW(wp) * gui.char_height;
+       }
+       else
+ #endif
+       {
+           // We roughly estimate the position of the terminal window inside
+           // the Vim window by assuing a 10 x 7 character cell.
+           x += wp->w_wincol * 7;
+           y += W_WINROW(wp) * 10;
+       }
+     }
+ 
+     len = vim_snprintf(buf, 100, "\x1b[3;%d;%dt", x, y);
+     channel_send(term->tl_job->jv_channel, get_tty_part(term),
+                                                    (char_u *)buf, len, NULL);
+     return 1;
+ }
+ 
  static VTermParserCallbacks parser_fallbacks = {
!   NULL,               // text
!   NULL,               // control
!   NULL,               // escape
!   parse_csi,  // csi
!   parse_osc,  // osc
!   NULL,               // dcs
!   NULL                // resize
  };
  
  /*
*** ../vim-8.1.1124/src/ui.c    2019-03-02 10:13:36.800974804 +0100
--- src/ui.c    2019-04-06 16:18:21.290945446 +0200
***************
*** 627,632 ****
--- 627,653 ----
      }
  }
  
+ #if (defined(FEAT_EVAL) \
+     && (defined(FEAT_GUI) \
+           || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)))) \
+       || defined(PROTO)
+ /*
+  * Get the window position in pixels, if possible.
+  * Return FAIL when not possible.
+  */
+     int
+ ui_get_winpos(int *x, int *y, varnumber_T timeout)
+ {
+ # ifdef FEAT_GUI
+     if (gui.in_use)
+       return gui_mch_get_winpos(x, y);
+ # endif
+ # if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
+     return term_get_winpos(x, y, timeout);
+ # endif
+ }
+ #endif
+ 
      void
  ui_breakcheck(void)
  {
*** ../vim-8.1.1124/src/proto/ui.pro    2019-01-27 16:55:44.276707556 +0100
--- src/proto/ui.pro    2019-04-06 15:15:57.453489712 +0200
***************
*** 11,16 ****
--- 11,17 ----
  int ui_get_shellsize(void);
  void ui_set_shellsize(int mustset);
  void ui_new_shellsize(void);
+ int ui_get_winpos(int *x, int *y, varnumber_T timeout);
  void ui_breakcheck(void);
  void ui_breakcheck_force(int force);
  void clip_init(int can_use);
*** ../vim-8.1.1124/src/evalfunc.c      2019-04-06 13:18:06.737335067 +0200
--- src/evalfunc.c      2019-04-06 16:18:24.146930813 +0200
***************
*** 5985,6004 ****
  
      if (rettv_list_alloc(rettv) == FAIL)
        return;
! #ifdef FEAT_GUI
!     if (gui.in_use)
!       (void)gui_mch_get_winpos(&x, &y);
! # if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
!     else
! # endif
! #endif
! #if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
      {
        varnumber_T timeout = 100;
  
        if (argvars[0].v_type != VAR_UNKNOWN)
            timeout = tv_get_number(&argvars[0]);
!       term_get_winpos(&x, &y, timeout);
      }
  #endif
      list_append_number(rettv->vval.v_list, (varnumber_T)x);
--- 5985,5998 ----
  
      if (rettv_list_alloc(rettv) == FAIL)
        return;
! #if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
      {
        varnumber_T timeout = 100;
  
        if (argvars[0].v_type != VAR_UNKNOWN)
            timeout = tv_get_number(&argvars[0]);
! 
!       (void)ui_get_winpos(&x, &y, timeout);
      }
  #endif
      list_append_number(rettv->vval.v_list, (varnumber_T)x);
***************
*** 6013,6033 ****
  f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
  {
      rettv->vval.v_number = -1;
! #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       int         x, y;
! 
!       if (gui_mch_get_winpos(&x, &y) == OK)
!           rettv->vval.v_number = x;
!       return;
!     }
! #endif
! #if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
      {
        int         x, y;
  
!       if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
            rettv->vval.v_number = x;
      }
  #endif
--- 6007,6017 ----
  f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
  {
      rettv->vval.v_number = -1;
! #if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
      {
        int         x, y;
  
!       if (ui_get_winpos(&x, &y, 100) == OK)
            rettv->vval.v_number = x;
      }
  #endif
***************
*** 6040,6060 ****
  f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
  {
      rettv->vval.v_number = -1;
! #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       int         x, y;
! 
!       if (gui_mch_get_winpos(&x, &y) == OK)
!           rettv->vval.v_number = y;
!       return;
!     }
! #endif
! #if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
      {
        int         x, y;
  
!       if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
            rettv->vval.v_number = y;
      }
  #endif
--- 6024,6034 ----
  f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
  {
      rettv->vval.v_number = -1;
! #if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
      {
        int         x, y;
  
!       if (ui_get_winpos(&x, &y, 100) == OK)
            rettv->vval.v_number = y;
      }
  #endif
*** ../vim-8.1.1125/src/testdir/test_terminal.vim       2019-04-06 
12:39:47.439967638 +0200
--- src/testdir/test_terminal.vim       2019-04-06 17:22:33.203006052 +0200
***************
*** 1887,1889 ****
--- 1887,1922 ----
    au! BufLeave
    set statusline=
  endfunc
+ 
+ func Test_terminal_getwinpos()
+   " split, go to the bottom-right window
+   split
+   wincmd j
+   set splitright
+ 
+   call writefile([
+       \ 'echo getwinpos()',
+       \ ], 'XTest_getwinpos')
+   let buf = RunVimInTerminal('-S XTest_getwinpos', {'cols': 60})
+   call term_wait(buf)
+ 
+   " Find the output of getwinpos() in the bottom line.
+   let rows = term_getsize(buf)[0]
+   call WaitForAssert({-> assert_match('\[\d\+, \d\+\]', term_getline(buf, 
rows))})
+   let line = term_getline(buf, rows)
+   let xpos = str2nr(substitute(line, '\[\(\d\+\), \d\+\]', '\1', ''))
+   let ypos = str2nr(substitute(line, '\[\d\+, \(\d\+\)\]', '\1', ''))
+ 
+   " Position must be bigger than the getwinpos() result of Vim itself.
+   let [xroot, yroot] = getwinpos()
+   call assert_inrange(xroot + 2, xroot + 1000, xpos)
+   call assert_inrange(yroot + 2, yroot + 1000, ypos)
+ 
+   call term_wait(buf)
+   call term_sendkeys(buf, ":q\<CR>")
+   call StopVimInTerminal(buf)
+   call delete('XTest_getwinpos')
+   exe buf . 'bwipe!'
+   set splitright&
+   only!
+ endfunc
*** ../vim-8.1.1124/src/version.c       2019-04-06 14:22:17.758642630 +0200
--- src/version.c       2019-04-06 17:24:10.354521046 +0200
***************
*** 773,774 ****
--- 773,776 ----
  {   /* Add new patch number below this line */
+ /**/
+     1125,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
214. Your MCI "Circle of Friends" are all Hayes-compatible.

 /// 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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui