Skip to content
Merged
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
10 changes: 10 additions & 0 deletions doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,15 @@ longest line.
Type: `string | number | fun(): number|string`
Default: `-1`

*nvim-tree.view.width.lines_excluded*
Exclude these lines when computing width.
Supported values: `"root".
Type: `table`
Default:
`{`
`"root"`
`}`

*nvim-tree.view.width.padding*
Extra padding to the right.
Type: `number | fun(): number|string`
Expand Down Expand Up @@ -3323,6 +3332,7 @@ highlight group is not, hard linking as follows: >
|nvim-tree.view.side|
|nvim-tree.view.signcolumn|
|nvim-tree.view.width|
|nvim-tree.view.width.lines_excluded|
|nvim-tree.view.width.max|
|nvim-tree.view.width.min|
|nvim-tree.view.width.padding|
Expand Down
67 changes: 43 additions & 24 deletions lua/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ local ACCEPTED_TYPES = {
"table",
min = { "string", "function", "number" },
max = { "string", "function", "number" },
lines_excluded = { "table" },
padding = { "function", "number" },
},
},
Expand Down Expand Up @@ -612,6 +613,14 @@ local ACCEPTED_STRINGS = {
},
}

local ACCEPTED_ENUMS = {
view = {
width = {
lines_excluded = { "root", },
},
},
}

---@param conf table|nil
local function validate_options(conf)
local msg
Expand All @@ -620,15 +629,19 @@ local function validate_options(conf)
---@param def any
---@param strs table
---@param types table
---@param enums table
---@param prefix string
local function validate(user, def, strs, types, prefix)
local function validate(user, def, strs, types, enums, prefix)
-- if user's option is not a table there is nothing to do
if type(user) ~= "table" then
return
end

-- only compare tables with contents that are not integer indexed
if type(def) ~= "table" or not next(def) or type(next(def)) == "number" then
-- we have hit a leaf enum to validate against - it's an integer indexed table
local enum_value = type(enums) == "table" and next(enums) and type(next(enums)) == "number"

-- only compare tables with contents that are not integer indexed nor enums
if not enum_value and (type(def) ~= "table" or not next(def) or type(next(def)) == "number") then
-- unless the field can be a table (and is not a table in default config)
if vim.tbl_contains(types, "table") then
-- use a dummy default to allow all checks
Expand All @@ -642,27 +655,33 @@ local function validate_options(conf)
if not FIELD_SKIP_VALIDATE[k] then
local invalid

if def[k] == nil and types[k] == nil then
-- option does not exist
invalid = string.format("Unknown option: %s%s", prefix, k)
elseif type(v) ~= type(def[k]) then
local expected

if types[k] and #types[k] > 0 then
if not vim.tbl_contains(types[k], type(v)) then
expected = table.concat(types[k], "|")
end
else
expected = type(def[k])
if enum_value then
if not vim.tbl_contains(enums, v) then
invalid = string.format("Invalid value for field %s%s: Expected one of enum '%s', got '%s'", prefix, k, table.concat(enums, "'|'"), tostring(v))
end
else
if def[k] == nil and types[k] == nil then
-- option does not exist
invalid = string.format("Unknown option: %s%s", prefix, k)
elseif type(v) ~= type(def[k]) then
local expected

if types[k] and #types[k] > 0 then
if not vim.tbl_contains(types[k], type(v)) then
expected = table.concat(types[k], "|")
end
else
expected = type(def[k])
end

if expected then
-- option is of the wrong type
invalid = string.format("Invalid option: %s%s. Expected %s, got %s", prefix, k, expected, type(v))
if expected then
-- option is of the wrong type
invalid = string.format("Invalid option: %s%s. Expected %s, got %s", prefix, k, expected, type(v))
end
elseif type(v) == "string" and strs[k] and not vim.tbl_contains(strs[k], v) then
-- option has type `string` but value is not accepted
invalid = string.format("Invalid value for field %s%s: '%s'", prefix, k, v)
end
elseif type(v) == "string" and strs[k] and not vim.tbl_contains(strs[k], v) then
-- option has type `string` but value is not accepted
invalid = string.format("Invalid value for field %s%s: '%s'", prefix, k, v)
end

if invalid then
Expand All @@ -672,14 +691,14 @@ local function validate_options(conf)
msg = invalid
end
user[k] = nil
else
validate(v, def[k], strs[k] or {}, types[k] or {}, prefix .. k .. ".")
elseif not enum_value then
validate(v, def[k], strs[k] or {}, types[k] or {}, enums[k] or {}, prefix .. k .. ".")
end
end
end
end

validate(conf, DEFAULT_OPTS, ACCEPTED_STRINGS, ACCEPTED_TYPES, "")
validate(conf, DEFAULT_OPTS, ACCEPTED_STRINGS, ACCEPTED_TYPES, ACCEPTED_ENUMS, "")

if msg then
notify.warn(msg .. "\n\nsee :help nvim-tree-opts for available configuration options")
Expand Down
33 changes: 16 additions & 17 deletions lua/nvim-tree/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ local M = {}

local DEFAULT_MIN_WIDTH = 30
local DEFAULT_MAX_WIDTH = -1
local DEFAULT_LINES_EXCLUDED = {
"root",
}
local DEFAULT_PADDING = 1

M.View = {
Expand Down Expand Up @@ -303,7 +306,7 @@ function M.open(options)
end

local function grow()
local starts_at = M.is_root_folder_visible(require("nvim-tree.core").get_cwd()) and 1 or 0
local starts_at = (M.is_root_folder_visible(require("nvim-tree.core").get_cwd()) and M.View.root_excluded) and 1 or 0
local lines = vim.api.nvim_buf_get_lines(M.get_bufnr(), starts_at, -1, false)
-- number of columns of right-padding to indicate end of path
local padding = get_size(M.View.padding)
Expand All @@ -314,31 +317,25 @@ local function grow()
padding = padding + wininfo[1].textoff
end

local resizing_width = M.View.initial_width - padding
local max_width

-- maybe bound max
if M.View.max_width == -1 then
max_width = -1
else
max_width = get_width(M.View.max_width) - padding
local final_width = M.View.initial_width
local max_width = math.huge
if M.View.max_width ~= -1 then
max_width = get_width(M.View.max_width)
end

local ns_id = vim.api.nvim_get_namespaces()["NvimTreeExtmarks"]
for line_nr, l in pairs(lines) do
local count = vim.fn.strchars(l)
local line_width = vim.fn.strchars(l)
-- also add space for right-aligned icons
local extmarks = vim.api.nvim_buf_get_extmarks(M.get_bufnr(), ns_id, { line_nr, 0 }, { line_nr, -1 }, { details = true })
count = count + utils.extmarks_length(extmarks)
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
line_width = line_width + utils.extmarks_length(extmarks) + padding
final_width = math.max(final_width, line_width)
if final_width >= max_width then
final_width = max_width
break
end
end
M.resize(resizing_width + padding)
M.resize(final_width)
end

function M.grow_from_content()
Expand Down Expand Up @@ -600,6 +597,8 @@ function M.configure_width(width)
M.View.adaptive_size = true
M.View.width = width.min or DEFAULT_MIN_WIDTH
M.View.max_width = width.max or DEFAULT_MAX_WIDTH
local lines_excluded = width.lines_excluded or DEFAULT_LINES_EXCLUDED
M.View.root_excluded = vim.tbl_contains(lines_excluded, "root")
M.View.padding = width.padding or DEFAULT_PADDING
elseif width == nil then
if M.config.width ~= nil then
Expand Down
Loading