Skip to content

Commit 96506fe

Browse files
feat(view): add view.width.min/max replacing adaptive_size, allowing upper bound (#1915)
* feat: max_width for adaptive_size * view grow calculates size correctly based on sign column visibility * limit width to a minimum of 20 * adaptive_size -> min/max table * harden view size calculations against bad user input * style * add back an extra column of padding to adaptive resizing * back out: limit width to a minimum of 20 * revert unnecessary change * backout: view grow calculates size correctly based on sign column visibility * remove adaptive_size from help * backout unnecessary change M.View.config Co-authored-by: Alexander Courtis <alex@courtis.org>
1 parent 13adc94 commit 96506fe

File tree

4 files changed

+63
-21
lines changed

4 files changed

+63
-21
lines changed

doc/nvim-tree-lua.txt

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ Setup should be run in a lua file or in a |lua-heredoc| if using in a vim file.
8181
require("nvim-tree").setup({
8282
sort_by = "case_sensitive",
8383
view = {
84-
adaptive_size = true,
8584
mappings = {
8685
list = {
8786
{ key = "u", action = "dir_up" },
@@ -188,7 +187,6 @@ Subsequent calls to setup will replace the previous configuration.
188187
remove_keymaps = false,
189188
select_prompts = false,
190189
view = {
191-
adaptive_size = false,
192190
centralize_selection = false,
193191
cursorline = true,
194192
debounce_delay = 15,
@@ -709,10 +707,6 @@ Type: `boolean`, Default: `false`
709707
*nvim-tree.view*
710708
Window / buffer setup.
711709

712-
*nvim-tree.view.adaptive_size*
713-
Resize the window on each draw based on the longest line.
714-
Type: `boolean`, Default: `false`
715-
716710
*nvim-tree.view.centralize_selection*
717711
When entering nvim-tree, reposition the view so that the current node is
718712
initially centralized, see |zz|.
@@ -732,9 +726,19 @@ Window / buffer setup.
732726
Type: `boolean`, Default: `false`
733727

734728
*nvim-tree.view.width*
735-
Width of the window, can be a `%` string, a number representing columns or
736-
a function.
737-
Type: `string | number | function`, Default: `30`
729+
Width of the window: can be a `%` string, a number representing columns, a
730+
function or a table.
731+
A table indicates that the view should be dynamically sized based on the
732+
longest line (previously `view.adaptive_size`).
733+
Type: `string | number | function | table`, Default: `30`
734+
735+
*nvim-tree.view.width.min*
736+
Minimum dynamic width.
737+
Type: `string | number | function`, Default: `30`
738+
739+
*nvim-tree.view.width.max*
740+
Maximum dynamic width, -1 for unbounded.
741+
Type: `string | number | function`, Default: `-1`
738742

739743
*nvim-tree.view.side*
740744
Side of the tree, can be `"left"`, `"right"`.

lua/nvim-tree.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
513513
remove_keymaps = false,
514514
select_prompts = false,
515515
view = {
516-
adaptive_size = false,
517516
centralize_selection = false,
518517
cursorline = true,
519518
debounce_delay = 15,
@@ -744,7 +743,9 @@ local FIELD_SKIP_VALIDATE = {
744743
}
745744

746745
local FIELD_OVERRIDE_TYPECHECK = {
747-
width = { string = true, ["function"] = true, number = true },
746+
width = { string = true, ["function"] = true, number = true, ["table"] = true },
747+
max = { string = true, ["function"] = true, number = true },
748+
min = { string = true, ["function"] = true, number = true },
748749
remove_keymaps = { boolean = true, table = true },
749750
on_attach = { ["function"] = true, string = true },
750751
sort_by = { ["function"] = true, string = true },

lua/nvim-tree/legacy.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ local function refactored(opts)
3030

3131
-- 2023/01/08
3232
utils.move_missing_val(opts, "trash", "require_confirm", opts, "ui.confirm", "trash", true)
33+
34+
-- 2023/01/15
35+
if opts.view and opts.view.adaptive_size ~= nil then
36+
if opts.view.adaptive_size and type(opts.view.width) ~= "table" then
37+
local width = opts.view.width
38+
opts.view.width = {
39+
min = width,
40+
}
41+
end
42+
opts.view.adaptive_size = nil
43+
end
3344
end
3445

3546
local function removed(opts)

lua/nvim-tree/view.lua

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ local events = require "nvim-tree.events"
44
local utils = require "nvim-tree.utils"
55
local log = require "nvim-tree.log"
66

7+
local DEFAULT_MIN_WIDTH = 30
8+
local DEFAULT_MAX_WIDTH = -1
9+
710
M.View = {
811
adaptive_size = false,
912
centralize_selection = false,
@@ -98,8 +101,8 @@ local function create_buffer(bufnr)
98101
events._dispatch_tree_attached_post(M.get_bufnr())
99102
end
100103

101-
local function get_size()
102-
local size = M.View.width
104+
local function get_size(size)
105+
size = size or M.View.width
103106
if type(size) == "number" then
104107
return size
105108
elseif type(size) == "function" then
@@ -246,14 +249,29 @@ end
246249
local function grow()
247250
local starts_at = M.is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0
248251
local lines = vim.api.nvim_buf_get_lines(M.get_bufnr(), starts_at, -1, false)
249-
local max_length = M.View.initial_width
252+
-- 1 column of right-padding to indicate end of path
253+
local padding = 3
254+
local resizing_width = M.View.initial_width - padding
255+
local max_width
256+
257+
-- maybe bound max
258+
if M.View.max_width == -1 then
259+
max_width = -1
260+
else
261+
max_width = get_size(M.View.max_width) - padding
262+
end
263+
250264
for _, l in pairs(lines) do
251-
local count = vim.fn.strchars(l) + 3 -- plus some padding
252-
if max_length < count then
253-
max_length = count
265+
local count = vim.fn.strchars(l)
266+
if resizing_width < count then
267+
resizing_width = count
268+
end
269+
if M.View.adaptive_size and max_width >= 0 and resizing_width >= max_width then
270+
resizing_width = max_width
271+
break
254272
end
255273
end
256-
M.resize(max_length)
274+
M.resize(resizing_width + padding)
257275
end
258276

259277
function M.grow_from_content()
@@ -482,12 +500,9 @@ end
482500

483501
function M.setup(opts)
484502
local options = opts.view or {}
485-
M.View.adaptive_size = options.adaptive_size
486503
M.View.centralize_selection = options.centralize_selection
487504
M.View.side = (options.side == "right") and "right" or "left"
488-
M.View.width = options.width
489505
M.View.height = options.height
490-
M.View.initial_width = get_size()
491506
M.View.hide_root_folder = options.hide_root_folder
492507
M.View.tab = opts.tab
493508
M.View.preserve_window_proportions = options.preserve_window_proportions
@@ -497,6 +512,17 @@ function M.setup(opts)
497512
M.View.winopts.signcolumn = options.signcolumn
498513
M.View.float = options.float
499514
M.on_attach = opts.on_attach
515+
516+
if type(options.width) == "table" then
517+
M.View.adaptive_size = true
518+
M.View.width = options.width.min or DEFAULT_MIN_WIDTH
519+
M.View.max_width = options.width.max or DEFAULT_MAX_WIDTH
520+
else
521+
M.View.adaptive_size = false
522+
M.View.width = options.width
523+
end
524+
525+
M.View.initial_width = get_size()
500526
end
501527

502528
return M

0 commit comments

Comments
 (0)