@@ -66,7 +66,6 @@ typedef enum {
6666/// If inversion is possible we use it. Else '=' characters are used.
6767void win_redr_status (win_T * wp )
6868{
69- int attr ;
7069 bool is_stl_global = global_stl_height () > 0 ;
7170 static bool busy = false;
7271
@@ -92,15 +91,16 @@ void win_redr_status(win_T *wp)
9291 redraw_custom_statusline (wp );
9392 }
9493
94+ hlf_T group = HLF_C ;
9595 // May need to draw the character below the vertical separator.
9696 if (wp -> w_vsep_width != 0 && wp -> w_status_height != 0 && redrawing ()) {
9797 schar_T fillchar ;
9898 if (stl_connected (wp )) {
99- fillchar = fillchar_status (& attr , wp );
99+ fillchar = fillchar_status (& group , wp );
100100 } else {
101- attr = win_hl_attr (wp , HLF_C );
102101 fillchar = wp -> w_p_fcs_chars .vert ;
103102 }
103+ int attr = win_hl_attr (wp , (int )group );
104104 grid_line_start (& default_gridview , W_ENDROW (wp ));
105105 grid_line_put_schar (W_ENDCOL (wp ), fillchar , attr );
106106 grid_line_flush ();
@@ -208,15 +208,17 @@ void stl_fill_click_defs(StlClickDefinition *click_defs, StlClickRecord *click_r
208208 }
209209}
210210
211- /// Redraw the status line, window bar or ruler of window "wp".
212- /// When "wp" is NULL redraw the tab pages line from 'tabline'.
213- static void win_redr_custom (win_T * wp , bool draw_winbar , bool draw_ruler )
211+ /// Redraw the status line, window bar, ruler or tabline.
212+ /// @param wp target window, NULL for 'tabline'
213+ /// @param draw_winbar redraw 'winbar'
214+ /// @param draw_ruler redraw 'rulerformat'
215+ /// @param ui_event emit UI-event instead of drawing
216+ static void win_redr_custom (win_T * wp , bool draw_winbar , bool draw_ruler , bool ui_event )
214217{
215218 static bool entered = false;
216- int attr ;
217- int row ;
218219 int col = 0 ;
219- int maxwidth ;
220+ int attr , row , maxwidth ;
221+ hlf_T group ;
220222 schar_T fillchar ;
221223 char buf [MAXPATHL ];
222224 char transbuf [MAXPATHL ];
@@ -243,7 +245,8 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
243245 stl = p_tal ;
244246 row = 0 ;
245247 fillchar = schar_from_ascii (' ' );
246- attr = HL_ATTR (HLF_TPF );
248+ group = HLF_TPF ;
249+ attr = HL_ATTR (group );
247250 maxwidth = Columns ;
248251 opt_idx = kOptTabline ;
249252 } else if (draw_winbar ) {
@@ -259,14 +262,15 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
259262 }
260263
261264 fillchar = wp -> w_p_fcs_chars .wbr ;
262- attr = (wp == curwin ) ? win_hl_attr (wp , HLF_WBR ) : win_hl_attr (wp , HLF_WBRNC );
265+ group = (wp == curwin ) ? HLF_WBR : HLF_WBRNC ;
266+ attr = win_hl_attr (wp , (int )group );
263267 maxwidth = wp -> w_view_width ;
264268 stl_clear_click_defs (wp -> w_winbar_click_defs , wp -> w_winbar_click_defs_size );
265269 wp -> w_winbar_click_defs = stl_alloc_click_defs (wp -> w_winbar_click_defs , maxwidth ,
266270 & wp -> w_winbar_click_defs_size );
267271 } else {
268272 row = is_stl_global ? (Rows - (int )p_ch - 1 ) : W_ENDROW (wp );
269- fillchar = fillchar_status (& attr , wp );
273+ fillchar = fillchar_status (& group , wp );
270274 const bool in_status_line = wp -> w_status_height != 0 || is_stl_global ;
271275 maxwidth = in_status_line && !is_stl_global ? wp -> w_width : Columns ;
272276 stl_clear_click_defs (wp -> w_status_click_defs , wp -> w_status_click_defs_size );
@@ -297,14 +301,15 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
297301 grid = grid_adjust (& msg_grid_adj , & row , & col );
298302 maxwidth -- ; // writing in last column may cause scrolling
299303 fillchar = schar_from_ascii (' ' );
300- attr = HL_ATTR ( HLF_MSG ) ;
304+ group = HLF_MSG ;
301305 }
302306 } else {
303307 opt_idx = kOptStatusline ;
304308 stl = ((* wp -> w_p_stl != NUL ) ? wp -> w_p_stl : p_stl );
305309 opt_scope = ((* wp -> w_p_stl != NUL ) ? OPT_LOCAL : 0 );
306310 }
307311
312+ attr = win_hl_attr (wp , (int )group );
308313 if (in_status_line && !is_stl_global ) {
309314 col += wp -> w_wincol ;
310315 }
@@ -332,31 +337,57 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
332337 int len = (int )strlen (buf );
333338 int start_col = col ;
334339
335- // Draw each snippet with the specified highlighting.
336- screengrid_line_start (grid , row , 0 );
340+ if (!ui_event ) {
341+ // Draw each snippet with the specified highlighting.
342+ screengrid_line_start (grid , row , 0 );
343+ }
337344
338- int curattr = attr ;
339345 char * p = buf ;
340- for (int n = 0 ; hltab [n ].start != NULL ; n ++ ) {
341- int textlen = (int )(hltab [n ].start - p );
342- // Make all characters printable.
343- size_t tsize = transstr_buf (p , textlen , transbuf , sizeof transbuf , true);
344- col += grid_line_puts (col , transbuf , (int )tsize , curattr );
345- p = hltab [n ].start ;
346-
347- if (hltab [n ].userhl == 0 ) {
346+ int curattr = attr ;
347+ int curgroup = (int )group ;
348+ Array content = ARRAY_DICT_INIT ;
349+ for (stl_hlrec_t * sp = hltab ;; sp ++ ) {
350+ int textlen = (int )(sp -> start ? sp -> start - p : buf + len - p );
351+ // Make all characters printable. Use an empty string instead of p, if p is beyond buf + len.
352+ size_t tsize = transstr_buf (p >= buf + len ? "" : p , textlen , transbuf , sizeof transbuf , true);
353+ if (!ui_event ) {
354+ col += grid_line_puts (col , transbuf , (int )tsize , curattr );
355+ } else {
356+ Array chunk = ARRAY_DICT_INIT ;
357+ ADD (chunk , INTEGER_OBJ (curattr ));
358+ ADD (chunk , STRING_OBJ (cbuf_as_string (xmemdupz (transbuf , tsize ), tsize )));
359+ ADD (chunk , INTEGER_OBJ (curgroup ));
360+ ADD (content , ARRAY_OBJ (chunk ));
361+ }
362+ p = sp -> start ;
363+
364+ if (p == NULL ) {
365+ break ;
366+ } else if (sp -> userhl == 0 ) {
348367 curattr = attr ;
349- } else if ( hltab [ n ]. userhl < 0 ) {
350- curattr = hl_combine_attr ( attr , syn_id2attr ( - hltab [ n ]. userhl ));
351- } else if ( wp != NULL && wp != curwin && wp -> w_status_height != 0 ) {
352- curattr = highlight_stlnc [ hltab [ n ]. userhl - 1 ] ;
368+ curgroup = ( int ) group ;
369+ } else if ( sp -> userhl < 0 ) {
370+ curattr = syn_id2attr ( - sp -> userhl );
371+ curgroup = - sp -> userhl ;
353372 } else {
354- curattr = highlight_user [hltab [n ].userhl - 1 ];
373+ int * userhl = (wp != NULL && wp != curwin && wp -> w_status_height != 0 )
374+ ? highlight_stlnc : highlight_user ;
375+ char userbuf [5 ] = "User" ;
376+ userbuf [4 ] = (char )sp -> userhl + '0' ;
377+ curattr = userhl [sp -> userhl - 1 ];
378+ curgroup = syn_name2id_len (userbuf , 5 );
379+ }
380+ if (curattr != attr ) {
381+ curattr = hl_combine_attr (attr , curattr );
355382 }
356383 }
357- // Make sure to use an empty string instead of p, if p is beyond buf + len.
358- size_t tsize = transstr_buf (p >= buf + len ? "" : p , -1 , transbuf , sizeof transbuf , true);
359- col += grid_line_puts (col , transbuf , (int )tsize , curattr );
384+
385+ if (ui_event ) {
386+ ui_call_msg_ruler (content );
387+ api_free_array (content );
388+ goto theend ;
389+ }
390+
360391 int maxcol = start_col + maxwidth ;
361392
362393 // fill up with "fillchar"
@@ -389,7 +420,7 @@ void win_redr_winbar(win_T *wp)
389420 if (wp -> w_winbar_height == 0 || !redrawing ()) {
390421 // Do nothing.
391422 } else if (* p_wbr != NUL || * wp -> w_p_wbr != NUL ) {
392- win_redr_custom (wp , true, false);
423+ win_redr_custom (wp , true, false, false );
393424 }
394425 entered = false;
395426}
@@ -423,43 +454,21 @@ void redraw_ruler(void)
423454
424455 // Don't draw the ruler while doing insert-completion, it might overwrite
425456 // the (long) mode message.
426- if (wp -> w_status_height == 0 && !is_stl_global ) {
427- if (edit_submode != NULL ) {
428- return ;
429- }
457+ if (wp -> w_status_height == 0 && !is_stl_global && edit_submode != NULL ) {
458+ return ;
430459 }
431460
432- if (* p_ruf && p_ch > 0 && !ui_has (kUIMessages )) {
433- win_redr_custom (wp , false, true);
461+ bool part_of_status = wp -> w_status_height || is_stl_global ;
462+ if (* p_ruf && (p_ch > 0 || (ui_has (kUIMessages ) && !part_of_status ))) {
463+ win_redr_custom (wp , false, true, ui_has (kUIMessages ));
434464 return ;
435465 }
436466
437- // Check if not in Insert mode and the line is empty (will show "0-1").
438- int empty_line = (State & MODE_INSERT ) == 0
439- && * ml_get_buf (wp -> w_buffer , wp -> w_cursor .lnum ) == NUL ;
440-
441- int width ;
442- schar_T fillchar ;
443- int attr ;
444- int off ;
445- bool part_of_status = false;
446-
447- if (wp -> w_status_height ) {
448- fillchar = fillchar_status (& attr , wp );
449- off = wp -> w_wincol ;
450- width = wp -> w_width ;
451- part_of_status = true;
452- } else if (is_stl_global ) {
453- fillchar = fillchar_status (& attr , wp );
454- off = 0 ;
455- width = Columns ;
456- part_of_status = true;
457- } else {
458- fillchar = schar_from_ascii (' ' );
459- attr = HL_ATTR (HLF_MSG );
460- width = Columns ;
461- off = 0 ;
462- }
467+ hlf_T group = HLF_MSG ;
468+ int off = wp -> w_status_height ? wp -> w_wincol : 0 ;
469+ int width = wp -> w_status_height ? wp -> w_width : Columns ;
470+ schar_T fillchar = part_of_status ? fillchar_status (& group , wp ) : schar_from_ascii (' ' );
471+ int attr = win_hl_attr (wp , (int )group );
463472
464473 // In list mode virtcol needs to be recomputed
465474 colnr_T virtcol = wp -> w_virtcol ;
@@ -469,6 +478,10 @@ void redraw_ruler(void)
469478 wp -> w_p_list = true;
470479 }
471480
481+ // Check if not in Insert mode and the line is empty (will show "0-1").
482+ int empty_line = (State & MODE_INSERT ) == 0
483+ && * ml_get_buf (wp -> w_buffer , wp -> w_cursor .lnum ) == NUL ;
484+
472485#define RULER_BUF_LEN 70
473486 char buffer [RULER_BUF_LEN ];
474487
@@ -542,13 +555,13 @@ void redraw_ruler(void)
542555}
543556
544557/// Get the character to use in a status line. Get its attributes in "*attr".
545- schar_T fillchar_status (int * attr , win_T * wp )
558+ schar_T fillchar_status (hlf_T * group , win_T * wp )
546559{
547560 if (wp == curwin ) {
548- * attr = win_hl_attr ( wp , HLF_S ) ;
561+ * group = HLF_S ;
549562 return wp -> w_p_fcs_chars .stl ;
550563 } else {
551- * attr = win_hl_attr ( wp , HLF_SNC ) ;
564+ * group = HLF_SNC ;
552565 return wp -> w_p_fcs_chars .stlnc ;
553566 }
554567}
@@ -566,7 +579,7 @@ void redraw_custom_statusline(win_T *wp)
566579 }
567580 entered = true;
568581
569- win_redr_custom (wp , false, false);
582+ win_redr_custom (wp , false, false, false );
570583 entered = false;
571584}
572585
@@ -644,7 +657,7 @@ void draw_tabline(void)
644657
645658 // Use the 'tabline' option if it's set.
646659 if (* p_tal != NUL ) {
647- win_redr_custom (NULL , false, false);
660+ win_redr_custom (NULL , false, false, false );
648661 } else {
649662 int tabcount = 0 ;
650663 int col = 0 ;
0 commit comments