Patch 8.0.1076
Problem:    term_start() does not take callbacks. When using two terminals
            without a job only one is read from.  A terminal without a window
            returns the wrong pty.
Solution:   Support "callback", "out_cb" and "err_cb".  Fix terminal without a
            window. Fix reading from multiple channels.
Files:      src/terminal.c, src/proto/terminal.pro, src/channel.c, 


*** ../vim-8.0.1075/src/terminal.c      2017-09-08 16:25:49.864776293 +0200
--- src/terminal.c      2017-09-08 20:38:03.161664708 +0200
***************
*** 245,251 ****
        opt->jo_term_cols = cols;
  }
  
!     static void
  term_start(typval_T *argvar, jobopt_T *opt, int forceit)
  {
      exarg_T   split_ea;
--- 245,255 ----
        opt->jo_term_cols = cols;
  }
  
! /*
!  * Start a terminal window and return its buffer.
!  * Returns NULL when failed.
!  */
!     static buf_T *
  term_start(typval_T *argvar, jobopt_T *opt, int forceit)
  {
      exarg_T   split_ea;
***************
*** 253,261 ****
      term_T    *term;
      buf_T     *old_curbuf = NULL;
      int               res;
  
      if (check_restricted() || check_secure())
!       return;
  
      if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO))
                                         == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)
--- 257,266 ----
      term_T    *term;
      buf_T     *old_curbuf = NULL;
      int               res;
+     buf_T     *newbuf;
  
      if (check_restricted() || check_secure())
!       return NULL;
  
      if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO))
                                         == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)
***************
*** 263,274 ****
        || (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF)))
      {
        EMSG(_(e_invarg));
!       return;
      }
  
      term = (term_T *)alloc_clear(sizeof(term_T));
      if (term == NULL)
!       return;
      term->tl_dirty_row_end = MAX_ROW;
      term->tl_cursor_visible = TRUE;
      term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK;
--- 268,279 ----
        || (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF)))
      {
        EMSG(_(e_invarg));
!       return NULL;
      }
  
      term = (term_T *)alloc_clear(sizeof(term_T));
      if (term == NULL)
!       return NULL;
      term->tl_dirty_row_end = MAX_ROW;
      term->tl_cursor_visible = TRUE;
      term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK;
***************
*** 283,295 ****
        {
            no_write_message();
            vim_free(term);
!           return;
        }
        if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE,
                     ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
        {
            vim_free(term);
!           return;
        }
      }
      else if (opt->jo_hidden)
--- 288,300 ----
        {
            no_write_message();
            vim_free(term);
!           return NULL;
        }
        if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE,
                     ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
        {
            vim_free(term);
!           return NULL;
        }
      }
      else if (opt->jo_hidden)
***************
*** 303,309 ****
        if (buf == NULL || ml_open(buf) == FAIL)
        {
            vim_free(term);
!           return;
        }
        old_curbuf = curbuf;
        --curbuf->b_nwindows;
--- 308,314 ----
        if (buf == NULL || ml_open(buf) == FAIL)
        {
            vim_free(term);
!           return NULL;
        }
        old_curbuf = curbuf;
        --curbuf->b_nwindows;
***************
*** 333,339 ****
        {
            /* split failed */
            vim_free(term);
!           return;
        }
      }
      term->tl_buffer = curbuf;
--- 338,344 ----
        {
            /* split failed */
            vim_free(term);
!           return NULL;
        }
      }
      term->tl_buffer = curbuf;
***************
*** 419,424 ****
--- 424,430 ----
      else
        res = term_and_job_init(term, argvar, opt);
  
+     newbuf = curbuf;
      if (res == OK)
      {
        /* Get and remember the size we ended up with.  Update the pty. */
***************
*** 453,459 ****
--- 459,467 ----
        /* Wiping out the buffer will also close the window and call
         * free_terminal(). */
        do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
+       return NULL;
      }
+     return newbuf;
  }
  
  /*
***************
*** 688,694 ****
            update_screen(0);
            update_cursor(term, TRUE);
        }
!       else
            redraw_after_callback(TRUE);
      }
  }
--- 696,702 ----
            update_screen(0);
            update_cursor(term, TRUE);
        }
!       else if (buffer->b_nwindows > 0)
            redraw_after_callback(TRUE);
      }
  }
***************
*** 879,884 ****
--- 887,906 ----
  }
  
  /*
+  * Return TRUE if "term" has an active channel and used ":term NONE".
+  */
+     int
+ term_none_open(term_T *term)
+ {
+     /* Also consider the job finished when the channel is closed, to avoid a
+      * race condition when updating the title. */
+     return term != NULL
+       && term->tl_job != NULL
+       && channel_is_open(term->tl_job->jv_channel)
+       && term->tl_job->jv_channel->ch_keep_open;
+ }
+ 
+ /*
   * Add the last line of the scrollback buffer to the buffer in the window.
   */
      static void
***************
*** 2379,2384 ****
--- 2401,2408 ----
        }
        else if (term->tl_title != NULL)
            txt = term->tl_title;
+       else if (term_none_open(term))
+           txt = (char_u *)_("active");
        else if (term_job_running(term))
            txt = (char_u *)_("running");
        else
***************
*** 2858,2868 ****
--- 2882,2894 ----
  f_term_start(typval_T *argvars, typval_T *rettv)
  {
      jobopt_T  opt;
+     buf_T     *buf;
  
      init_job_options(&opt);
      if (argvars[1].v_type != VAR_UNKNOWN
            && get_job_options(&argvars[1], &opt,
                JO_TIMEOUT_ALL + JO_STOPONEXIT
+                   + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK
                    + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
                JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
                    + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
***************
*** 2871,2880 ****
  
      if (opt.jo_vertical)
        cmdmod.split = WSP_VERT;
!     term_start(&argvars[0], &opt, FALSE);
  
!     if (curbuf->b_term != NULL)
!       rettv->vval.v_number = curbuf->b_fnum;
  }
  
  /*
--- 2897,2906 ----
  
      if (opt.jo_vertical)
        cmdmod.split = WSP_VERT;
!     buf = term_start(&argvars[0], &opt, FALSE);
  
!     if (buf != NULL && buf->b_term != NULL)
!       rettv->vval.v_number = buf->b_fnum;
  }
  
  /*
***************
*** 3359,3366 ****
      static int
  create_pty_only(term_T *term, jobopt_T *opt)
  {
-     int ret;
- 
      create_vterm(term, term->tl_rows, term->tl_cols);
  
      term->tl_job = job_alloc();
--- 3385,3390 ----
***************
*** 3371,3379 ****
      /* behave like the job is already finished */
      term->tl_job->jv_status = JOB_FINISHED;
  
!     ret = mch_create_pty_channel(term->tl_job, opt);
! 
!     return ret;
  }
  
  /*
--- 3395,3401 ----
      /* behave like the job is already finished */
      term->tl_job->jv_status = JOB_FINISHED;
  
!     return mch_create_pty_channel(term->tl_job, opt);
  }
  
  /*
*** ../vim-8.0.1075/src/proto/terminal.pro      2017-09-02 14:54:16.380533155 
+0200
--- src/proto/terminal.pro      2017-09-08 19:58:28.757407950 +0200
***************
*** 3,8 ****
--- 3,9 ----
  void free_terminal(buf_T *buf);
  void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
  int term_job_running(term_T *term);
+ int term_none_open(term_T *term);
  int term_in_normal_mode(void);
  void term_enter_job_mode(void);
  int send_keys_to_term(term_T *term, int c, int typed);
***************
*** 16,22 ****
  int term_is_finished(buf_T *buf);
  int term_show_buffer(buf_T *buf);
  void term_change_in_curbuf(void);
- void term_send_eof(channel_T *ch);
  int term_get_attr(buf_T *buf, linenr_T lnum, int col);
  char_u *term_get_status_text(term_T *term);
  int set_ref_in_term(int copyID);
--- 17,22 ----
***************
*** 35,39 ****
--- 35,40 ----
  void f_term_sendkeys(typval_T *argvars, typval_T *rettv);
  void f_term_start(typval_T *argvars, typval_T *rettv);
  void f_term_wait(typval_T *argvars, typval_T *rettv);
+ void term_send_eof(channel_T *ch);
  int terminal_enabled(void);
  /* vim: set ft=c : */
*** ../vim-8.0.1075/src/channel.c       2017-09-08 14:39:25.638102889 +0200
--- src/channel.c       2017-09-08 17:43:56.634079364 +0200
***************
*** 3692,3704 ****
        {
            res = fd_write(fd, (char *)buf, len);
  #ifdef WIN32
!           if (channel->ch_named_pipe)
            {
!               if (res < 0)
!               {
!                   DisconnectNamedPipe((HANDLE)fd);
!                   ConnectNamedPipe((HANDLE)fd, NULL);
!               }
            }
  #endif
  
--- 3692,3701 ----
        {
            res = fd_write(fd, (char *)buf, len);
  #ifdef WIN32
!           if (channel->ch_named_pipe && res < 0)
            {
!               DisconnectNamedPipe((HANDLE)fd);
!               ConnectNamedPipe((HANDLE)fd, NULL);
            }
  #endif
  
***************
*** 4084,4089 ****
--- 4081,4087 ----
            if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds))
            {
                channel_read(channel, part, "channel_select_check");
+               FD_CLR(fd, rfds);
                --ret;
            }
        }
***************
*** 4093,4098 ****
--- 4091,4097 ----
                                            && FD_ISSET(in_part->ch_fd, wfds))
        {
            channel_write_input(channel);
+           FD_CLR(in_part->ch_fd, wfds);
            --ret;
        }
      }
*** ../vim-8.0.1075/src/version.c       2017-09-08 16:25:49.868776266 +0200
--- src/version.c       2017-09-08 17:03:13.470137745 +0200
***************
*** 771,772 ****
--- 771,774 ----
  {   /* Add new patch number below this line */
+ /**/
+     1076,
  /**/

-- 
>From "know your smileys":
 :-D    Big smile

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