Skip to content

feat: max_width for adaptive_size #1915

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

Merged
merged 12 commits into from
Jan 21, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
25 changes: 20 additions & 5 deletions doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ Setup should be run in a lua file or in a |lua-heredoc| if using in a vim file.
require("nvim-tree").setup({
sort_by = "case_sensitive",
view = {
adaptive_size = true,
mappings = {
list = {
{ key = "u", action = "dir_up" },
Expand Down Expand Up @@ -189,7 +188,6 @@ Subsequent calls to setup will replace the previous configuration.
remove_keymaps = false,
select_prompts = false,
view = {
adaptive_size = false,
centralize_selection = false,
cursorline = true,
debounce_delay = 15,
Expand Down Expand Up @@ -726,9 +724,26 @@ Window / buffer setup.
Type: `boolean`, Default: `false`

*nvim-tree.view.width*
Width of the window, can be a `%` string, a number representing columns or
a function.
Type: `string | number | function`, Default: `30`
Width of the window: can be a `%` string, a number representing columns, a
function or a table.
A minimum of 20 as per the |winwidth| default will always apply.
A table indicates that the view should be dynamically sized based on the
longest line (previously `view.adaptive_size`).
Type: `string | number | function | table`, Default: `30`

*nvim-tree.view.width.min*
Minimum dynamic width.
Type: `string | number | function`, Default: `20`

*nvim-tree.view.width.max*
Maximum dynamic width, -1 for unbounded.
Type: `string | number | function`, Default: `-1`

*nvim-tree.view.max_width*
Maximum width of the window when `nvim-tree.view.adaptive_size` is `true`, can be
a `%` string, a number representing columns or a function. If set to `-1`, the
width is unbounded.
Type: `string | number | function`, Default: `-1`

*nvim-tree.view.side*
Side of the tree, can be `"left"`, `"right"`.
Expand Down
5 changes: 3 additions & 2 deletions lua/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
remove_keymaps = false,
select_prompts = false,
view = {
adaptive_size = false,
centralize_selection = false,
cursorline = true,
debounce_delay = 15,
Expand Down Expand Up @@ -744,7 +743,9 @@ local FIELD_SKIP_VALIDATE = {
}

local FIELD_OVERRIDE_TYPECHECK = {
width = { string = true, ["function"] = true, number = true },
width = { string = true, ["function"] = true, number = true, ["table"] = true },
max = { string = true, ["function"] = true, number = true },
min = { string = true, ["function"] = true, number = true },
remove_keymaps = { boolean = true, table = true },
on_attach = { ["function"] = true, string = true },
sort_by = { ["function"] = true, string = true },
Expand Down
4 changes: 2 additions & 2 deletions lua/nvim-tree/events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ function M._dispatch_on_tree_close()
end

--@private
function M._dispatch_on_tree_resize(size)
dispatch(M.Event.Resize, size)
function M._dispatch_on_tree_resize(width)
dispatch(M.Event.Resize, width)
end

--@private
Expand Down
11 changes: 11 additions & 0 deletions lua/nvim-tree/legacy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ local function refactored(opts)

-- 2023/01/08
utils.move_missing_val(opts, "trash", "require_confirm", opts, "ui.confirm", "trash", true)

-- 2023/01/15
if opts.view and opts.view.adaptive_size ~= nil then
if opts.view.adaptive_size and type(opts.view.width) ~= "table" then
local width = opts.view.width
opts.view.width = {
min = width,
}
end
opts.view.adaptive_size = nil
end
end

local function removed(opts)
Expand Down
108 changes: 75 additions & 33 deletions lua/nvim-tree/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ local events = require "nvim-tree.events"
local utils = require "nvim-tree.utils"
local log = require "nvim-tree.log"

-- there are sizing oddities when dropping below the default winwidth of 20
local MIN_WIDTH = 20

M.View = {
adaptive_size = false,
centralize_selection = false,
Expand Down Expand Up @@ -89,25 +92,41 @@ local function create_buffer(bufnr)
vim.bo[M.get_bufnr()][option] = value
end

if type(M.on_attach) == "function" then
if type(M.config.on_attach) == "function" then
require("nvim-tree.keymap").set_keymaps(M.get_bufnr())
M.on_attach(M.get_bufnr())
M.config.on_attach(M.get_bufnr())
else
require("nvim-tree.actions").apply_mappings(M.get_bufnr())
end
events._dispatch_tree_attached_post(M.get_bufnr())
end

local function get_size()
local size = M.View.width
---Calculate a window width, minimum MIN_WIDTH
---@param size number|function|string
---@return number
local function calculate_width(size)
local width

if type(size) == "number" then
return size
width = size
elseif type(size) == "function" then
return size()
width = size()
if type(width) ~= "number" then
width = MIN_WIDTH
end
elseif type(size) == "string" then
local size_as_number = tonumber(size:sub(0, -2))
if type(size_as_number) == "number" then
local percent_as_decimal = size_as_number / 100
width = math.floor(vim.o.columns * percent_as_decimal)
else
width = MIN_WIDTH
end
else
width = MIN_WIDTH
end
local size_as_number = tonumber(size:sub(0, -2))
local percent_as_decimal = size_as_number / 100
return math.floor(vim.o.columns * percent_as_decimal)

return math.max(MIN_WIDTH, width)
end

local move_tbl = {
Expand Down Expand Up @@ -246,14 +265,28 @@ end
local function grow()
local starts_at = M.is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0
local lines = vim.api.nvim_buf_get_lines(M.get_bufnr(), starts_at, -1, false)
local max_length = M.View.initial_width
local padding = M.View.winopts.signcolumn and 2 or 0
local resizing_width = M.View.initial_width - padding
local max_width

-- maybe bound max
if M.config.width.max == -1 then
max_width = -1
else
max_width = calculate_width(M.config.width.max) - padding
end

for _, l in pairs(lines) do
local count = vim.fn.strchars(l) + 3 -- plus some padding
if max_length < count then
max_length = count
local count = vim.fn.strchars(l)
if resizing_width < count then
resizing_width = count
end
if M.View.adaptive_size and max_width >= 0 and resizing_width >= max_width then
resizing_width = max_width
break
end
end
M.resize(max_length)
M.resize(resizing_width + padding)
end

function M.grow_from_content()
Expand Down Expand Up @@ -292,10 +325,10 @@ function M.resize(size)
return
end

local new_size = get_size()
vim.api.nvim_win_set_width(M.get_winnr(), new_size)
local new_width = calculate_width(M.View.width)
vim.api.nvim_win_set_width(M.get_winnr(), new_width)

events._dispatch_on_tree_resize(new_size)
events._dispatch_on_tree_resize(new_width)

if not M.View.preserve_window_proportions then
vim.cmd ":wincmd ="
Expand Down Expand Up @@ -481,22 +514,31 @@ function M.reset_winhl()
end

function M.setup(opts)
local options = opts.view or {}
M.View.adaptive_size = options.adaptive_size
M.View.centralize_selection = options.centralize_selection
M.View.side = (options.side == "right") and "right" or "left"
M.View.width = options.width
M.View.height = options.height
M.View.initial_width = get_size()
M.View.hide_root_folder = options.hide_root_folder
M.View.tab = opts.tab
M.View.preserve_window_proportions = options.preserve_window_proportions
M.View.winopts.cursorline = options.cursorline
M.View.winopts.number = options.number
M.View.winopts.relativenumber = options.relativenumber
M.View.winopts.signcolumn = options.signcolumn
M.View.float = options.float
M.on_attach = opts.on_attach
M.config = opts.view or {}

M.View.centralize_selection = M.config.centralize_selection
M.View.side = (M.config.side == "right") and "right" or "left"
M.View.height = M.config.height
M.View.hide_root_folder = M.config.hide_root_folder
M.View.tab = M.config.tab
M.View.preserve_window_proportions = M.config.preserve_window_proportions
M.View.winopts.cursorline = M.config.cursorline
M.View.winopts.number = M.config.number
M.View.winopts.relativenumber = M.config.relativenumber
M.View.winopts.signcolumn = M.config.signcolumn
M.View.float = M.config.float

if type(M.config.width) == "table" then
M.config.width.min = M.config.width.min or MIN_WIDTH
M.config.width.max = M.config.width.max or -1
M.View.adaptive_size = true
M.View.width = M.config.width.min
else
M.View.adaptive_size = false
M.View.width = M.config.width
end

M.View.initial_width = calculate_width(M.View.width)
end

return M