@@ -294,6 +294,13 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
294294 set_string_option_direct_in_win (wp , (char_u * )"wincolor" , -1 ,
295295 str , OPT_FREE |OPT_LOCAL , 0 );
296296
297+ str = dict_get_string (dict , (char_u * )"title" , FALSE);
298+ if (str != NULL )
299+ {
300+ vim_free (wp -> w_popup_title );
301+ wp -> w_popup_title = vim_strsave (str );
302+ }
303+
297304 wp -> w_firstline = dict_get_number (dict , (char_u * )"firstline" );
298305 if (wp -> w_firstline < 1 )
299306 wp -> w_firstline = 1 ;
@@ -531,6 +538,19 @@ popup_width(win_T *wp)
531538 + wp -> w_popup_padding [1 ] + wp -> w_popup_border [1 ];
532539}
533540
541+ /*
542+ * Get the padding plus border at the top, adjusted to 1 if there is a title.
543+ */
544+ static int
545+ popup_top_extra (win_T * wp )
546+ {
547+ int extra = wp -> w_popup_border [0 ] + wp -> w_popup_padding [0 ];
548+
549+ if (extra == 0 && wp -> w_popup_title != NULL && * wp -> w_popup_title != NUL )
550+ return 1 ;
551+ return extra ;
552+ }
553+
534554/*
535555 * Adjust the position and size of the popup to fit on the screen.
536556 */
@@ -543,7 +563,7 @@ popup_adjust_position(win_T *wp)
543563 int center_vert = FALSE;
544564 int center_hor = FALSE;
545565 int allow_adjust_left = !wp -> w_popup_fixed ;
546- int top_extra = wp -> w_popup_border [ 0 ] + wp -> w_popup_padding [ 0 ] ;
566+ int top_extra = popup_top_extra ( wp ) ;
547567 int right_extra = wp -> w_popup_border [1 ] + wp -> w_popup_padding [1 ];
548568 int bot_extra = wp -> w_popup_border [2 ] + wp -> w_popup_padding [2 ];
549569 int left_extra = wp -> w_popup_border [3 ] + wp -> w_popup_padding [3 ];
@@ -553,6 +573,7 @@ popup_adjust_position(win_T *wp)
553573 int org_wincol = wp -> w_wincol ;
554574 int org_width = wp -> w_width ;
555575 int org_height = wp -> w_height ;
576+ int minwidth ;
556577
557578 wp -> w_winrow = 0 ;
558579 wp -> w_wincol = 0 ;
@@ -646,8 +667,17 @@ popup_adjust_position(win_T *wp)
646667 break ;
647668 }
648669
649- if (wp -> w_minwidth > 0 && wp -> w_width < wp -> w_minwidth )
650- wp -> w_width = wp -> w_minwidth ;
670+ minwidth = wp -> w_minwidth ;
671+ if (wp -> w_popup_title != NULL && * wp -> w_popup_title != NUL )
672+ {
673+ int title_len = vim_strsize (wp -> w_popup_title ) + 2 - extra_width ;
674+
675+ if (minwidth < title_len )
676+ minwidth = title_len ;
677+ }
678+
679+ if (minwidth > 0 && wp -> w_width < minwidth )
680+ wp -> w_width = minwidth ;
651681 if (wp -> w_width > maxwidth )
652682 wp -> w_width = maxwidth ;
653683 if (center_hor )
@@ -1384,7 +1414,7 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
13841414 {
13851415 if (wp == NULL )
13861416 return ; // invalid {id}
1387- top_extra = wp -> w_popup_border [ 0 ] + wp -> w_popup_padding [ 0 ] ;
1417+ top_extra = popup_top_extra ( wp ) ;
13881418 left_extra = wp -> w_popup_border [3 ] + wp -> w_popup_padding [3 ];
13891419
13901420 dict = rettv -> vval .v_dict ;
@@ -1750,6 +1780,7 @@ update_popups(void (*win_update)(win_T *wp))
17501780 int left_off ;
17511781 int total_width ;
17521782 int total_height ;
1783+ int top_padding ;
17531784 int popup_attr ;
17541785 int border_attr [4 ];
17551786 int border_char [8 ];
@@ -1770,7 +1801,7 @@ update_popups(void (*win_update)(win_T *wp))
17701801
17711802 // adjust w_winrow and w_wincol for border and padding, since
17721803 // win_update() doesn't handle them.
1773- top_off = wp -> w_popup_padding [ 0 ] + wp -> w_popup_border [ 0 ] ;
1804+ top_off = popup_top_extra ( wp ) ;
17741805 left_off = wp -> w_popup_padding [3 ] + wp -> w_popup_border [3 ];
17751806 wp -> w_winrow += top_off ;
17761807 wp -> w_wincol += left_off ;
@@ -1783,7 +1814,7 @@ update_popups(void (*win_update)(win_T *wp))
17831814
17841815 total_width = wp -> w_popup_border [3 ] + wp -> w_popup_padding [3 ]
17851816 + wp -> w_width + wp -> w_popup_padding [1 ] + wp -> w_popup_border [1 ];
1786- total_height = wp -> w_popup_border [ 0 ] + wp -> w_popup_padding [ 0 ]
1817+ total_height = popup_top_extra ( wp )
17871818 + wp -> w_height + wp -> w_popup_padding [2 ] + wp -> w_popup_border [2 ];
17881819 popup_attr = get_wcr_attr (wp );
17891820
@@ -1816,6 +1847,7 @@ update_popups(void (*win_update)(win_T *wp))
18161847 border_attr [i ] = syn_name2attr (wp -> w_border_highlight [i ]);
18171848 }
18181849
1850+ top_padding = wp -> w_popup_padding [0 ];
18191851 if (wp -> w_popup_border [0 ] > 0 )
18201852 {
18211853 // top border
@@ -1832,17 +1864,24 @@ update_popups(void (*win_update)(win_T *wp))
18321864 wp -> w_wincol + total_width - 1 , border_attr [1 ]);
18331865 }
18341866 }
1867+ else if (wp -> w_popup_padding [0 ] == 0 && popup_top_extra (wp ) > 0 )
1868+ top_padding = 1 ;
18351869
1836- if (wp -> w_popup_padding [ 0 ] > 0 )
1870+ if (top_padding > 0 )
18371871 {
18381872 // top padding
18391873 row = wp -> w_winrow + wp -> w_popup_border [0 ];
1840- screen_fill (row , row + wp -> w_popup_padding [ 0 ] ,
1874+ screen_fill (row , row + top_padding ,
18411875 wp -> w_wincol + wp -> w_popup_border [3 ],
18421876 wp -> w_wincol + total_width - wp -> w_popup_border [1 ],
18431877 ' ' , ' ' , popup_attr );
18441878 }
18451879
1880+ // Title goes on top of border or padding.
1881+ if (wp -> w_popup_title != NULL )
1882+ screen_puts (wp -> w_popup_title , wp -> w_winrow , wp -> w_wincol + 1 ,
1883+ wp -> w_popup_border [0 ] > 0 ? border_attr [0 ] : popup_attr );
1884+
18461885 for (row = wp -> w_winrow + wp -> w_popup_border [0 ];
18471886 row < wp -> w_winrow + total_height - wp -> w_popup_border [2 ];
18481887 ++ row )
0 commit comments