@@ -669,12 +669,12 @@ channel_set_job(channel_T *channel, job_T *job)
669669}
670670
671671/*
672- * Set the json mode of channel "channel" to "ch_mode ".
672+ * Set the mode of channel "channel" to "mode ".
673673 */
674674 void
675- channel_set_json_mode (channel_T * channel , ch_mode_T ch_mode )
675+ channel_set_mode (channel_T * channel , ch_mode_T mode )
676676{
677- channel -> ch_mode = ch_mode ;
677+ channel -> ch_mode = mode ;
678678}
679679
680680/*
@@ -1057,7 +1057,8 @@ channel_exe_cmd(channel_T *channel, char_u *cmd, typval_T *arg2, typval_T *arg3)
10571057
10581058/*
10591059 * Invoke a callback for channel "channel" if needed.
1060- * Return OK when a message was handled, there might be another one.
1060+ * TODO: add "which" argument, read stderr.
1061+ * Return TRUE when a message was handled, there might be another one.
10611062 */
10621063 static int
10631064may_invoke_callback (channel_T * channel )
@@ -1074,7 +1075,7 @@ may_invoke_callback(channel_T *channel)
10741075 /* this channel is handled elsewhere (netbeans) */
10751076 return FALSE;
10761077
1077- if (ch_mode != MODE_RAW )
1078+ if (ch_mode == MODE_JSON || ch_mode == MODE_JS )
10781079 {
10791080 /* Get any json message in the queue. */
10801081 if (channel_get_json (channel , -1 , & listtv ) == FAIL )
@@ -1113,18 +1114,51 @@ may_invoke_callback(channel_T *channel)
11131114 }
11141115 else if (channel_peek (channel ) == NULL )
11151116 {
1116- /* nothing to read on raw channel */
1117+ /* nothing to read on RAW or NL channel */
11171118 return FALSE;
11181119 }
11191120 else
11201121 {
1121- /* If there is no callback, don't do anything . */
1122+ /* If there is no callback drop the message . */
11221123 if (channel -> ch_callback == NULL )
1124+ {
1125+ while ((msg = channel_get (channel )) != NULL )
1126+ vim_free (msg );
11231127 return FALSE;
1128+ }
1129+
1130+ if (ch_mode == MODE_NL )
1131+ {
1132+ char_u * nl ;
1133+ char_u * buf ;
1134+
1135+ /* See if we have a message ending in NL in the first buffer. If
1136+ * not try to concatenate the first and the second buffer. */
1137+ while (TRUE)
1138+ {
1139+ buf = channel_peek (channel );
1140+ nl = vim_strchr (buf , NL );
1141+ if (nl != NULL )
1142+ break ;
1143+ if (channel_collapse (channel ) == FAIL )
1144+ return FALSE; /* incomplete message */
1145+ }
1146+ if (nl [1 ] == NUL )
1147+ /* get the whole buffer */
1148+ msg = channel_get (channel );
1149+ else
1150+ {
1151+ /* Copy the message into allocated memory and remove it from
1152+ * the buffer. */
1153+ msg = vim_strnsave (buf , (int )(nl - buf ));
1154+ mch_memmove (buf , nl + 1 , STRLEN (nl + 1 ) + 1 );
1155+ }
1156+ }
1157+ else
1158+ /* For a raw channel we don't know where the message ends, just
1159+ * get everything we have. */
1160+ msg = channel_get_all (channel );
11241161
1125- /* For a raw channel we don't know where the message ends, just get
1126- * everything. */
1127- msg = channel_get_all (channel );
11281162 argv [1 ].v_type = VAR_STRING ;
11291163 argv [1 ].vval .v_string = msg ;
11301164 }
@@ -1276,12 +1310,20 @@ channel_save(channel_T *channel, char_u *buf, int len)
12761310 return FAIL ; /* out of memory */
12771311 }
12781312
1279- /* TODO: don't strip CR when channel is in raw mode */
1280- p = node -> rq_buffer ;
1281- for (i = 0 ; i < len ; ++ i )
1282- if (buf [i ] != CAR || i + 1 >= len || buf [i + 1 ] != NL )
1283- * p ++ = buf [i ];
1284- * p = NUL ;
1313+ if (channel -> ch_mode == MODE_NL )
1314+ {
1315+ /* Drop any CR before a NL. */
1316+ p = node -> rq_buffer ;
1317+ for (i = 0 ; i < len ; ++ i )
1318+ if (buf [i ] != CAR || i + 1 >= len || buf [i + 1 ] != NL )
1319+ * p ++ = buf [i ];
1320+ * p = NUL ;
1321+ }
1322+ else
1323+ {
1324+ mch_memmove (node -> rq_buffer , buf , len );
1325+ node -> rq_buffer [len ] = NUL ;
1326+ }
12851327
12861328 /* append node to the tail of the queue */
12871329 node -> rq_next = NULL ;
@@ -1570,31 +1612,64 @@ channel_read(channel_T *channel, int which, char *func)
15701612}
15711613
15721614/*
1573- * Read from raw channel "channel". Blocks until there is something to read or
1574- * the timeout expires.
1615+ * Read from RAW or NL channel "channel". Blocks until there is something to
1616+ * read or the timeout expires.
1617+ * TODO: add "which" argument and read from stderr.
15751618 * Returns what was read in allocated memory.
15761619 * Returns NULL in case of error or timeout.
15771620 */
15781621 char_u *
15791622channel_read_block (channel_T * channel )
15801623{
1581- ch_log (channel , "Reading raw\n" );
1582- if (channel_peek (channel ) == NULL )
1624+ char_u * buf ;
1625+ char_u * msg ;
1626+ ch_mode_T mode = channel -> ch_mode ;
1627+ sock_T fd = get_read_fd (channel );
1628+ char_u * nl ;
1629+
1630+ ch_logsn (channel , "Blocking %s read, timeout: %d msec\n" ,
1631+ mode == MODE_RAW ? "RAW" : "NL" , channel -> ch_timeout );
1632+
1633+ while (TRUE)
15831634 {
1584- sock_T fd = get_read_fd (channel );
1635+ buf = channel_peek (channel );
1636+ if (buf != NULL && (mode == MODE_RAW
1637+ || (mode == MODE_NL && vim_strchr (buf , NL ) != NULL )))
1638+ break ;
1639+ if (buf != NULL && channel_collapse (channel ) == OK )
1640+ continue ;
15851641
1586- /* TODO: read both out and err if they are different */
1587- ch_log (channel , "No readahead\n" );
15881642 /* Wait for up to the channel timeout. */
15891643 if (fd == CHAN_FD_INVALID
15901644 || channel_wait (channel , fd , channel -> ch_timeout ) == FAIL )
15911645 return NULL ;
15921646 channel_read (channel , -1 , "channel_read_block" );
15931647 }
15941648
1595- /* TODO: only get the first message */
1596- ch_log (channel , "Returning readahead\n" );
1597- return channel_get_all (channel );
1649+ if (mode == MODE_RAW )
1650+ {
1651+ msg = channel_get_all (channel );
1652+ }
1653+ else
1654+ {
1655+ nl = vim_strchr (buf , NL );
1656+ if (nl [1 ] == NUL )
1657+ {
1658+ /* get the whole buffer */
1659+ msg = channel_get (channel );
1660+ * nl = NUL ;
1661+ }
1662+ else
1663+ {
1664+ /* Copy the message into allocated memory and remove it from the
1665+ * buffer. */
1666+ msg = vim_strnsave (buf , (int )(nl - buf ));
1667+ mch_memmove (buf , nl + 1 , STRLEN (nl + 1 ) + 1 );
1668+ }
1669+ }
1670+ if (log_fd != NULL )
1671+ ch_logn (channel , "Returning %d bytes\n" , (int )STRLEN (msg ));
1672+ return msg ;
15981673}
15991674
16001675/*
0 commit comments