@@ -292,14 +292,61 @@ void msg_multiline(String str, int hl_id, bool check_int, bool hist, bool *need_
292292// Avoid starting a new message for each chunk and adding message to history in msg_keep().
293293static bool is_multihl = false;
294294
295+ /// Format a progress message, adding title and percent if given.
296+ ///
297+ /// @param hl_msg Message chunks
298+ /// @param msg_data Additional data for progress messages
299+ static HlMessage format_progress_message (HlMessage hl_msg , MessageData * msg_data )
300+ {
301+ HlMessage updated_msg = KV_INITIAL_VALUE ;
302+ // progress messages are special. displayed as "title: percent% msg"
303+ if (msg_data -> title .size != 0 ) {
304+ // this block draws the "title:" before the progress-message
305+ int hl_id = 0 ;
306+ if (msg_data -> status .data == NULL ) {
307+ hl_id = 0 ;
308+ } else if (strequal (msg_data -> status .data , "success" )) {
309+ hl_id = syn_check_group ("OkMsg" , STRLEN_LITERAL ("OkMsg" ));
310+ } else if (strequal (msg_data -> status .data , "failed" )) {
311+ hl_id = syn_check_group ("ErrorMsg" , STRLEN_LITERAL ("ErrorMsg" ));
312+ } else if (strequal (msg_data -> status .data , "running" )) {
313+ hl_id = syn_check_group ("MoreMsg" , STRLEN_LITERAL ("MoreMsg" ));
314+ } else if (strequal (msg_data -> status .data , "cancel" )) {
315+ hl_id = syn_check_group ("WarningMsg" , STRLEN_LITERAL ("WarningMsg" ));
316+ }
317+ kv_push (updated_msg ,
318+ ((HlMessageChunk ){ .text = copy_string (msg_data -> title , NULL ), .hl_id = hl_id }));
319+ kv_push (updated_msg , ((HlMessageChunk ){ .text = cstr_to_string (": " ), .hl_id = 0 }));
320+ }
321+ if (msg_data -> percent > 0 ) {
322+ char percent_buf [10 ];
323+ vim_snprintf (percent_buf , sizeof (percent_buf ), "%3ld%% " , (long )msg_data -> percent );
324+ String percent = cstr_to_string (percent_buf );
325+ int hl_id = syn_check_group ("WarningMsg" , STRLEN_LITERAL ("WarningMsg" ));
326+ kv_push (updated_msg , ((HlMessageChunk ){ .text = percent , .hl_id = hl_id }));
327+ }
328+
329+ if (kv_size (updated_msg ) != 0 ) {
330+ for (uint32_t i = 0 ; i < kv_size (hl_msg ); i ++ ) {
331+ kv_push (updated_msg ,
332+ ((HlMessageChunk ){ .text = copy_string (kv_A (hl_msg , i ).text , NULL ),
333+ .hl_id = kv_A (hl_msg , i ).hl_id }));
334+ }
335+ return updated_msg ;
336+ } else {
337+ return hl_msg ;
338+ }
339+ }
340+
295341/// Print message chunks, each with their own highlight ID.
296342///
297343/// @param hl_msg Message chunks
298344/// @param kind Message kind (can be NULL to avoid setting kind)
299345/// @param history Whether to add message to history
300346/// @param err Whether to print message as an error
347+ /// @param msg_data Additional data for progress messages
301348MsgID msg_multihl (MsgID id , HlMessage hl_msg , const char * kind , bool history , bool err ,
302- MessageData * msg_data )
349+ MessageData * msg_data , bool * needs_msg_clear )
303350{
304351 no_wait_return ++ ;
305352 msg_start ();
@@ -311,7 +358,6 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
311358 }
312359 is_multihl = true;
313360 msg_ext_skip_flush = true;
314- bool is_progress = strequal (kind , "progress" );
315361
316362 // provide a new id if not given
317363 if (id .type == kObjectTypeNil ) {
@@ -323,12 +369,13 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
323369 }
324370 }
325371
326- // progress message are special displayed as "title: msg...percent%"
327- if (is_progress && msg_data && msg_data -> title .size != 0 ) {
328- // this block draws the "title:" before the progress-message
329- String title = cstr_as_string (concat_str (msg_data -> title .data , ": " ));
330- msg_multiline (title , 0 , true, false, & need_clear );
331- api_free_string (title );
372+ // progress message are special displayed as "title: percent% msg"
373+ if (strequal (kind , "progress" ) && msg_data ) {
374+ HlMessage formated_message = format_progress_message (hl_msg , msg_data );
375+ if (formated_message .items != hl_msg .items ) {
376+ * needs_msg_clear = true;
377+ hl_msg = formated_message ;
378+ }
332379 }
333380
334381 for (uint32_t i = 0 ; i < kv_size (hl_msg ); i ++ ) {
@@ -341,12 +388,6 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
341388 assert (!ui_has (kUIMessages ) || kind == NULL || msg_ext_kind == kind );
342389 }
343390
344- if (is_progress && msg_data && msg_data -> percent > 0 ) {
345- // this block draws the "...percent%" before the progress-message
346- char percent_buf [10 ];
347- vim_snprintf (percent_buf , sizeof (percent_buf ), "...%ld%%" , (long )msg_data -> percent );
348- msg_multiline (cstr_as_string (percent_buf ), 0 , true, false, & need_clear );
349- }
350391 if (history && kv_size (hl_msg )) {
351392 msg_hist_add_multihl (id , hl_msg , false, msg_data );
352393 }
@@ -1265,7 +1306,8 @@ void ex_messages(exarg_T *eap)
12651306 }
12661307 if (redirecting () || !ui_has (kUIMessages )) {
12671308 msg_silent += ui_has (kUIMessages );
1268- msg_multihl (INTEGER_OBJ (0 ), p -> msg , p -> kind , false, false, NULL );
1309+ bool needs_clear = false;
1310+ msg_multihl (INTEGER_OBJ (0 ), p -> msg , p -> kind , false, false, NULL , & needs_clear );
12691311 msg_silent -= ui_has (kUIMessages );
12701312 }
12711313 }
0 commit comments