patch 8.0.0739: terminal resizing doesn't work well.
Problem: Terminal resizing doesn't work well.
Solution: Resize the terminal to the Vim window and the other way around.
Avoid mapping typed keys. Set the environment properly.
diff --git a/src/os_unix.c b/src/os_unix.c
index fbe550d..9869d30 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4054,38 +4054,48 @@
#if !defined(USE_SYSTEM) || defined(FEAT_JOB_CHANNEL)
static void
-set_child_environment(void)
+set_child_environment(long rows, long columns, char *term)
{
# ifdef HAVE_SETENV
char envbuf[50];
# else
+ static char envbuf_TERM[30];
static char envbuf_Rows[20];
+ static char envbuf_Lines[20];
static char envbuf_Columns[20];
# endif
/* Simulate to have a dumb terminal (for now) */
# ifdef HAVE_SETENV
- setenv("TERM", "dumb", 1);
- sprintf((char *)envbuf, "%ld", Rows);
+ setenv("TERM", term, 1);
+ sprintf((char *)envbuf, "%ld", rows);
setenv("ROWS", (char *)envbuf, 1);
- sprintf((char *)envbuf, "%ld", Rows);
+ sprintf((char *)envbuf, "%ld", rows);
setenv("LINES", (char *)envbuf, 1);
- sprintf((char *)envbuf, "%ld", Columns);
+ sprintf((char *)envbuf, "%ld", columns);
setenv("COLUMNS", (char *)envbuf, 1);
# else
/*
* Putenv does not copy the string, it has to remain valid.
* Use a static array to avoid losing allocated memory.
*/
- putenv("TERM=dumb");
- sprintf(envbuf_Rows, "ROWS=%ld", Rows);
+ vim_snprintf(envbuf_Term, sizeof(envbuf_Term), "TERM=%s", term);
+ putenv(envbuf_Term);
+ vim_snprintf(envbuf_Rows, sizeof(envbuf_Rows), "ROWS=%ld", rows);
putenv(envbuf_Rows);
- sprintf(envbuf_Rows, "LINES=%ld", Rows);
- putenv(envbuf_Rows);
- sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
+ vim_snprintf(envbuf_Lines, sizeof(envbuf_Lines), "LINES=%ld", rows);
+ putenv(envbuf_Lines);
+ vim_snprintf(envbuf_Columns, sizeof(envbuf_Columns),
+ "COLUMNS=%ld", columns);
putenv(envbuf_Columns);
# endif
}
+
+ static void
+set_default_child_environment(void)
+{
+ set_child_environment(Rows, Columns, "dumb");
+}
#endif
int
@@ -4417,7 +4427,7 @@
# endif
}
# endif
- set_child_environment();
+ set_default_child_environment();
/*
* stderr is only redirected when using the GUI, so that a
@@ -5090,7 +5100,7 @@
#if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
void
-mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
+mch_start_job(char **argv, job_T *job, jobopt_T *options)
{
pid_t pid;
int fd_in[2]; /* for stdin */
@@ -5200,7 +5210,15 @@
(void)setsid();
# endif
- set_child_environment();
+# ifdef FEAT_TERMINAL
+ if (options->jo_term_rows > 0)
+ set_child_environment(
+ (long)options->jo_term_rows,
+ (long)options->jo_term_cols,
+ "xterm");
+ else
+# endif
+ set_default_child_environment();
if (use_null_for_in || use_null_for_out || use_null_for_err)
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
diff --git a/src/structs.h b/src/structs.h
index 88e71b6..5a7f28b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1732,6 +1732,12 @@
int jo_id;
char_u jo_soe_buf[NUMBUFLEN];
char_u *jo_stoponexit;
+
+#ifdef FEAT_TERMINAL
+ /* when non-zero run the job in a terminal window of this size */
+ int jo_term_rows;
+ int jo_term_cols;
+#endif
} jobopt_T;
diff --git a/src/terminal.c b/src/terminal.c
index 82aa2c2..ac5b7b8 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -184,6 +184,8 @@
opt.jo_io_buf[PART_OUT] = curbuf->b_fnum;
opt.jo_io_buf[PART_ERR] = curbuf->b_fnum;
opt.jo_set |= JO_OUT_BUF + (JO_OUT_BUF << (PART_ERR - PART_OUT));
+ opt.jo_term_rows = rows;
+ opt.jo_term_cols = cols;
term->tl_job = job_start(argvars, &opt);
}
@@ -267,7 +269,11 @@
update_screen(0);
setcursor();
out_flush();
+ ++no_mapping;
+ ++allow_keys;
c = vgetc();
+ --no_mapping;
+ --allow_keys;
/* Catch keys that need to be handled as in Normal mode. */
switch (c)
@@ -331,6 +337,13 @@
term_update_lines(wp);
}
+ static void
+position_cursor(win_T *wp, VTermPos *pos)
+{
+ wp->w_wrow = MIN(pos->row, MAX(0, wp->w_height - 1));
+ wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1));
+}
+
#ifdef WIN3264
/**************************************
@@ -486,7 +499,7 @@
}
static int
-handle_moverect(VTermRect dest, VTermRect src, void *user)
+handle_moverect(VTermRect dest UNUSED, VTermRect src UNUSED, void *user)
{
term_T *term = (term_T *)user;
@@ -496,7 +509,11 @@
}
static int
-handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
+handle_movecursor(
+ VTermPos pos,
+ VTermPos oldpos UNUSED,
+ int visible UNUSED,
+ void *user)
{
term_T *term = (term_T *)user;
win_T *wp;
@@ -506,9 +523,7 @@
{
if (wp->w_buffer == term->tl_buffer)
{
- /* TODO: limit to window size? */
- wp->w_wrow = pos.row;
- wp->w_wcol = pos.col;
+ position_cursor(wp, &pos);
if (wp == curwin)
is_current = TRUE;
}
@@ -527,8 +542,17 @@
handle_resize(int rows, int cols, void *user)
{
term_T *term = (term_T *)user;
+ win_T *wp;
- /* TODO: handle terminal resize. */
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == term->tl_buffer)
+ {
+ win_setheight_win(rows, wp);
+ win_setwidth_win(cols, wp);
+ }
+ }
+
redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
@@ -648,10 +672,23 @@
int vterm_cols;
VTerm *vterm = wp->w_buffer->b_term->tl_vterm;
VTermScreen *screen = vterm_obtain_screen(vterm);
+ VTermState *state = vterm_obtain_state(vterm);
VTermPos pos;
vterm_get_size(vterm, &vterm_rows, &vterm_cols);
+ if (*wp->w_p_tms == NUL
+ && (vterm_rows != wp->w_height || vterm_cols != wp->w_width))
+ {
+ vterm_set_size(vterm, wp->w_height, wp->w_width);
+ /* Get the size again, in case setting the didn't work. */
+ vterm_get_size(vterm, &vterm_rows, &vterm_cols);
+ }
+
+ /* The cursor may have been moved when resizing. */
+ vterm_state_get_cursorpos(state, &pos);
+ position_cursor(wp, &pos);
+
/* TODO: Only redraw what changed. */
for (pos.row = 0; pos.row < wp->w_height; ++pos.row)
{
diff --git a/src/version.c b/src/version.c
index 5149be9..fc0f2da 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 739,
+/**/
738,
/**/
737,