Skip to content

Commit

Permalink
fix(windowing): positioning of relative floats
Browse files Browse the repository at this point in the history
Fix relative floating windows so that they open in the correct position
relative to each other. Also make sure that their positions are correct
immediately after creation without a redraw.
  • Loading branch information
andrew-pa committed Sep 8, 2021
1 parent 1df8a34 commit 9065730
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 1 deletion.
34 changes: 33 additions & 1 deletion src/nvim/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,37 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
redraw_later(wp, NOT_VALID);
}

// compute initial position
if (wp->w_float_config.relative == kFloatRelativeWindow) {
int row = wp->w_float_config.row;
int col = 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;
screen_adjust_grid(&grid, &row_off, &col_off);
row += row_off;
col += col_off;
}
api_clear_error(&dummy);
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(wp, &pos, &trow, &tcol, &tcolc, &tcole, true);
row += trow - 1;
col += tcol - 1;
}
wp->w_winrow = row;
wp->w_wincol = col;
} else {
wp->w_winrow = fconfig.row;
wp->w_wincol = fconfig.col;
}

// changing border style while keeping border only requires redrawing border
if (fconfig.border) {
wp->w_redr_border = true;
Expand Down Expand Up @@ -770,7 +801,6 @@ int win_fdccol_count(win_T *wp)
}
}


void ui_ext_win_position(win_T *wp)
{
if (!wp->w_floating) {
Expand Down Expand Up @@ -817,6 +847,8 @@ void ui_ext_win_position(win_T *wp)

int comp_row = (int)row - (south ? wp->w_height : 0);
int comp_col = (int)col - (east ? wp->w_width : 0);
comp_row += grid->comp_row;
comp_col += grid->comp_col;
comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0);
comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0);
wp->w_winrow = comp_row;
Expand Down
126 changes: 126 additions & 0 deletions test/functional/ui/float_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,132 @@ describe('float window', function()
eq(10, width)
end)

it('opened with correct position', function()
local pos = exec_lua([[
local bufnr = vim.api.nvim_create_buf(false, true)
local opts = {
width = 10,
height = 10,
col = 7,
row = 9,
relative = 'editor',
style = 'minimal'
}
local win_id = vim.api.nvim_open_win(bufnr, false, opts)
return vim.api.nvim_win_get_position(win_id)
]])

eq(9, pos[1])
eq(7, pos[2])
end)

it('opened with correct position relative to the cursor', function()
local pos = exec_lua([[
local bufnr = vim.api.nvim_create_buf(false, true)
local opts = {
width = 10,
height = 10,
col = 7,
row = 9,
relative = 'cursor',
style = 'minimal'
}
local win_id = vim.api.nvim_open_win(bufnr, false, opts)
return vim.api.nvim_win_get_position(win_id)
]])

eq(9, pos[1])
eq(7, pos[2])
end)

it('opened with correct position relative to another window', function()
local pos = exec_lua([[
local bufnr = vim.api.nvim_create_buf(false, true)
local par_opts = {
width = 50,
height = 50,
col = 7,
row = 9,
relative = 'editor',
style = 'minimal'
}
local par_win_id = vim.api.nvim_open_win(bufnr, false, par_opts)
local opts = {
width = 10,
height = 10,
col = 7,
row = 9,
relative = 'win',
style = 'minimal',
win = par_win_id
}
local win_id = vim.api.nvim_open_win(bufnr, false, opts)
return vim.api.nvim_win_get_position(win_id)
]])

eq(18, pos[1])
eq(14, pos[2])
end)


it('opened with correct position relative to another relative window', function()
local pos = exec_lua([[
local bufnr = vim.api.nvim_create_buf(false, true)
local root_opts = {
width = 50,
height = 50,
col = 7,
row = 9,
relative = 'editor',
style = 'minimal'
}
local root_win_id = vim.api.nvim_open_win(bufnr, false, root_opts)
local par_opts = {
width = 20,
height = 20,
col = 2,
row = 3,
relative = 'win',
win = root_win_id,
style = 'minimal'
}
local par_win_id = vim.api.nvim_open_win(bufnr, false, par_opts)
local opts = {
width = 10,
height = 10,
col = 3,
row = 2,
relative = 'win',
win = par_win_id,
style = 'minimal'
}
local win_id = vim.api.nvim_open_win(bufnr, false, opts)
return vim.api.nvim_win_get_position(win_id)
]])

eq(14, pos[1])
eq(12, pos[2])
end)


local function with_ext_multigrid(multigrid)
local screen
before_each(function()
Expand Down

0 comments on commit 9065730

Please sign in to comment.