@@ -838,13 +838,32 @@ channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err)
838838#endif
839839
840840/*
841- * Sets the job the channel is associated with.
841+ * Sets the job the channel is associated with and associated options .
842842 * This does not keep a refcount, when the job is freed ch_job is cleared.
843843 */
844844 void
845- channel_set_job (channel_T * channel , job_T * job )
845+ channel_set_job (channel_T * channel , job_T * job , jobopt_T * options )
846846{
847847 channel -> ch_job = job ;
848+
849+ channel_set_options (channel , options );
850+
851+ if (job -> jv_in_buf != NULL )
852+ {
853+ chanpart_T * in_part = & channel -> ch_part [PART_IN ];
854+
855+ in_part -> ch_buffer = job -> jv_in_buf ;
856+ ch_logs (channel , "reading from buffer '%s'" ,
857+ (char * )in_part -> ch_buffer -> b_ffname );
858+ if (options -> jo_set & JO_IN_TOP )
859+ in_part -> ch_buf_top = options -> jo_in_top ;
860+ else
861+ in_part -> ch_buf_top = 1 ;
862+ if (options -> jo_set & JO_IN_BOT )
863+ in_part -> ch_buf_bot = options -> jo_in_bot ;
864+ else
865+ in_part -> ch_buf_bot = in_part -> ch_buffer -> b_ml .ml_line_count ;
866+ }
848867}
849868
850869/*
@@ -982,6 +1001,47 @@ channel_set_req_callback(
9821001 }
9831002}
9841003
1004+ /*
1005+ * Write any lines to the in channel.
1006+ */
1007+ void
1008+ channel_write_in (channel_T * channel )
1009+ {
1010+ chanpart_T * in_part = & channel -> ch_part [PART_IN ];
1011+ linenr_T lnum ;
1012+ buf_T * buf = in_part -> ch_buffer ;
1013+
1014+ if (buf == NULL )
1015+ return ;
1016+ if (!buf_valid (buf ) || buf -> b_ml .ml_mfp == NULL )
1017+ {
1018+ /* buffer was wiped out or unloaded */
1019+ in_part -> ch_buffer = NULL ;
1020+ return ;
1021+ }
1022+ if (in_part -> ch_fd == INVALID_FD )
1023+ /* pipe was closed */
1024+ return ;
1025+
1026+ for (lnum = in_part -> ch_buf_top ; lnum <= in_part -> ch_buf_bot
1027+ && lnum <= buf -> b_ml .ml_line_count ; ++ lnum )
1028+ {
1029+ char_u * line = ml_get_buf (buf , lnum , FALSE);
1030+ int len = STRLEN (line );
1031+ char_u * p ;
1032+
1033+ /* TODO: check if channel can be written to */
1034+ if ((p = alloc (len + 2 )) == NULL )
1035+ break ;
1036+ STRCPY (p , line );
1037+ p [len ] = NL ;
1038+ p [len + 1 ] = NUL ;
1039+ channel_send (channel , PART_IN , p , "channel_write_in()" );
1040+ vim_free (p );
1041+ }
1042+ in_part -> ch_buf_top = lnum ;
1043+ }
1044+
9851045/*
9861046 * Invoke the "callback" on channel "channel".
9871047 */
@@ -1409,6 +1469,23 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
14091469 }
14101470}
14111471
1472+ static void
1473+ invoke_one_time_callback (
1474+ channel_T * channel ,
1475+ cbq_T * cbhead ,
1476+ cbq_T * item ,
1477+ typval_T * argv )
1478+ {
1479+ ch_logs (channel , "Invoking one-time callback %s" ,
1480+ (char * )item -> cq_callback );
1481+ /* Remove the item from the list first, if the callback
1482+ * invokes ch_close() the list will be cleared. */
1483+ remove_cb_node (cbhead , item );
1484+ invoke_callback (channel , item -> cq_callback , argv );
1485+ vim_free (item -> cq_callback );
1486+ vim_free (item );
1487+ }
1488+
14121489/*
14131490 * Invoke a callback for "channel"/"part" if needed.
14141491 * Return TRUE when a message was handled, there might be another one.
@@ -1421,14 +1498,19 @@ may_invoke_callback(channel_T *channel, int part)
14211498 typval_T argv [CH_JSON_MAX_ARGS ];
14221499 int seq_nr = -1 ;
14231500 ch_mode_T ch_mode = channel -> ch_part [part ].ch_mode ;
1501+ cbq_T * cbhead = & channel -> ch_part [part ].ch_cb_head ;
1502+ cbq_T * cbitem = cbhead -> cq_next ;
14241503 char_u * callback = NULL ;
14251504 buf_T * buffer = NULL ;
14261505
14271506 if (channel -> ch_nb_close_cb != NULL )
14281507 /* this channel is handled elsewhere (netbeans) */
14291508 return FALSE;
14301509
1431- if (channel -> ch_part [part ].ch_callback != NULL )
1510+ /* use a message-specific callback, part callback or channel callback */
1511+ if (cbitem != NULL )
1512+ callback = cbitem -> cq_callback ;
1513+ else if (channel -> ch_part [part ].ch_callback != NULL )
14321514 callback = channel -> ch_part [part ].ch_callback ;
14331515 else
14341516 callback = channel -> ch_callback ;
@@ -1544,27 +1626,18 @@ may_invoke_callback(channel_T *channel, int part)
15441626
15451627 if (seq_nr > 0 )
15461628 {
1547- cbq_T * head = & channel -> ch_part [part ].ch_cb_head ;
1548- cbq_T * item = head -> cq_next ;
15491629 int done = FALSE;
15501630
15511631 /* invoke the one-time callback with the matching nr */
1552- while (item != NULL )
1632+ while (cbitem != NULL )
15531633 {
1554- if (item -> cq_seq_nr == seq_nr )
1634+ if (cbitem -> cq_seq_nr == seq_nr )
15551635 {
1556- ch_logs (channel , "Invoking one-time callback %s" ,
1557- (char * )item -> cq_callback );
1558- /* Remove the item from the list first, if the callback
1559- * invokes ch_close() the list will be cleared. */
1560- remove_cb_node (head , item );
1561- invoke_callback (channel , item -> cq_callback , argv );
1562- vim_free (item -> cq_callback );
1563- vim_free (item );
1636+ invoke_one_time_callback (channel , cbhead , cbitem , argv );
15641637 done = TRUE;
15651638 break ;
15661639 }
1567- item = item -> cq_next ;
1640+ cbitem = cbitem -> cq_next ;
15681641 }
15691642 if (!done )
15701643 ch_logn (channel , "Dropping message %d without callback" , seq_nr );
@@ -1618,11 +1691,18 @@ may_invoke_callback(channel_T *channel, int part)
16181691 }
16191692 }
16201693 }
1694+
16211695 if (callback != NULL )
16221696 {
1623- /* invoke the channel callback */
1624- ch_logs (channel , "Invoking channel callback %s" , (char * )callback );
1625- invoke_callback (channel , callback , argv );
1697+ if (cbitem != NULL )
1698+ invoke_one_time_callback (channel , cbhead , cbitem , argv );
1699+ else
1700+ {
1701+ /* invoke the channel callback */
1702+ ch_logs (channel , "Invoking channel callback %s" ,
1703+ (char * )callback );
1704+ invoke_callback (channel , callback , argv );
1705+ }
16261706 }
16271707 }
16281708 else
0 commit comments