mirror of
https://github.com/neovim/neovim.git
synced 2025-10-07 02:16:31 +00:00
feat(ui): add 'winbar'
Adds support for a bar at the top of each window, enabled through the `'winbar'` option. Co-authored-by: Björn Linse <bjorn.linse@gmail.com>
This commit is contained in:
@@ -276,25 +276,25 @@ void redrawWinline(win_T *wp, linenr_T lnum)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* update all windows that are editing the current buffer
|
||||
*/
|
||||
void update_curbuf(int type)
|
||||
{
|
||||
redraw_curbuf_later(type);
|
||||
update_screen(type);
|
||||
}
|
||||
|
||||
/// called when the status bars for the buffer 'buf' need to be updated
|
||||
void redraw_buf_status_later(buf_T *buf)
|
||||
{
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_buffer == buf
|
||||
&& (wp->w_status_height || (wp == curwin && global_stl_height()))) {
|
||||
if (wp->w_buffer != buf) {
|
||||
continue;
|
||||
}
|
||||
bool redraw = false;
|
||||
|
||||
if (wp->w_status_height || (wp == curwin && global_stl_height())) {
|
||||
wp->w_redr_status = true;
|
||||
if (must_redraw < VALID) {
|
||||
must_redraw = VALID;
|
||||
}
|
||||
redraw = true;
|
||||
}
|
||||
if (wp->w_winbar_height) {
|
||||
wp->w_redr_winbar = true;
|
||||
redraw = true;
|
||||
}
|
||||
if (redraw && must_redraw < VALID) {
|
||||
must_redraw = VALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,6 +400,9 @@ int update_screen(int type)
|
||||
if (wp->w_floating) {
|
||||
continue;
|
||||
}
|
||||
if (wp->w_winrow + wp->w_winbar_height > valid) {
|
||||
wp->w_redr_winbar = true;
|
||||
}
|
||||
if (W_ENDROW(wp) > valid) {
|
||||
wp->w_redr_type = MAX(wp->w_redr_type, NOT_VALID);
|
||||
}
|
||||
@@ -431,6 +434,9 @@ int update_screen(int type)
|
||||
wp->w_redr_type = REDRAW_TOP;
|
||||
} else {
|
||||
wp->w_redr_type = NOT_VALID;
|
||||
if (wp->w_winrow + wp->w_winbar_height <= msg_scrolled) {
|
||||
wp->w_redr_winbar = true;
|
||||
}
|
||||
if (!is_stl_global && W_ENDROW(wp) + wp->w_status_height <= msg_scrolled) {
|
||||
wp->w_redr_status = true;
|
||||
}
|
||||
@@ -585,10 +591,13 @@ int update_screen(int type)
|
||||
win_update(wp, &providers);
|
||||
}
|
||||
|
||||
// redraw status line after the window to minimize cursor movement
|
||||
// redraw status line and window bar after the window to minimize cursor movement
|
||||
if (wp->w_redr_status) {
|
||||
win_redr_status(wp);
|
||||
}
|
||||
if (wp->w_redr_winbar) {
|
||||
win_redr_winbar(wp);
|
||||
}
|
||||
}
|
||||
|
||||
end_search_hl();
|
||||
@@ -743,6 +752,7 @@ static void win_update(win_T *wp, DecorProviders *providers)
|
||||
|
||||
if (type >= NOT_VALID) {
|
||||
wp->w_redr_status = true;
|
||||
wp->w_redr_winbar = true;
|
||||
wp->w_lines_valid = 0;
|
||||
}
|
||||
|
||||
@@ -4528,42 +4538,55 @@ void rl_mirror(char_u *str)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mark all status lines for redraw; used after first :cd
|
||||
*/
|
||||
/// Mark all status lines and window bars for redraw; used after first :cd
|
||||
void status_redraw_all(void)
|
||||
{
|
||||
if (global_stl_height()) {
|
||||
curwin->w_redr_status = true;
|
||||
redraw_later(curwin, VALID);
|
||||
} else {
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_status_height) {
|
||||
wp->w_redr_status = true;
|
||||
redraw_later(wp, VALID);
|
||||
}
|
||||
bool is_stl_global = global_stl_height() != 0;
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
bool redraw = false;
|
||||
|
||||
if ((!is_stl_global && wp->w_status_height) || (is_stl_global && wp == curwin)) {
|
||||
wp->w_redr_status = true;
|
||||
redraw = true;
|
||||
}
|
||||
if (wp->w_winbar_height) {
|
||||
wp->w_redr_winbar = true;
|
||||
redraw = true;
|
||||
}
|
||||
if (redraw) {
|
||||
redraw_later(wp, VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks all status lines of the current buffer for redraw.
|
||||
/// Marks all status lines and window bars of the current buffer for redraw.
|
||||
void status_redraw_curbuf(void)
|
||||
{
|
||||
status_redraw_buf(curbuf);
|
||||
}
|
||||
|
||||
/// Marks all status lines of the specified buffer for redraw.
|
||||
/// Marks all status lines and window bars of the given buffer for redraw.
|
||||
void status_redraw_buf(buf_T *buf)
|
||||
{
|
||||
if (global_stl_height() != 0 && curwin->w_buffer == buf) {
|
||||
curwin->w_redr_status = true;
|
||||
redraw_later(curwin, VALID);
|
||||
} else {
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_status_height != 0 && wp->w_buffer == buf) {
|
||||
wp->w_redr_status = true;
|
||||
redraw_later(wp, VALID);
|
||||
}
|
||||
bool is_stl_global = global_stl_height() != 0;
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_buffer != buf) {
|
||||
continue;
|
||||
}
|
||||
bool redraw = false;
|
||||
|
||||
if ((!is_stl_global && wp->w_status_height) || (is_stl_global && wp == curwin)) {
|
||||
wp->w_redr_status = true;
|
||||
redraw = true;
|
||||
}
|
||||
if (wp->w_winbar_height) {
|
||||
wp->w_redr_winbar = true;
|
||||
redraw = true;
|
||||
}
|
||||
if (redraw) {
|
||||
redraw_later(wp, VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4577,6 +4600,9 @@ void redraw_statuslines(void)
|
||||
if (wp->w_redr_status) {
|
||||
win_redr_status(wp);
|
||||
}
|
||||
if (wp->w_redr_winbar) {
|
||||
win_redr_winbar(wp);
|
||||
}
|
||||
}
|
||||
if (redraw_tabline) {
|
||||
draw_tabline();
|
||||
@@ -5075,7 +5101,7 @@ static void redraw_custom_statusline(win_T *wp)
|
||||
entered = true;
|
||||
|
||||
did_emsg = false;
|
||||
win_redr_custom(wp, false);
|
||||
win_redr_custom(wp, false, false);
|
||||
if (did_emsg) {
|
||||
// When there is an error disable the statusline, otherwise the
|
||||
// display is messed up with errors and a redraw triggers the problem
|
||||
@@ -5088,6 +5114,41 @@ static void redraw_custom_statusline(win_T *wp)
|
||||
entered = false;
|
||||
}
|
||||
|
||||
static void win_redr_winbar(win_T *wp)
|
||||
{
|
||||
static bool entered = false;
|
||||
|
||||
// Return when called recursively. This can happen when the winbar contains an expression
|
||||
// that triggers a redraw.
|
||||
if (entered) {
|
||||
return;
|
||||
}
|
||||
entered = true;
|
||||
|
||||
wp->w_redr_winbar = false;
|
||||
if (wp->w_winbar_height == 0) {
|
||||
// No window bar, do nothing.
|
||||
} else if (!redrawing()) {
|
||||
// Don't redraw right now, do it later.
|
||||
wp->w_redr_winbar = true;
|
||||
} else if (*p_wbr != NUL || *wp->w_p_wbr != NUL) {
|
||||
int saved_did_emsg = did_emsg;
|
||||
|
||||
did_emsg = false;
|
||||
win_redr_custom(wp, true, false);
|
||||
if (did_emsg) {
|
||||
// When there is an error disable the winbar, otherwise the
|
||||
// display is messed up with errors and a redraw triggers the problem
|
||||
// again and again.
|
||||
set_string_option_direct("winbar", -1, (char_u *)"",
|
||||
OPT_FREE | (*wp->w_p_stl != NUL
|
||||
? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
|
||||
}
|
||||
did_emsg |= saved_did_emsg;
|
||||
}
|
||||
entered = false;
|
||||
}
|
||||
|
||||
/// Only call if (wp->w_vsep_width != 0).
|
||||
///
|
||||
/// @return true if the status line of window "wp" is connected to the status
|
||||
@@ -5224,11 +5285,9 @@ bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len)
|
||||
return buf[0] != NUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Redraw the status line or ruler of window "wp".
|
||||
* When "wp" is NULL redraw the tab pages line from 'tabline'.
|
||||
*/
|
||||
static void win_redr_custom(win_T *wp, bool draw_ruler)
|
||||
/// Redraw the status line, window bar or ruler of window "wp".
|
||||
/// When "wp" is NULL redraw the tab pages line from 'tabline'.
|
||||
static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
|
||||
{
|
||||
static bool entered = false;
|
||||
int attr;
|
||||
@@ -5269,6 +5328,14 @@ static void win_redr_custom(win_T *wp, bool draw_ruler)
|
||||
attr = HL_ATTR(HLF_TPF);
|
||||
maxwidth = Columns;
|
||||
use_sandbox = was_set_insecurely(wp, "tabline", 0);
|
||||
} else if (draw_winbar) {
|
||||
stl = (char_u *)((*wp->w_p_wbr != NUL) ? wp->w_p_wbr : p_wbr);
|
||||
row = wp->w_winrow;
|
||||
col = wp->w_wincol;
|
||||
fillchar = wp->w_p_fcs_chars.wbr;
|
||||
attr = (wp == curwin) ? HL_ATTR(HLF_WBR) : HL_ATTR(HLF_WBRNC);
|
||||
maxwidth = wp->w_width_inner;
|
||||
use_sandbox = was_set_insecurely(wp, "winbar", 0);
|
||||
} else {
|
||||
row = is_stl_global ? (Rows - p_ch - 1) : W_ENDROW(wp);
|
||||
fillchar = fillchar_status(&attr, wp);
|
||||
@@ -5553,14 +5620,17 @@ void win_grid_alloc(win_T *wp)
|
||||
grid->Rows = rows;
|
||||
grid->Columns = cols;
|
||||
|
||||
wp->w_winrow_off = wp->w_border_adj[0] + wp->w_winbar_height;
|
||||
wp->w_wincol_off = wp->w_border_adj[3];
|
||||
|
||||
if (want_allocation) {
|
||||
grid->target = grid_allocated;
|
||||
grid->row_offset = wp->w_border_adj[0];
|
||||
grid->col_offset = wp->w_border_adj[3];
|
||||
grid->row_offset = wp->w_winrow_off;
|
||||
grid->col_offset = wp->w_wincol_off;
|
||||
} else {
|
||||
grid->target = &default_grid;
|
||||
grid->row_offset = wp->w_winrow;
|
||||
grid->col_offset = wp->w_wincol;
|
||||
grid->row_offset = wp->w_winrow + wp->w_winrow_off;
|
||||
grid->col_offset = wp->w_wincol + wp->w_wincol_off;
|
||||
}
|
||||
|
||||
// send grid resize event if:
|
||||
@@ -6220,7 +6290,7 @@ void draw_tabline(void)
|
||||
// Check for an error. If there is one we would loop in redrawing the
|
||||
// screen. Avoid that by making 'tabline' empty.
|
||||
did_emsg = false;
|
||||
win_redr_custom(NULL, false);
|
||||
win_redr_custom(NULL, false, false);
|
||||
if (did_emsg) {
|
||||
set_string_option_direct("tabline", -1,
|
||||
(char_u *)"", OPT_FREE, SID_ERROR);
|
||||
@@ -6516,7 +6586,7 @@ static void win_redr_ruler(win_T *wp, bool always)
|
||||
int save_called_emsg = called_emsg;
|
||||
|
||||
called_emsg = false;
|
||||
win_redr_custom(wp, true);
|
||||
win_redr_custom(wp, false, true);
|
||||
if (called_emsg) {
|
||||
set_string_option_direct("rulerformat", -1, (char_u *)"",
|
||||
OPT_FREE, SID_ERROR);
|
||||
|
Reference in New Issue
Block a user