mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
refactor: move some functions to winfloat.c (#26020)
This commit is contained in:
@ -25,6 +25,7 @@
|
||||
#include "nvim/syntax.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "api/win_config.c.generated.h"
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nvim/ui_compositor.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "auevents_name_map.generated.h"
|
||||
|
@ -101,6 +101,7 @@
|
||||
#include "nvim/version.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "buffer.c.generated.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "eval/window.c.generated.h"
|
||||
@ -635,7 +636,7 @@ void f_win_splitmove(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
|
||||
if (wp == NULL || targetwin == NULL || wp == targetwin
|
||||
|| !win_valid(wp) || !win_valid(targetwin)
|
||||
|| win_valid_floating(wp) || win_valid_floating(targetwin)) {
|
||||
|| win_float_valid(wp) || win_float_valid(targetwin)) {
|
||||
emsg(_(e_invalwindow));
|
||||
rettv->vval.v_number = -1;
|
||||
return;
|
||||
|
@ -83,6 +83,7 @@
|
||||
#include "nvim/usercmd.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
static const char e_ambiguous_use_of_user_defined_command[]
|
||||
= N_("E464: Ambiguous use of user-defined command");
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
typedef struct {
|
||||
linenr_T lnum; // line number
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "nvim/ui_compositor.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "ui.c.generated.h"
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "nvim/undo.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "window.c.generated.h"
|
||||
@ -734,204 +735,6 @@ void win_set_buf(win_T *win, buf_T *buf, bool noautocmd, Error *err)
|
||||
RedrawingDisabled--;
|
||||
}
|
||||
|
||||
/// Create a new float.
|
||||
///
|
||||
/// @param wp if NULL, allocate a new window, otherwise turn existing window into a float.
|
||||
/// It must then already belong to the current tabpage!
|
||||
/// @param last make the window the last one in the window list.
|
||||
/// Only used when allocating the autocommand window.
|
||||
/// @param config must already have been validated!
|
||||
win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err)
|
||||
{
|
||||
if (wp == NULL) {
|
||||
wp = win_alloc(last ? lastwin : lastwin_nofloating(), false);
|
||||
win_init(wp, curwin, 0);
|
||||
} else {
|
||||
assert(!last);
|
||||
assert(!wp->w_floating);
|
||||
if (firstwin == wp && lastwin_nofloating() == wp) {
|
||||
// last non-float
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change last window into float");
|
||||
return NULL;
|
||||
} else if (!win_valid(wp)) {
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change window from different tabpage into float");
|
||||
return NULL;
|
||||
}
|
||||
int dir;
|
||||
winframe_remove(wp, &dir, NULL);
|
||||
XFREE_CLEAR(wp->w_frame);
|
||||
(void)win_comp_pos(); // recompute window positions
|
||||
win_remove(wp, NULL);
|
||||
win_append(lastwin_nofloating(), wp);
|
||||
}
|
||||
wp->w_floating = true;
|
||||
wp->w_status_height = 0;
|
||||
wp->w_winbar_height = 0;
|
||||
wp->w_hsep_height = 0;
|
||||
wp->w_vsep_width = 0;
|
||||
|
||||
win_config_float(wp, fconfig);
|
||||
win_set_inner_size(wp, true);
|
||||
wp->w_pos_changed = true;
|
||||
redraw_later(wp, UPD_VALID);
|
||||
return wp;
|
||||
}
|
||||
|
||||
void win_set_minimal_style(win_T *wp)
|
||||
{
|
||||
wp->w_p_nu = false;
|
||||
wp->w_p_rnu = false;
|
||||
wp->w_p_cul = false;
|
||||
wp->w_p_cuc = false;
|
||||
wp->w_p_spell = false;
|
||||
wp->w_p_list = false;
|
||||
|
||||
// Hide EOB region: use " " fillchar and cleared highlighting
|
||||
if (wp->w_p_fcs_chars.eob != ' ') {
|
||||
char *old = wp->w_p_fcs;
|
||||
wp->w_p_fcs = ((*old == NUL)
|
||||
? xstrdup("eob: ")
|
||||
: concat_str(old, ",eob: "));
|
||||
free_string_option(old);
|
||||
}
|
||||
|
||||
// TODO(bfredl): this could use a highlight namespace directly,
|
||||
// and avoid peculiarities around window options
|
||||
char *old = wp->w_p_winhl;
|
||||
wp->w_p_winhl = ((*old == NUL)
|
||||
? xstrdup("EndOfBuffer:")
|
||||
: concat_str(old, ",EndOfBuffer:"));
|
||||
free_string_option(old);
|
||||
parse_winhl_opt(wp);
|
||||
|
||||
// signcolumn: use 'auto'
|
||||
if (wp->w_p_scl[0] != 'a' || strlen(wp->w_p_scl) >= 8) {
|
||||
free_string_option(wp->w_p_scl);
|
||||
wp->w_p_scl = xstrdup("auto");
|
||||
}
|
||||
|
||||
// foldcolumn: use '0'
|
||||
if (wp->w_p_fdc[0] != '0') {
|
||||
free_string_option(wp->w_p_fdc);
|
||||
wp->w_p_fdc = xstrdup("0");
|
||||
}
|
||||
|
||||
// colorcolumn: cleared
|
||||
if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
|
||||
free_string_option(wp->w_p_cc);
|
||||
wp->w_p_cc = xstrdup("");
|
||||
}
|
||||
|
||||
// statuscolumn: cleared
|
||||
if (wp->w_p_stc != NULL && *wp->w_p_stc != NUL) {
|
||||
free_string_option(wp->w_p_stc);
|
||||
wp->w_p_stc = xstrdup("");
|
||||
}
|
||||
}
|
||||
|
||||
void win_config_float(win_T *wp, FloatConfig fconfig)
|
||||
{
|
||||
wp->w_width = MAX(fconfig.width, 1);
|
||||
wp->w_height = MAX(fconfig.height, 1);
|
||||
|
||||
if (fconfig.relative == kFloatRelativeCursor) {
|
||||
fconfig.relative = kFloatRelativeWindow;
|
||||
fconfig.row += curwin->w_wrow;
|
||||
fconfig.col += curwin->w_wcol;
|
||||
fconfig.window = curwin->handle;
|
||||
} else if (fconfig.relative == kFloatRelativeMouse) {
|
||||
int row = mouse_row, col = mouse_col, grid = mouse_grid;
|
||||
win_T *mouse_win = mouse_find_win(&grid, &row, &col);
|
||||
if (mouse_win != NULL) {
|
||||
fconfig.relative = kFloatRelativeWindow;
|
||||
fconfig.row += row;
|
||||
fconfig.col += col;
|
||||
fconfig.window = mouse_win->handle;
|
||||
}
|
||||
}
|
||||
|
||||
bool change_external = fconfig.external != wp->w_float_config.external;
|
||||
bool change_border = (fconfig.border != wp->w_float_config.border
|
||||
|| memcmp(fconfig.border_hl_ids,
|
||||
wp->w_float_config.border_hl_ids,
|
||||
sizeof fconfig.border_hl_ids) != 0);
|
||||
|
||||
wp->w_float_config = fconfig;
|
||||
|
||||
bool has_border = wp->w_floating && wp->w_float_config.border;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int new_adj = has_border && wp->w_float_config.border_chars[2 * i + 1][0];
|
||||
if (new_adj != wp->w_border_adj[i]) {
|
||||
change_border = true;
|
||||
wp->w_border_adj[i] = new_adj;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ui_has(kUIMultigrid)) {
|
||||
wp->w_height = MIN(wp->w_height, Rows - win_border_height(wp));
|
||||
wp->w_width = MIN(wp->w_width, Columns - win_border_width(wp));
|
||||
}
|
||||
|
||||
win_set_inner_size(wp, true);
|
||||
must_redraw = MAX(must_redraw, UPD_VALID);
|
||||
|
||||
wp->w_pos_changed = true;
|
||||
if (change_external || change_border) {
|
||||
wp->w_hl_needs_update = true;
|
||||
redraw_later(wp, UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
// compute initial position
|
||||
if (wp->w_float_config.relative == kFloatRelativeWindow) {
|
||||
int row = (int)wp->w_float_config.row;
|
||||
int col = (int)wp->w_float_config.col;
|
||||
Error dummy = ERROR_INIT;
|
||||
win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy);
|
||||
if (parent) {
|
||||
row += parent->w_winrow;
|
||||
col += parent->w_wincol;
|
||||
ScreenGrid *grid = &parent->w_grid;
|
||||
int row_off = 0, col_off = 0;
|
||||
grid_adjust(&grid, &row_off, &col_off);
|
||||
row += row_off;
|
||||
col += col_off;
|
||||
if (wp->w_float_config.bufpos.lnum >= 0) {
|
||||
pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
|
||||
wp->w_float_config.bufpos.col, 0 };
|
||||
int trow, tcol, tcolc, tcole;
|
||||
textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true);
|
||||
row += trow - 1;
|
||||
col += tcol - 1;
|
||||
}
|
||||
}
|
||||
api_clear_error(&dummy);
|
||||
wp->w_winrow = row;
|
||||
wp->w_wincol = col;
|
||||
} else {
|
||||
wp->w_winrow = (int)fconfig.row;
|
||||
wp->w_wincol = (int)fconfig.col;
|
||||
}
|
||||
|
||||
// changing border style while keeping border only requires redrawing border
|
||||
if (fconfig.border) {
|
||||
wp->w_redr_border = true;
|
||||
redraw_later(wp, UPD_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
void win_check_anchored_floats(win_T *win)
|
||||
{
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
// float might be anchored to moved window
|
||||
if (wp->w_float_config.relative == kFloatRelativeWindow
|
||||
&& wp->w_float_config.window == win->handle) {
|
||||
wp->w_pos_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the number of fold columns to display
|
||||
int win_fdccol_count(win_T *wp)
|
||||
{
|
||||
@ -1659,7 +1462,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
// The windows will both edit the same buffer.
|
||||
// WSP_NEWLOC may be specified in flags to prevent the location list from
|
||||
// being copied.
|
||||
static void win_init(win_T *newp, win_T *oldp, int flags)
|
||||
void win_init(win_T *newp, win_T *oldp, int flags)
|
||||
{
|
||||
newp->w_buffer = oldp->w_buffer;
|
||||
newp->w_s = &(oldp->w_buffer->b_s);
|
||||
@ -1736,24 +1539,6 @@ static void win_init_some(win_T *newp, win_T *oldp)
|
||||
win_copy_options(oldp, newp);
|
||||
}
|
||||
|
||||
/// Return true if "win" is floating window in the current tab page.
|
||||
///
|
||||
/// @param win window to check
|
||||
bool win_valid_floating(const win_T *win)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (win == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp == win) {
|
||||
return wp->w_floating;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check if "win" is a pointer to an existing window in the current tabpage.
|
||||
///
|
||||
/// @param win window to check
|
||||
@ -5112,7 +4897,7 @@ win_T *buf_jump_open_tab(buf_T *buf)
|
||||
|
||||
/// @param hidden allocate a window structure and link it in the window if
|
||||
// false.
|
||||
static win_T *win_alloc(win_T *after, bool hidden)
|
||||
win_T *win_alloc(win_T *after, bool hidden)
|
||||
{
|
||||
static int last_win_id = LOWEST_WIN_ID - 1;
|
||||
|
||||
@ -5790,13 +5575,6 @@ int win_comp_pos(void)
|
||||
return row + global_stl_height();
|
||||
}
|
||||
|
||||
void win_reconfig_floats(void)
|
||||
{
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
win_config_float(wp, wp->w_float_config);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the position of the windows in frame "topfrp", using the width and
|
||||
// height of the frames.
|
||||
// "*row" and "*col" are the top-left position of the frame. They are updated
|
||||
@ -6754,16 +6532,6 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
|
||||
wp->w_redr_status = true;
|
||||
}
|
||||
|
||||
static int win_border_height(win_T *wp)
|
||||
{
|
||||
return wp->w_border_adj[0] + wp->w_border_adj[2];
|
||||
}
|
||||
|
||||
static int win_border_width(win_T *wp)
|
||||
{
|
||||
return wp->w_border_adj[1] + wp->w_border_adj[3];
|
||||
}
|
||||
|
||||
/// Set the width of a window.
|
||||
void win_new_width(win_T *wp, int width)
|
||||
{
|
||||
@ -7654,29 +7422,3 @@ win_T *lastwin_nofloating(void)
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int float_zindex_cmp(const void *a, const void *b)
|
||||
{
|
||||
return (*(win_T **)b)->w_float_config.zindex - (*(win_T **)a)->w_float_config.zindex;
|
||||
}
|
||||
|
||||
void win_float_remove(bool bang, int count)
|
||||
{
|
||||
kvec_t(win_T *) float_win_arr = KV_INITIAL_VALUE;
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
kv_push(float_win_arr, wp);
|
||||
}
|
||||
qsort(float_win_arr.items, float_win_arr.size, sizeof(win_T *), float_zindex_cmp);
|
||||
for (size_t i = 0; i < float_win_arr.size; i++) {
|
||||
if (win_close(float_win_arr.items[i], false, false) == FAIL) {
|
||||
break;
|
||||
}
|
||||
if (!bang) {
|
||||
count--;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kv_destroy(float_win_arr);
|
||||
}
|
||||
|
279
src/nvim/winfloat.c
Normal file
279
src/nvim/winfloat.c
Normal file
@ -0,0 +1,279 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "klib/kvec.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/drawscreen.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/grid.h"
|
||||
#include "nvim/mouse.h"
|
||||
#include "nvim/move.h"
|
||||
#include "nvim/option.h"
|
||||
#include "nvim/optionstr.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/winfloat.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "winfloat.c.generated.h"
|
||||
#endif
|
||||
|
||||
/// Create a new float.
|
||||
///
|
||||
/// @param wp if NULL, allocate a new window, otherwise turn existing window into a float.
|
||||
/// It must then already belong to the current tabpage!
|
||||
/// @param last make the window the last one in the window list.
|
||||
/// Only used when allocating the autocommand window.
|
||||
/// @param config must already have been validated!
|
||||
win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err)
|
||||
{
|
||||
if (wp == NULL) {
|
||||
wp = win_alloc(last ? lastwin : lastwin_nofloating(), false);
|
||||
win_init(wp, curwin, 0);
|
||||
} else {
|
||||
assert(!last);
|
||||
assert(!wp->w_floating);
|
||||
if (firstwin == wp && lastwin_nofloating() == wp) {
|
||||
// last non-float
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change last window into float");
|
||||
return NULL;
|
||||
} else if (!win_valid(wp)) {
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Cannot change window from different tabpage into float");
|
||||
return NULL;
|
||||
}
|
||||
int dir;
|
||||
winframe_remove(wp, &dir, NULL);
|
||||
XFREE_CLEAR(wp->w_frame);
|
||||
(void)win_comp_pos(); // recompute window positions
|
||||
win_remove(wp, NULL);
|
||||
win_append(lastwin_nofloating(), wp);
|
||||
}
|
||||
wp->w_floating = true;
|
||||
wp->w_status_height = 0;
|
||||
wp->w_winbar_height = 0;
|
||||
wp->w_hsep_height = 0;
|
||||
wp->w_vsep_width = 0;
|
||||
|
||||
win_config_float(wp, fconfig);
|
||||
win_set_inner_size(wp, true);
|
||||
wp->w_pos_changed = true;
|
||||
redraw_later(wp, UPD_VALID);
|
||||
return wp;
|
||||
}
|
||||
|
||||
void win_set_minimal_style(win_T *wp)
|
||||
{
|
||||
wp->w_p_nu = false;
|
||||
wp->w_p_rnu = false;
|
||||
wp->w_p_cul = false;
|
||||
wp->w_p_cuc = false;
|
||||
wp->w_p_spell = false;
|
||||
wp->w_p_list = false;
|
||||
|
||||
// Hide EOB region: use " " fillchar and cleared highlighting
|
||||
if (wp->w_p_fcs_chars.eob != ' ') {
|
||||
char *old = wp->w_p_fcs;
|
||||
wp->w_p_fcs = ((*old == NUL)
|
||||
? xstrdup("eob: ")
|
||||
: concat_str(old, ",eob: "));
|
||||
free_string_option(old);
|
||||
}
|
||||
|
||||
// TODO(bfredl): this could use a highlight namespace directly,
|
||||
// and avoid peculiarities around window options
|
||||
char *old = wp->w_p_winhl;
|
||||
wp->w_p_winhl = ((*old == NUL)
|
||||
? xstrdup("EndOfBuffer:")
|
||||
: concat_str(old, ",EndOfBuffer:"));
|
||||
free_string_option(old);
|
||||
parse_winhl_opt(wp);
|
||||
|
||||
// signcolumn: use 'auto'
|
||||
if (wp->w_p_scl[0] != 'a' || strlen(wp->w_p_scl) >= 8) {
|
||||
free_string_option(wp->w_p_scl);
|
||||
wp->w_p_scl = xstrdup("auto");
|
||||
}
|
||||
|
||||
// foldcolumn: use '0'
|
||||
if (wp->w_p_fdc[0] != '0') {
|
||||
free_string_option(wp->w_p_fdc);
|
||||
wp->w_p_fdc = xstrdup("0");
|
||||
}
|
||||
|
||||
// colorcolumn: cleared
|
||||
if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
|
||||
free_string_option(wp->w_p_cc);
|
||||
wp->w_p_cc = xstrdup("");
|
||||
}
|
||||
|
||||
// statuscolumn: cleared
|
||||
if (wp->w_p_stc != NULL && *wp->w_p_stc != NUL) {
|
||||
free_string_option(wp->w_p_stc);
|
||||
wp->w_p_stc = xstrdup("");
|
||||
}
|
||||
}
|
||||
|
||||
int win_border_height(win_T *wp)
|
||||
{
|
||||
return wp->w_border_adj[0] + wp->w_border_adj[2];
|
||||
}
|
||||
|
||||
int win_border_width(win_T *wp)
|
||||
{
|
||||
return wp->w_border_adj[1] + wp->w_border_adj[3];
|
||||
}
|
||||
|
||||
void win_config_float(win_T *wp, FloatConfig fconfig)
|
||||
{
|
||||
wp->w_width = MAX(fconfig.width, 1);
|
||||
wp->w_height = MAX(fconfig.height, 1);
|
||||
|
||||
if (fconfig.relative == kFloatRelativeCursor) {
|
||||
fconfig.relative = kFloatRelativeWindow;
|
||||
fconfig.row += curwin->w_wrow;
|
||||
fconfig.col += curwin->w_wcol;
|
||||
fconfig.window = curwin->handle;
|
||||
} else if (fconfig.relative == kFloatRelativeMouse) {
|
||||
int row = mouse_row, col = mouse_col, grid = mouse_grid;
|
||||
win_T *mouse_win = mouse_find_win(&grid, &row, &col);
|
||||
if (mouse_win != NULL) {
|
||||
fconfig.relative = kFloatRelativeWindow;
|
||||
fconfig.row += row;
|
||||
fconfig.col += col;
|
||||
fconfig.window = mouse_win->handle;
|
||||
}
|
||||
}
|
||||
|
||||
bool change_external = fconfig.external != wp->w_float_config.external;
|
||||
bool change_border = (fconfig.border != wp->w_float_config.border
|
||||
|| memcmp(fconfig.border_hl_ids,
|
||||
wp->w_float_config.border_hl_ids,
|
||||
sizeof fconfig.border_hl_ids) != 0);
|
||||
|
||||
wp->w_float_config = fconfig;
|
||||
|
||||
bool has_border = wp->w_floating && wp->w_float_config.border;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int new_adj = has_border && wp->w_float_config.border_chars[2 * i + 1][0];
|
||||
if (new_adj != wp->w_border_adj[i]) {
|
||||
change_border = true;
|
||||
wp->w_border_adj[i] = new_adj;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ui_has(kUIMultigrid)) {
|
||||
wp->w_height = MIN(wp->w_height, Rows - win_border_height(wp));
|
||||
wp->w_width = MIN(wp->w_width, Columns - win_border_width(wp));
|
||||
}
|
||||
|
||||
win_set_inner_size(wp, true);
|
||||
must_redraw = MAX(must_redraw, UPD_VALID);
|
||||
|
||||
wp->w_pos_changed = true;
|
||||
if (change_external || change_border) {
|
||||
wp->w_hl_needs_update = true;
|
||||
redraw_later(wp, UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
// compute initial position
|
||||
if (wp->w_float_config.relative == kFloatRelativeWindow) {
|
||||
int row = (int)wp->w_float_config.row;
|
||||
int col = (int)wp->w_float_config.col;
|
||||
Error dummy = ERROR_INIT;
|
||||
win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy);
|
||||
if (parent) {
|
||||
row += parent->w_winrow;
|
||||
col += parent->w_wincol;
|
||||
ScreenGrid *grid = &parent->w_grid;
|
||||
int row_off = 0, col_off = 0;
|
||||
grid_adjust(&grid, &row_off, &col_off);
|
||||
row += row_off;
|
||||
col += col_off;
|
||||
if (wp->w_float_config.bufpos.lnum >= 0) {
|
||||
pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
|
||||
wp->w_float_config.bufpos.col, 0 };
|
||||
int trow, tcol, tcolc, tcole;
|
||||
textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true);
|
||||
row += trow - 1;
|
||||
col += tcol - 1;
|
||||
}
|
||||
}
|
||||
api_clear_error(&dummy);
|
||||
wp->w_winrow = row;
|
||||
wp->w_wincol = col;
|
||||
} else {
|
||||
wp->w_winrow = (int)fconfig.row;
|
||||
wp->w_wincol = (int)fconfig.col;
|
||||
}
|
||||
|
||||
// changing border style while keeping border only requires redrawing border
|
||||
if (fconfig.border) {
|
||||
wp->w_redr_border = true;
|
||||
redraw_later(wp, UPD_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
static int float_zindex_cmp(const void *a, const void *b)
|
||||
{
|
||||
return (*(win_T **)b)->w_float_config.zindex - (*(win_T **)a)->w_float_config.zindex;
|
||||
}
|
||||
|
||||
void win_float_remove(bool bang, int count)
|
||||
{
|
||||
kvec_t(win_T *) float_win_arr = KV_INITIAL_VALUE;
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
kv_push(float_win_arr, wp);
|
||||
}
|
||||
qsort(float_win_arr.items, float_win_arr.size, sizeof(win_T *), float_zindex_cmp);
|
||||
for (size_t i = 0; i < float_win_arr.size; i++) {
|
||||
if (win_close(float_win_arr.items[i], false, false) == FAIL) {
|
||||
break;
|
||||
}
|
||||
if (!bang) {
|
||||
count--;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kv_destroy(float_win_arr);
|
||||
}
|
||||
|
||||
void win_check_anchored_floats(win_T *win)
|
||||
{
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
// float might be anchored to moved window
|
||||
if (wp->w_float_config.relative == kFloatRelativeWindow
|
||||
&& wp->w_float_config.window == win->handle) {
|
||||
wp->w_pos_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void win_reconfig_floats(void)
|
||||
{
|
||||
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||
win_config_float(wp, wp->w_float_config);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if "win" is floating window in the current tab page.
|
||||
///
|
||||
/// @param win window to check
|
||||
bool win_float_valid(const win_T *win)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (win == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp == win) {
|
||||
return wp->w_floating;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
7
src/nvim/winfloat.h
Normal file
7
src/nvim/winfloat.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "nvim/buffer_defs.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "winfloat.h.generated.h"
|
||||
#endif
|
Reference in New Issue
Block a user