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.