Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add focused window minwidth and minheight options #171

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ require("focus").setup({
height = 0, -- Force height for the focused window
minwidth = 0, -- Force minimum width for the unfocused window
minheight = 0, -- Force minimum height for the unfocused window
focusedwindow_minwidth = 0, --Force minimum width for the focused window
focusedwindow_minheight = 0, --Force minimum height for the focused window
height_quickfix = 10, -- Set the height of quickfix panel
},
split = {
Expand Down Expand Up @@ -187,6 +189,13 @@ require("focus").setup({ autoresize = { width = 120 } })
require("focus").setup({ autoresize = { minwidth = 80} })
```

**Set Focus Minimum Width for Focused Window**
```lua
-- Force minimum width for the focused window
-- Default: Calculated based on golden ratio
require("focus").setup({ autoresize = { focusedwindow_minwidth = 80} })
```

**Set Focus Height**
```lua
-- Force height for the focused window
Expand All @@ -201,6 +210,13 @@ require("focus").setup({ autoresize = { height = 40 } })
require("focus").setup({ autoresize = { minheight = 10} })
```

**Set Focus Minimum Height for Focused Window**
```lua
-- Force minimum height for the focused window
-- Default: Calculated based on golden ratio
require("focus").setup({ autoresize = { focusedwindow_minheight = 80} })
```

**Set Focus Quickfix Height**
```lua
-- Sets the height of quickfix panel, in case you pass the height to
Expand Down
30 changes: 24 additions & 6 deletions doc/focus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ default settings:
height = 0, -- Force height for the focused window
minwidth = 0, -- Force minimum width for the unfocused window
minheight = 0, -- Force minimum height for the unfocused window
focusedwindow_minwidth = 0, -- Force minimum width for the focused window
focusedwindow_minheight = 0, -- Force minimum height for the focused window
height_quickfix = 10, -- Set the height of quickfix panel
},
split = {
Expand All @@ -91,7 +93,7 @@ default settings:
relativenumber = false, -- Display relative line numbers in the focussed window only
hybridnumber = false, -- Display hybrid line numbers in the focussed window only
absolutenumber_unfocussed = false, -- Preserve absolute numbers in the unfocussed windows

cursorline = true, -- Display a cursorline in the focussed window only
cursorcolumn = false, -- Display cursorcolumn in the focussed window only
colorcolumn = {
Expand Down Expand Up @@ -154,6 +156,14 @@ SETUP OPTIONS ~
require("focus").setup({ autoresize = { minwidth = 80} })
<

**Set Focus Minimum Width for Focused Window**

>lua
-- Force minimum width for the focused window
-- Default: Calculated based on golden ratio
require("focus").setup({ autoresize = { focusedwindow_minwidth = 80} })
<

**Set Focus Height**

>lua
Expand All @@ -170,6 +180,14 @@ SETUP OPTIONS ~
require("focus").setup({ autoresize = { minheight = 10} })
<

**Set Focus Minimum Height for Focused Window**

>lua
-- Force minimum height for the focused window
-- Default: Calculated based on golden ratio
require("focus").setup({ autoresize = { focusedwindow_minheight = 80} })
<

**Set Focus Quickfix Height**

>lua
Expand Down Expand Up @@ -287,7 +305,7 @@ buffer**
-- Enable auto highlighting for focussed/unfocussed windows
-- Default: false
require("focus").setup({ ui = { winhighlight = true } })

-- By default, the highlight groups are setup as such:
-- hi default link FocusedWindow VertSplit
-- hi default link UnfocusedWindow Normal
Expand All @@ -312,10 +330,10 @@ Here is an example:
>lua
local ignore_filetypes = { 'neo-tree' }
local ignore_buftypes = { 'nofile', 'prompt', 'popup' }

local augroup =
vim.api.nvim_create_augroup('FocusDisable', { clear = true })

vim.api.nvim_create_autocmd('WinEnter', {
group = augroup,
callback = function(_)
Expand All @@ -328,7 +346,7 @@ Here is an example:
end,
desc = 'Disable focus autoresize for BufType',
})

vim.api.nvim_create_autocmd('FileType', {
group = augroup,
callback = function(_)
Expand Down Expand Up @@ -473,7 +491,7 @@ LEVERAGE HJKL TO MOVE OR CREATE YOUR SPLITS DIRECTIONALLY ~
require('focus').split_command(direction)
end, { desc = string.format('Create or move to split (%s)', direction) })
end

-- Use `<Leader>h` to split the screen to the left, same as command FocusSplitLeft etc
focusmap('h')
focusmap('j')
Expand Down
2 changes: 2 additions & 0 deletions extras/repro.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ require('focus').setup({
height = 0, -- Force height for the focused window
minwidth = 0, -- Force minimum width for the unfocused window
minheight = 0, -- Force minimum height for the unfocused window
focusedwindow_minwidth = 0, -- Force minimum width for the focused window
focusedwindow_minheight = 0, -- Force minimum height for the focused window
height_quickfix = 10, -- Set the height of quickfix panel
},
split = {
Expand Down
10 changes: 10 additions & 0 deletions lua/focus/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Focus.config = {
height = 0, -- Force height for the focused window
minwidth = 0, -- Force minimum width for the unfocused window
minheight = 0, -- Force minimum height for the unfocused window
focusedwindow_minwidth = 0, -- Force minimum width for the focused window
focusedwindow_minheight = 0, -- Force minimum height for the focused window
height_quickfix = 10, -- Set the height of quickfix panel
},
split = {
Expand Down Expand Up @@ -196,6 +198,14 @@ H.setup_config = function(config)
['autoresize.height'] = { config.autoresize.height, 'number' },
['autoresize.minwidth'] = { config.autoresize.minwidth, 'number' },
['autoresize.minheight'] = { config.autoresize.minheight, 'number' },
['autoresize.focusedwindow_minwidth'] = {
config.autoresize.focusedwindow_minwidth,
'number',
},
['autoresize.focusedwindow_minheight'] = {
config.autoresize.focusedwindow_minheight,
'number',
},
['autoresize.height_quickfix'] = {
config.autoresize.height_quickfix,
'number',
Expand Down
22 changes: 18 additions & 4 deletions lua/focus/modules/resizer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ function M.autoresize(config)
width = config.autoresize.width
else
width = golden_ratio_width()
if config.autoresize.minwidth > 0 then
if config.autoresize.focusedwindow_minwidth > 0 then
if width < config.autoresize.focusedwindow_minwidth then
width = config.autoresize.focusedwindow_minwidth
end
elseif config.autoresize.minwidth > 0 then
width = math.max(width, config.autoresize.minwidth)
elseif width < golden_ratio_minwidth() then
width = golden_ratio_minwidth()
Expand All @@ -66,7 +70,11 @@ function M.autoresize(config)
height = config.autoresize.height
else
height = golden_ratio_height()
if config.autoresize.minheight > 0 then
if config.autoresize.focusedwindow_minheight > 0 then
if height < config.autoresize.focusedwindow_minheight then
height = config.autoresize.focusedwindow_minheight
end
elseif config.autoresize.minheight > 0 then
height = math.max(height, config.autoresize.minheight)
elseif height < golden_ratio_minheight() then
height = golden_ratio_minheight()
Expand Down Expand Up @@ -121,13 +129,19 @@ function M.split_resizer(config, goal) --> Only resize normal buffers, set qf to
vim.o.winheight = 1
return
else
if config.autoresize.minwidth > 0 then
if
config.autoresize.minwidth > 0
and config.autoresize.focusedwindow_minwidth <= 0
then
if vim.o.winwidth < config.autoresize.minwidth then
vim.o.winwidth = config.autoresize.minwidth
end
vim.o.winminwidth = config.autoresize.minwidth
end
if config.autoresize.minheight > 0 then
if
config.autoresize.minheight > 0
and config.autoresize.focusedwindow_minheight <= 0
then
if vim.o.winheight < config.autoresize.minheight then
vim.o.winheight = config.autoresize.minheight
end
Expand Down
123 changes: 123 additions & 0 deletions tests/test_autoresize.lua
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,129 @@ T['autoresize']['vsplit minwidth'] = function()
validate_win_dims(win_id_right, { 30, 23 })
end

-- focused minwidth for vertical splits
T['autoresize']['vsplit focusedwindow_minwidth'] = function()
reload_module({ autoresize = { focusedwindow_minwidth = 55 } })
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('vsplit')
local resize_state = child.get_resize_state()
local win_id_left = resize_state.windows[1]
local win_id_right = resize_state.windows[2]

eq(win_id_left, child.api.nvim_get_current_win())

-- Expect the left window's width to be at least 55.
-- In the default test, the left width is 49.
-- With forced focusedwindow_minwidth, we now expect 55.
validate_win_dims(win_id_left, { 55, 23 })
-- The right window should take the remaining width
validate_win_dims(win_id_right, { 24, 23 })
end

-- focused minwidth for vertical splits inferior to the default one obtained by
-- the golden ratio
T['autoresize']['vsplit focusedwindow_minwidth < golden_ratio expected value'] = function()
reload_module({ autoresize = { focusedwindow_minwidth = 40 } })
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('vsplit')
local resize_state = child.get_resize_state()
local win_id_left = resize_state.windows[1]
local win_id_right = resize_state.windows[2]

eq(win_id_left, child.api.nvim_get_current_win())

-- The expected value is the golden ratio one
validate_win_dims(win_id_left, { 49, 23 })
-- The right window should take the remaining width
validate_win_dims(win_id_right, { 30, 23 })
end

-- focused minheight for horizontal splits
T['autoresize']['split focusedwindow_minheight'] = function()
reload_module({ autoresize = { focusedwindow_minheight = 17 } })
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('split')
local resize_state = child.get_resize_state()
local win_id_upper = resize_state.windows[1]
local win_id_lower = resize_state.windows[2]

-- In the default test, the upper window height is 15.
-- With forced focusedwindow_minheight, we now expect 17.
validate_win_dims(win_id_upper, { 80, 17 })
-- The lower window gets the rest (assuming total height used equals 22)
validate_win_dims(win_id_lower, { 80, 5 })
end

-- focused minheight for horizontal splits inferior to the default one obtained by
-- the golden ratio
T['autoresize']['split focusedwindow_minheight < golden_ratio expected value'] = function()
reload_module({ autoresize = { focusedwindow_minheight = 10 } })
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('split')
local resize_state = child.get_resize_state()
local win_id_upper = resize_state.windows[1]
local win_id_lower = resize_state.windows[2]

-- The expected value is the golden ratio one
validate_win_dims(win_id_upper, { 80, 15 })
-- The lower window gets the rest
validate_win_dims(win_id_lower, { 80, 7 })
end

-- focused minwidth for vertical splits with minwidth + focusedwindow_minwidth >
-- maxwidth.
T['autoresize']['vsplit minwidth focusedwindow_minwidth'] = function()
reload_module({
autoresize = { minwidth = 20, focusedwindow_minwidth = 80 },
})
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('vsplit')
local resize_state = child.get_resize_state()
local win_id_left = resize_state.windows[1]
local win_id_right = resize_state.windows[2]

eq(win_id_left, child.api.nvim_get_current_win())

-- Expect the left window's width to be at least the maxwidth (80) minus 21,
-- 20 from the right window as the minimum width possible and 1 from the
-- separator.
-- With forced focusedwindow_minwidth, we now expect 59.
validate_win_dims(win_id_left, { 78, 23 })
-- The right window should have the minwidth.
validate_win_dims(win_id_right, { 1, 23 })

child.api.nvim_set_current_win(win_id_right)

validate_win_dims(win_id_left, { 1, 23 })
-- The right window should have the minwidth.
validate_win_dims(win_id_right, { 78, 23 })
end

-- focused minheight for horizontal splits with minheight as 0
T['autoresize']['split minheight focusedwindow_minheight'] = function()
reload_module({
autoresize = { minheight = 10, focusedwindow_minheight = 25 },
})
edit(lorem_ipsum_file)
child.set_cursor(15, 1)
child.cmd('split')
local resize_state = child.get_resize_state()
local win_id_upper = resize_state.windows[1]
local win_id_lower = resize_state.windows[2]

-- Expect the upper window's height to be at least the maxheight (23) minus 2,
-- 1 from the lower window as the minimum height and 1 from the separator.
-- With forced focusedwindow_minheight, we now expect 21.
validate_win_dims(win_id_upper, { 80, 21 })
-- The lower window should have the minimum height.
validate_win_dims(win_id_lower, { 80, 1 })
end

T['autoresize']['quickfix'] = function()
reload_module({ autoresize = { height_quickfix = 10 } })
child.cmd('vimgrep /ipsum/' .. lorem_ipsum_file)
Expand Down