Patch 8.0.1801
Problem:    MS-Windows: redirecting terminal output does not work.
Solution:   Intercept the text written to the terminal and write it to the
            file.
Files:      src/terminal.c, src/testdir/test_terminal.vim


*** ../vim-8.0.1800/src/terminal.c      2018-05-06 16:40:12.239619606 +0200
--- src/terminal.c      2018-05-06 21:44:39.219762827 +0200
***************
*** 38,53 ****
   * in tl_scrollback are no longer used.
   *
   * TODO:
!  * - Win32: Make terminal used for :!cmd in the GUI work better.  Allow for
!  *   redirection.  Probably in call to channel_set_pipes().
!  * - Win32: Redirecting output does not work, Test_terminal_redir_file()
   *   is disabled.
   * - Copy text in the vterm to the Vim buffer once in a while, so that
   *   completion works.
   * - When the job only outputs lines, we could handle resizing the terminal
   *   better: store lines separated by line breaks, instead of screen lines,
   *   then when the window is resized redraw those lines.
!  * - Redrawing is slow with Athena and Motif.  Also other GUI? (Ramel Eshed)
   * - For the GUI fill termios with default values, perhaps like pangoterm:
   *   
http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
   * - When 'encoding' is not utf-8, or the job is using another encoding, setup
--- 38,54 ----
   * in tl_scrollback are no longer used.
   *
   * TODO:
!  * - Win32: Redirecting input does not work, half of 
Test_terminal_redir_file()
   *   is disabled.
+  * - Win32: Redirecting output works but includes escape sequences.
+  * - Win32: Make terminal used for :!cmd in the GUI work better.  Allow for
+  *   redirection.
   * - Copy text in the vterm to the Vim buffer once in a while, so that
   *   completion works.
   * - When the job only outputs lines, we could handle resizing the terminal
   *   better: store lines separated by line breaks, instead of screen lines,
   *   then when the window is resized redraw those lines.
!  * - Redrawing is slow with Athena and Motif. (Ramel Eshed)
   * - For the GUI fill termios with default values, perhaps like pangoterm:
   *   
http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
   * - When 'encoding' is not utf-8, or the job is using another encoding, setup
***************
*** 99,109 ****
      /* Set when setting the size of a vterm, reset after redrawing. */
      int               tl_vterm_size_changed;
  
-     /* used when tl_job is NULL and only a pty was created */
-     int               tl_tty_fd;
-     char_u    *tl_tty_in;
-     char_u    *tl_tty_out;
- 
      int               tl_normal_mode; /* TRUE: Terminal-Normal mode */
      int               tl_channel_closed;
      int               tl_finish;
--- 100,105 ----
***************
*** 117,122 ****
--- 113,120 ----
  #ifdef WIN3264
      void      *tl_winpty_config;
      void      *tl_winpty;
+ 
+     FILE      *tl_out_fd;
  #endif
  #if defined(FEAT_SESSION)
      char_u    *tl_command;
***************
*** 169,175 ****
  /*
   * Functions with separate implementation for MS-Windows and Unix-like 
systems.
   */
! static int term_and_job_init(term_T *term, typval_T *argvar, char **argv, 
jobopt_T *opt);
  static int create_pty_only(term_T *term, jobopt_T *opt);
  static void term_report_winsize(term_T *term, int rows, int cols);
  static void term_free_vterm(term_T *term);
--- 167,173 ----
  /*
   * Functions with separate implementation for MS-Windows and Unix-like 
systems.
   */
! static int term_and_job_init(term_T *term, typval_T *argvar, char **argv, 
jobopt_T *opt, jobopt_T *orig_opt);
  static int create_pty_only(term_T *term, jobopt_T *opt);
  static void term_report_winsize(term_T *term, int rows, int cols);
  static void term_free_vterm(term_T *term);
***************
*** 283,289 ****
--- 281,291 ----
      static void
  setup_job_options(jobopt_T *opt, int rows, int cols)
  {
+ #ifndef WIN3264
+     /* Win32: Redirecting the job output won't work, thus always connect 
stdout
+      * here. */
      if (!(opt->jo_set & JO_OUT_IO))
+ #endif
      {
        /* Connect stdout to the terminal. */
        opt->jo_io[PART_OUT] = JIO_BUFFER;
***************
*** 292,298 ****
--- 294,304 ----
        opt->jo_set |= JO_OUT_IO + JO_OUT_BUF + JO_OUT_MODIFIABLE;
      }
  
+ #ifndef WIN3264
+     /* Win32: Redirecting the job output won't work, thus always connect 
stderr
+      * here. */
      if (!(opt->jo_set & JO_ERR_IO))
+ #endif
      {
        /* Connect stderr to the terminal. */
        opt->jo_io[PART_ERR] = JIO_BUFFER;
***************
*** 350,355 ****
--- 356,362 ----
      int               res;
      buf_T     *newbuf;
      int               vertical = opt->jo_vertical || (cmdmod.split & 
WSP_VERT);
+     jobopt_T  orig_opt;  // only partly filled
  
      if (check_restricted() || check_secure())
        return NULL;
***************
*** 517,522 ****
--- 524,532 ----
      curbuf->b_p_ma = FALSE;
  
      set_term_and_win_size(term);
+ #ifdef WIN3264
+     mch_memmove(orig_opt.jo_io, opt->jo_io, sizeof(orig_opt.jo_io));
+ #endif
      setup_job_options(opt, term->tl_rows, term->tl_cols);
  
      if (flags & TERM_START_NOJOB)
***************
*** 582,588 ****
            && STRCMP(argvar->vval.v_string, "NONE") == 0)
        res = create_pty_only(term, opt);
      else
!       res = term_and_job_init(term, argvar, argv, opt);
  
      newbuf = curbuf;
      if (res == OK)
--- 592,598 ----
            && STRCMP(argvar->vval.v_string, "NONE") == 0)
        res = create_pty_only(term, opt);
      else
!       res = term_and_job_init(term, argvar, argv, opt, &orig_opt);
  
      newbuf = curbuf;
      if (res == OK)
***************
*** 823,828 ****
--- 833,842 ----
      vim_free(term->tl_status_text);
      vim_free(term->tl_opencmd);
      vim_free(term->tl_eof_chars);
+ #ifdef WIN3264
+     if (term->tl_out_fd != NULL)
+       fclose(term->tl_out_fd);
+ #endif
      if (desired_cursor_color == term->tl_cursor_color)
        desired_cursor_color = (char_u *)"";
      vim_free(term->tl_cursor_color);
***************
*** 918,923 ****
--- 932,948 ----
      size_t    len = STRLEN(msg);
      term_T    *term = buffer->b_term;
  
+ #ifdef WIN3264
+     /* Win32: Cannot redirect output of the job, intercept it here and write 
to
+      * the file. */
+     if (term->tl_out_fd != NULL)
+     {
+       ch_log(channel, "Writing %d bytes to output file", (int)len);
+       fwrite(msg, len, 1, term->tl_out_fd);
+       return;
+     }
+ #endif
+ 
      if (term->tl_vterm == NULL)
      {
        ch_log(channel, "NOT writing %d bytes to terminal", (int)len);
***************
*** 4740,4753 ****
        case 0:
            if (buf->b_term->tl_job != NULL)
                p = buf->b_term->tl_job->jv_tty_out;
-           else
-               p = buf->b_term->tl_tty_out;
            break;
        case 1:
            if (buf->b_term->tl_job != NULL)
                p = buf->b_term->tl_job->jv_tty_in;
-           else
-               p = buf->b_term->tl_tty_in;
            break;
        default:
            EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
--- 4765,4774 ----
***************
*** 5239,5245 ****
        term_T      *term,
        typval_T    *argvar,
        char        **argv UNUSED,
!       jobopt_T    *opt)
  {
      WCHAR         *cmd_wchar = NULL;
      WCHAR         *cwd_wchar = NULL;
--- 5260,5267 ----
        term_T      *term,
        typval_T    *argvar,
        char        **argv UNUSED,
!       jobopt_T    *opt,
!       jobopt_T    *orig_opt)
  {
      WCHAR         *cmd_wchar = NULL;
      WCHAR         *cwd_wchar = NULL;
***************
*** 5393,5398 ****
--- 5415,5433 ----
      ++job->jv_refcount;
      term->tl_job = job;
  
+     /* Redirecting stdout and stderr doesn't work at the job level.  Instead
+      * open the file here and handle it in.  opt->jo_io was changed in
+      * setup_job_options(), use the original flags here. */
+     if (orig_opt->jo_io[PART_OUT] == JIO_FILE)
+     {
+       char_u *fname = opt->jo_io_name[PART_OUT];
+ 
+       ch_log(channel, "Opening output file %s", fname);
+       term->tl_out_fd = mch_fopen((char *)fname, WRITEBIN);
+       if (term->tl_out_fd == NULL)
+           EMSG2(_(e_notopen), fname);
+     }
+ 
      return OK;
  
  failed:
***************
*** 5546,5552 ****
        term_T      *term,
        typval_T    *argvar,
        char        **argv,
!       jobopt_T    *opt)
  {
      create_vterm(term, term->tl_rows, term->tl_cols);
  
--- 5581,5588 ----
        term_T      *term,
        typval_T    *argvar,
        char        **argv,
!       jobopt_T    *opt,
!       jobopt_T    *orig_opt UNUSED)
  {
      create_vterm(term, term->tl_rows, term->tl_cols);
  
*** ../vim-8.0.1800/src/testdir/test_terminal.vim       2018-05-03 
20:40:15.714154543 +0200
--- src/testdir/test_terminal.vim       2018-05-06 21:12:06.003573297 +0200
***************
*** 675,692 ****
  endfunc
  
  func Test_terminal_redir_file()
!   " TODO: this should work on MS-Window
!   if has('unix')
!     let cmd = Get_cat_123_cmd()
!     let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
!     call term_wait(buf)
!     call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
!     call assert_match('123', readfile('Xfile')[0])
!     let g:job = term_getjob(buf)
!     call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
!     call delete('Xfile')
!     bwipe
!   endif
  
    if has('unix')
      call writefile(['one line'], 'Xfile')
--- 675,689 ----
  endfunc
  
  func Test_terminal_redir_file()
!   let cmd = Get_cat_123_cmd()
!   let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
!   call term_wait(buf)
!   call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
!   call assert_match('123', readfile('Xfile')[0])
!   let g:job = term_getjob(buf)
!   call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
!   call delete('Xfile')
!   bwipe
  
    if has('unix')
      call writefile(['one line'], 'Xfile')
*** ../vim-8.0.1800/src/version.c       2018-05-06 19:19:32.382254324 +0200
--- src/version.c       2018-05-06 21:11:40.931724251 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1801,
  /**/

-- 
ARTHUR:  Shut up!  Will you shut up!
DENNIS:  Ah, now we see the violence inherent in the system.
ARTHUR:  Shut up!
DENNIS:  Oh!  Come and see the violence inherent in the system!
         HELP! HELP!  I'm being repressed!
                                  The Quest for the Holy Grail (Monty Python)

 /// 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