]> granicus.if.org Git - vim/commitdiff
patch 8.0.0739: terminal resizing doesn't work well. v8.0.0739
authorBram Moolenaar <Bram@vim.org>
Thu, 20 Jul 2017 21:04:46 +0000 (23:04 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 20 Jul 2017 21:04:46 +0000 (23:04 +0200)
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.

src/os_unix.c
src/structs.h
src/terminal.c
src/version.c

index fbe550de905c89f15ad9c3436cdd042834f39148..9869d30da643ceb6ff7fb8b93cfc1299ee014add 100644 (file)
@@ -4054,37 +4054,47 @@ mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
 
 #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
 
@@ -4417,7 +4427,7 @@ mch_call_shell(
 #  endif
                }
 # endif
-               set_child_environment();
+               set_default_child_environment();
 
                /*
                 * stderr is only redirected when using the GUI, so that a
@@ -5090,7 +5100,7 @@ error:
 
 #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 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
        (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);
index 88e71b60e9827a6ec7f8497491532e123b1a0b12..5a7f28b797f28f11bb3248f56e2b24b1ceaaeab9 100644 (file)
@@ -1732,6 +1732,12 @@ typedef struct
     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;
 
 
index 82aa2c21b95d28c04feb86ae5b78152cc63b39e5..ac5b7b892d841c851f0458fa2e061e1d06a4f513 100644 (file)
@@ -184,6 +184,8 @@ ex_terminal(exarg_T *eap)
        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 @@ terminal_loop(void)
        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_window(win_T *wp)
     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 @@ handle_damage(VTermRect rect, void *user)
 }
 
     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 @@ handle_moverect(VTermRect dest, VTermRect src, void *user)
 }
 
   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 @@ handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
     {
        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_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
 handle_resize(int rows, int cols, void *user)
 {
     term_T     *term = (term_T *)user;
+    win_T      *wp;
+
+    FOR_ALL_WINDOWS(wp)
+    {
+       if (wp->w_buffer == term->tl_buffer)
+       {
+           win_setheight_win(rows, wp);
+           win_setwidth_win(cols, wp);
+       }
+    }
 
-    /* TODO: handle terminal resize. */
     redraw_buf_later(term->tl_buffer, NOT_VALID);
     return 1;
 }
@@ -648,10 +672,23 @@ term_update_lines(win_T *wp)
     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)
     {
index 5149be91bbe63f7a56a17e344fa67142e121cb67..fc0f2da9730fc4e9fbb4891a62665328856a6851 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    739,
 /**/
     738,
 /**/