]> granicus.if.org Git - vim/commitdiff
patch 8.0.1616: Win32: shell commands in the GUI open a new console v8.0.1616
authorBram Moolenaar <Bram@vim.org>
Sun, 18 Mar 2018 18:29:34 +0000 (19:29 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 18 Mar 2018 18:29:34 +0000 (19:29 +0100)
Problem:    Win32: shell commands in the GUI open a new console.
Solution:   Use a terminal window for interactive use when 'guioptions'
            contains "!".

src/os_win32.c
src/version.c

index 0199996a869eb8bf71837bdaa345643a8601583e..c3f3f687e3d69bfa65865b4d45b0897bdc20b6ab 100644 (file)
@@ -4488,7 +4488,7 @@ mch_system_piped(char *cmd, int options)
     int                c;
     int                noread_cnt = 0;
     garray_T   ga;
-    int            delay = 1;
+    int                delay = 1;
     DWORD      buffer_off = 0; /* valid bytes in buffer[] */
     char       *p = NULL;
 
@@ -4782,6 +4782,69 @@ mch_system(char *cmd, int options)
 
 #endif
 
+#if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
+/*
+ * Use a terminal window to run a shell command in.
+ */
+    static int
+mch_call_shell_terminal(
+    char_u     *cmd,
+    int                options UNUSED) /* SHELL_*, see vim.h */
+{
+    jobopt_T   opt;
+    char_u     *newcmd = NULL;
+    typval_T   argvar[2];
+    long_u     cmdlen;
+    int                retval = -1;
+    buf_T      *buf;
+    aco_save_T aco;
+    oparg_T    oa;             /* operator arguments */
+
+    cmdlen = STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10;
+
+    newcmd = lalloc(cmdlen, TRUE);
+    if (newcmd == NULL)
+       return 255;
+    vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", p_sh, p_shcf, cmd);
+
+    init_job_options(&opt);
+    ch_log(NULL, "starting terminal for system command '%s'", cmd);
+
+    argvar[0].v_type = VAR_STRING;
+    argvar[0].vval.v_string = newcmd;
+    argvar[1].v_type = VAR_UNKNOWN;
+    buf = term_start(argvar, NULL, &opt, TERM_START_SYSTEM);
+
+    /* Find a window to make "buf" curbuf. */
+    aucmd_prepbuf(&aco, buf);
+
+    clear_oparg(&oa);
+    while (term_use_loop())
+    {
+       if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
+       {
+           /* If terminal_loop() returns OK we got a key that is handled
+            * in Normal model. We don't do redrawing anyway. */
+           if (terminal_loop(TRUE) == OK)
+               normal_cmd(&oa, TRUE);
+       }
+       else
+           normal_cmd(&oa, TRUE);
+    }
+    retval = 0;
+    ch_log(NULL, "system command finished");
+
+    /* restore curwin/curbuf and a few other things */
+    aucmd_restbuf(&aco);
+
+    wait_return(TRUE);
+    do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
+
+    vim_free(newcmd);
+    return retval;
+}
+#endif
+
 /*
  * Either execute a command by calling the shell or start a new shell
  */
@@ -4851,6 +4914,19 @@ mch_call_shell(
        fflush(fdDump);
     }
 #endif
+#if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
+    /* TODO: make the terminal window work with input or output redirected. */
+    if (vim_strchr(p_go, GO_TERMINAL) != NULL
+        && (options & (SHELL_FILTER|SHELL_DOOUT|SHELL_WRITE|SHELL_READ)) == 0)
+    {
+       /* Use a terminal window to run the command in. */
+       x = mch_call_shell_terminal(cmd, options);
+#ifdef FEAT_TITLE
+       resettitle();
+#endif
+       return x;
+    }
+#endif
 
     /*
      * Catch all deadly signals while running the external command, because a
index 6beb36e4145ccc76981ff640d5d9a37c609aa846..58c4e89848653dc8023289dbb52f092bdf67d573 100644 (file)
@@ -766,6 +766,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1616,
 /**/
     1615,
 /**/