* implement floating window * reset width on closing window * use gap from new config parameter * use minimal style for preview in floating * lower z-index * add configuration of preview position in floating window * fix in verions earlier than nvim 0.10 * close preview on opening floating window Close the any existing preview because otherwise strange errors happen when the preview is open and the floating window is opened at the same time. * reset formatting changes * remove empty line * change z-index of preview window to floating window z-index * add configurations to oil.txt * formatting * add auto configuration * update oil doc * refactor: move logic into layout.lua and eliminate flicker * fix: floating preview window title is file name * doc: clarify default_file_explorer * refactor: don't need a preview_gap option * refactor: only find preview win in current tabpage --------- Co-authored-by: Steven Arcangeli <stevearc@stevearc.com>
185 lines
5 KiB
Lua
185 lines
5 KiB
Lua
local M = {}
|
|
|
|
local function is_float(value)
|
|
local _, p = math.modf(value)
|
|
return p ~= 0
|
|
end
|
|
|
|
local function calc_float(value, max_value)
|
|
if value and is_float(value) then
|
|
return math.min(max_value, value * max_value)
|
|
else
|
|
return value
|
|
end
|
|
end
|
|
|
|
---@return integer
|
|
M.get_editor_width = function()
|
|
return vim.o.columns
|
|
end
|
|
|
|
---@return integer
|
|
M.get_editor_height = function()
|
|
local editor_height = vim.o.lines - vim.o.cmdheight
|
|
-- Subtract 1 if tabline is visible
|
|
if vim.o.showtabline == 2 or (vim.o.showtabline == 1 and #vim.api.nvim_list_tabpages() > 1) then
|
|
editor_height = editor_height - 1
|
|
end
|
|
-- Subtract 1 if statusline is visible
|
|
if
|
|
vim.o.laststatus >= 2 or (vim.o.laststatus == 1 and #vim.api.nvim_tabpage_list_wins(0) > 1)
|
|
then
|
|
editor_height = editor_height - 1
|
|
end
|
|
return editor_height
|
|
end
|
|
|
|
local function calc_list(values, max_value, aggregator, limit)
|
|
local ret = limit
|
|
if not max_value or not values then
|
|
return nil
|
|
elseif type(values) == "table" then
|
|
for _, v in ipairs(values) do
|
|
ret = aggregator(ret, calc_float(v, max_value))
|
|
end
|
|
return ret
|
|
else
|
|
ret = aggregator(ret, calc_float(values, max_value))
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function calculate_dim(desired_size, exact_size, min_size, max_size, total_size)
|
|
local ret = calc_float(exact_size, total_size)
|
|
local min_val = calc_list(min_size, total_size, math.max, 1)
|
|
local max_val = calc_list(max_size, total_size, math.min, total_size)
|
|
if not ret then
|
|
if not desired_size then
|
|
if min_val and max_val then
|
|
ret = (min_val + max_val) / 2
|
|
else
|
|
ret = 80
|
|
end
|
|
else
|
|
ret = calc_float(desired_size, total_size)
|
|
end
|
|
end
|
|
if max_val then
|
|
ret = math.min(ret, max_val)
|
|
end
|
|
if min_val then
|
|
ret = math.max(ret, min_val)
|
|
end
|
|
return math.floor(ret)
|
|
end
|
|
|
|
M.calculate_width = function(desired_width, opts)
|
|
return calculate_dim(
|
|
desired_width,
|
|
opts.width,
|
|
opts.min_width,
|
|
opts.max_width,
|
|
M.get_editor_width()
|
|
)
|
|
end
|
|
|
|
M.calculate_height = function(desired_height, opts)
|
|
return calculate_dim(
|
|
desired_height,
|
|
opts.height,
|
|
opts.min_height,
|
|
opts.max_height,
|
|
M.get_editor_height()
|
|
)
|
|
end
|
|
|
|
---@class (exact) conform.WinLayout
|
|
---@field width integer
|
|
---@field height integer
|
|
---@field row integer
|
|
---@field col integer
|
|
|
|
---@return vim.api.keyset.win_config
|
|
M.get_fullscreen_win_opts = function()
|
|
local config = require("oil.config")
|
|
|
|
local total_width = M.get_editor_width()
|
|
local total_height = M.get_editor_height()
|
|
local width = total_width - 2 * config.float.padding
|
|
if config.float.border ~= "none" then
|
|
width = width - 2 -- The border consumes 1 col on each side
|
|
end
|
|
if config.float.max_width > 0 then
|
|
width = math.min(width, config.float.max_width)
|
|
end
|
|
local height = total_height - 2 * config.float.padding
|
|
if config.float.max_height > 0 then
|
|
height = math.min(height, config.float.max_height)
|
|
end
|
|
local row = math.floor((total_height - height) / 2)
|
|
local col = math.floor((total_width - width) / 2) - 1 -- adjust for border width
|
|
|
|
local win_opts = {
|
|
relative = "editor",
|
|
width = width,
|
|
height = height,
|
|
row = row,
|
|
col = col,
|
|
border = config.float.border,
|
|
zindex = 45,
|
|
}
|
|
return config.float.override(win_opts) or win_opts
|
|
end
|
|
|
|
---@param winid integer
|
|
---@param direction "above"|"below"|"left"|"right"|"auto"
|
|
---@param gap integer
|
|
---@return conform.WinLayout root_dim New dimensions of the original window
|
|
---@return conform.WinLayout new_dim New dimensions of the new window
|
|
M.split_window = function(winid, direction, gap)
|
|
if direction == "auto" then
|
|
direction = vim.o.splitright and "right" or "left"
|
|
end
|
|
|
|
local float_config = vim.api.nvim_win_get_config(winid)
|
|
local dim_root = {
|
|
width = float_config.width,
|
|
height = float_config.height,
|
|
col = float_config.col,
|
|
row = float_config.row,
|
|
}
|
|
if vim.fn.has("nvim-0.10") == 0 then
|
|
-- read https://github.com/neovim/neovim/issues/24430 for more infos.
|
|
dim_root.col = float_config.col[vim.val_idx]
|
|
dim_root.row = float_config.row[vim.val_idx]
|
|
end
|
|
local dim_new = vim.deepcopy(dim_root)
|
|
|
|
if direction == "left" or direction == "right" then
|
|
dim_new.width = math.floor(float_config.width / 2) - math.ceil(gap / 2)
|
|
dim_root.width = dim_new.width
|
|
else
|
|
dim_new.height = math.floor(float_config.height / 2) - math.ceil(gap / 2)
|
|
dim_root.height = dim_new.height
|
|
end
|
|
|
|
if direction == "left" then
|
|
dim_root.col = dim_root.col + dim_root.width + gap
|
|
elseif direction == "right" then
|
|
dim_new.col = dim_new.col + dim_new.width + gap
|
|
elseif direction == "above" then
|
|
dim_root.row = dim_root.row + dim_root.height + gap
|
|
elseif direction == "below" then
|
|
dim_new.row = dim_new.row + dim_new.height + gap
|
|
end
|
|
|
|
return dim_root, dim_new
|
|
end
|
|
|
|
M.calculate_dims = function(desired_width, desired_height, opts)
|
|
local width = M.calculate_width(desired_width, opts)
|
|
local height = M.calculate_height(desired_height, opts)
|
|
return width, height
|
|
end
|
|
|
|
return M
|