Compare commits

...

10 Commits

Author SHA1 Message Date
github-actions[bot]
f1b3e6a7eb release nvim-tree 0.99.0 (#2587)
* chore(master): release nvim-tree 0.99.0

* doc: tidy changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-01-01 12:46:40 +11:00
Alexander Courtis
b6b86e1f3e chore: release 0.99.0
Release-As: 0.99.0
2024-01-01 12:40:29 +11:00
Alexander Courtis
fac4900bd1 fix(#2609): help toggle (#2611) 2024-01-01 12:36:57 +11:00
Azad
f779abaf2a refactor: improve API readability and tidy actions submodules (#2593)
* refactor: improve API readability, tidy actions modules

* Apply requested changes

* `actions/reloaders/reloaders.lua` -> `actions/reloaders.lua`

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2023-12-31 15:52:27 +11:00
Devansh Sharma
dc839a72a6 feat: add kind param to vim.ui.select function calls (#2602)
* feat: add kind param to vim.ui.select function calls

* feat: add kind param to prompts for bookmark actions

* docs: add section for prompts

* docs: add section for prompts

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2023-12-31 15:37:16 +11:00
geril2207
02ae52357b fix: hijack_cursor on update focused file and vim search (#2600)
refactor: hijack_cursor search skip
2023-12-31 14:40:58 +11:00
Max
96a783fbd6 fix(#2519): Diagnostics Not Updated When Tree Not Visible (#2597)
* fix(#2519): diagnostics overhaul

Signed-off-by: iusmac <iusico.maxim@libero.it>

* fix: Properly filter diagnostics from coc

Also, while we're at it, refactor the lsp function for consistency.
There should be no functional change, just cosmetic.

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Assign diagnostic version per node to reduce overhead

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Require renderer once

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Revert "Require renderer once"

Causes circular requires after the previous commit.

This reverts commit 7413041630.

* Rename `buffer_severity_dict` to `BUFFER_SEVERITY`

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Log diagnostics update properly

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Implement error handling for coc.nvim

Signed-off-by: iusmac <iusico.maxim@libero.it>

* CI style fixes

Signed-off-by: iusmac <iusico.maxim@libero.it>

* Capture `Keyboard interrupt` when handling coc exceptions

Signed-off-by: iusmac <iusico.maxim@libero.it>

* add more doc

---------

Signed-off-by: iusmac <iusico.maxim@libero.it>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2023-12-30 14:30:07 +11:00
Azad
50f30bcd8c feat: add option to skip gitignored files on git navigation (#2583)
* feat: add option to skip gitignored files on git navigation

* Add API bindings

* stylua: ignore
2023-12-19 11:29:01 +01:00
Alexander Courtis
8f92e1edd3 feat(#1850): add "no bookmark" filter (#2571)
* feat(#1850): add no bookmark filter

* feat(#1850): add no bookmark filter - style
2023-12-19 16:18:24 +11:00
gegoune
141c0f97c3 chore: first release (#2588) 2023-12-11 01:36:12 +01:00
32 changed files with 474 additions and 226 deletions

View File

@@ -1,3 +1,3 @@
{ {
".": "0.0.0" ".": "0.99.0"
} }

17
CHANGELOG.md Normal file
View File

@@ -0,0 +1,17 @@
# Changelog
## 0.99.0 (2024-01-01)
### Features
* **#1850:** add "no bookmark" filter ([#2571](https://github.com/nvim-tree/nvim-tree.lua/issues/2571)) ([8f92e1e](https://github.com/nvim-tree/nvim-tree.lua/commit/8f92e1edd399f839a23776dcc6eee4ba18030370))
* add kind param to vim.ui.select function calls ([#2602](https://github.com/nvim-tree/nvim-tree.lua/issues/2602)) ([dc839a7](https://github.com/nvim-tree/nvim-tree.lua/commit/dc839a72a6496ce22ebd3dd959115cf97c1b20a0))
* add option to skip gitignored files on git navigation ([#2583](https://github.com/nvim-tree/nvim-tree.lua/issues/2583)) ([50f30bc](https://github.com/nvim-tree/nvim-tree.lua/commit/50f30bcd8c62ac4a83d133d738f268279f2c2ce2))
### Bug Fixes
* **#2519:** Diagnostics Not Updated When Tree Not Visible ([#2597](https://github.com/nvim-tree/nvim-tree.lua/issues/2597)) ([96a783f](https://github.com/nvim-tree/nvim-tree.lua/commit/96a783fbd606a458bcce2ef8041240a8b94510ce))
* **#2609:** help toggle ([#2611](https://github.com/nvim-tree/nvim-tree.lua/issues/2611)) ([fac4900](https://github.com/nvim-tree/nvim-tree.lua/commit/fac4900bd18a9fa15be3d104645d9bdef7b3dcec))
* hijack_cursor on update focused file and vim search ([#2600](https://github.com/nvim-tree/nvim-tree.lua/issues/2600)) ([02ae523](https://github.com/nvim-tree/nvim-tree.lua/commit/02ae52357ba4da77a4c120390791584a81d15340))

View File

@@ -47,8 +47,9 @@ CONTENTS *nvim-tree*
7.1 Mappings: Default |nvim-tree-mappings-default| 7.1 Mappings: Default |nvim-tree-mappings-default|
8. Highlight |nvim-tree-highlight| 8. Highlight |nvim-tree-highlight|
9. Events |nvim-tree-events| 9. Events |nvim-tree-events|
10. OS Specific Restrictions |nvim-tree-os-specific| 10. Prompts |nvim-tree-prompts|
11. Netrw |nvim-tree-netrw| 11. OS Specific Restrictions |nvim-tree-os-specific|
12. Netrw |nvim-tree-netrw|
============================================================================== ==============================================================================
1. INTRODUCTION *nvim-tree-introduction* 1. INTRODUCTION *nvim-tree-introduction*
@@ -170,14 +171,15 @@ Show the mappings: `g?`
`e` Rename: Basename |nvim-tree-api.fs.rename_basename()| `e` Rename: Basename |nvim-tree-api.fs.rename_basename()|
`]e` Next Diagnostic |nvim-tree-api.node.navigate.diagnostics.next()| `]e` Next Diagnostic |nvim-tree-api.node.navigate.diagnostics.next()|
`[e` Prev Diagnostic |nvim-tree-api.node.navigate.diagnostics.prev()| `[e` Prev Diagnostic |nvim-tree-api.node.navigate.diagnostics.prev()|
`F` Clean Filter |nvim-tree-api.live_filter.clear()| `F` Live Filter: Clear |nvim-tree-api.live_filter.clear()|
`f` Filter |nvim-tree-api.live_filter.start()| `f` Live Filter: Start |nvim-tree-api.live_filter.start()|
`g?` Help |nvim-tree-api.tree.toggle_help()| `g?` Help |nvim-tree-api.tree.toggle_help()|
`gy` Copy Absolute Path |nvim-tree-api.fs.copy.absolute_path()| `gy` Copy Absolute Path |nvim-tree-api.fs.copy.absolute_path()|
`H` Toggle Filter: Dotfiles |nvim-tree-api.tree.toggle_hidden_filter()| `H` Toggle Filter: Dotfiles |nvim-tree-api.tree.toggle_hidden_filter()|
`I` Toggle Filter: Git Ignore |nvim-tree-api.tree.toggle_gitignore_filter()| `I` Toggle Filter: Git Ignore |nvim-tree-api.tree.toggle_gitignore_filter()|
`J` Last Sibling |nvim-tree-api.node.navigate.sibling.last()| `J` Last Sibling |nvim-tree-api.node.navigate.sibling.last()|
`K` First Sibling |nvim-tree-api.node.navigate.sibling.first()| `K` First Sibling |nvim-tree-api.node.navigate.sibling.first()|
`M` Toggle Filter: No Bookmark |nvim-tree-api.tree.toggle_no_bookmark_filter()|
`m` Toggle Bookmark |nvim-tree-api.marks.toggle()| `m` Toggle Bookmark |nvim-tree-api.marks.toggle()|
`o` Open |nvim-tree-api.node.open.edit()| `o` Open |nvim-tree-api.node.open.edit()|
`O` Open: No Window Picker |nvim-tree-api.node.open.no_window_picker()| `O` Open: No Window Picker |nvim-tree-api.node.open.no_window_picker()|
@@ -502,6 +504,7 @@ Following is the default configuration. See |nvim-tree-opts| for details.
dotfiles = false, dotfiles = false,
git_clean = false, git_clean = false,
no_buffer = false, no_buffer = false,
no_bookmark = false,
custom = {}, custom = {},
exclude = {}, exclude = {},
}, },
@@ -1223,6 +1226,12 @@ For performance reasons this may not immediately update on buffer
delete/wipe. A reload or filesystem event will result in an update. delete/wipe. A reload or filesystem event will result in an update.
Type: `boolean`, Default: `false` Type: `boolean`, Default: `false`
*nvim-tree.filters.no_bookmark*
Do not show files that are not bookarked.
Toggle via |nvim-tree-api.tree.toggle_no_bookmark_filter()|, default `M`
Enabling this is not useful as there is no means yet to persist bookmarks.
Type: `boolean`, Default: `false`
*nvim-tree.filters.custom* *nvim-tree.filters.custom*
Custom list of vim regex for file/directory names that will not be shown. Custom list of vim regex for file/directory names that will not be shown.
Backslashes must be escaped e.g. "^\\.git". See |string-match|. Backslashes must be escaped e.g. "^\\.git". See |string-match|.
@@ -1666,6 +1675,10 @@ tree.toggle_git_clean_filter()
tree.toggle_no_buffer_filter() tree.toggle_no_buffer_filter()
Toggle |nvim-tree.filters.no_buffer| filter. Toggle |nvim-tree.filters.no_buffer| filter.
*nvim-tree-api.tree.toggle_no_bookmark_filter()*
tree.toggle_no_bookmark_filter()
Toggle |nvim-tree.filters.no_bookmark| filter.
*nvim-tree-api.tree.toggle_custom_filter()* *nvim-tree-api.tree.toggle_custom_filter()*
tree.toggle_custom_filter() tree.toggle_custom_filter()
Toggle |nvim-tree.filters.custom| filter. Toggle |nvim-tree.filters.custom| filter.
@@ -1862,9 +1875,17 @@ node.open.preview_no_picker() *nvim-tree-api.node.open.preview_no_picker()*
node.navigate.git.next() *nvim-tree-api.node.navigate.git.next()* node.navigate.git.next() *nvim-tree-api.node.navigate.git.next()*
Navigate to the next item showing git status. Navigate to the next item showing git status.
*nvim-tree-api.node.navigate.git.next_skip_gitignored()*
node.navigate.git.next_skip_gitignored()
Same as |node.navigate.git.next()|, but skips gitignored files.
node.navigate.git.prev() *nvim-tree-api.node.navigate.git.prev()* node.navigate.git.prev() *nvim-tree-api.node.navigate.git.prev()*
Navigate to the previous item showing git status. Navigate to the previous item showing git status.
*nvim-tree-api.node.navigate.git.prev_skip_gitignored()*
node.navigate.git.prev_skip_gitignored()
Same as |node.navigate.git.prev()|, but skips gitignored files.
*nvim-tree-api.node.navigate.diagnostics.next()* *nvim-tree-api.node.navigate.diagnostics.next()*
node.navigate.diagnostics.next() node.navigate.diagnostics.next()
Navigate to the next item showing diagnostic status. Navigate to the next item showing diagnostic status.
@@ -2138,14 +2159,15 @@ You are encouraged to copy these to your own |nvim-tree.on_attach| function.
vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename')) vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename'))
vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic')) vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic'))
vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic')) vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic'))
vim.keymap.set('n', 'F', api.live_filter.clear, opts('Clean Filter')) vim.keymap.set('n', 'F', api.live_filter.clear, opts('Live Filter: Clear'))
vim.keymap.set('n', 'f', api.live_filter.start, opts('Filter')) vim.keymap.set('n', 'f', api.live_filter.start, opts('Live Filter: Start'))
vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help')) vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path')) vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles')) vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles'))
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore')) vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling')) vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling')) vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark')) vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open')) vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker')) vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker'))
@@ -2421,7 +2443,32 @@ Example subscription: >
}) })
< <
============================================================================== ==============================================================================
10. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific* 10. PROMPTS *nvim-tree-prompts*
Some NvimTree actions use the builtin |vim.ui.select| prompt API for
confirmations when the |nvim_tree.select_prompts| option is set.
The API accepts the optional `kind` key as part of the {opts} parameter, which
can can be used to identify the type of prompt, to allow user side
configurations for different types of prompts.
- `nvimtree_overwrite_rename`
overwrite or rename during |nvim-tree-api.fs.paste()|
- `nvimtree_remove`
delete during |nvim-tree-api.fs.remove()|
- `nvimtree_trash`
send to trash during |nvim-tree-api.fs.trash()|
- `nvimtree_bulk_delete`
delete all bookmarked during |nvim-tree-api.marks.bulk.delete()|
- `nvimtree_bulk_trash`
send all bookmarked to trash during |nvim-tree-api.marks.bulk.trash()|
==============================================================================
11. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific*
macOS macOS
- Rename to different case is not possible when using a case insensitive file - Rename to different case is not possible when using a case insensitive file
@@ -2434,7 +2481,7 @@ Windows WSL and PowerShell
- Some filesystem watcher error related to permissions will not be reported - Some filesystem watcher error related to permissions will not be reported
============================================================================== ==============================================================================
11. NETRW *nvim-tree-netrw* 12. NETRW *nvim-tree-netrw*
|netrw| is a standard neovim plugin that is enabled by default. It provides, |netrw| is a standard neovim plugin that is enabled by default. It provides,
amongst other functionality, a file/directory browser. amongst other functionality, a file/directory browser.

View File

@@ -5,14 +5,12 @@ local renderer = require "nvim-tree.renderer"
local view = require "nvim-tree.view" local view = require "nvim-tree.view"
local commands = require "nvim-tree.commands" local commands = require "nvim-tree.commands"
local utils = require "nvim-tree.utils" local utils = require "nvim-tree.utils"
local change_dir = require "nvim-tree.actions.root.change-dir" local actions = require "nvim-tree.actions"
local legacy = require "nvim-tree.legacy" local legacy = require "nvim-tree.legacy"
local core = require "nvim-tree.core" local core = require "nvim-tree.core"
local reloaders = require "nvim-tree.actions.reloaders.reloaders"
local git = require "nvim-tree.git" local git = require "nvim-tree.git"
local filters = require "nvim-tree.explorer.filters" local filters = require "nvim-tree.explorer.filters"
local modified = require "nvim-tree.modified" local modified = require "nvim-tree.modified"
local find_file = require "nvim-tree.actions.tree.find-file"
local events = require "nvim-tree.events" local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify" local notify = require "nvim-tree.notify"
@@ -51,7 +49,7 @@ function M.change_root(path, bufnr)
-- test if in vim_cwd -- test if in vim_cwd
if utils.path_relative(path, vim_cwd) ~= path then if utils.path_relative(path, vim_cwd) ~= path then
if vim_cwd ~= cwd then if vim_cwd ~= cwd then
change_dir.fn(vim_cwd) actions.root.change_dir.fn(vim_cwd)
end end
return return
end end
@@ -62,19 +60,19 @@ function M.change_root(path, bufnr)
-- otherwise test M.init_root -- otherwise test M.init_root
if _config.prefer_startup_root and utils.path_relative(path, M.init_root) ~= path then if _config.prefer_startup_root and utils.path_relative(path, M.init_root) ~= path then
change_dir.fn(M.init_root) actions.root.change_dir.fn(M.init_root)
return return
end end
-- otherwise root_dirs -- otherwise root_dirs
for _, dir in pairs(_config.root_dirs) do for _, dir in pairs(_config.root_dirs) do
dir = vim.fn.fnamemodify(dir, ":p") dir = vim.fn.fnamemodify(dir, ":p")
if utils.path_relative(path, dir) ~= path then if utils.path_relative(path, dir) ~= path then
change_dir.fn(dir) actions.root.change_dir.fn(dir)
return return
end end
end end
-- finally fall back to the folder containing the file -- finally fall back to the folder containing the file
change_dir.fn(vim.fn.fnamemodify(path, ":p:h")) actions.root.change_dir.fn(vim.fn.fnamemodify(path, ":p:h"))
end end
function M.tab_enter() function M.tab_enter()
@@ -87,7 +85,7 @@ function M.tab_enter()
end end
end end
view.open { focus_tree = false } view.open { focus_tree = false }
require("nvim-tree.renderer").draw() renderer.draw()
end end
end end
@@ -103,7 +101,7 @@ function M.open_on_directory()
return return
end end
change_dir.force_dirchange(bufname, true) actions.root.change_dir.force_dirchange(bufname, true)
end end
function M.reset_highlight() function M.reset_highlight()
@@ -112,13 +110,11 @@ function M.reset_highlight()
renderer.render_hl(view.get_bufnr()) renderer.render_hl(view.get_bufnr())
end end
local prev_line
function M.place_cursor_on_node() function M.place_cursor_on_node()
local l = vim.api.nvim_win_get_cursor(0)[1] local search = vim.fn.searchcount()
if l == prev_line then if search and search.exact_match == 1 then
return return
end end
prev_line = l
local node = lib.get_node_at_cursor() local node = lib.get_node_at_cursor()
if not node or node.name == ".." then if not node or node.name == ".." then
@@ -156,11 +152,11 @@ end
---@param name string|nil ---@param name string|nil
function M.change_dir(name) function M.change_dir(name)
if name then if name then
change_dir.fn(name) actions.root.change_dir.fn(name)
end end
if _config.update_focused_file.enable then if _config.update_focused_file.enable then
find_file.fn() actions.tree.find_file.fn()
end end
end end
@@ -193,7 +189,7 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd("BufWritePost", { create_nvim_tree_autocmd("BufWritePost", {
callback = function() callback = function()
if opts.auto_reload_on_write and not opts.filesystem_watchers.enable then if opts.auto_reload_on_write and not opts.filesystem_watchers.enable then
reloaders.reload_explorer() actions.reloaders.reload_explorer()
end end
end, end,
}) })
@@ -203,7 +199,7 @@ local function setup_autocommands(opts)
-- update opened file buffers -- update opened file buffers
if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function() utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
reloaders.reload_explorer() actions.reloaders.reload_explorer()
end) end)
end end
end, end,
@@ -214,7 +210,7 @@ local function setup_autocommands(opts)
-- update opened file buffers -- update opened file buffers
if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function() utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
reloaders.reload_explorer(nil, data.buf) actions.reloaders.reload_explorer(nil, data.buf)
end) end)
end end
end, end,
@@ -224,7 +220,7 @@ local function setup_autocommands(opts)
pattern = { "FugitiveChanged", "NeogitStatusRefreshed" }, pattern = { "FugitiveChanged", "NeogitStatusRefreshed" },
callback = function() callback = function()
if not opts.filesystem_watchers.enable and opts.git.enable then if not opts.filesystem_watchers.enable and opts.git.enable then
reloaders.reload_git() actions.reloaders.reload_git()
end end
end, end,
}) })
@@ -253,7 +249,7 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd("BufEnter", { create_nvim_tree_autocmd("BufEnter", {
callback = function() callback = function()
utils.debounce("BufEnter:find_file", opts.view.debounce_delay, function() utils.debounce("BufEnter:find_file", opts.view.debounce_delay, function()
find_file.fn() actions.tree.find_file.fn()
end) end)
end, end,
}) })
@@ -268,7 +264,7 @@ local function setup_autocommands(opts)
callback = function() callback = function()
if utils.is_nvim_tree_buf(0) then if utils.is_nvim_tree_buf(0) then
if vim.fn.getcwd() ~= core.get_cwd() or (opts.reload_on_bufenter and not opts.filesystem_watchers.enable) then if vim.fn.getcwd() ~= core.get_cwd() or (opts.reload_on_bufenter and not opts.filesystem_watchers.enable) then
reloaders.reload_explorer() actions.reloaders.reload_explorer()
end end
end end
end, end,
@@ -319,7 +315,7 @@ local function setup_autocommands(opts)
callback = function() callback = function()
utils.debounce("Buf:modified", opts.view.debounce_delay, function() utils.debounce("Buf:modified", opts.view.debounce_delay, function()
modified.reload() modified.reload()
reloaders.reload_explorer() actions.reloaders.reload_explorer()
end) end)
end, end,
}) })
@@ -507,6 +503,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
dotfiles = false, dotfiles = false,
git_clean = false, git_clean = false,
no_buffer = false, no_buffer = false,
no_bookmark = false,
custom = {}, custom = {},
exclude = {}, exclude = {},
}, },

View File

@@ -0,0 +1,6 @@
local M = {}
M.find_file = require "nvim-tree.actions.finders.find-file"
M.search_node = require "nvim-tree.actions.finders.search-node"
return M

View File

@@ -5,7 +5,7 @@ local core = require "nvim-tree.core"
local events = require "nvim-tree.events" local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify" local notify = require "nvim-tree.notify"
local renderer = require "nvim-tree.renderer" local renderer = require "nvim-tree.renderer"
local reloaders = require "nvim-tree.actions.reloaders.reloaders" local reloaders = require "nvim-tree.actions.reloaders"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION local HL_POSITION = require("nvim-tree.enum").HL_POSITION
@@ -131,7 +131,7 @@ local function do_single_paste(source, dest, action_type, action_fn)
else else
local prompt_select = "Overwrite " .. dest .. " ?" local prompt_select = "Overwrite " .. dest .. " ?"
local prompt_input = prompt_select .. " R(ename)/y/n: " local prompt_input = prompt_select .. " R(ename)/y/n: "
lib.prompt(prompt_input, prompt_select, { "", "y", "n" }, { "Rename", "Yes", "No" }, function(item_short) lib.prompt(prompt_input, prompt_select, { "", "y", "n" }, { "Rename", "Yes", "No" }, "nvimtree_overwrite_rename", function(item_short)
utils.clear_prompt() utils.clear_prompt()
if item_short == "y" then if item_short == "y" then
on_process() on_process()

View File

@@ -0,0 +1,16 @@
local M = {}
M.copy_paste = require "nvim-tree.actions.fs.copy-paste"
M.create_file = require "nvim-tree.actions.fs.create-file"
M.remove_file = require "nvim-tree.actions.fs.remove-file"
M.rename_file = require "nvim-tree.actions.fs.rename-file"
M.trash = require "nvim-tree.actions.fs.trash"
function M.setup(opts)
M.copy_paste.setup(opts)
M.remove_file.setup(opts)
M.rename_file.setup(opts)
M.trash.setup(opts)
end
return M

View File

@@ -112,7 +112,7 @@ function M.fn(node)
local function do_remove() local function do_remove()
M.remove(node) M.remove(node)
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() require("nvim-tree.actions.reloaders").reload_explorer()
end end
end end
@@ -130,7 +130,7 @@ function M.fn(node)
items_long = { "No", "Yes" } items_long = { "No", "Yes" }
end end
lib.prompt(prompt_input, prompt_select, items_short, items_long, function(item_short) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_remove", function(item_short)
utils.clear_prompt() utils.clear_prompt()
if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then
do_remove() do_remove()

View File

@@ -102,7 +102,7 @@ function M.fn(default_modifier)
M.rename(node, prepend .. new_file_path .. append) M.rename(node, prepend .. new_file_path .. append)
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() require("nvim-tree.actions.reloaders").reload_explorer()
end end
find_file(utils.path_remove_trailing(new_file_path)) find_file(utils.path_remove_trailing(new_file_path))

View File

@@ -1,5 +1,6 @@
local lib = require "nvim-tree.lib" local lib = require "nvim-tree.lib"
local notify = require "nvim-tree.notify" local notify = require "nvim-tree.notify"
local reloaders = require "nvim-tree.actions.reloaders"
local M = { local M = {
config = {}, config = {},
@@ -59,7 +60,7 @@ function M.remove(node)
end end
events._dispatch_folder_removed(node.absolute_path) events._dispatch_folder_removed(node.absolute_path)
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() reloaders.reload_explorer()
end end
end) end)
else else
@@ -72,7 +73,7 @@ function M.remove(node)
events._dispatch_file_removed(node.absolute_path) events._dispatch_file_removed(node.absolute_path)
clear_buffer(node.absolute_path) clear_buffer(node.absolute_path)
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() reloaders.reload_explorer()
end end
end) end)
end end
@@ -102,7 +103,7 @@ function M.fn(node)
items_long = { "No", "Yes" } items_long = { "No", "Yes" }
end end
lib.prompt(prompt_input, prompt_select, items_short, items_long, function(item_short) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_trash", function(item_short)
utils.clear_prompt() utils.clear_prompt()
if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then
do_trash() do_trash()

View File

@@ -1,18 +1,18 @@
local M = {} local M = {}
M.finders = require "nvim-tree.actions.finders"
M.fs = require "nvim-tree.actions.fs"
M.moves = require "nvim-tree.actions.moves"
M.node = require "nvim-tree.actions.node"
M.reloaders = require "nvim-tree.actions.reloaders"
M.root = require "nvim-tree.actions.root"
M.tree = require "nvim-tree.actions.tree"
function M.setup(opts) function M.setup(opts)
require("nvim-tree.actions.fs.trash").setup(opts) M.fs.setup(opts)
require("nvim-tree.actions.node.system-open").setup(opts) M.node.setup(opts)
require("nvim-tree.actions.node.file-popup").setup(opts) M.root.setup(opts)
require("nvim-tree.actions.node.open-file").setup(opts) M.tree.setup(opts)
require("nvim-tree.actions.root.change-dir").setup(opts)
require("nvim-tree.actions.fs.rename-file").setup(opts)
require("nvim-tree.actions.fs.remove-file").setup(opts)
require("nvim-tree.actions.fs.copy-paste").setup(opts)
require("nvim-tree.actions.tree-modifiers.expand-all").setup(opts)
require("nvim-tree.actions.tree.find-file").setup(opts)
require("nvim-tree.actions.tree.open").setup(opts)
require("nvim-tree.actions.tree.toggle").setup(opts)
end end
return M return M

View File

@@ -0,0 +1,7 @@
local M = {}
M.item = require "nvim-tree.actions.moves.item"
M.parent = require "nvim-tree.actions.moves.parent"
M.sibling = require "nvim-tree.actions.moves.sibling"
return M

View File

@@ -3,6 +3,7 @@ local view = require "nvim-tree.view"
local core = require "nvim-tree.core" local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib" local lib = require "nvim-tree.lib"
local explorer_node = require "nvim-tree.explorer.node" local explorer_node = require "nvim-tree.explorer.node"
local diagnostics = require "nvim-tree.diagnostics"
local M = {} local M = {}
@@ -30,9 +31,11 @@ function M.fn(opts)
local valid = false local valid = false
if opts.what == "git" then if opts.what == "git" then
valid = explorer_node.get_git_status(node) ~= nil local git_status = explorer_node.get_git_status(node)
valid = git_status ~= nil and (not opts.skip_gitignored or git_status[1] ~= "!!")
elseif opts.what == "diag" then elseif opts.what == "diag" then
valid = node.diag_status ~= nil local diag_status = diagnostics.get_diag_status(node)
valid = diag_status ~= nil and diag_status.value ~= nil
elseif opts.what == "opened" then elseif opts.what == "opened" then
valid = vim.fn.bufloaded(node.absolute_path) ~= 0 valid = vim.fn.bufloaded(node.absolute_path) ~= 0
end end

View File

@@ -0,0 +1,14 @@
local M = {}
M.file_popup = require "nvim-tree.actions.node.file-popup"
M.open_file = require "nvim-tree.actions.node.open-file"
M.run_command = require "nvim-tree.actions.node.run-command"
M.system_open = require "nvim-tree.actions.node.system-open"
function M.setup(opts)
require("nvim-tree.actions.node.system-open").setup(opts)
require("nvim-tree.actions.node.file-popup").setup(opts)
require("nvim-tree.actions.node.open-file").setup(opts)
end
return M

View File

@@ -0,0 +1,10 @@
local M = {}
M.change_dir = require "nvim-tree.actions.root.change-dir"
M.dir_up = require "nvim-tree.actions.root.dir-up"
function M.setup(opts)
M.change_dir.setup(opts)
end
return M

View File

@@ -0,0 +1,15 @@
local M = {}
M.find_file = require "nvim-tree.actions.tree.find-file"
M.modifiers = require "nvim-tree.actions.tree.modifiers"
M.open = require "nvim-tree.actions.tree.open"
M.toggle = require "nvim-tree.actions.tree.toggle"
function M.setup(opts)
M.find_file.setup(opts)
M.modifiers.setup(opts)
M.open.setup(opts)
M.toggle.setup(opts)
end
return M

View File

@@ -0,0 +1,11 @@
local M = {}
M.collapse_all = require "nvim-tree.actions.tree.modifiers.collapse-all"
M.expand_all = require "nvim-tree.actions.tree.modifiers.expand-all"
M.toggles = require "nvim-tree.actions.tree.modifiers.toggles"
function M.setup(opts)
M.expand_all.setup(opts)
end
return M

View File

@@ -1,7 +1,7 @@
local lib = require "nvim-tree.lib" local lib = require "nvim-tree.lib"
local utils = require "nvim-tree.utils" local utils = require "nvim-tree.utils"
local filters = require "nvim-tree.explorer.filters" local filters = require "nvim-tree.explorer.filters"
local reloaders = require "nvim-tree.actions.reloaders.reloaders" local reloaders = require "nvim-tree.actions.reloaders"
local M = {} local M = {}
@@ -31,6 +31,11 @@ function M.no_buffer()
reload() reload()
end end
function M.no_bookmark()
filters.config.filter_no_bookmark = not filters.config.filter_no_bookmark
reload()
end
function M.dotfiles() function M.dotfiles()
filters.config.filter_dotfiles = not filters.config.filter_dotfiles filters.config.filter_dotfiles = not filters.config.filter_dotfiles
reload() reload()

View File

@@ -1,3 +1,16 @@
local lib = require "nvim-tree.lib"
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local actions = require "nvim-tree.actions"
local events = require "nvim-tree.events"
local help = require "nvim-tree.help"
local live_filter = require "nvim-tree.live-filter"
local marks = require "nvim-tree.marks"
local marks_navigation = require "nvim-tree.marks.navigation"
local marks_bulk_delete = require "nvim-tree.marks.bulk-delete"
local marks_bulk_trash = require "nvim-tree.marks.bulk-trash"
local marks_bulk_move = require "nvim-tree.marks.bulk-move"
local keymap = require "nvim-tree.keymap"
local notify = require "nvim-tree.notify" local notify = require "nvim-tree.notify"
local Api = { local Api = {
@@ -45,7 +58,7 @@ end
---@param fn function function to invoke ---@param fn function function to invoke
local function wrap_node(fn) local function wrap_node(fn)
return function(node, ...) return function(node, ...)
node = node or require("nvim-tree.lib").get_node_at_cursor() node = node or lib.get_node_at_cursor()
if node then if node then
fn(node, ...) fn(node, ...)
end end
@@ -56,7 +69,7 @@ end
---@param fn function function to invoke ---@param fn function function to invoke
local function wrap_node_or_nil(fn) local function wrap_node_or_nil(fn)
return function(node, ...) return function(node, ...)
node = node or require("nvim-tree.lib").get_node_at_cursor() node = node or lib.get_node_at_cursor()
fn(node, ...) fn(node, ...)
end end
end end
@@ -68,7 +81,8 @@ end
---@field find_file boolean|nil default false ---@field find_file boolean|nil default false
---@field update_root boolean|nil default false ---@field update_root boolean|nil default false
Api.tree.open = wrap(require("nvim-tree.actions.tree.open").fn) Api.tree.open = wrap(actions.tree.open.fn)
Api.tree.focus = Api.tree.open
---@class ApiTreeToggleOpts ---@class ApiTreeToggleOpts
---@field path string|nil ---@field path string|nil
@@ -78,19 +92,11 @@ Api.tree.open = wrap(require("nvim-tree.actions.tree.open").fn)
---@field update_root boolean|nil default false ---@field update_root boolean|nil default false
---@field focus boolean|nil default true ---@field focus boolean|nil default true
Api.tree.toggle = wrap(require("nvim-tree.actions.tree.toggle").fn) Api.tree.toggle = wrap(actions.tree.toggle.fn)
Api.tree.close = wrap(view.close)
Api.tree.close = wrap(require("nvim-tree.view").close) Api.tree.close_in_this_tab = wrap(view.close_this_tab_only)
Api.tree.close_in_all_tabs = wrap(view.close_all_tabs)
Api.tree.close_in_this_tab = wrap(require("nvim-tree.view").close_this_tab_only) Api.tree.reload = wrap(actions.reloaders.reload_explorer)
Api.tree.close_in_all_tabs = wrap(require("nvim-tree.view").close_all_tabs)
Api.tree.focus = wrap(function()
Api.tree.open()
end)
Api.tree.reload = wrap(require("nvim-tree.actions.reloaders.reloaders").reload_explorer)
Api.tree.change_root = wrap(function(...) Api.tree.change_root = wrap(function(...)
require("nvim-tree").change_dir(...) require("nvim-tree").change_dir(...)
@@ -98,17 +104,15 @@ end)
Api.tree.change_root_to_node = wrap_node(function(node) Api.tree.change_root_to_node = wrap_node(function(node)
if node.name == ".." then if node.name == ".." then
require("nvim-tree.actions.root.change-dir").fn ".." actions.root.change_dir.fn ".."
elseif node.nodes ~= nil then elseif node.nodes ~= nil then
require("nvim-tree.actions.root.change-dir").fn(require("nvim-tree.lib").get_last_group_node(node).absolute_path) actions.root.change_dir.fn(lib.get_last_group_node(node).absolute_path)
end end
end) end)
Api.tree.change_root_to_parent = wrap_node(require("nvim-tree.actions.root.dir-up").fn) Api.tree.change_root_to_parent = wrap_node(actions.root.dir_up.fn)
Api.tree.get_node_under_cursor = wrap(lib.get_node_at_cursor)
Api.tree.get_node_under_cursor = wrap(require("nvim-tree.lib").get_node_at_cursor) Api.tree.get_nodes = wrap(lib.get_nodes)
Api.tree.get_nodes = wrap(require("nvim-tree.lib").get_nodes)
---@class ApiTreeFindFileOpts ---@class ApiTreeFindFileOpts
---@field buf string|number|nil ---@field buf string|number|nil
@@ -118,55 +122,46 @@ Api.tree.get_nodes = wrap(require("nvim-tree.lib").get_nodes)
---@field update_root boolean|nil default false ---@field update_root boolean|nil default false
---@field focus boolean|nil default false ---@field focus boolean|nil default false
Api.tree.find_file = wrap(require("nvim-tree.actions.tree.find-file").fn) Api.tree.find_file = wrap(actions.tree.find_file.fn)
Api.tree.search_node = wrap(actions.finders.search_node.fn)
Api.tree.search_node = wrap(require("nvim-tree.actions.finders.search-node").fn) Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse_all.fn)
Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand_all.fn)
Api.tree.collapse_all = wrap(require("nvim-tree.actions.tree-modifiers.collapse-all").fn) Api.tree.toggle_gitignore_filter = wrap(actions.tree.modifiers.toggles.git_ignored)
Api.tree.toggle_git_clean_filter = wrap(actions.tree.modifiers.toggles.git_clean)
Api.tree.expand_all = wrap_node(require("nvim-tree.actions.tree-modifiers.expand-all").fn) Api.tree.toggle_no_buffer_filter = wrap(actions.tree.modifiers.toggles.no_buffer)
Api.tree.toggle_custom_filter = wrap(actions.tree.modifiers.toggles.custom)
Api.tree.toggle_gitignore_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").git_ignored) Api.tree.toggle_hidden_filter = wrap(actions.tree.modifiers.toggles.dotfiles)
Api.tree.toggle_no_bookmark_filter = wrap(actions.tree.modifiers.toggles.no_bookmark)
Api.tree.toggle_git_clean_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").git_clean) Api.tree.toggle_help = wrap(help.toggle)
Api.tree.is_tree_buf = wrap(utils.is_nvim_tree_buf)
Api.tree.toggle_no_buffer_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").no_buffer)
Api.tree.toggle_custom_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").custom)
Api.tree.toggle_hidden_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").dotfiles)
Api.tree.toggle_help = wrap(require("nvim-tree.help").toggle)
Api.tree.is_tree_buf = wrap(require("nvim-tree.utils").is_nvim_tree_buf)
---@class ApiTreeIsVisibleOpts ---@class ApiTreeIsVisibleOpts
---@field tabpage number|nil ---@field tabpage number|nil
---@field any_tabpage boolean|nil default false ---@field any_tabpage boolean|nil default false
Api.tree.is_visible = wrap(require("nvim-tree.view").is_visible) Api.tree.is_visible = wrap(view.is_visible)
---@class ApiTreeWinIdOpts ---@class ApiTreeWinIdOpts
---@field tabpage number|nil default nil ---@field tabpage number|nil default nil
Api.tree.winid = wrap(require("nvim-tree.view").winid) Api.tree.winid = wrap(view.winid)
Api.fs.create = wrap_node_or_nil(require("nvim-tree.actions.fs.create-file").fn) Api.fs.create = wrap_node_or_nil(actions.fs.create_file.fn)
Api.fs.remove = wrap_node(require("nvim-tree.actions.fs.remove-file").fn) Api.fs.remove = wrap_node(actions.fs.remove_file.fn)
Api.fs.trash = wrap_node(require("nvim-tree.actions.fs.trash").fn) Api.fs.trash = wrap_node(actions.fs.trash.fn)
Api.fs.rename_node = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t") Api.fs.rename_node = wrap_node(actions.fs.rename_file.fn ":t")
Api.fs.rename = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t") Api.fs.rename = wrap_node(actions.fs.rename_file.fn ":t")
Api.fs.rename_sub = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":p:h") Api.fs.rename_sub = wrap_node(actions.fs.rename_file.fn ":p:h")
Api.fs.rename_basename = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t:r") Api.fs.rename_basename = wrap_node(actions.fs.rename_file.fn ":t:r")
Api.fs.rename_full = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":p") Api.fs.rename_full = wrap_node(actions.fs.rename_file.fn ":p")
Api.fs.cut = wrap_node(require("nvim-tree.actions.fs.copy-paste").cut) Api.fs.cut = wrap_node(actions.fs.copy_paste.cut)
Api.fs.paste = wrap_node(require("nvim-tree.actions.fs.copy-paste").paste) Api.fs.paste = wrap_node(actions.fs.copy_paste.paste)
Api.fs.clear_clipboard = wrap(require("nvim-tree.actions.fs.copy-paste").clear_clipboard) Api.fs.clear_clipboard = wrap(actions.fs.copy_paste.clear_clipboard)
Api.fs.print_clipboard = wrap(require("nvim-tree.actions.fs.copy-paste").print_clipboard) Api.fs.print_clipboard = wrap(actions.fs.copy_paste.print_clipboard)
Api.fs.copy.node = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy) Api.fs.copy.node = wrap_node(actions.fs.copy_paste.copy)
Api.fs.copy.absolute_path = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_absolute_path) Api.fs.copy.absolute_path = wrap_node(actions.fs.copy_paste.copy_absolute_path)
Api.fs.copy.filename = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_filename) Api.fs.copy.filename = wrap_node(actions.fs.copy_paste.copy_filename)
Api.fs.copy.relative_path = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_path) Api.fs.copy.relative_path = wrap_node(actions.fs.copy_paste.copy_path)
---@param mode string ---@param mode string
---@param node table ---@param node table
@@ -175,7 +170,7 @@ local function edit(mode, node)
if node.link_to and not node.nodes then if node.link_to and not node.nodes then
path = node.link_to path = node.link_to
end end
require("nvim-tree.actions.node.open-file").fn(mode, path) actions.node.open_file.fn(mode, path)
end end
---@param mode string ---@param mode string
@@ -183,9 +178,9 @@ end
local function open_or_expand_or_dir_up(mode) local function open_or_expand_or_dir_up(mode)
return function(node) return function(node)
if node.name == ".." then if node.name == ".." then
require("nvim-tree.actions.root.change-dir").fn ".." actions.root.change_dir.fn ".."
elseif node.nodes then elseif node.nodes then
require("nvim-tree.lib").expand_or_collapse(node) lib.expand_or_collapse(node)
else else
edit(mode, node) edit(mode, node)
end end
@@ -203,50 +198,47 @@ Api.node.open.tab = wrap_node(open_or_expand_or_dir_up "tabnew")
Api.node.open.preview = wrap_node(open_or_expand_or_dir_up "preview") Api.node.open.preview = wrap_node(open_or_expand_or_dir_up "preview")
Api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up "preview_no_picker") Api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up "preview_no_picker")
Api.node.show_info_popup = wrap_node(require("nvim-tree.actions.node.file-popup").toggle_file_info) Api.node.show_info_popup = wrap_node(actions.node.file_popup.toggle_file_info)
Api.node.run.cmd = wrap_node(require("nvim-tree.actions.node.run-command").run_file_command) Api.node.run.cmd = wrap_node(actions.node.run_command.run_file_command)
Api.node.run.system = wrap_node(require("nvim-tree.actions.node.system-open").fn) Api.node.run.system = wrap_node(actions.node.system_open.fn)
Api.node.navigate.sibling.next = wrap_node(require("nvim-tree.actions.moves.sibling").fn "next")
Api.node.navigate.sibling.prev = wrap_node(require("nvim-tree.actions.moves.sibling").fn "prev")
Api.node.navigate.sibling.first = wrap_node(require("nvim-tree.actions.moves.sibling").fn "first")
Api.node.navigate.sibling.last = wrap_node(require("nvim-tree.actions.moves.sibling").fn "last")
Api.node.navigate.parent = wrap_node(require("nvim-tree.actions.moves.parent").fn(false))
Api.node.navigate.parent_close = wrap_node(require("nvim-tree.actions.moves.parent").fn(true))
Api.node.navigate.git.next = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "next", what = "git" })
Api.node.navigate.git.prev = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "prev", what = "git" })
Api.node.navigate.diagnostics.next = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "next", what = "diag" })
Api.node.navigate.diagnostics.prev = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "prev", what = "diag" })
Api.node.navigate.opened.next = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "next", what = "opened" })
Api.node.navigate.opened.prev = wrap_node(require("nvim-tree.actions.moves.item").fn { where = "prev", what = "opened" })
Api.git.reload = wrap(require("nvim-tree.actions.reloaders.reloaders").reload_git) Api.node.navigate.sibling.next = wrap_node(actions.moves.sibling.fn "next")
Api.node.navigate.sibling.prev = wrap_node(actions.moves.sibling.fn "prev")
Api.node.navigate.sibling.first = wrap_node(actions.moves.sibling.fn "first")
Api.node.navigate.sibling.last = wrap_node(actions.moves.sibling.fn "last")
Api.node.navigate.parent = wrap_node(actions.moves.parent.fn(false))
Api.node.navigate.parent_close = wrap_node(actions.moves.parent.fn(true))
Api.node.navigate.git.next = wrap_node(actions.moves.item.fn { where = "next", what = "git" })
Api.node.navigate.git.next_skip_gitignored = wrap_node(actions.moves.item.fn { where = "next", what = "git", skip_gitignored = true })
Api.node.navigate.git.prev = wrap_node(actions.moves.item.fn { where = "prev", what = "git" })
Api.node.navigate.git.prev_skip_gitignored = wrap_node(actions.moves.item.fn { where = "prev", what = "git", skip_gitignored = true })
Api.node.navigate.diagnostics.next = wrap_node(actions.moves.item.fn { where = "next", what = "diag" })
Api.node.navigate.diagnostics.prev = wrap_node(actions.moves.item.fn { where = "prev", what = "diag" })
Api.node.navigate.opened.next = wrap_node(actions.moves.item.fn { where = "next", what = "opened" })
Api.node.navigate.opened.prev = wrap_node(actions.moves.item.fn { where = "prev", what = "opened" })
Api.events.subscribe = require("nvim-tree.events").subscribe Api.git.reload = wrap(actions.reloaders.reload_git)
Api.events.Event = require("nvim-tree.events").Event
Api.live_filter.start = wrap(require("nvim-tree.live-filter").start_filtering) Api.events.subscribe = events.subscribe
Api.live_filter.clear = wrap(require("nvim-tree.live-filter").clear_filter) Api.events.Event = events.Event
Api.marks.get = wrap_node(require("nvim-tree.marks").get_mark) Api.live_filter.start = wrap(live_filter.start_filtering)
Api.marks.list = wrap(require("nvim-tree.marks").get_marks) Api.live_filter.clear = wrap(live_filter.clear_filter)
Api.marks.toggle = wrap_node(require("nvim-tree.marks").toggle_mark)
Api.marks.clear = wrap(require("nvim-tree.marks").clear_marks)
Api.marks.bulk.delete = wrap(require("nvim-tree.marks.bulk-delete").bulk_delete)
Api.marks.bulk.trash = wrap(require("nvim-tree.marks.bulk-trash").bulk_trash)
Api.marks.bulk.move = wrap(require("nvim-tree.marks.bulk-move").bulk_move)
Api.marks.navigate.next = wrap(require("nvim-tree.marks.navigation").next)
Api.marks.navigate.prev = wrap(require("nvim-tree.marks.navigation").prev)
Api.marks.navigate.select = wrap(require("nvim-tree.marks.navigation").select)
Api.config.mappings.default_on_attach = require("nvim-tree.keymap").default_on_attach Api.marks.get = wrap_node(marks.get_mark)
Api.marks.list = wrap(marks.get_marks)
Api.marks.toggle = wrap_node(marks.toggle_mark)
Api.marks.clear = wrap(marks.clear_marks)
Api.marks.bulk.delete = wrap(marks_bulk_delete.bulk_delete)
Api.marks.bulk.trash = wrap(marks_bulk_trash.bulk_trash)
Api.marks.bulk.move = wrap(marks_bulk_move.bulk_move)
Api.marks.navigate.next = wrap(marks_navigation.next)
Api.marks.navigate.prev = wrap(marks_navigation.prev)
Api.marks.navigate.select = wrap(marks_navigation.select)
Api.config.mappings.get_keymap = wrap(function() Api.config.mappings.get_keymap = wrap(keymap.get_keymap)
return require("nvim-tree.keymap").get_keymap() Api.config.mappings.get_keymap_default = wrap(keymap.get_keymap_default)
end) Api.config.mappings.default_on_attach = keymap.default_on_attach
Api.config.mappings.get_keymap_default = wrap(function()
return require("nvim-tree.keymap").get_keymap_default()
end)
Api.commands.get = wrap(function() Api.commands.get = wrap(function()
return require("nvim-tree.commands").get() return require("nvim-tree.commands").get()

View File

@@ -1,18 +1,44 @@
local utils = require "nvim-tree.utils" local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view" local view = require "nvim-tree.view"
local core = require "nvim-tree.core"
local log = require "nvim-tree.log" local log = require "nvim-tree.log"
local M = {} local M = {}
local severity_levels = { ---TODO add "$VIMRUNTIME" to "workspace.library" and use the @enum instead of this integer
---@alias lsp.DiagnosticSeverity integer
---COC severity level strings to LSP severity levels
---@enum COC_SEVERITY_LEVELS
local COC_SEVERITY_LEVELS = {
Error = 1, Error = 1,
Warning = 2, Warning = 2,
Information = 3, Information = 3,
Hint = 4, Hint = 4,
} }
---@return table ---Absolute Node path to LSP severity level
---@alias NodeSeverities table<string, lsp.DiagnosticSeverity>
---@class DiagStatus
---@field value lsp.DiagnosticSeverity|nil
---@field cache_version integer
--- The buffer-severity mappings derived during the last diagnostic list update.
---@type NodeSeverities
local NODE_SEVERITIES = {}
---The cache version number of the buffer-severity mappings.
---@type integer
local NODE_SEVERITIES_VERSION = 0
---@param path string
---@return string
local function uniformize_path(path)
return utils.canonical_path(path:gsub("\\", "/"))
end
---Marshal severities from LSP. Does nothing when LSP disabled.
---@return NodeSeverities
local function from_nvim_lsp() local function from_nvim_lsp()
local buffer_severity = {} local buffer_severity = {}
@@ -25,11 +51,10 @@ local function from_nvim_lsp()
for _, diagnostic in ipairs(vim.diagnostic.get(nil, { severity = M.severity })) do for _, diagnostic in ipairs(vim.diagnostic.get(nil, { severity = M.severity })) do
local buf = diagnostic.bufnr local buf = diagnostic.bufnr
if vim.api.nvim_buf_is_valid(buf) then if vim.api.nvim_buf_is_valid(buf) then
local bufname = vim.api.nvim_buf_get_name(buf) local bufname = uniformize_path(vim.api.nvim_buf_get_name(buf))
local lowest_severity = buffer_severity[bufname] local severity = diagnostic.severity
if not lowest_severity or diagnostic.severity < lowest_severity then local highest_severity = buffer_severity[bufname] or severity
buffer_severity[bufname] = diagnostic.severity buffer_severity[bufname] = math.min(highest_severity, severity)
end
end end
end end
end end
@@ -37,91 +62,148 @@ local function from_nvim_lsp()
return buffer_severity return buffer_severity
end end
---@param severity integer ---Severity is within diagnostics.severity.min, diagnostics.severity.max
---@param severity lsp.DiagnosticSeverity
---@param config table ---@param config table
---@return boolean ---@return boolean
local function is_severity_in_range(severity, config) local function is_severity_in_range(severity, config)
return config.max <= severity and severity <= config.min return config.max <= severity and severity <= config.min
end end
---@return table ---Handle any COC exceptions, preventing any propagation
---@param err string
local function handle_coc_exception(err)
log.line("diagnostics", "handle_coc_exception: %s", vim.inspect(err))
local notify = true
-- avoid distractions on interrupts (CTRL-C)
if err:find "Vim:Interrupt" or err:find "Keyboard interrupt" then
notify = false
end
if notify then
require("nvim-tree.notify").error("Diagnostics update from coc.nvim failed. " .. vim.inspect(err))
end
end
---COC service initialized
---@return boolean
local function is_using_coc()
return vim.g.coc_service_initialized == 1
end
---Marshal severities from COC. Does nothing when COC service not started.
---@return NodeSeverities
local function from_coc() local function from_coc()
if vim.g.coc_service_initialized ~= 1 then if not is_using_coc() then
return {} return {}
end end
local diagnostic_list = vim.fn.CocAction "diagnosticList" local ok, diagnostic_list = xpcall(function()
if type(diagnostic_list) ~= "table" or vim.tbl_isempty(diagnostic_list) then return vim.fn.CocAction "diagnosticList"
end, handle_coc_exception)
if not ok or type(diagnostic_list) ~= "table" or vim.tbl_isempty(diagnostic_list) then
return {} return {}
end end
local diagnostics = {}
for _, diagnostic in ipairs(diagnostic_list) do
local bufname = diagnostic.file
local coc_severity = severity_levels[diagnostic.severity]
local serverity = diagnostics[bufname] or vim.diagnostic.severity.HINT
diagnostics[bufname] = math.min(coc_severity, serverity)
end
local buffer_severity = {} local buffer_severity = {}
for bufname, severity in pairs(diagnostics) do for _, diagnostic in ipairs(diagnostic_list) do
if is_severity_in_range(severity, M.severity) then local bufname = uniformize_path(diagnostic.file)
buffer_severity[bufname] = severity local coc_severity = COC_SEVERITY_LEVELS[diagnostic.severity]
local highest_severity = buffer_severity[bufname] or coc_severity
if is_severity_in_range(highest_severity, M.severity) then
buffer_severity[bufname] = math.min(highest_severity, coc_severity)
end end
end end
return buffer_severity return buffer_severity
end end
local function is_using_coc() ---Maybe retrieve severity level from the cache
return vim.g.coc_service_initialized == 1 ---@param node Node
---@return DiagStatus
local function from_cache(node)
local nodepath = uniformize_path(node.absolute_path)
local max_severity = nil
if not node.nodes then
-- direct cache hit for files
max_severity = NODE_SEVERITIES[nodepath]
else
-- dirs should be searched in the list of cached buffer names by prefix
for bufname, severity in pairs(NODE_SEVERITIES) do
local node_contains_buf = vim.startswith(bufname, nodepath .. "/")
if node_contains_buf then
if severity == M.severity.max then
max_severity = severity
break
else
max_severity = math.min(max_severity or severity, severity)
end
end
end
end
return { value = max_severity, cache_version = NODE_SEVERITIES_VERSION }
end end
---Fired on DiagnosticChanged and CocDiagnosticChanged events:
---debounced retrieval, cache update, version increment and draw
function M.update() function M.update()
if not M.enable or not core.get_explorer() or not view.is_buf_valid(view.get_bufnr()) then if not M.enable then
return return
end end
utils.debounce("diagnostics", M.debounce_delay, function() utils.debounce("diagnostics", M.debounce_delay, function()
local profile = log.profile_start "diagnostics update" local profile = log.profile_start "diagnostics update"
log.line("diagnostics", "update")
local buffer_severity
if is_using_coc() then if is_using_coc() then
buffer_severity = from_coc() NODE_SEVERITIES = from_coc()
else else
buffer_severity = from_nvim_lsp() NODE_SEVERITIES = from_nvim_lsp()
end
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())
for _, node in pairs(nodes_by_line) do
node.diag_status = nil
end
for bufname, severity in pairs(buffer_severity) do
local bufpath = utils.canonical_path(bufname)
log.line("diagnostics", " bufpath '%s' severity %d", bufpath, severity)
if 0 < severity and severity < 5 then
for line, node in pairs(nodes_by_line) do
local nodepath = utils.canonical_path(node.absolute_path)
log.line("diagnostics", " %d checking nodepath '%s'", line, nodepath)
local node_contains_buf = vim.startswith(bufpath:gsub("\\", "/"), nodepath:gsub("\\", "/") .. "/")
if M.show_on_dirs and node_contains_buf and (not node.open or M.show_on_open_dirs) then
log.line("diagnostics", " matched fold node '%s'", node.absolute_path)
node.diag_status = severity
elseif nodepath == bufpath then
log.line("diagnostics", " matched file node '%s'", node.absolute_path)
node.diag_status = severity
end
end end
NODE_SEVERITIES_VERSION = NODE_SEVERITIES_VERSION + 1
if log.enabled "diagnostics" then
for bufname, severity in pairs(NODE_SEVERITIES) do
log.line("diagnostics", "Indexing bufname '%s' with severity %d", bufname, severity)
end end
end end
log.profile_end(profile) log.profile_end(profile)
if view.is_buf_valid(view.get_bufnr()) then
require("nvim-tree.renderer").draw() require("nvim-tree.renderer").draw()
end
end) end)
end end
---Maybe retrieve diagnostic status for a node.
---Returns cached value when node's version matches.
---@param node Node
---@return DiagStatus|nil
function M.get_diag_status(node)
if not M.enable then
return nil
end
-- dir but we shouldn't show on dirs at all
if node.nodes ~= nil and not M.show_on_dirs then
return nil
end
-- here, we do a lazy update of the diagnostic status carried by the node.
-- This is by design, as diagnostics and nodes live in completely separate
-- worlds, and this module is the link between the two
if not node.diag_status or node.diag_status.cache_version < NODE_SEVERITIES_VERSION then
node.diag_status = from_cache(node)
end
-- file
if not node.nodes then
return node.diag_status
end
-- dir is closed or we should show on open_dirs
if not node.open or M.show_on_open_dirs then
return node.diag_status
end
return nil
end
function M.setup(opts) function M.setup(opts)
M.enable = opts.diagnostics.enable M.enable = opts.diagnostics.enable
M.debounce_delay = opts.diagnostics.debounce_delay M.debounce_delay = opts.diagnostics.debounce_delay

View File

@@ -1,4 +1,5 @@
local utils = require "nvim-tree.utils" local utils = require "nvim-tree.utils"
local marks = require "nvim-tree.marks"
local M = { local M = {
ignore_list = {}, ignore_list = {},
@@ -69,6 +70,12 @@ local function dotfile(path)
return M.config.filter_dotfiles and utils.path_basename(path):sub(1, 1) == "." return M.config.filter_dotfiles and utils.path_basename(path):sub(1, 1) == "."
end end
---@param path string
---@param bookmarks table<string, boolean> absolute paths bookmarked
local function bookmark(path, bookmarks)
return M.config.filter_no_bookmark and not bookmarks[path]
end
---@param path string ---@param path string
---@return boolean ---@return boolean
local function custom(path) local function custom(path)
@@ -103,17 +110,23 @@ end
--- git_status: reference --- git_status: reference
--- unloaded_bufnr: copy --- unloaded_bufnr: copy
--- bufinfo: empty unless no_buffer set: vim.fn.getbufinfo { buflisted = 1 } --- bufinfo: empty unless no_buffer set: vim.fn.getbufinfo { buflisted = 1 }
--- bookmarks: absolute paths to boolean
function M.prepare(git_status, unloaded_bufnr) function M.prepare(git_status, unloaded_bufnr)
local status = { local status = {
git_status = git_status or {}, git_status = git_status or {},
unloaded_bufnr = unloaded_bufnr, unloaded_bufnr = unloaded_bufnr,
bufinfo = {}, bufinfo = {},
bookmarks = {},
} }
if M.config.filter_no_buffer then if M.config.filter_no_buffer then
status.bufinfo = vim.fn.getbufinfo { buflisted = 1 } status.bufinfo = vim.fn.getbufinfo { buflisted = 1 }
end end
for _, node in pairs(marks.get_marks()) do
status.bookmarks[node.absolute_path] = true
end
return status return status
end end
@@ -127,7 +140,11 @@ function M.should_filter(path, status)
return false return false
end end
return git(path, status.git_status) or buf(path, status.bufinfo, status.unloaded_bufnr) or dotfile(path) or custom(path) return git(path, status.git_status)
or buf(path, status.bufinfo, status.unloaded_bufnr)
or dotfile(path)
or custom(path)
or bookmark(path, status.bookmarks)
end end
function M.setup(opts) function M.setup(opts)
@@ -137,6 +154,7 @@ function M.setup(opts)
filter_git_ignored = opts.filters.git_ignored, filter_git_ignored = opts.filters.git_ignored,
filter_git_clean = opts.filters.git_clean, filter_git_clean = opts.filters.git_clean,
filter_no_buffer = opts.filters.no_buffer, filter_no_buffer = opts.filters.no_buffer,
filter_no_bookmark = opts.filters.no_bookmark,
} }
M.ignore_list = {} M.ignore_list = {}

View File

@@ -64,14 +64,15 @@ function M.default_on_attach(bufnr)
vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename')) vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename'))
vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic')) vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic'))
vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic')) vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic'))
vim.keymap.set('n', 'F', api.live_filter.clear, opts('Clean Filter')) vim.keymap.set('n', 'F', api.live_filter.clear, opts('Live Filter: Clear'))
vim.keymap.set('n', 'f', api.live_filter.start, opts('Filter')) vim.keymap.set('n', 'f', api.live_filter.start, opts('Live Filter: Start'))
vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help')) vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path')) vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles')) vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles'))
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore')) vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling')) vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling')) vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark')) vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open')) vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker')) vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker'))

View File

@@ -157,8 +157,9 @@ end
---@param prompt_select string ---@param prompt_select string
---@param items_short string[] ---@param items_short string[]
---@param items_long string[] ---@param items_long string[]
---@param kind string|nil
---@param callback fun(item_short: string) ---@param callback fun(item_short: string)
function M.prompt(prompt_input, prompt_select, items_short, items_long, callback) function M.prompt(prompt_input, prompt_select, items_short, items_long, kind, callback)
local function format_item(short) local function format_item(short)
for i, s in ipairs(items_short) do for i, s in ipairs(items_short) do
if short == s then if short == s then
@@ -169,7 +170,7 @@ function M.prompt(prompt_input, prompt_select, items_short, items_long, callback
end end
if M.select_prompts then if M.select_prompts then
vim.ui.select(items_short, { prompt = prompt_select, format_item = format_item }, function(item_short) vim.ui.select(items_short, { prompt = prompt_select, kind = kind, format_item = format_item }, function(item_short)
callback(item_short) callback(item_short)
end) end)
else else

View File

@@ -18,7 +18,7 @@ local function do_delete(nodes)
marks.clear_marks() marks.clear_marks()
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() require("nvim-tree.actions.reloaders").reload_explorer()
end end
end end
@@ -33,7 +33,7 @@ function M.bulk_delete()
if M.config.ui.confirm.remove then if M.config.ui.confirm.remove then
local prompt_select = "Remove bookmarked ?" local prompt_select = "Remove bookmarked ?"
local prompt_input = prompt_select .. " y/N: " local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, function(item_short) lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_delete", function(item_short)
utils.clear_prompt() utils.clear_prompt()
if item_short == "y" then if item_short == "y" then
do_delete(nodes) do_delete(nodes)

View File

@@ -40,7 +40,7 @@ function M.bulk_move()
marks.clear_marks() marks.clear_marks()
if not M.config.filesystem_watchers.enable then if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() require("nvim-tree.actions.reloaders").reload_explorer()
end end
end) end)
end end

View File

@@ -28,7 +28,7 @@ function M.bulk_trash()
if M.config.ui.confirm.trash then if M.config.ui.confirm.trash then
local prompt_select = "Trash bookmarked ?" local prompt_select = "Trash bookmarked ?"
local prompt_input = prompt_select .. " y/N: " local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, function(item_short) lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_trash", function(item_short)
utils.clear_prompt() utils.clear_prompt()
if item_short == "y" then if item_short == "y" then
do_trash(nodes) do_trash(nodes)

View File

@@ -17,6 +17,7 @@
---@field parent DirNode ---@field parent DirNode
---@field type string ---@field type string
---@field watcher function|nil ---@field watcher function|nil
---@field diag_status DiagStatus|nil
---@class DirNode: BaseNode ---@class DirNode: BaseNode
---@field has_children boolean ---@field has_children boolean

View File

@@ -1,4 +1,5 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local diagnostics = require "nvim-tree.diagnostics"
local M = { local M = {
HS_FILE = {}, HS_FILE = {},
@@ -17,10 +18,11 @@ function M.get_highlight(node)
end end
local group local group
local diag_status = diagnostics.get_diag_status(node)
if node.nodes then if node.nodes then
group = M.HS_FOLDER[node.diag_status] group = M.HS_FOLDER[diag_status and diag_status.value]
else else
group = M.HS_FILE[node.diag_status] group = M.HS_FILE[diag_status and diag_status.value]
end end
if group then if group then
@@ -35,7 +37,8 @@ end
---@return HighlightedString|nil modified icon ---@return HighlightedString|nil modified icon
function M.get_icon(node) function M.get_icon(node)
if node and M.config.diagnostics.enable and M.config.renderer.icons.show.diagnostics then if node and M.config.diagnostics.enable and M.config.renderer.icons.show.diagnostics then
return M.ICON[node.diag_status] local diag_status = diagnostics.get_diag_status(node)
return M.ICON[diag_status and diag_status.value]
end end
end end

View File

@@ -1,6 +1,7 @@
{ {
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"include-v-in-tag": true, "include-v-in-tag": true,
"bootstrap-sha": "34780aca5bac0a58c163ea30719a276fead1bd95",
"packages": { "packages": {
".": { ".": {
"package-name": "nvim-tree", "package-name": "nvim-tree",