@@ -1390,6 +1390,23 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
13901390 }
13911391}
13921392
1393+ static void
1394+ invoke_one_time_callback (
1395+ channel_T * channel ,
1396+ cbq_T * cbhead ,
1397+ cbq_T * item ,
1398+ typval_T * argv )
1399+ {
1400+ ch_logs (channel , "Invoking one-time callback %s" ,
1401+ (char * )item -> cq_callback );
1402+ /* Remove the item from the list first, if the callback
1403+ * invokes ch_close() the list will be cleared. */
1404+ remove_cb_node (cbhead , item );
1405+ invoke_callback (channel , item -> cq_callback , argv );
1406+ vim_free (item -> cq_callback );
1407+ vim_free (item );
1408+ }
1409+
13931410/*
13941411 * Invoke a callback for "channel"/"part" if needed.
13951412 * Return TRUE when a message was handled, there might be another one.
@@ -1402,14 +1419,19 @@ may_invoke_callback(channel_T *channel, int part)
14021419 typval_T argv [CH_JSON_MAX_ARGS ];
14031420 int seq_nr = -1 ;
14041421 ch_mode_T ch_mode = channel -> ch_part [part ].ch_mode ;
1422+ cbq_T * cbhead = & channel -> ch_part [part ].ch_cb_head ;
1423+ cbq_T * cbitem = cbhead -> cq_next ;
14051424 char_u * callback = NULL ;
14061425 buf_T * buffer = NULL ;
14071426
14081427 if (channel -> ch_nb_close_cb != NULL )
14091428 /* this channel is handled elsewhere (netbeans) */
14101429 return FALSE;
14111430
1412- if (channel -> ch_part [part ].ch_callback != NULL )
1431+ /* use a message-specific callback, part callback or channel callback */
1432+ if (cbitem != NULL )
1433+ callback = cbitem -> cq_callback ;
1434+ else if (channel -> ch_part [part ].ch_callback != NULL )
14131435 callback = channel -> ch_part [part ].ch_callback ;
14141436 else
14151437 callback = channel -> ch_callback ;
@@ -1525,27 +1547,18 @@ may_invoke_callback(channel_T *channel, int part)
15251547
15261548 if (seq_nr > 0 )
15271549 {
1528- cbq_T * head = & channel -> ch_part [part ].ch_cb_head ;
1529- cbq_T * item = head -> cq_next ;
15301550 int done = FALSE;
15311551
15321552 /* invoke the one-time callback with the matching nr */
1533- while (item != NULL )
1553+ while (cbitem != NULL )
15341554 {
1535- if (item -> cq_seq_nr == seq_nr )
1555+ if (cbitem -> cq_seq_nr == seq_nr )
15361556 {
1537- ch_logs (channel , "Invoking one-time callback %s" ,
1538- (char * )item -> cq_callback );
1539- /* Remove the item from the list first, if the callback
1540- * invokes ch_close() the list will be cleared. */
1541- remove_cb_node (head , item );
1542- invoke_callback (channel , item -> cq_callback , argv );
1543- vim_free (item -> cq_callback );
1544- vim_free (item );
1557+ invoke_one_time_callback (channel , cbhead , cbitem , argv );
15451558 done = TRUE;
15461559 break ;
15471560 }
1548- item = item -> cq_next ;
1561+ cbitem = cbitem -> cq_next ;
15491562 }
15501563 if (!done )
15511564 ch_logn (channel , "Dropping message %d without callback" , seq_nr );
@@ -1599,11 +1612,18 @@ may_invoke_callback(channel_T *channel, int part)
15991612 }
16001613 }
16011614 }
1615+
16021616 if (callback != NULL )
16031617 {
1604- /* invoke the channel callback */
1605- ch_logs (channel , "Invoking channel callback %s" , (char * )callback );
1606- invoke_callback (channel , callback , argv );
1618+ if (cbitem != NULL )
1619+ invoke_one_time_callback (channel , cbhead , cbitem , argv );
1620+ else
1621+ {
1622+ /* invoke the channel callback */
1623+ ch_logs (channel , "Invoking channel callback %s" ,
1624+ (char * )callback );
1625+ invoke_callback (channel , callback , argv );
1626+ }
16071627 }
16081628 }
16091629 else
0 commit comments