diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/win_config.c | 18 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 11 | ||||
-rw-r--r-- | src/nvim/fold.c | 2 | ||||
-rw-r--r-- | src/nvim/generators/gen_options.lua | 17 | ||||
-rw-r--r-- | src/nvim/getchar.c | 8 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 7 | ||||
-rw-r--r-- | src/nvim/option.c | 65 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 6 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 10 | ||||
-rw-r--r-- | src/nvim/terminal.c | 45 | ||||
-rw-r--r-- | src/nvim/vterm/screen.c | 12 | ||||
-rw-r--r-- | src/nvim/vterm/state.c | 19 | ||||
-rw-r--r-- | src/nvim/vterm/vterm_defs.h | 3 | ||||
-rw-r--r-- | src/nvim/vterm/vterm_internal_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/window.c | 6 | ||||
-rw-r--r-- | src/nvim/winfloat.c | 9 |
17 files changed, 135 insertions, 106 deletions
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 45c9e3f56c..225189a3f9 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -101,10 +101,12 @@ /// @param config Map defining the window configuration. Keys: /// - relative: Sets the window layout to "floating", placed at (row,col) /// coordinates relative to: -/// - "editor" The global editor grid -/// - "win" Window given by the `win` field, or current window. -/// - "cursor" Cursor position in current window. -/// - "mouse" Mouse position +/// - "cursor" Cursor position in current window. +/// - "editor" The global editor grid. +/// - "laststatus" 'laststatus' if present, or last row. +/// - "mouse" Mouse position. +/// - "tabline" Tabline if present, or first row. +/// - "win" Window given by the `win` field, or current window. /// - win: |window-ID| window to split, or relative window when creating a /// float (relative="win"). /// - anchor: Decides which corner of the float to place at (row,col): @@ -699,7 +701,9 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err) FUNC_API_SINCE(6) { /// Keep in sync with FloatRelative in buffer_defs.h - static const char *const float_relative_str[] = { "editor", "win", "cursor", "mouse" }; + static const char *const float_relative_str[] = { + "editor", "win", "cursor", "mouse", "tabline", "laststatus" + }; /// Keep in sync with WinSplit in buffer_defs.h static const char *const win_split_str[] = { "left", "right", "above", "below" }; @@ -805,6 +809,10 @@ static bool parse_float_relative(String relative, FloatRelative *out) *out = kFloatRelativeCursor; } else if (striequal(str, "mouse")) { *out = kFloatRelativeMouse; + } else if (striequal(str, "tabline")) { + *out = kFloatRelativeTabline; + } else if (striequal(str, "laststatus")) { + *out = kFloatRelativeLaststatus; } else { return false; } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3fe44beab9..bffb29578f 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -900,6 +900,8 @@ typedef enum { kFloatRelativeWindow = 1, kFloatRelativeCursor = 2, kFloatRelativeMouse = 3, + kFloatRelativeTabline = 4, + kFloatRelativeLaststatus = 5, } FloatRelative; /// Keep in sync with win_split_str[] in nvim_win_get_config() (api/win_config.c) diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index b9b5a055fb..012d23b567 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -843,11 +843,10 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, goto theend; } - // Don't assume current and new values are of the same type in order to future-proof the code for - // when an option can have multiple types. - const bool is_num = ((curval.type == kOptValTypeNumber || curval.type == kOptValTypeBoolean) - && (newval.type == kOptValTypeNumber || newval.type == kOptValTypeBoolean)); - const bool is_string = curval.type == kOptValTypeString && newval.type == kOptValTypeString; + // Current value and new value must have the same type. + assert(curval.type == newval.type); + const bool is_num = curval.type == kOptValTypeNumber || curval.type == kOptValTypeBoolean; + const bool is_string = curval.type == kOptValTypeString; if (op != NULL && *op != '=') { if (!hidden && is_num) { // number or bool @@ -1900,8 +1899,6 @@ static void getwinvar(typval_T *argvars, typval_T *rettv, int off) /// /// @return Typval converted to OptVal. Must be freed by caller. /// Returns NIL_OPTVAL for invalid option name. -/// -/// TODO(famiu): Refactor this to support multitype options. static OptVal tv_to_optval(typval_T *tv, OptIndex opt_idx, const char *option, bool *error) { OptVal value = NIL_OPTVAL; diff --git a/src/nvim/fold.c b/src/nvim/fold.c index c9699cb161..b59933d600 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1658,7 +1658,7 @@ static void foldDelMarker(buf_T *buf, linenr_T lnum, char *marker, size_t marker if (*cms != NUL) { // Also delete 'commentstring' if it matches. char *cms2 = strstr(cms, "%s"); - if (p - line >= cms2 - cms + if (cms2 != NULL && p - line >= cms2 - cms && strncmp(p - (cms2 - cms), cms, (size_t)(cms2 - cms)) == 0 && strncmp(p + len, cms2 + 2, strlen(cms2 + 2)) == 0) { p -= cms2 - cms; diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index c79683dc00..0298381ece 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -314,21 +314,6 @@ end --- @param o vim.option_meta --- @return string -local function get_type_flags(o) - local opt_types = (type(o.type) == 'table') and o.type or { o.type } - local type_flags = '0' - assert(type(opt_types) == 'table') - - for _, opt_type in ipairs(opt_types) do - assert(type(opt_type) == 'string') - type_flags = ('%s | (1 << %s)'):format(type_flags, opt_type_enum(opt_type)) - end - - return type_flags -end - ---- @param o vim.option_meta ---- @return string local function get_scope_flags(o) local scope_flags = '0' @@ -427,8 +412,8 @@ local function dump_option(i, o) if o.abbreviation then w(' .shortname=' .. cstr(o.abbreviation)) end + w(' .type=' .. opt_type_enum(o.type)) w(' .flags=' .. get_flags(o)) - w(' .type_flags=' .. get_type_flags(o)) w(' .scope_flags=' .. get_scope_flags(o)) w(' .scope_idx=' .. get_scope_idx(o)) if o.enable_if then diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 60aa1055c3..6cf4556a9f 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1518,9 +1518,11 @@ int merge_modifiers(int c_arg, int *modifiers) if (*modifiers & MOD_MASK_CTRL) { if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')) { - c &= 0x1f; - if (c == NUL) { - c = K_ZERO; + if (!(State & MODE_TERMINAL) || !(c == 'I' || c == 'J' || c == 'M' || c == '[')) { + c &= 0x1f; + if (c == NUL) { + c = K_ZERO; + } } } else if (c == '6') { // CTRL-6 is equivalent to CTRL-^ diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 9bd2baad27..3493384a8f 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -128,9 +128,9 @@ static const TSLanguage *load_language_from_object(lua_State *L, const char *pat { uv_lib_t lib; if (uv_dlopen(path, &lib)) { + xstrlcpy(IObuff, uv_dlerror(&lib), sizeof(IObuff)); uv_dlclose(&lib); - luaL_error(L, "Failed to load parser for language '%s': uv_dlopen: %s", - lang_name, uv_dlerror(&lib)); + luaL_error(L, "Failed to load parser for language '%s': uv_dlopen: %s", lang_name, IObuff); } char symbol_buf[128]; @@ -138,8 +138,9 @@ static const TSLanguage *load_language_from_object(lua_State *L, const char *pat TSLanguage *(*lang_parser)(void); if (uv_dlsym(&lib, symbol_buf, (void **)&lang_parser)) { + xstrlcpy(IObuff, uv_dlerror(&lib), sizeof(IObuff)); uv_dlclose(&lib); - luaL_error(L, "Failed to load parser: uv_dlsym: %s", uv_dlerror(&lib)); + luaL_error(L, "Failed to load parser: uv_dlsym: %s", IObuff); } TSLanguage *lang = lang_parser(); diff --git a/src/nvim/option.c b/src/nvim/option.c index 551ea0be20..593ac62172 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3121,17 +3121,10 @@ bool optval_equal(OptVal o1, OptVal o2) UNREACHABLE; } -/// Get type of option. Does not support multitype options. +/// Get type of option. static OptValType option_get_type(const OptIndex opt_idx) { - assert(!option_is_multitype(opt_idx)); - - // If the option only supports a single type, it means that the index of the option's type flag - // corresponds to the value of the type enum. So get the index of the type flag using xctz() and - // use that as the option's type. - OptValType type = xctz(options[opt_idx].type_flags); - assert(type > kOptValTypeNil && type < kOptValTypeSize); - return type; + return options[opt_idx].type; } /// Create OptVal from var pointer. @@ -3149,11 +3142,6 @@ OptVal optval_from_varp(OptIndex opt_idx, void *varp) return BOOLEAN_OPTVAL(curbufIsChanged()); } - if (option_is_multitype(opt_idx)) { - // Multitype options are stored as OptVal. - return *(OptVal *)varp; - } - OptValType type = option_get_type(opt_idx); switch (type) { @@ -3264,33 +3252,6 @@ OptVal object_as_optval(Object o, bool *error) UNREACHABLE; } -/// Get an allocated string containing a list of valid types for an option. -/// For options with a singular type, it returns the name of the type. For options with multiple -/// possible types, it returns a slash separated list of types. For example, if an option can be a -/// number, boolean or string, the function returns "number/boolean/string" -static char *option_get_valid_types(OptIndex opt_idx) -{ - StringBuilder str = KV_INITIAL_VALUE; - kv_resize(str, 32); - - // Iterate through every valid option value type and check if the option supports that type - for (OptValType type = 0; type < kOptValTypeSize; type++) { - if (option_has_type(opt_idx, type)) { - const char *typename = optval_type_get_name(type); - - if (str.size == 0) { - kv_concat(str, typename); - } else { - kv_printf(str, "/%s", typename); - } - } - } - - // Ensure that the string is NUL-terminated. - kv_push(str, NUL); - return str.items; -} - /// Check if option is hidden. /// /// @param opt_idx Option index in options[] table. @@ -3303,25 +3264,10 @@ bool is_option_hidden(OptIndex opt_idx) && options[opt_idx].var == &options[opt_idx].def_val.data; } -/// Check if option is multitype (supports multiple types). -static bool option_is_multitype(OptIndex opt_idx) -{ - const OptTypeFlags type_flags = get_option(opt_idx)->type_flags; - assert(type_flags != 0); - return !is_power_of_two(type_flags); -} - /// Check if option supports a specific type. bool option_has_type(OptIndex opt_idx, OptValType type) { - // Ensure that type flags variable can hold all types. - STATIC_ASSERT(kOptValTypeSize <= sizeof(OptTypeFlags) * 8, - "Option type_flags cannot fit all option types"); - // Ensure that the type is valid before accessing type_flags. - assert(type > kOptValTypeNil && type < kOptValTypeSize); - // Bitshift 1 by the value of type to get the type's corresponding flag, and check if it's set in - // the type_flags bit field. - return get_option(opt_idx)->type_flags & (1 << type); + return options[opt_idx].type == type; } /// Check if option supports a specific scope. @@ -3658,11 +3604,10 @@ static const char *validate_option_value(const OptIndex opt_idx, OptVal *newval, } } else if (!option_has_type(opt_idx, newval->type)) { char *rep = optval_to_cstr(*newval); - char *valid_types = option_get_valid_types(opt_idx); + const char *type_str = optval_type_get_name(opt->type); snprintf(errbuf, IOSIZE, _("Invalid value for option '%s': expected %s, got %s %s"), - opt->fullname, valid_types, optval_type_get_name(newval->type), rep); + opt->fullname, type_str, optval_type_get_name(newval->type), rep); xfree(rep); - xfree(valid_types); errmsg = errbuf; } else if (newval->type == kOptValTypeNumber) { // Validate and bound check num option values. diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 832e03148a..2b51547004 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -54,9 +54,6 @@ typedef enum { kOptValTypeNumber, kOptValTypeString, } OptValType; -/// Always update this whenever a new option type is added. -#define kOptValTypeSize (kOptValTypeString + 1) -typedef uint32_t OptTypeFlags; /// Scopes that an option can support. typedef enum { @@ -99,7 +96,6 @@ typedef struct { int os_flags; /// Old value of the option. - /// TODO(famiu): Convert `os_oldval` and `os_newval` to `OptVal` to accommodate multitype options. OptValData os_oldval; /// New value of the option. OptValData os_newval; @@ -173,7 +169,7 @@ typedef struct { char *fullname; ///< full option name char *shortname; ///< permissible abbreviation uint32_t flags; ///< see above - OptTypeFlags type_flags; ///< option type flags, see OptValType + OptValType type; ///< option type OptScopeFlags scope_flags; ///< option scope flags, see OptScope void *var; ///< global option: pointer to variable; ///< window-local option: NULL; diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index eac9ea02e0..93871905db 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -44,6 +44,7 @@ #include "nvim/spellfile.h" #include "nvim/spellsuggest.h" #include "nvim/strings.h" +#include "nvim/terminal.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" #include "nvim/window.h" @@ -532,6 +533,15 @@ const char *did_set_background(optset_T *args) check_string_option(&p_bg); init_highlight(false, false); } + + // Notify all terminal buffers that the background color changed so they can + // send a theme update notification + FOR_ALL_BUFFERS(buf) { + if (buf->terminal) { + terminal_notify_theme(buf->terminal, dark); + } + } + return NULL; } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index d7ed709906..2ad5ac49ca 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -179,6 +179,8 @@ struct terminal { StringBuilder *send; ///< When there is a pending TermRequest autocommand, block and store input. } pending; + bool theme_updates; ///< Send a theme update notification when 'bg' changes + bool color_set[16]; char *selection_buffer; /// libvterm selection buffer @@ -193,6 +195,7 @@ static VTermScreenCallbacks vterm_screen_callbacks = { .movecursor = term_movecursor, .settermprop = term_settermprop, .bell = term_bell, + .theme = term_theme, .sb_pushline = term_sb_push, // Called before a line goes offscreen. .sb_popline = term_sb_pop, }; @@ -1011,7 +1014,7 @@ static void terminal_send_key(Terminal *term, int c) c = Ctrl_AT; } - VTermKey key = convert_key(c, &mod); + VTermKey key = convert_key(&c, &mod); if (key) { vterm_keyboard_key(term->vt, key, mod); @@ -1141,6 +1144,20 @@ bool terminal_running(const Terminal *term) return !term->closed; } +void terminal_notify_theme(Terminal *term, bool dark) + FUNC_ATTR_NONNULL_ALL +{ + if (!term->theme_updates) { + return; + } + + char buf[10]; + ssize_t ret = snprintf(buf, sizeof(buf), "\x1b[997;%cn", dark ? '1' : '2'); + assert(ret > 0); + assert((size_t)ret <= sizeof(buf)); + terminal_send(term, buf, (size_t)ret); +} + static void terminal_focus(const Terminal *term, bool focus) FUNC_ATTR_NONNULL_ALL { @@ -1259,6 +1276,10 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data) invalidate_terminal(term, -1, -1); break; + case VTERM_PROP_THEMEUPDATES: + term->theme_updates = val->boolean; + break; + default: return 0; } @@ -1273,6 +1294,14 @@ static int term_bell(void *data) return 1; } +/// Called when the terminal wants to query the system theme. +static int term_theme(bool *dark, void *data) + FUNC_ATTR_NONNULL_ALL +{ + *dark = (*p_bg == 'd'); + return 1; +} + /// Scrollback push handler: called just before a line goes offscreen (and libvterm will forget it), /// giving us a chance to store it. /// @@ -1415,19 +1444,23 @@ static int term_selection_set(VTermSelectionMask mask, VTermStringFragment frag, // }}} // input handling {{{ -static void convert_modifiers(int key, VTermModifier *statep) +static void convert_modifiers(int *key, VTermModifier *statep) { if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; } if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; + if (!(mod_mask & MOD_MASK_SHIFT) && *key >= 'A' && *key <= 'Z') { + // vterm interprets CTRL+A as SHIFT+CTRL, change to CTRL+a + *key += ('a' - 'A'); + } } if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } - switch (key) { + switch (*key) { case K_S_TAB: case K_S_UP: case K_S_DOWN: @@ -1459,11 +1492,11 @@ static void convert_modifiers(int key, VTermModifier *statep) } } -static VTermKey convert_key(int key, VTermModifier *statep) +static VTermKey convert_key(int *key, VTermModifier *statep) { convert_modifiers(key, statep); - switch (key) { + switch (*key) { case K_BS: return VTERM_KEY_BACKSPACE; case K_S_TAB: @@ -1791,7 +1824,7 @@ static bool send_mouse_event(Terminal *term, int c) } VTermModifier mod = VTERM_MOD_NONE; - convert_modifiers(c, &mod); + convert_modifiers(&c, &mod); mouse_action(term, button, row, col - offset, pressed, mod); return false; } diff --git a/src/nvim/vterm/screen.c b/src/nvim/vterm/screen.c index c91c6fb84f..45bd5e2a27 100644 --- a/src/nvim/vterm/screen.c +++ b/src/nvim/vterm/screen.c @@ -784,6 +784,17 @@ static int resize(int new_rows, int new_cols, VTermStateFields *fields, void *us return 1; } +static int theme(bool *dark, void *user) +{ + VTermScreen *screen = user; + + if (screen->callbacks && screen->callbacks->theme) { + return (*screen->callbacks->theme)(dark, screen->cbdata); + } + + return 1; +} + static int setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user) { @@ -838,6 +849,7 @@ static VTermStateCallbacks state_cbs = { .settermprop = &settermprop, .bell = &bell, .resize = &resize, + .theme = &theme, .setlineinfo = &setlineinfo, .sb_clear = &sb_clear, }; diff --git a/src/nvim/vterm/state.c b/src/nvim/vterm/state.c index 9e787acd9b..4ad07377de 100644 --- a/src/nvim/vterm/state.c +++ b/src/nvim/vterm/state.c @@ -819,6 +819,10 @@ static void set_dec_mode(VTermState *state, int num, int val) state->mode.bracketpaste = (unsigned)val; break; + case 2031: + settermprop_bool(state, VTERM_PROP_THEMEUPDATES, val); + break; + default: DEBUG_LOG("libvterm: Unknown DEC mode %d\n", num); return; @@ -894,6 +898,10 @@ static void request_dec_mode(VTermState *state, int num) reply = state->mode.bracketpaste; break; + case 2031: + reply = state->mode.theme_updates; + break; + default: vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "?%d;%d$y", num, 0); return; @@ -1387,6 +1395,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha { char *qmark = (leader_byte == '?') ? "?" : ""; + bool dark = false; switch (val) { case 0: @@ -1403,6 +1412,13 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "%s%d;%dR", qmark, state->pos.row + 1, state->pos.col + 1); break; + case 996: + if (state->callbacks && state->callbacks->theme) { + if (state->callbacks->theme(&dark, state->cbdata)) { + vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "?997;%cn", dark ? '1' : '2'); + } + } + break; } } break; @@ -2268,6 +2284,9 @@ int vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val) case VTERM_PROP_FOCUSREPORT: state->mode.report_focus = (unsigned)val->boolean; return 1; + case VTERM_PROP_THEMEUPDATES: + state->mode.theme_updates = (unsigned)val->boolean; + return 1; case VTERM_N_PROPS: return 0; diff --git a/src/nvim/vterm/vterm_defs.h b/src/nvim/vterm/vterm_defs.h index d0a8ba8814..9aa933bef0 100644 --- a/src/nvim/vterm/vterm_defs.h +++ b/src/nvim/vterm/vterm_defs.h @@ -86,6 +86,7 @@ typedef enum { VTERM_PROP_CURSORSHAPE, // number VTERM_PROP_MOUSE, // number VTERM_PROP_FOCUSREPORT, // bool + VTERM_PROP_THEMEUPDATES, // bool VTERM_N_PROPS, } VTermProp; @@ -111,6 +112,7 @@ typedef struct { int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, void *user); + int (*theme)(bool *dark, void *user); int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user); int (*sb_popline)(int cols, VTermScreenCell *cells, void *user); int (*sb_clear)(void *user); @@ -263,6 +265,7 @@ typedef struct { int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, VTermStateFields *fields, void *user); + int (*theme)(bool *dark, void *user); int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user); int (*sb_clear)(void *user); diff --git a/src/nvim/vterm/vterm_internal_defs.h b/src/nvim/vterm/vterm_internal_defs.h index 770f862ce3..d4d59867bf 100644 --- a/src/nvim/vterm/vterm_internal_defs.h +++ b/src/nvim/vterm/vterm_internal_defs.h @@ -119,6 +119,7 @@ struct VTermState { unsigned leftrightmargin:1; unsigned bracketpaste:1; unsigned report_focus:1; + unsigned theme_updates:1; } mode; VTermEncodingInstance encoding[4], encoding_utf8; diff --git a/src/nvim/window.c b/src/nvim/window.c index 68f45ec5ba..1c0d8c1027 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -835,6 +835,10 @@ void ui_ext_win_position(win_T *wp, bool validate) col += tcol - 1; } } + } else if (c.relative == kFloatRelativeLaststatus) { + row += Rows - (int)p_ch - last_stl_height(false); + } else if (c.relative == kFloatRelativeTabline) { + row += tabline_height(); } bool resort = wp->w_grid_alloc.comp_index != 0 @@ -1066,6 +1070,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl return NULL; } need_status = STATUS_HEIGHT; + win_float_anchor_laststatus(); } bool do_equal = false; @@ -6803,6 +6808,7 @@ void last_status(bool morewin) { // Don't make a difference between horizontal or vertical split. last_status_rec(topframe, last_stl_height(morewin) > 0, global_stl_height() > 0); + win_float_anchor_laststatus(); } // Remove status line from window, replacing it with a horizontal separator if needed. diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 3e791e2beb..d11b965dfc 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -307,6 +307,15 @@ void win_check_anchored_floats(win_T *win) } } +void win_float_anchor_laststatus(void) +{ + FOR_ALL_WINDOWS_IN_TAB(win, curtab) { + if (win->w_config.relative == kFloatRelativeLaststatus) { + win->w_pos_changed = true; + } + } +} + void win_reconfig_floats(void) { for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { |