Compare commits

...

12 Commits
v1 ... master

Author SHA1 Message Date
7c0f7e906a add padding first column
Some checks failed
CI / lint (5.1, 1.2.0) (push) Has been cancelled
CI / check (3.15.0, nightly) (push) Has been cancelled
CI / check (3.15.0, stable) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
2025-10-20 21:25:44 +03:00
Eric Wong
64e2192f52
feat: set filter input filetype to NvimTreeFilter (#3207)
feat: add NvimTreeFilter filetype
2025-10-20 00:50:08 +00:00
phanium
e397756d2a
fix: prevent NvimTree to be alternate buffer when tab open (#3205)
* fix: prevent NvimTree to be alternate buffer when tab open

* fix: prevent tabnew leave a dangling "[No Name]" buffer

* Update lua/nvim-tree/actions/node/open-file.lua

Co-authored-by: Alexander Courtis <alex@courtis.org>

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2025-10-08 10:57:48 +11:00
dependabot[bot]
87d096a39c
chore(deps): bump leafo/gh-actions-luarocks from 5 to 6 (#3201)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 10:52:12 +02:00
dependabot[bot]
01b2e8e5f7
chore(deps): bump leafo/gh-actions-lua from 11 to 12 (#3202)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 09:52:10 +02:00
Alexander Courtis
e179ad2f83
refactor(#2942): multi instance: move utils functions to Explorer methods (#3200)
* refactor(#2942): multi instance: move find_node_line to Explorer

* refactor(#2942): multi instance: move get_node_from_path to Explorer

* refactor(#2942): multi instance: move focus_file to Explorer

* refactor(#2942): multi instance: move focus_node_or_parent to Explorer

* refactor(#2942): multi instance: move get_node_from_path to Explorer

* refactor(#2942): multi instance: move find_node to Explorer

* refactor(#2942): multi instance: move get_nodes_by_line to Explorer

* refactor(#2942): multi instance: remove unnecessary focus_file

* refactor(#2942): style
2025-09-08 16:26:42 +10:00
Alexander Courtis
f92cc3a91c
chore(#3196): remove unused utils and refactor (#3199)
* chore(#3196): remove unused utils.read_file

* chore(#3196): move utils.move_missing_val to legacy

* chore(#3196): move utils.table_create_missing to legacy
2025-09-08 11:12:31 +10:00
Igor Lacerda
fefa335f1c
feat(#1826): add diagnostics.diagnostic_opts: vim.diagnostic.Opts will override diagnostics.severity and diagnostics.icons (#3190)
* feat(#1826): allow using config from vim.diagnostic for icons + severity

* update help default options, add index

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2025-08-25 13:22:05 +10:00
dependabot[bot]
b70a741f5a
chore(deps): bump amannn/action-semantic-pull-request from 6.1.0 to 6.1.1 (#3193)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 13:01:24 +02:00
dependabot[bot]
f4fa6ebd3c
chore(deps): bump amannn/action-semantic-pull-request from 6.0.1 to 6.1.0 (#3192)
chore(deps): bump amannn/action-semantic-pull-request

Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 6.0.1 to 6.1.0.
- [Release notes](https://github.com/amannn/action-semantic-pull-request/releases)
- [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v6.0.1...v6.1.0)

---
updated-dependencies:
- dependency-name: amannn/action-semantic-pull-request
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 13:44:53 +10:00
dependabot[bot]
f0e9951778
chore(deps): bump amannn/action-semantic-pull-request from 5.5.3 to 6.0.1 (#3189)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 14:31:09 +02:00
dependabot[bot]
feb901a09e
chore(deps): bump actions/checkout from 4 to 5 (#3188)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-13 09:08:14 +02:00
23 changed files with 288 additions and 270 deletions

View File

@ -24,15 +24,15 @@ jobs:
steps:
- name: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: install lua ${{ matrix.lua_version }}
uses: leafo/gh-actions-lua@v11
uses: leafo/gh-actions-lua@v12
with:
luaVersion: ${{ matrix.lua_version }}
- name: install luarocks
uses: leafo/gh-actions-luarocks@v5
uses: leafo/gh-actions-luarocks@v6
- name: install luacheck ${{ matrix.luacheck_version }}
run: luarocks install luacheck ${{ matrix.luacheck_version }}
@ -56,7 +56,7 @@ jobs:
steps:
- name: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: install nvim ${{ matrix.nvim_version }}
uses: rhysd/action-setup-vim@v1

View File

@ -10,7 +10,7 @@ jobs:
luarocks-upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: LuaRocks Upload
uses: nvim-neorocks/luarocks-tag-release@v7
env:

View File

@ -16,7 +16,7 @@ jobs:
steps:
- uses: google-github-actions/release-please-action@v4
id: release
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: tag major and minor versions
if: ${{ steps.release.outputs.release_created }}
run: |

View File

@ -14,6 +14,6 @@ jobs:
semantic-pr-subject:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5.5.3
- uses: amannn/action-semantic-pull-request@v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -545,6 +545,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua
warning = "",
error = "",
},
diagnostic_opts = false,
},
modified = {
enable = false,
@ -1329,6 +1330,10 @@ Icons for diagnostic severity.
error = ""
}
<
*nvim-tree.diagnostics.diagnostic_opts*
|vim.diagnostic.Opts| overrides |nvim-tree.diagnostics.severity| and
|nvim-tree.diagnostics.icons|
Type: `boolean`, Default: `false`
==============================================================================
5.9 OPTS: MODIFIED *nvim-tree-opts-modified*
@ -2334,6 +2339,7 @@ events.Event *nvim-tree-api.events.Event*
live_filter.start() *nvim-tree-api.live_filter.start()*
Enter |nvim-tree.live_filter| mode.
Opens an input window with |filetype| `"NvimTreeFilter"`
live_filter.clear() *nvim-tree-api.live_filter.clear()*
Exit |nvim-tree.live_filter| mode.
@ -3175,6 +3181,7 @@ highlight group is not, hard linking as follows: >
|nvim-tree.actions.use_system_clipboard|
|nvim-tree.auto_reload_on_write|
|nvim-tree.diagnostics.debounce_delay|
|nvim-tree.diagnostics.diagnostic_opts|
|nvim-tree.diagnostics.enable|
|nvim-tree.diagnostics.icons|
|nvim-tree.diagnostics.severity|

View File

@ -420,6 +420,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
warning = "",
error = "",
},
diagnostic_opts = false,
},
modified = {
enable = false,

View File

@ -32,7 +32,7 @@ function M.fn(path)
local profile = log.profile_start("find file %s", path_real)
-- refresh the contents of all parents, expanding groups as needed
if utils.get_node_from_path(path_real) == nil then
if explorer:get_node_from_path(path_real) == nil then
explorer:refresh_parent_nodes_for_path(vim.fn.fnamemodify(path_real, ":h"))
end

View File

@ -1,4 +1,3 @@
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local core = require("nvim-tree.core")
local diagnostics = require("nvim-tree.diagnostics")
@ -36,7 +35,7 @@ end
---@param skip_gitignored boolean? default false
local function move(explorer, where, what, skip_gitignored)
local first_node_line = core.get_nodes_starting_line()
local nodes_by_line = utils.get_nodes_by_line(explorer.nodes, first_node_line)
local nodes_by_line = explorer:get_nodes_by_line(first_node_line)
local iter_start, iter_end, iter_step, cur, first, nex
local cursor = explorer:get_cursor_position()
@ -191,7 +190,7 @@ local function move_prev_recursive(explorer, what, skip_gitignored)
if node_init.name == ".." then -- root node
view.set_cursor({ 1, 0 }) -- move to root node (position 1)
else
local node_init_line = utils.find_node_line(node_init)
local node_init_line = explorer:find_node_line(node_init)
if node_init_line < 0 then
return
end

View File

@ -1,6 +1,4 @@
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local DirectoryNode = require("nvim-tree.node.directory")
local M = {}
@ -29,7 +27,7 @@ function M.fn(should_close)
return
end
local _, line = utils.find_node(parent.explorer.nodes, function(n)
local _, line = parent.explorer:find_node(function(n)
return n.absolute_path == parent.absolute_path
end)

View File

@ -1,4 +1,3 @@
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local Iterator = require("nvim-tree.iterators.node-iterator")
@ -12,9 +11,14 @@ function M.fn(direction)
return
end
local explorer = core.get_explorer()
if not explorer then
return
end
local first, last, next, prev = nil, nil, nil, nil
local found = false
local parent = node.parent or core.get_explorer()
local parent = node.parent or explorer
Iterator.builder(parent and parent.nodes or {})
:recursor(function()
return nil
@ -45,7 +49,7 @@ function M.fn(direction)
end
if target_node then
utils.focus_file(target_node.absolute_path)
explorer:focus_node_or_parent(target_node)
end
end
end

View File

@ -198,7 +198,15 @@ local function open_file_in_tab(filename)
if M.relative_path then
filename = utils.path_relative(filename, vim.fn.getcwd())
end
vim.cmd("tabe " .. vim.fn.fnameescape(filename))
vim.cmd.tabnew()
vim.bo.bufhidden = "wipe"
-- Following vim.fn.tabnew the # buffer may be set to the tree buffer. There is no way to clear the # buffer via vim.fn.setreg as it requires a valid buffer. Clear # by setting it to a new temporary scratch buffer.
if utils.is_nvim_tree_buf(vim.fn.bufnr("#")) then
local tmpbuf = vim.api.nvim_create_buf(false, true)
vim.fn.setreg("#", tmpbuf)
vim.api.nvim_buf_delete(tmpbuf, { force = true })
end
vim.cmd.edit(vim.fn.fnameescape(filename))
end
local function drop(filename)

View File

@ -56,7 +56,7 @@ local function collapse(node, opts)
:iterate()
explorer.renderer:draw()
utils.focus_node_or_parent(node_at_cursor)
explorer:focus_node_or_parent(node_at_cursor)
end

View File

@ -231,7 +231,10 @@ end
function M.setup(opts)
M.enable = opts.diagnostics.enable
M.debounce_delay = opts.diagnostics.debounce_delay
M.severity = opts.diagnostics.severity
M.severity = opts.diagnostics.diagnostic_opts and {
min = vim.diagnostic.severity.HINT,
max = vim.diagnostic.severity.ERROR
} or opts.diagnostics.severity
if M.enable then
log.line("diagnostics", "setup")

View File

@ -280,7 +280,7 @@ function Filters:toggle(type)
local node = self.explorer:get_node_at_cursor()
self.explorer:reload_explorer()
if node then
utils.focus_node_or_parent(node)
self.explorer:focus_node_or_parent(node)
end
end

View File

@ -527,7 +527,7 @@ function Explorer:get_node_at_cursor()
return self
end
return utils.get_nodes_by_line(self.nodes, core.get_nodes_starting_line())[cursor[1]]
return self:get_nodes_by_line(core.get_nodes_starting_line())[cursor[1]]
end
function Explorer:place_cursor_on_node()
@ -551,6 +551,114 @@ function Explorer:place_cursor_on_node()
end
end
-- Find the line number of a node.
---@param node Node?
---@return integer -1 not found
function Explorer:find_node_line(node)
if not node then
return -1
end
local first_node_line = core.get_nodes_starting_line()
local nodes_by_line = self:get_nodes_by_line(first_node_line)
local iter_start, iter_end = first_node_line, #nodes_by_line
for line = iter_start, iter_end, 1 do
if nodes_by_line[line] == node then
return line
end
end
return -1
end
-- get the node in the tree state depending on the absolute path of the node
-- (grouped or hidden too)
---@param path string
---@return Node|nil
---@return number|nil
function Explorer:get_node_from_path(path)
if self.absolute_path == path then
return self
end
return Iterator.builder(self.nodes)
:hidden()
:matcher(function(node)
return node.absolute_path == path or node.link_to == path
end)
:recursor(function(node)
if node.group_next then
return { node.group_next }
end
if node.nodes then
return node.nodes
end
end)
:iterate()
end
---Focus node passed as parameter if visible, otherwise focus first visible parent.
---If none of the parents is visible focus root.
---If node is nil do nothing.
---@param node Node? node to focus
function Explorer:focus_node_or_parent(node)
while node do
local found_node, i = self:find_node(function(node_)
return node_.absolute_path == node.absolute_path
end)
if found_node or node.parent == nil then
view.set_cursor({ i + 1, 1 })
break
end
node = node.parent
end
end
--- Get the node and index of the node from the tree that matches the predicate.
--- The explored nodes are those displayed on the view.
---@param fn fun(node: Node): boolean
---@return table|nil
---@return number
function Explorer:find_node(fn)
local node, i = Iterator.builder(self.nodes)
:matcher(fn)
:recursor(function(node)
return node.group_next and { node.group_next } or (node.open and #node.nodes > 0 and node.nodes)
end)
:iterate()
i = view.is_root_folder_visible() and i or i - 1
if node and node.explorer.live_filter.filter then
i = i + 1
end
return node, i
end
--- Return visible nodes indexed by line
---@param line_start number
---@return table
function Explorer:get_nodes_by_line(line_start)
local nodes_by_line = {}
local line = line_start
Iterator.builder(self.nodes)
:applier(function(node)
if node.group_next then
return
end
nodes_by_line[line] = node
line = line + 1
end)
:recursor(function(node)
return node.group_next and { node.group_next } or (node.open and #node.nodes > 0 and node.nodes)
end)
:iterate()
return nodes_by_line
end
---Api.tree.get_nodes
---@return nvim_tree.api.Node
function Explorer:get_nodes()

View File

@ -188,8 +188,10 @@ local function create_overlay(self)
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", true, { buf = overlay_bufnr })
vim.api.nvim_set_option_value("filetype", "NvimTreeFilter", { buf = overlay_bufnr })
else
vim.api.nvim_buf_set_option(overlay_bufnr, "modifiable", true) ---@diagnostic disable-line: deprecated
vim.api.nvim_buf_set_option(overlay_bufnr, "filetype", "NvimTreeFilter") ---@diagnostic disable-line: deprecated
end
vim.api.nvim_buf_set_lines(overlay_bufnr, 0, -1, false, { self.filter })
@ -220,9 +222,9 @@ function LiveFilter:clear_filter()
self.explorer.renderer:draw()
if node then
utils.focus_file(node.absolute_path)
self.explorer:focus_node_or_parent(node)
elseif last_node then
utils.focus_file(last_node.absolute_path)
self.explorer:focus_node_or_parent(last_node)
end
end

View File

@ -233,7 +233,13 @@ local function reload_tree_at(toplevel)
end
log.line("watcher", "git event executing '%s'", toplevel)
local root_node = utils.get_node_from_path(toplevel)
local explorer = require("nvim-tree.core").get_explorer()
if not explorer then
return nil
end
local root_node = explorer:get_node_from_path(toplevel)
if not root_node then
return
end
@ -252,7 +258,7 @@ local function reload_tree_at(toplevel)
end)
:iterate()
root_node.explorer.renderer:draw()
explorer.renderer:draw()
end)
end

View File

@ -1,27 +1,74 @@
local utils = require("nvim-tree.utils")
local notify = require("nvim-tree.notify")
local M = {}
--- Create empty sub-tables if not present
---@param tbl table to create empty inside of
---@param path string dot separated string of sub-tables
---@return table deepest sub-table
local function create(tbl, path)
local t = tbl
for s in string.gmatch(path, "([^%.]+)%.*") do
if t[s] == nil then
t[s] = {}
end
t = t[s]
end
return t
end
--- Move a value from src to dst if value is nil on dst.
--- Remove value from src
---@param src table to copy from
---@param src_path string dot separated string of sub-tables
---@param src_pos string value pos
---@param dst table to copy to
---@param dst_path string dot separated string of sub-tables, created when missing
---@param dst_pos string value pos
---@param remove boolean
local function move(src, src_path, src_pos, dst, dst_path, dst_pos, remove)
for pos in string.gmatch(src_path, "([^%.]+)%.*") do
if src[pos] and type(src[pos]) == "table" then
src = src[pos]
else
return
end
end
local src_val = src[src_pos]
if src_val == nil then
return
end
dst = create(dst, dst_path)
if dst[dst_pos] == nil then
dst[dst_pos] = src_val
end
if remove then
src[src_pos] = nil
end
end
-- silently move, please add to help nvim-tree-legacy-opts
local function refactored(opts)
-- 2022/06/20
utils.move_missing_val(opts, "update_focused_file", "update_cwd", opts, "update_focused_file", "update_root", true)
utils.move_missing_val(opts, "", "update_cwd", opts, "", "sync_root_with_cwd", true)
move(opts, "update_focused_file", "update_cwd", opts, "update_focused_file", "update_root", true)
move(opts, "", "update_cwd", opts, "", "sync_root_with_cwd", true)
-- 2022/11/07
utils.move_missing_val(opts, "", "open_on_tab", opts, "tab.sync", "open", false)
utils.move_missing_val(opts, "", "open_on_tab", opts, "tab.sync", "close", true)
utils.move_missing_val(opts, "", "ignore_buf_on_tab_change", opts, "tab.sync", "ignore", true)
move(opts, "", "open_on_tab", opts, "tab.sync", "open", false)
move(opts, "", "open_on_tab", opts, "tab.sync", "close", true)
move(opts, "", "ignore_buf_on_tab_change", opts, "tab.sync", "ignore", true)
-- 2022/11/22
utils.move_missing_val(opts, "renderer", "root_folder_modifier", opts, "renderer", "root_folder_label", true)
move(opts, "renderer", "root_folder_modifier", opts, "renderer", "root_folder_label", true)
-- 2023/01/01
utils.move_missing_val(opts, "update_focused_file", "debounce_delay", opts, "view", "debounce_delay", true)
move(opts, "update_focused_file", "debounce_delay", opts, "view", "debounce_delay", true)
-- 2023/01/08
utils.move_missing_val(opts, "trash", "require_confirm", opts, "ui.confirm", "trash", true)
move(opts, "trash", "require_confirm", opts, "ui.confirm", "trash", true)
-- 2023/01/15
if type(opts.view) == "table" and opts.view.adaptive_size ~= nil then
@ -35,13 +82,13 @@ local function refactored(opts)
end
-- 2023/07/15
utils.move_missing_val(opts, "", "sort_by", opts, "sort", "sorter", true)
move(opts, "", "sort_by", opts, "sort", "sorter", true)
-- 2023/07/16
utils.move_missing_val(opts, "git", "ignore", opts, "filters", "git_ignored", true)
move(opts, "git", "ignore", opts, "filters", "git_ignored", true)
-- 2023/08/26
utils.move_missing_val(opts, "renderer.icons", "webdev_colors", opts, "renderer.icons.web_devicons.file", "color", true)
move(opts, "renderer.icons", "webdev_colors", opts, "renderer.icons.web_devicons.file", "color", true)
-- 2023/10/08
if type(opts.renderer) == "table" and type(opts.renderer.highlight_diagnostics) == "boolean" then
@ -59,7 +106,7 @@ local function refactored(opts)
opts.update_focused_file.update_root = { enable = opts.update_focused_file.update_root }
end
end
utils.move_missing_val(opts, "update_focused_file", "ignore_list", opts, "update_focused_file.update_root", "ignore_list", true)
move(opts, "update_focused_file", "ignore_list", opts, "update_focused_file.update_root", "ignore_list", true)
-- 2025/04/30
if opts.renderer and opts.renderer.icons and type(opts.renderer.icons.padding) == "string" then

View File

@ -227,9 +227,9 @@ function Marks:navigate(up)
end
if up then
utils.focus_node_or_parent(prev or last)
self.explorer:focus_node_or_parent(prev or last)
else
utils.focus_node_or_parent(next or first)
self.explorer:focus_node_or_parent(next or first)
end
end
@ -263,7 +263,7 @@ function Marks:navigate_select()
if node and not node:is(DirectoryNode) and not utils.get_win_buf_from_path(node.absolute_path) then
open_file.fn("edit", node.absolute_path)
elseif node then
utils.focus_file(node.absolute_path)
self.explorer:focus_node_or_parent(node)
end
end)
end

View File

@ -101,7 +101,7 @@ end
---@param end_ number|nil
function Builder:insert_highlight(groups, start, end_)
for _, higroup in ipairs(groups) do
table.insert(self.hl_range_args, { higroup = higroup, start = { self.index, start, }, finish = { self.index, end_ or -1, } })
table.insert(self.hl_range_args, { higroup = higroup, start = { self.index, start }, finish = { self.index, end_ or -1 } })
end
end
@ -381,8 +381,28 @@ end
function Builder:build_header()
if view.is_root_folder_visible(self.explorer.absolute_path) then
local root_name = self:format_root_name(self.explorer.opts.renderer.root_folder_label)
table.insert(self.lines, root_name)
self:insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name))
-- Pad to window width so the highlight spans the whole row.
local win = view.get_winnr()
local width = 0
if win and vim.api.nvim_win_is_valid(win) then
width = vim.api.nvim_win_get_width(win)
end
-- Use display width for proper padding with Nerd Font / wide glyphs.
local name_display_w = vim.fn.strdisplaywidth(root_name)
local pad = 0
if width and width > name_display_w then
pad = width - name_display_w
end
local padded_root = pad > 0 and (root_name .. string.rep(" ", pad)) or root_name
table.insert(self.lines, padded_root)
-- Highlight the entire padded string (covers the full visible row)
self:insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(padded_root))
-- Keep original indexing behavior
self.index = 1
end
@ -395,7 +415,6 @@ function Builder:build_header()
self.index = self.index + 1
end
end
---Sanitize lines for rendering.
---Replace newlines with literal \n
---@private
@ -449,7 +468,8 @@ function Builder:setup_hidden_display_function(opts)
local ok, result = pcall(hidden_display, hidden_stats)
if not ok then
notify.warn(
"Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree")
"Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree"
)
return nil
end
return result

View File

@ -22,8 +22,8 @@ local function check_siblings_for_folder(node, with_arrows)
end
local function get_padding_indent_markers(depth, idx, nodes_number, markers, with_arrows, inline_arrows, node, early_stop)
local base_padding = with_arrows and (not node.nodes or depth > 0) and " " or ""
local padding = (inline_arrows or depth == 0) and base_padding or ""
local base_padding = with_arrows and (not node.nodes or depth > 0) and " " or " "
local padding = (inline_arrows or depth == 0) and base_padding or " "
if depth > 0 then
local has_folder_sibling = check_siblings_for_folder(node, with_arrows)

View File

@ -47,11 +47,23 @@ function DiagnosticsDecorator:new(args)
self.highlight_range = self.explorer.opts.renderer.highlight_diagnostics or "none"
self.icon_placement = self.explorer.opts.renderer.icons.diagnostics_placement or "none"
local vim_diagnostic_icons = {}
if self.explorer.opts.diagnostics.diagnostic_opts then
local vim_diagnostic_config = vim.diagnostic.config() or {}
local signs = vim_diagnostic_config.signs or {}
if type(signs) == "function" then
signs = signs(0, 0)
end
vim_diagnostic_icons = (type(signs) == "table" and signs.text) or {}
end
if self.explorer.opts.renderer.icons.show.diagnostics then
self.diag_icons = {}
for name, sev in pairs(ICON_KEYS) do
self.diag_icons[sev] = {
str = self.explorer.opts.diagnostics.icons[name],
str = vim_diagnostic_icons[sev] or self.explorer.opts.diagnostics.icons[name],
hl = { HG_ICON[sev] },
}
self:define_sign(self.diag_icons[sev])

View File

@ -1,5 +1,3 @@
local Iterator = require("nvim-tree.iterators.node-iterator")
local M = {
debouncers = {},
}
@ -17,22 +15,6 @@ function M.str_find(haystack, needle)
return vim.fn.stridx(haystack, needle) ~= -1
end
---@param path string
---@return string|uv.uv_fs_t
function M.read_file(path)
local fd = vim.loop.fs_open(path, "r", 438)
if not fd then
return ""
end
local stat = vim.loop.fs_fstat(fd)
if not stat then
return ""
end
local data = vim.loop.fs_read(fd, stat.size, 0)
vim.loop.fs_close(fd)
return data or ""
end
local path_separator = package.config:sub(1, 1)
---@param paths string[]
---@return string
@ -130,48 +112,6 @@ end
M.path_separator = path_separator
--- Get the node and index of the node from the tree that matches the predicate.
--- The explored nodes are those displayed on the view.
---@param nodes Node[]
---@param fn fun(node: Node): boolean
---@return table|nil
---@return number
function M.find_node(nodes, fn)
local node, i = Iterator.builder(nodes)
:matcher(fn)
:recursor(function(node)
return node.group_next and { node.group_next } or (node.open and #node.nodes > 0 and node.nodes)
end)
:iterate()
i = require("nvim-tree.view").is_root_folder_visible() and i or i - 1
if node and node.explorer.live_filter.filter then
i = i + 1
end
return node, i
end
-- Find the line number of a node.
-- Return -1 is node is nil or not found.
---@param node Node?
---@return integer
function M.find_node_line(node)
if not node then
return -1
end
local first_node_line = require("nvim-tree.core").get_nodes_starting_line()
local nodes_by_line = M.get_nodes_by_line(require("nvim-tree.core").get_explorer().nodes, first_node_line)
local iter_start, iter_end = first_node_line, #nodes_by_line
for line = iter_start, iter_end, 1 do
if nodes_by_line[line] == node then
return line
end
end
return -1
end
---@param extmarks vim.api.keyset.get_extmark_item[] as per vim.api.nvim_buf_get_extmarks
---@return number
function M.extmarks_length(extmarks)
@ -187,39 +127,6 @@ function M.extmarks_length(extmarks)
return length
end
-- get the node in the tree state depending on the absolute path of the node
-- (grouped or hidden too)
---@param path string
---@return Node|nil
---@return number|nil
function M.get_node_from_path(path)
local explorer = require("nvim-tree.core").get_explorer()
-- tree may not yet be loaded
if not explorer then
return
end
if explorer.absolute_path == path then
return explorer
end
return Iterator.builder(explorer.nodes)
:hidden()
:matcher(function(node)
return node.absolute_path == path or node.link_to == path
end)
:recursor(function(node)
if node.group_next then
return { node.group_next }
end
if node.nodes then
return node.nodes
end
end)
:iterate()
end
M.default_format_hidden_count = function(hidden_count, simple)
local parts = {}
local total_count = 0
@ -240,30 +147,6 @@ M.default_format_hidden_count = function(hidden_count, simple)
return nil
end
--- Return visible nodes indexed by line
---@param nodes_all Node[]
---@param line_start number
---@return table
function M.get_nodes_by_line(nodes_all, line_start)
local nodes_by_line = {}
local line = line_start
Iterator.builder(nodes_all)
:applier(function(node)
if node.group_next then
return
end
nodes_by_line[line] = node
line = line + 1
end)
:recursor(function(node)
return node.group_next and { node.group_next } or (node.open and #node.nodes > 0 and node.nodes)
end)
:iterate()
return nodes_by_line
end
function M.rename_loaded_buffers(old_path, new_path)
-- delete new if it exists
for _, buf in pairs(vim.api.nvim_list_bufs()) do
@ -377,54 +260,6 @@ function M.escape_special_chars(path)
return M.is_windows and escape_special_char_for_windows(path) or path
end
--- Create empty sub-tables if not present
---@param tbl table to create empty inside of
---@param path string dot separated string of sub-tables
---@return table deepest sub-table
function M.table_create_missing(tbl, path)
local t = tbl
for s in string.gmatch(path, "([^%.]+)%.*") do
if t[s] == nil then
t[s] = {}
end
t = t[s]
end
return t
end
--- Move a value from src to dst if value is nil on dst.
--- Remove value from src
---@param src table to copy from
---@param src_path string dot separated string of sub-tables
---@param src_pos string value pos
---@param dst table to copy to
---@param dst_path string dot separated string of sub-tables, created when missing
---@param dst_pos string value pos
---@param remove boolean
function M.move_missing_val(src, src_path, src_pos, dst, dst_path, dst_pos, remove)
for pos in string.gmatch(src_path, "([^%.]+)%.*") do
if src[pos] and type(src[pos]) == "table" then
src = src[pos]
else
return
end
end
local src_val = src[src_pos]
if src_val == nil then
return
end
dst = M.table_create_missing(dst, dst_path)
if dst[dst_pos] == nil then
dst[dst_pos] = src_val
end
if remove then
src[src_pos] = nil
end
end
local function round(value)
-- Amount of digits to round to after floating point.
local digits = 2
@ -533,38 +368,6 @@ function M.debounce(context, timeout, callback)
end)
end
function M.focus_file(path)
local _, i = M.find_node(require("nvim-tree.core").get_explorer().nodes, function(node)
return node.absolute_path == path
end)
require("nvim-tree.view").set_cursor({ i + 1, 1 })
end
---Focus node passed as parameter if visible, otherwise focus first visible parent.
---If none of the parents is visible focus root.
---If node is nil do nothing.
---@param node Node? node to focus
function M.focus_node_or_parent(node)
local explorer = require("nvim-tree.core").get_explorer()
if explorer == nil then
return
end
while node do
local found_node, i = M.find_node(explorer.nodes, function(node_)
return node_.absolute_path == node.absolute_path
end)
if found_node or node.parent == nil then
require("nvim-tree.view").set_cursor({ i + 1, 1 })
break
end
node = node.parent
end
end
---@param path string
---@return integer|nil
---@return integer|nil