Compare commits

...

28 Commits
v1.6.0 ... v1.7

Author SHA1 Message Date
github-actions[bot]
4a9e82d10a chore(master): release nvim-tree 1.7.1 (#2921)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-30 11:26:35 +10:00
Alexander Courtis
4520c0355c fix(#2930): empty groups expanded on reload (#2935) 2024-09-30 11:21:27 +10:00
Alexander Courtis
1ae1c33ce1 chore(#2931): stylua -> EmmyLuaCodeStyle (#2932)
* stylua -> EmmyLuaCodeStyle: config and doc

* stylua -> EmmyLuaCodeStyle: CI

* stylua -> EmmyLuaCodeStyle: CI

* stylua -> EmmyLuaCodeStyle: CI

* stylua -> EmmyLuaCodeStyle: CI

* stylua -> EmmyLuaCodeStyle: CI

* stylua -> EmmyLuaCodeStyle

* stylua -> EmmyLuaCodeStyle: call_arg_parentheses = always

* stylua -> EmmyLuaCodeStyle

* stylua -> EmmyLuaCodeStyle
2024-09-29 14:05:52 +10:00
Eric 李
9650e735ba fix(#2794): sshfs compatibility (#2922)
* Revert "revert(#2794): sshfs compatibility (#2920)"

This reverts commit 8405ecfbd6.

Fix for symlinks is simple

* fix sshfs compatibility with symlinks

* add suggestions

* revert variable name change to ease multi-instance feature branch conflicts

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-29 09:21:02 +10:00
Lin Tinusgrag
59a8a6ae5e fix: invalid explorer on open (#2927)
* fix: use of possibly stale value

The return value of `core.get_explorer()` could be changed by `core.init(..)`.

* fix style

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-25 19:27:25 +10:00
Lucas Reyna Córdoba
0429f286b3 fix(#2928): nil explorer in parent move action (#2929) 2024-09-25 19:23:57 +10:00
Alexander Courtis
8405ecfbd6 revert(#2794): sshfs compatibility (#2920)
* refactor(#2875): multi instance renderer: remove unused code

* Revert "fix(#2794): sshfs compatibility (#2893)"

This reverts commit 2d6e64dd8c.
2024-09-22 15:23:42 +10:00
Alexander Courtis
0ae9ad4ded refactor(#2875): multi instance renderer: remove unused code (#2919) 2024-09-22 15:22:06 +10:00
github-actions[bot]
e7cdecc636 chore(master): release nvim-tree 1.7.0 (#2910)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-21 12:12:45 +10:00
Alexander Courtis
b18ce8be8f fix(#2917): fix root copy paths: Y, ge, gy, y (#2918) 2024-09-21 12:05:16 +10:00
Alexander Courtis
03ae60313b refactor(#2875): multi instance renderer (#2900)
* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): deal with some cyclic require

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer

* refactor(#2875): multi instance renderer
2024-09-21 10:41:35 +10:00
Zifan Zhu
45a93d9979 fix(#2862): windows path replaces backslashes with forward slashes (#2903)
* Fix Winodws path issue by replacing backslashes with forward slashes

* Fix #2862 (handle all filename-related tasks)

* fix type mismatch

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-15 12:23:37 +10:00
Kyle Beede
bd4881660b fix: safely close last tree window (#2913)
fix: safely close tree window with pcall and debug logging

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-14 16:34:36 +10:00
Alexander Courtis
cd9c6db77f refactor(#2882, #2883): multi instance explore, reloaders (#2897)
* refactor(#2883): multi instance explore

* refactor(#2882): multi instance reloaders

* style
2024-09-14 15:35:31 +10:00
Alexander Courtis
03f737e574 feat(#2430): use vim.ui.open as default system_open, for neovim 0.10+ (#2912)
* feat(#2430): use vim.ui.open as default system_open, for neovim 0.10+

* feat(#2430): use vim.ui.open as default system_open, for neovim 0.10+
2024-09-14 15:15:44 +10:00
Ian Homer
a4dd5ad5c8 fix(#2906): resource leak on populate children (#2907)
Don't collect reason statistics for reason none

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-14 13:39:59 +10:00
Alexander Courtis
b652dbd0e0 feat: help closes on <Esc> and api.tree.toggle_help mappings (#2909)
* feat: help closes on <Esc> and api.tree.toggle_help mappings

* feat: help closes on <Esc> and api.tree.toggle_help mappings
2024-09-14 12:24:07 +10:00
github-actions[bot]
d41b4ca013 chore(master): release nvim-tree 1.6.1 (#2877)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-09 10:41:48 +10:00
Eric 李
2d6e64dd8c fix(#2794): sshfs compatibility (#2893)
* add type fallback for nil types

* add PR suggestions

* Update lua/nvim-tree/explorer/explore.lua

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

* use type from fs_stat for sshfs compatibility

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-09-09 10:31:55 +10:00
Alexander Courtis
cb57691536 docs: clarify node parameters in API, use of function {rhs} in on_attach (#2899)
* docs: specify node parameters for all API

* docs: clarify need to use a custom functions in on_attach
2024-09-08 15:11:02 +10:00
Alexander Courtis
70d7377c3f chore: lua-language-server 3.9.1 -> 3.10.5 (#2898) 2024-09-08 14:40:17 +10:00
Alexander Courtis
ea55ef1203 refactor(#2837): multi instance reload (#2885)
* refactor(#2837): multi instance reload

* refactor(#2837): multi instance reload
2024-09-01 15:50:03 +10:00
Alexander Courtis
43c3c36c7a doc(#2891): remove unused option hidden.enable 2024-09-01 14:52:25 +10:00
Alexander Courtis
d43ab67d0e fix(#2879): remove unnecessary tree window width setting to prevent unnecessary :wincmd = (#2881) 2024-08-25 13:23:28 +10:00
Alexander Courtis
6fbcb5a892 refactor(#2831): multi instance clipboard (#2869)
* refactor(#2831): multi instance clipboard

* refactor(#2831): multi instance clipboard

* refactor(#2831): multi instance clipboard
2024-08-25 12:49:46 +10:00
Alexander Courtis
e962e97cab refactor(#2830): multi instance marks (#2873)
* refactor(#2830): multi instance marks

* refactor(#2830): multi instance marks

* refactor(#2830): multi instance marks
2024-08-25 12:32:09 +10:00
Alexander Courtis
42340952af fix(#2878): nowrapscan prevents move from root (#2880)
* fix(#2878): nowrapscan prevents move from root

* fix(#2878): nowrapscan prevents move from root
2024-08-25 12:21:17 +10:00
Alexander Courtis
210478677c fix(#2868): windows: do not visit unenumerable directories such as Application Data (#2874) 2024-08-24 13:09:12 +10:00
91 changed files with 1922 additions and 1760 deletions

View File

@@ -4,9 +4,17 @@ root = true
insert_final_newline = true
end_of_line = lf
[*.lua]
indent_style = space
indent_size = 2
[nvim-tree-lua.txt]
max_line_length = 78
[*.lua]
indent_style = space
max_line_length = 140
indent_size = 2
# EmmyLuaCodeStyle specific, see
# https://github.com/CppCXY/EmmyLuaCodeStyle/blob/master/lua.template.editorconfig
continuation_indent = 2
quote_style = double
call_arg_parentheses = always
space_before_closure_open_parenthesis = false

View File

@@ -38,22 +38,24 @@ jobs:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.stylua_version }}-${{ github.head_ref || github.ref_name }}
group: ${{ github.workflow }}-${{ matrix.emmy_lua_code_style_version }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
strategy:
matrix:
stylua_version: [ 0.19.1 ]
emmy_lua_code_style_version: [ 1.5.6 ]
steps:
- uses: actions/checkout@v4
- name: stylua
uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ matrix.stylua_version }}
args: --check lua
- name: install emmy_lua_code_style
run: |
mkdir -p CodeFormat
curl -L "https://github.com/CppCXY/EmmyLuaCodeStyle/releases/download/${{ matrix.emmy_lua_code_style_version }}/linux-x64.tar.gz" | tar zx --directory CodeFormat
- run: echo "CodeFormat/linux-x64/bin" >> "$GITHUB_PATH"
- run: make style
- run: make style-doc
@@ -67,7 +69,7 @@ jobs:
strategy:
matrix:
nvim_version: [ stable, nightly ]
luals_version: [ 3.9.1 ]
luals_version: [ 3.10.5 ]
steps:
- uses: actions/checkout@v4

View File

@@ -1,3 +1,3 @@
{
".": "1.6.0"
".": "1.7.1"
}

View File

@@ -1,6 +0,0 @@
column_width = 140
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"
call_parentheses = "None"

View File

@@ -1,5 +1,47 @@
# Changelog
## [1.7.1](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.7.0...nvim-tree-v1.7.1) (2024-09-30)
### Bug Fixes
* **#2794:** sshfs compatibility ([#2922](https://github.com/nvim-tree/nvim-tree.lua/issues/2922)) ([9650e73](https://github.com/nvim-tree/nvim-tree.lua/commit/9650e735baad0d39505f4cb4867a60f02858536a))
* **#2928:** nil explorer in parent move action ([#2929](https://github.com/nvim-tree/nvim-tree.lua/issues/2929)) ([0429f28](https://github.com/nvim-tree/nvim-tree.lua/commit/0429f286b350c65118d66b646775bf187936fa47))
* **#2930:** empty groups expanded on reload ([#2935](https://github.com/nvim-tree/nvim-tree.lua/issues/2935)) ([4520c03](https://github.com/nvim-tree/nvim-tree.lua/commit/4520c0355cc561830ee2cf90dc37a2a75abf7995))
* invalid explorer on open ([#2927](https://github.com/nvim-tree/nvim-tree.lua/issues/2927)) ([59a8a6a](https://github.com/nvim-tree/nvim-tree.lua/commit/59a8a6ae5e9d3eae99d08ab655d12fd51d5d17f3))
### Reverts
* **#2794:** sshfs compatibility ([#2920](https://github.com/nvim-tree/nvim-tree.lua/issues/2920)) ([8405ecf](https://github.com/nvim-tree/nvim-tree.lua/commit/8405ecfbd6bb08a94ffc9c68fef211eea56e8a3b))
## [1.7.0](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.6.1...nvim-tree-v1.7.0) (2024-09-21)
### Features
* **#2430:** use vim.ui.open as default system_open, for neovim 0.10+ ([#2912](https://github.com/nvim-tree/nvim-tree.lua/issues/2912)) ([03f737e](https://github.com/nvim-tree/nvim-tree.lua/commit/03f737e5744a2b3ebb4b086f7636a3399224ec0c))
* help closes on &lt;Esc&gt; and api.tree.toggle_help mappings ([#2909](https://github.com/nvim-tree/nvim-tree.lua/issues/2909)) ([b652dbd](https://github.com/nvim-tree/nvim-tree.lua/commit/b652dbd0e0489c5fbb81fbededf0d99029cd2f38))
### Bug Fixes
* **#2862:** windows path replaces backslashes with forward slashes ([#2903](https://github.com/nvim-tree/nvim-tree.lua/issues/2903)) ([45a93d9](https://github.com/nvim-tree/nvim-tree.lua/commit/45a93d99794fff3064141d5b3a50db98ce352697))
* **#2906:** resource leak on populate children ([#2907](https://github.com/nvim-tree/nvim-tree.lua/issues/2907)) ([a4dd5ad](https://github.com/nvim-tree/nvim-tree.lua/commit/a4dd5ad5c8f9349142291d24e0e6466995594b9a))
* **#2917:** fix root copy paths: Y, ge, gy, y ([#2918](https://github.com/nvim-tree/nvim-tree.lua/issues/2918)) ([b18ce8b](https://github.com/nvim-tree/nvim-tree.lua/commit/b18ce8be8f162eee0bc37addcfe17d7d019fcec7))
* safely close last tree window ([#2913](https://github.com/nvim-tree/nvim-tree.lua/issues/2913)) ([bd48816](https://github.com/nvim-tree/nvim-tree.lua/commit/bd4881660bf0ddfa6acb21259f856ba3dcb26a93))
* safely close tree window with pcall and debug logging ([bd48816](https://github.com/nvim-tree/nvim-tree.lua/commit/bd4881660bf0ddfa6acb21259f856ba3dcb26a93))
## [1.6.1](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.6.0...nvim-tree-v1.6.1) (2024-09-09)
### Bug Fixes
* **#2794:** sshfs compatibility ([#2893](https://github.com/nvim-tree/nvim-tree.lua/issues/2893)) ([2d6e64d](https://github.com/nvim-tree/nvim-tree.lua/commit/2d6e64dd8c45a86f312552b7a47eef2c8623a25c))
* **#2868:** windows: do not visit unenumerable directories such as Application Data ([#2874](https://github.com/nvim-tree/nvim-tree.lua/issues/2874)) ([2104786](https://github.com/nvim-tree/nvim-tree.lua/commit/210478677cb9d672c4265deb0e9b59d58b675bd4))
* **#2878:** nowrapscan prevents move from root ([#2880](https://github.com/nvim-tree/nvim-tree.lua/issues/2880)) ([4234095](https://github.com/nvim-tree/nvim-tree.lua/commit/42340952af598a08ab80579d067b6da72a9e6d29))
* **#2879:** remove unnecessary tree window width setting to prevent unnecessary :wincmd = ([#2881](https://github.com/nvim-tree/nvim-tree.lua/issues/2881)) ([d43ab67](https://github.com/nvim-tree/nvim-tree.lua/commit/d43ab67d0eb4317961c5e9d15fffe908519debe0))
## [1.6.0](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.5.0...nvim-tree-v1.6.0) (2024-08-10)

View File

@@ -8,11 +8,13 @@ See [Development](https://github.com/nvim-tree/nvim-tree.lua/wiki/Development) f
Following are used during CI and strongly recommended during local development.
Language server: [luals](https://luals.github.io)
Lint: [luacheck](https://github.com/lunarmodules/luacheck/)
Style: [StyLua](https://github.com/JohnnyMorganz/StyLua)
Style: [EmmyLuaCodeStyle](https://github.com/CppCXY/EmmyLuaCodeStyle): `CodeCheck`
Language server: [luals](https://luals.github.io)
nvim-tree.lua migrated from stylua to EmmyLuaCodeStyle ~2024/10. `vim.lsp.buf.format()` may be used as it is the default formatter for luals
You can install them via you OS package manager e.g. `pacman`, `brew` or other via other package managers such as `cargo` or `luarocks`
@@ -34,14 +36,14 @@ make lint
## style
1. Runs stylua using `.stylua.toml` settings
1. Runs CodeCheck using `.editorconfig` settings
1. Runs `scripts/doc-comments.sh` to validate annotated documentation
```sh
make style
```
You can automatically fix stylua issues via:
You can automatically fix `CodeCheck` issues via:
```sh
make style-fix

View File

@@ -5,7 +5,7 @@ all: lint style check
#
lint: luacheck
style: stylua style-doc
style: style-check style-doc
check: luals
@@ -15,8 +15,9 @@ check: luals
luacheck:
luacheck -q lua
stylua:
stylua lua --check
# --diagnosis-as-error does not function for workspace, hence we post-process the output
style-check:
CodeFormat check --config .editorconfig --diagnosis-as-error --workspace lua
style-doc:
scripts/doc-comments.sh
@@ -28,7 +29,7 @@ luals:
# fixes
#
style-fix:
stylua lua
CodeFormat format --config .editorconfig --workspace lua
#
# utility
@@ -43,5 +44,5 @@ help-check: help-update
git diff --exit-code doc/nvim-tree-lua.txt
.PHONY: all lint style check luacheck stylua style-doc luals style-fix help-update help-check
.PHONY: all lint style check luacheck style-check style-doc luals style-fix help-update help-check

View File

@@ -955,7 +955,6 @@ Value can be `"none"`, `"icon"`, `"name"` or `"all"`
*nvim-tree.renderer.highlight_hidden*
Highlight icons and/or names for hidden files (dotfiles) using the
`NvimTreeHiddenFileHL` highlight group.
Requires |nvim-tree.hidden.enable|
Value can be `"none"`, `"icon"`, `"name"` or `"all"`
Type: `string`, Default `"none"`
@@ -1089,8 +1088,7 @@ Icon order and sign column precedence:
*nvim-tree.renderer.icons.show.hidden*
Show a hidden icon, see |renderer.icons.hidden_placement|
Requires |hidden.enable| `= true`
Type: `boolean`, Default: `true`
Type: `boolean`, Default: `false`
*nvim-tree.renderer.icons.show.diagnostics*
Show a diagnostics status icon, see |renderer.icons.diagnostics_placement|
@@ -1200,11 +1198,18 @@ Takes the `BufEnter` event as an argument. see |autocmd-events|
Open a file or directory in your preferred application.
|vim.ui.open| was introduced in neovim 0.10 and is the default.
Once nvim-tree minimum neovim version is updated to 0.10, these options will
no longer be necessary and will be removed.
*nvim-tree.system_open.cmd*
The open command itself.
Type: `string`, Default: `""`
Leave empty for OS specific default:
neovim >= 0.10 defaults to |vim.ui.open|
neovim < 0.10 defaults to:
UNIX: `"xdg-open"`
macOS: `"open"`
Windows: `"cmd"`
@@ -1571,7 +1576,7 @@ Specify minimum notification level, uses the values from |vim.log.levels|
`ERROR`: hard errors e.g. failure to read from the file system.
`WARNING`: non-fatal errors e.g. unable to system open a file.
`INFO:` information only e.g. file copy path confirmation.
`DEBUG:` not used.
`DEBUG:` information for troubleshooting, e.g. failures in some window closing operations.
*nvim-tree.notify.absolute_path*
Whether to use absolute paths or item names in fs action notifications.
@@ -1681,10 +1686,8 @@ to avoid breaking configurations due to internal breaking changes.
The api is separated in multiple modules, which can be accessed with
`api.<module>.<function>`
Functions that needs a tree node parameter are exposed with an abstraction
that injects the node from the cursor position in the tree when calling
the function. It will use the node you pass as an argument in priority if it
exists.
Functions accepting {node} as their first argument will use the node under the
cursor when that argument is not present or nil.
==============================================================================
6.1 API TREE *nvim-tree-api.tree*
@@ -1810,9 +1813,11 @@ tree.collapse_all({keep_buffers}) *nvim-tree-api.tree.collapse_all()*
Parameters: ~
• {keep_buffers} (boolean) do not collapse nodes with open buffers.
tree.expand_all() *nvim-tree-api.tree.expand_all()*
Recursively expand all nodes in the tree.
Folder: only the nodes underneath that folder.
tree.expand_all({node}) *nvim-tree-api.tree.expand_all()*
Recursively expand all nodes under the tree root or specified folder.
Parameters: ~
• {node} (Node|nil) folder
*nvim-tree-api.tree.toggle_enable_filters()*
tree.toggle_enable_filters()
@@ -1887,86 +1892,93 @@ fs.create({node}) *nvim-tree-api.fs.create()*
Multiple directories/files may be created e.g. `foo/bar/baz`
Parameters: ~
• {node} (Node) parent, uses the parent of a file.
• {node} (Node|nil) parent, uses the parent of a file.
fs.remove({node}) *nvim-tree-api.fs.remove()*
Delete a file or folder from the file system.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.trash({node}) *nvim-tree-api.fs.trash()*
Trash a file or folder as per |nvim-tree.trash|
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.rename_node({node}) *nvim-tree-api.fs.rename_node()*
Prompt to rename a file or folder.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.rename({node}) *nvim-tree-api.fs.rename()*
Prompt to rename a file or folder by name.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.rename_basename({node}) *nvim-tree-api.fs.rename_basename()*
Prompt to rename a file or folder by name with extension omitted.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.rename_sub({node}) *nvim-tree-api.fs.rename_sub()*
Prompt to rename a file or folder by absolute path with name omitted.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.rename_full({node}) *nvim-tree-api.fs.rename_full()*
Prompt to rename a file or folder by absolute path.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.cut({node}) *nvim-tree-api.fs.cut()*
Cut a file or folder to the nvim-tree clipboard.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.paste({node}) *nvim-tree-api.fs.paste()*
Paste a file or folder from the nvim-tree clipboard.
Parameters: ~
• {node} (Node) destination folder, uses the parent of a file.
• {node} (Node|nil) destination folder, uses the parent of a file.
fs.copy.node({node}) *nvim-tree-api.fs.copy.node()*
Copy a file or folder from the nvim-tree clipboard.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.copy.absolute_path({node}) *nvim-tree-api.fs.copy.absolute_path()*
Copy the absolute path of a file or folder to the system clipboard.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.copy.basename({node}) *nvim-tree-api.fs.copy.basename()*
Copy the name of a file or folder with extension omitted to the system
clipboard.
Parameters: ~
• {node} (Node|nil) file or folder
fs.copy.filename({node}) *nvim-tree-api.fs.copy.filename()*
Copy the name of a file or folder to the system clipboard.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.copy.relative_path({node}) *nvim-tree-api.fs.copy.relative_path()*
Copy the path of a file or folder relative to the tree root to the system
clipboard.
Parameters: ~
• {node} (Node) file or folder
• {node} (Node|nil) file or folder
fs.clear_clipboard() *nvim-tree-api.fs.clear_clipboard()*
Clear the nvim-tree clipboard.
@@ -1977,34 +1989,37 @@ fs.print_clipboard() *nvim-tree-api.fs.print_clipboard()*
==============================================================================
6.3 API NODE *nvim-tree-api.node*
node.open.edit() *nvim-tree-api.node.open.edit()*
Parameters: ~
• {node} (Node|nil) file or folder
node.open.edit({node}) *nvim-tree-api.node.open.edit()*
File: open as per |nvim-tree.actions.open_file|
Folder: expand or collapse
Root: change directory up
*nvim-tree-api.node.open.replace_tree_buffer()*
node.open.replace_tree_buffer()
node.open.replace_tree_buffer({node})
|nvim-tree-api.node.edit()|, file will be opened in place: in the
nvim-tree window.
*nvim-tree-api.node.open.no_window_picker()*
node.open.no_window_picker()
node.open.no_window_picker({node})
|nvim-tree-api.node.edit()|, window picker will never be used as per
|nvim-tree.actions.open_file.window_picker.enable| `false`
node.open.vertical() *nvim-tree-api.node.open.vertical()*
node.open.vertical({node}) *nvim-tree-api.node.open.vertical()*
|nvim-tree-api.node.edit()|, file will be opened in a new vertical split.
node.open.horizontal() *nvim-tree-api.node.open.horizontal()*
node.open.horizontal({node}) *nvim-tree-api.node.open.horizontal()*
|nvim-tree-api.node.edit()|, file will be opened in a new horizontal split.
*nvim-tree-api.node.open.toggle_group_empty()*
node.open.toggle_group_empty()
node.open.toggle_group_empty({node})
Toggle |nvim-tree.renderer.group_empty| for a specific folder.
Does nothing on files.
Needs |nvim-tree.renderer.group_empty| set.
node.open.drop() *nvim-tree-api.node.open.drop()*
node.open.drop({node}) *nvim-tree-api.node.open.drop()*
Switch to window with selected file if it exists.
Open file otherwise.
See: `:h :drop`.
@@ -2013,11 +2028,11 @@ node.open.drop() *nvim-tree-api.node.open.drop()*
Folder: expand or collapse
Root: change directory up
node.open.tab() *nvim-tree-api.node.open.tab()*
node.open.tab({node}) *nvim-tree-api.node.open.tab()*
|nvim-tree-api.node.edit()|, file will be opened in a new tab.
*nvim-tree-api.node.open.tab_drop()*
node.open.tab_drop()
node.open.tab_drop({node})
Switch to tab containing window with selected file if it exists.
Open file in new tab otherwise.
@@ -2025,102 +2040,103 @@ node.open.tab_drop()
Folder: expand or collapse
Root: change directory up
node.open.preview() *nvim-tree-api.node.open.preview()*
node.open.preview({node}) *nvim-tree-api.node.open.preview()*
|nvim-tree-api.node.edit()|, file buffer will have |bufhidden| set to `delete`.
node.open.preview_no_picker() *nvim-tree-api.node.open.preview_no_picker()*
*nvim-tree-api.node.open.preview_no_picker()*
node.open.preview_no_picker({node})
|nvim-tree-api.node.edit()|, file buffer will have |bufhidden| set to `delete`.
window picker will never be used as per
|nvim-tree.actions.open_file.window_picker.enable| `false`
node.navigate.git.next() *nvim-tree-api.node.navigate.git.next()*
node.navigate.git.next({node}) *nvim-tree-api.node.navigate.git.next()*
Navigate to the next item showing git status.
*nvim-tree-api.node.navigate.git.next_recursive()*
node.navigate.git.next_recursive()
node.navigate.git.next_recursive({node})
Alternative to |nvim-tree-api.node.navigate.git.next()| that navigates to
the next file showing git status, recursively.
Needs |nvim-tree.git.show_on_dirs| set.
*nvim-tree-api.node.navigate.git.next_skip_gitignored()*
node.navigate.git.next_skip_gitignored()
node.navigate.git.next_skip_gitignored({node})
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({node}) *nvim-tree-api.node.navigate.git.prev()*
Navigate to the previous item showing git status.
*nvim-tree-api.node.navigate.git.prev_recursive()*
node.navigate.git.prev_recursive()
node.navigate.git.prev_recursive({node})
Alternative to |nvim-tree-api.node.navigate.git.prev()| that navigates to
the previous file showing git status, recursively.
Needs |nvim-tree.git.show_on_dirs| set.
*nvim-tree-api.node.navigate.git.prev_skip_gitignored()*
node.navigate.git.prev_skip_gitignored()
node.navigate.git.prev_skip_gitignored({node})
Same as |node.navigate.git.prev()|, but skips gitignored files.
*nvim-tree-api.node.navigate.diagnostics.next()*
node.navigate.diagnostics.next()
node.navigate.diagnostics.next({node})
Navigate to the next item showing diagnostic status.
*nvim-tree-api.node.navigate.diagnostics.next_recursive()*
node.navigate.diagnostics.next_recursive()
node.navigate.diagnostics.next_recursive({node})
Alternative to |nvim-tree-api.node.navigate.diagnostics.next()| that
navigates to the next file showing diagnostic status, recursively.
Needs |nvim-tree.diagnostics.show_on_dirs| set.
*nvim-tree-api.node.navigate.diagnostics.prev()*
node.navigate.diagnostics.prev()
node.navigate.diagnostics.prev({node})
Navigate to the next item showing diagnostic status.
*nvim-tree-api.node.navigate.diagnostics.prev_recursive()*
node.navigate.diagnostics.prev_recursive()
node.navigate.diagnostics.prev_recursive({node})
Alternative to |nvim-tree-api.node.navigate.diagnostics.prev()| that
navigates to the previous file showing diagnostic status, recursively.
Needs |nvim-tree.diagnostics.show_on_dirs| set.
*nvim-tree-api.node.navigate.opened.next()*
node.navigate.opened.next()
node.navigate.opened.next({node})
Navigate to the next |bufloaded()| item.
See |nvim-tree.renderer.highlight_opened_files|
*nvim-tree-api.node.navigate.opened.prev()*
node.navigate.opened.prev()
node.navigate.opened.prev({node})
Navigate to the previous |bufloaded()| item.
See |nvim-tree.renderer.highlight_opened_files|
*nvim-tree-api.node.navigate.sibling.next()*
node.navigate.sibling.next()
node.navigate.sibling.next({node})
Navigate to the next node in the current node's folder, wraps.
*nvim-tree-api.node.navigate.sibling.prev()*
node.navigate.sibling.prev()
node.navigate.sibling.prev({node})
Navigate to the previous node in the current node's folder, wraps.
*nvim-tree-api.node.navigate.sibling.first()*
node.navigate.sibling.first()
node.navigate.sibling.first({node})
Navigate to the first node in the current node's folder.
*nvim-tree-api.node.navigate.sibling.last()*
node.navigate.sibling.last()
node.navigate.sibling.last({node})
Navigate to the last node in the current node's folder.
*nvim-tree-api.node.navigate.parent()*
node.navigate.parent()
node.navigate.parent({node})
Navigate to the parent folder of the current node.
*nvim-tree-api.node.navigate.parent_close()*
node.navigate.parent_close()
node.navigate.parent_close({node})
|api.node.navigate.parent()|, closing that folder.
node.show_info_popup() *nvim-tree-api.node.show_info_popup()*
node.show_info_popup({node}) *nvim-tree-api.node.show_info_popup()*
Open a popup window showing: fullpath, size, accessed, modified, created.
node.run.cmd() *nvim-tree-api.node.run.cmd()*
node.run.cmd({node}) *nvim-tree-api.node.run.cmd()*
Enter |cmdline| with the full path of the node and the cursor at the start
of the line.
node.run.system() *nvim-tree-api.node.run.system()*
node.run.system({node}) *nvim-tree-api.node.run.system()*
Execute |nvim-tree.system_open|
==============================================================================
@@ -2195,8 +2211,8 @@ marks.navigate.prev() *nvim-tree-api.marks.navigate.prev()*
As per |nvim-tree-api.marks.navigate.next()|
marks.navigate.select() *nvim-tree-api.marks.navigate.select()*
Prompts for selection of a marked node as per
|nvim-tree-api.marks.navigate.next()|
Prompts for selection of a marked node, sorted by absolute paths.
A folder will be focused, a file will be opened.
==============================================================================
6.8 API CONFIG *nvim-tree-api.config*
@@ -2298,7 +2314,8 @@ Single left mouse mappings can be achieved via `<LeftRelease>`.
Single right / middle mouse mappings will require changes to |mousemodel| or |mouse|.
You may execute your own functions as well as |nvim-tree-api| functions e.g. >
|vim.keymap.set()| {rhs} is a `(function|string)` thus it may be necessary to
define your own function to map complex functionality e.g. >
local function print_node_path()
local api = require('nvim-tree.api')
@@ -3017,6 +3034,7 @@ highlight group is not, hard linking as follows: >
|nvim-tree-api.events.subscribe()|
|nvim-tree-api.fs.clear_clipboard()|
|nvim-tree-api.fs.copy.absolute_path()|
|nvim-tree-api.fs.copy.basename()|
|nvim-tree-api.fs.copy.filename()|
|nvim-tree-api.fs.copy.node()|
|nvim-tree-api.fs.copy.relative_path()|

View File

@@ -1,16 +1,11 @@
local lib = require "nvim-tree.lib"
local log = require "nvim-tree.log"
local appearance = require "nvim-tree.appearance"
local renderer = require "nvim-tree.renderer"
local view = require "nvim-tree.view"
local commands = require "nvim-tree.commands"
local utils = require "nvim-tree.utils"
local actions = require "nvim-tree.actions"
local legacy = require "nvim-tree.legacy"
local core = require "nvim-tree.core"
local git = require "nvim-tree.git"
local buffers = require "nvim-tree.buffers"
local notify = require "nvim-tree.notify"
local lib = require("nvim-tree.lib")
local log = require("nvim-tree.log")
local appearance = require("nvim-tree.appearance")
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local actions = require("nvim-tree.actions")
local core = require("nvim-tree.core")
local notify = require("nvim-tree.notify")
local _config = {}
@@ -26,7 +21,7 @@ function M.change_root(path, bufnr)
if type(bufnr) == "number" then
local ft
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
ft = vim.api.nvim_get_option_value("filetype", { buf = bufnr }) or ""
else
ft = vim.api.nvim_buf_get_option(bufnr, "filetype") or "" ---@diagnostic disable-line: deprecated
@@ -81,11 +76,11 @@ function M.change_root(path, bufnr)
end
function M.tab_enter()
if view.is_visible { any_tabpage = true } then
if view.is_visible({ any_tabpage = true }) then
local bufname = vim.api.nvim_buf_get_name(0)
local ft
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
ft = vim.api.nvim_get_option_value("filetype", { buf = 0 }) or ""
else
ft = vim.api.nvim_buf_get_option(0, "ft") ---@diagnostic disable-line: deprecated
@@ -96,8 +91,12 @@ function M.tab_enter()
return
end
end
view.open { focus_tree = false }
renderer.draw()
view.open({ focus_tree = false })
local explorer = core.get_explorer()
if explorer then
explorer.renderer:draw()
end
end
end
@@ -146,8 +145,8 @@ end
---@param hijack_netrw boolean
local function manage_netrw(disable_netrw, hijack_netrw)
if hijack_netrw then
vim.cmd "silent! autocmd! FileExplorer *"
vim.cmd "autocmd VimEnter * ++once silent! autocmd! FileExplorer *"
vim.cmd("silent! autocmd! FileExplorer *")
vim.cmd("autocmd VimEnter * ++once silent! autocmd! FileExplorer *")
end
if disable_netrw then
vim.g.loaded_netrw = 1
@@ -179,7 +178,11 @@ local function setup_autocommands(opts)
callback = function()
appearance.setup()
view.reset_winhl()
renderer.draw()
local explorer = core.get_explorer()
if explorer then
explorer.renderer:draw()
end
end,
})
@@ -201,7 +204,10 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd("BufWritePost", {
callback = function()
if opts.auto_reload_on_write and not opts.filesystem_watchers.enable then
actions.reloaders.reload_explorer()
local explorer = core.get_explorer()
if explorer then
explorer:reload_explorer()
end
end
end,
})
@@ -214,10 +220,10 @@ local function setup_autocommands(opts)
return
end
if
(explorer.filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == ""
(explorer.filters.config.filter_no_buffer or explorer.opts.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == ""
then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
actions.reloaders.reload_explorer()
explorer:reload_explorer()
end)
end
end,
@@ -231,10 +237,10 @@ local function setup_autocommands(opts)
return
end
if
(explorer.filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == ""
(explorer.filters.config.filter_no_buffer or explorer.opts.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == ""
then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
actions.reloaders.reload_explorer()
explorer:reload_explorer()
end)
end
end,
@@ -244,7 +250,10 @@ local function setup_autocommands(opts)
pattern = { "FugitiveChanged", "NeogitStatusRefreshed" },
callback = function()
if not opts.filesystem_watchers.enable and opts.git.enable then
actions.reloaders.reload_git()
local explorer = core.get_explorer()
if explorer then
explorer:reload_git()
end
end
end,
})
@@ -292,7 +301,10 @@ local function setup_autocommands(opts)
callback = function()
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
actions.reloaders.reload_explorer()
local explorer = core.get_explorer()
if explorer then
explorer:reload_explorer()
end
end
end
end,
@@ -304,7 +316,7 @@ local function setup_autocommands(opts)
callback = function()
vim.schedule(function()
vim.api.nvim_buf_call(0, function()
vim.cmd [[norm! zz]]
vim.cmd([[norm! zz]])
end)
end)
end,
@@ -342,8 +354,11 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd({ "BufModifiedSet", "BufWritePost" }, {
callback = function()
utils.debounce("Buf:modified", opts.view.debounce_delay, function()
buffers.reload_modified()
actions.reloaders.reload_explorer()
require("nvim-tree.buffers").reload_modified()
local explorer = core.get_explorer()
if explorer then
explorer:reload_explorer()
end
end)
end,
})
@@ -789,15 +804,15 @@ function M.purge_all_state()
view.close_all_tabs()
view.abandon_all_windows()
if core.get_explorer() ~= nil then
git.purge_state()
require("nvim-tree.git").purge_state()
core.reset_explorer()
end
end
---@param conf table|nil
function M.setup(conf)
if vim.fn.has "nvim-0.9" == 0 then
notify.warn "nvim-tree.lua requires Neovim 0.9 or higher"
if vim.fn.has("nvim-0.9") == 0 then
notify.warn("nvim-tree.lua requires Neovim 0.9 or higher")
return
end
@@ -805,7 +820,7 @@ function M.setup(conf)
localise_default_opts()
legacy.migrate_legacy_options(conf or {})
require("nvim-tree.legacy").migrate_legacy_options(conf or {})
validate_options(conf)
@@ -825,7 +840,7 @@ function M.setup(conf)
require("nvim-tree.notify").setup(opts)
require("nvim-tree.log").setup(opts)
if log.enabled "config" then
if log.enabled("config") then
log.line("config", "default config + user")
log.raw("config", "%s\n", vim.inspect(opts))
end
@@ -839,8 +854,7 @@ function M.setup(conf)
require("nvim-tree.git.utils").setup(opts)
require("nvim-tree.view").setup(opts)
require("nvim-tree.lib").setup(opts)
require("nvim-tree.renderer").setup(opts)
require("nvim-tree.marks").setup(opts)
require("nvim-tree.renderer.components").setup(opts)
require("nvim-tree.buffers").setup(opts)
require("nvim-tree.help").setup(opts)
require("nvim-tree.watcher").setup(opts)
@@ -852,7 +866,7 @@ function M.setup(conf)
if vim.g.NvimTreeSetup ~= 1 then
-- first call to setup
commands.setup()
require("nvim-tree.commands").setup()
else
-- subsequent calls to setup
M.purge_all_state()

View File

@@ -1,10 +1,8 @@
local log = require "nvim-tree.log"
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local renderer = require "nvim-tree.renderer"
local reload = require "nvim-tree.explorer.reload"
local core = require "nvim-tree.core"
local Iterator = require "nvim-tree.iterators.node-iterator"
local log = require("nvim-tree.log")
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local Iterator = require("nvim-tree.iterators.node-iterator")
local M = {}
@@ -13,7 +11,8 @@ local running = {}
---Find a path in the tree, expand it and focus it
---@param path string relative or absolute
function M.fn(path)
if not core.get_explorer() or not view.is_visible() then
local explorer = core.get_explorer()
if not explorer or not view.is_visible() then
return
end
@@ -32,7 +31,7 @@ function M.fn(path)
-- refresh the contents of all parents, expanding groups as needed
if utils.get_node_from_path(path_real) == nil then
reload.refresh_parent_nodes_for_path(vim.fn.fnamemodify(path_real, ":h"))
explorer:refresh_parent_nodes_for_path(vim.fn.fnamemodify(path_real, ":h"))
end
local line = core.get_nodes_starting_line()
@@ -76,8 +75,8 @@ function M.fn(path)
:iterate()
if found and view.is_visible() then
renderer.draw()
view.set_cursor { line, 0 }
explorer.renderer:draw()
view.set_cursor({ line, 0 })
end
running[path_real] = false

View File

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

View File

@@ -1,4 +1,4 @@
local core = require "nvim-tree.core"
local core = require("nvim-tree.core")
local find_file = require("nvim-tree.actions.finders.find-file").fn
local M = {}
@@ -75,7 +75,7 @@ function M.fn()
local bufnr = vim.api.nvim_get_current_buf()
local path_existed, path_opt
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
path_existed, path_opt = pcall(vim.api.nvim_get_option_value, "path", { buf = bufnr })
vim.api.nvim_set_option_value("path", core.get_cwd() .. "/**", { buf = bufnr })
else
@@ -89,13 +89,13 @@ function M.fn()
end
-- reset &path
if path_existed then
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("path", path_opt, { buf = bufnr })
else
vim.api.nvim_buf_set_option(bufnr, "path", path_opt) ---@diagnostic disable-line: deprecated
end
else
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("path", nil, { buf = bufnr })
else
vim.api.nvim_buf_set_option(bufnr, "path", nil) ---@diagnostic disable-line: deprecated

View File

@@ -1,22 +1,44 @@
local lib = require "nvim-tree.lib"
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify"
local renderer = require "nvim-tree.renderer"
local reloaders = require "nvim-tree.actions.reloaders"
local lib = require("nvim-tree.lib")
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local find_file = require("nvim-tree.actions.finders.find-file").fn
local M = {
config = {},
---@enum ACTION
local ACTION = {
copy = "copy",
cut = "cut",
}
local clipboard = {
cut = {},
copy = {},
}
---@class Clipboard to handle all actions.fs clipboard API
---@field config table hydrated user opts.filters
---@field private explorer Explorer
---@field private data table<ACTION, Node[]>
local Clipboard = {}
---@param opts table user options
---@param explorer Explorer
---@return Clipboard
function Clipboard:new(opts, explorer)
local o = {
explorer = explorer,
data = {
[ACTION.copy] = {},
[ACTION.cut] = {},
},
config = {
filesystem_watchers = opts.filesystem_watchers,
actions = opts.actions,
},
}
setmetatable(o, self)
self.__index = self
return o
end
---@param source string
---@param destination string
@@ -67,8 +89,8 @@ local function do_copy(source, destination)
break
end
local new_name = utils.path_join { source, name }
local new_destination = utils.path_join { destination, name }
local new_name = utils.path_join({ source, name })
local new_destination = utils.path_join({ destination, name })
success, errmsg = do_copy(new_name, new_destination)
if not success then
return false, errmsg
@@ -85,11 +107,11 @@ end
---@param source string
---@param dest string
---@param action_type string
---@param action ACTION
---@param action_fn fun(source: string, dest: string)
---@return boolean|nil -- success
---@return string|nil -- error message
local function do_single_paste(source, dest, action_type, action_fn)
local function do_single_paste(source, dest, action, action_fn)
local dest_stats
local success, errmsg, errcode
local notify_source = notify.render_path(source)
@@ -98,14 +120,14 @@ local function do_single_paste(source, dest, action_type, action_fn)
dest_stats, errmsg, errcode = vim.loop.fs_stat(dest)
if not dest_stats and errcode ~= "ENOENT" then
notify.error("Could not " .. action_type .. " " .. notify_source .. " - " .. (errmsg or "???"))
notify.error("Could not " .. action .. " " .. notify_source .. " - " .. (errmsg or "???"))
return false, errmsg
end
local function on_process()
success, errmsg = action_fn(source, dest)
if not success then
notify.error("Could not " .. action_type .. " " .. notify_source .. " - " .. (errmsg or "???"))
notify.error("Could not " .. action .. " " .. notify_source .. " - " .. (errmsg or "???"))
return false, errmsg
end
@@ -123,7 +145,7 @@ local function do_single_paste(source, dest, action_type, action_fn)
vim.ui.input(input_opts, function(new_dest)
utils.clear_prompt()
if new_dest then
do_single_paste(source, new_dest, action_type, action_fn)
do_single_paste(source, new_dest, action, action_fn)
end
end)
else
@@ -137,7 +159,7 @@ local function do_single_paste(source, dest, action_type, action_fn)
vim.ui.input(input_opts, function(new_dest)
utils.clear_prompt()
if new_dest then
do_single_paste(source, new_dest, action_type, action_fn)
do_single_paste(source, new_dest, action, action_fn)
end
end)
end
@@ -165,37 +187,42 @@ local function toggle(node, clip)
notify.info(notify_node .. " added to clipboard.")
end
function M.clear_clipboard()
clipboard.cut = {}
clipboard.copy = {}
notify.info "Clipboard has been emptied."
renderer.draw()
---Clear copied and cut
function Clipboard:clear_clipboard()
self.data[ACTION.copy] = {}
self.data[ACTION.cut] = {}
notify.info("Clipboard has been emptied.")
self.explorer.renderer:draw()
end
---Copy one node
---@param node Node
function M.copy(node)
utils.array_remove(clipboard.cut, node)
toggle(node, clipboard.copy)
renderer.draw()
function Clipboard:copy(node)
utils.array_remove(self.data[ACTION.cut], node)
toggle(node, self.data[ACTION.copy])
self.explorer.renderer:draw()
end
---Cut one node
---@param node Node
function M.cut(node)
utils.array_remove(clipboard.copy, node)
toggle(node, clipboard.cut)
renderer.draw()
function Clipboard:cut(node)
utils.array_remove(self.data[ACTION.copy], node)
toggle(node, self.data[ACTION.cut])
self.explorer.renderer:draw()
end
---Paste cut or cop
---@private
---@param node Node
---@param action_type string
---@param action ACTION
---@param action_fn fun(source: string, dest: string)
local function do_paste(node, action_type, action_fn)
function Clipboard:do_paste(node, action, action_fn)
node = lib.get_last_group_node(node)
local explorer = core.get_explorer()
if node.name == ".." and explorer then
node = explorer
end
local clip = clipboard[action_type]
local clip = self.data[action]
if #clip == 0 then
return
end
@@ -204,7 +231,7 @@ local function do_paste(node, action_type, action_fn)
local stats, errmsg, errcode = vim.loop.fs_stat(destination)
if not stats and errcode ~= "ENOENT" then
log.line("copy_paste", "do_paste fs_stat '%s' failed '%s'", destination, errmsg)
notify.error("Could not " .. action_type .. " " .. notify.render_path(destination) .. " - " .. (errmsg or "???"))
notify.error("Could not " .. action .. " " .. notify.render_path(destination) .. " - " .. (errmsg or "???"))
return
end
local is_dir = stats and stats.type == "directory"
@@ -213,13 +240,13 @@ local function do_paste(node, action_type, action_fn)
end
for _, _node in ipairs(clip) do
local dest = utils.path_join { destination, _node.name }
do_single_paste(_node.absolute_path, dest, action_type, action_fn)
local dest = utils.path_join({ destination, _node.name })
do_single_paste(_node.absolute_path, dest, action, action_fn)
end
clipboard[action_type] = {}
if not M.config.filesystem_watchers.enable then
reloaders.reload_explorer()
self.data[action] = {}
if not self.config.filesystem_watchers.enable then
self.explorer:reload_explorer()
end
end
@@ -246,26 +273,27 @@ local function do_cut(source, destination)
return true
end
---Paste cut (if present) or copy (if present)
---@param node Node
function M.paste(node)
if clipboard.cut[1] ~= nil then
do_paste(node, "cut", do_cut)
else
do_paste(node, "copy", do_copy)
function Clipboard:paste(node)
if self.data[ACTION.cut][1] ~= nil then
self:do_paste(node, ACTION.cut, do_cut)
elseif self.data[ACTION.copy][1] ~= nil then
self:do_paste(node, ACTION.copy, do_copy)
end
end
function M.print_clipboard()
function Clipboard:print_clipboard()
local content = {}
if #clipboard.cut > 0 then
if #self.data[ACTION.cut] > 0 then
table.insert(content, "Cut")
for _, node in pairs(clipboard.cut) do
for _, node in pairs(self.data[ACTION.cut]) do
table.insert(content, " * " .. (notify.render_path(node.absolute_path)))
end
end
if #clipboard.copy > 0 then
if #self.data[ACTION.copy] > 0 then
table.insert(content, "Copy")
for _, node in pairs(clipboard.copy) do
for _, node in pairs(self.data[ACTION.copy]) do
table.insert(content, " * " .. (notify.render_path(node.absolute_path)))
end
end
@@ -274,10 +302,10 @@ function M.print_clipboard()
end
---@param content string
local function copy_to_clipboard(content)
function Clipboard:copy_to_reg(content)
local clipboard_name
local reg
if M.config.actions.use_system_clipboard == true then
if self.config.actions.use_system_clipboard == true then
clipboard_name = "system"
reg = "+"
else
@@ -298,53 +326,80 @@ local function copy_to_clipboard(content)
end
---@param node Node
function M.copy_filename(node)
copy_to_clipboard(node.name)
end
function Clipboard:copy_filename(node)
local content
---@param node Node
function M.copy_basename(node)
local basename = vim.fn.fnamemodify(node.name, ":r")
copy_to_clipboard(basename)
end
---@param node Node
function M.copy_path(node)
local absolute_path = node.absolute_path
local cwd = core.get_cwd()
if cwd == nil then
return
if node.name == ".." then
-- root
content = vim.fn.fnamemodify(self.explorer.absolute_path, ":t")
else
-- node
content = node.name
end
local relative_path = utils.path_relative(absolute_path, cwd)
local content = node.nodes ~= nil and utils.path_add_trailing(relative_path) or relative_path
copy_to_clipboard(content)
self:copy_to_reg(content)
end
---@param node Node
function M.copy_absolute_path(node)
function Clipboard:copy_basename(node)
local content
if node.name == ".." then
-- root
content = vim.fn.fnamemodify(self.explorer.absolute_path, ":t:r")
else
-- node
content = vim.fn.fnamemodify(node.name, ":r")
end
self:copy_to_reg(content)
end
---@param node Node
function Clipboard:copy_path(node)
local content
if node.name == ".." then
-- root
content = utils.path_add_trailing("")
else
-- node
local absolute_path = node.absolute_path
local cwd = core.get_cwd()
if cwd == nil then
return
end
local relative_path = utils.path_relative(absolute_path, cwd)
content = node.nodes ~= nil and utils.path_add_trailing(relative_path) or relative_path
end
self:copy_to_reg(content)
end
---@param node Node
function Clipboard:copy_absolute_path(node)
if node.name == ".." then
node = self.explorer
end
local absolute_path = node.absolute_path
local content = node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path
copy_to_clipboard(content)
self:copy_to_reg(content)
end
---Node is cut. Will not be copied.
---@param node Node
---@return boolean
function M.is_cut(node)
return vim.tbl_contains(clipboard.cut, node)
function Clipboard:is_cut(node)
return vim.tbl_contains(self.data[ACTION.cut], node)
end
---Node is copied. Will not be cut.
---@param node Node
---@return boolean
function M.is_copied(node)
return vim.tbl_contains(clipboard.copy, node)
function Clipboard:is_copied(node)
return vim.tbl_contains(self.data[ACTION.copy], node)
end
function M.setup(opts)
M.config.filesystem_watchers = opts.filesystem_watchers
M.config.actions = opts.actions
end
return M
return Clipboard

View File

@@ -1,8 +1,8 @@
local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
local lib = require "nvim-tree.lib"
local core = require "nvim-tree.core"
local notify = require "nvim-tree.notify"
local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
local lib = require("nvim-tree.lib")
local core = require("nvim-tree.core")
local notify = require("nvim-tree.notify")
local find_file = require("nvim-tree.actions.finders.find-file").fn
@@ -72,7 +72,7 @@ function M.fn(node)
end
if utils.file_exists(new_file_path) then
notify.warn "Cannot create: file already exists"
notify.warn("Cannot create: file already exists")
return
end
@@ -87,10 +87,10 @@ function M.fn(node)
for path in utils.path_split(new_file_path) do
idx = idx + 1
local p = utils.path_remove_trailing(path)
if #path_to_create == 0 and vim.fn.has "win32" == 1 then
path_to_create = utils.path_join { p, path_to_create }
if #path_to_create == 0 and vim.fn.has("win32") == 1 then
path_to_create = utils.path_join({ p, path_to_create })
else
path_to_create = utils.path_join { path_to_create, p }
path_to_create = utils.path_join({ path_to_create, p })
end
if is_last_path_file and idx == num_nodes then
create_and_notify(path_to_create)

View File

@@ -1,13 +1,11 @@
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"
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)

View File

@@ -1,8 +1,9 @@
local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
local view = require "nvim-tree.view"
local lib = require "nvim-tree.lib"
local notify = require "nvim-tree.notify"
local core = require("nvim-tree.core")
local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
local view = require("nvim-tree.view")
local lib = require("nvim-tree.lib")
local notify = require("nvim-tree.notify")
local M = {
config = {},
@@ -26,13 +27,13 @@ end
---@param absolute_path string
local function clear_buffer(absolute_path)
local bufs = vim.fn.getbufinfo { bufloaded = 1, buflisted = 1 }
local bufs = vim.fn.getbufinfo({ bufloaded = 1, buflisted = 1 })
for _, buf in pairs(bufs) do
if buf.name == absolute_path then
local tree_winnr = vim.api.nvim_get_current_win()
if buf.hidden == 0 and (#bufs > 1 or view.View.float.enable) then
vim.api.nvim_set_current_win(buf.windows[1])
vim.cmd ":bn"
vim.cmd(":bn")
end
vim.api.nvim_buf_delete(buf.bufnr, { force = true })
if not view.View.float.quit_on_focus_loss then
@@ -56,13 +57,18 @@ local function remove_dir(cwd)
end
while true do
local name, t = vim.loop.fs_scandir_next(handle)
local name, _ = vim.loop.fs_scandir_next(handle)
if not name then
break
end
local new_cwd = utils.path_join { cwd, name }
if t == "directory" then
local new_cwd = utils.path_join({ cwd, name })
-- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility
local stat = vim.loop.fs_stat(new_cwd)
local type = stat and stat.type or nil
if type == "directory" then
local success = remove_dir(new_cwd)
if not success then
return false
@@ -111,8 +117,9 @@ function M.fn(node)
local function do_remove()
M.remove(node)
if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders").reload_explorer()
local explorer = core.get_explorer()
if not M.config.filesystem_watchers.enable and explorer then
explorer:reload_explorer()
end
end

View File

@@ -1,7 +1,8 @@
local lib = require "nvim-tree.lib"
local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify"
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local find_file = require("nvim-tree.actions.finders.find-file").fn
@@ -63,10 +64,10 @@ function M.rename(node, to)
idx = idx + 1
local p = utils.path_remove_trailing(path)
if #path_to_create == 0 and vim.fn.has "win32" == 1 then
path_to_create = utils.path_join { p, path_to_create }
if #path_to_create == 0 and vim.fn.has("win32") == 1 then
path_to_create = utils.path_join({ p, path_to_create })
else
path_to_create = utils.path_join { path_to_create, p }
path_to_create = utils.path_join({ path_to_create, p })
end
if idx == num_nodes then
@@ -155,7 +156,10 @@ function M.fn(default_modifier)
M.rename(node, prepend .. new_file_path .. append)
if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders").reload_explorer()
local explorer = core.get_explorer()
if explorer then
explorer:reload_explorer()
end
end
find_file(utils.path_remove_trailing(new_file_path))

View File

@@ -1,23 +1,23 @@
local lib = require "nvim-tree.lib"
local notify = require "nvim-tree.notify"
local reloaders = require "nvim-tree.actions.reloaders"
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local notify = require("nvim-tree.notify")
local M = {
config = {},
}
local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
---@param absolute_path string
local function clear_buffer(absolute_path)
local bufs = vim.fn.getbufinfo { bufloaded = 1, buflisted = 1 }
local bufs = vim.fn.getbufinfo({ bufloaded = 1, buflisted = 1 })
for _, buf in pairs(bufs) do
if buf.name == absolute_path then
if buf.hidden == 0 and #bufs > 1 then
local winnr = vim.api.nvim_get_current_win()
vim.api.nvim_set_current_win(buf.windows[1])
vim.cmd ":bn"
vim.cmd(":bn")
vim.api.nvim_set_current_win(winnr)
end
vim.api.nvim_buf_delete(buf.bufnr, {})
@@ -48,10 +48,12 @@ function M.remove(node)
on_stderr = on_stderr,
})
if need_sync_wait then
vim.fn.jobwait { job }
vim.fn.jobwait({ job })
end
end
local explorer = core.get_explorer()
if node.nodes ~= nil and not node.link_to then
trash_path(function(_, rc)
if rc ~= 0 then
@@ -59,8 +61,8 @@ function M.remove(node)
return
end
events._dispatch_folder_removed(node.absolute_path)
if not M.config.filesystem_watchers.enable then
reloaders.reload_explorer()
if not M.config.filesystem_watchers.enable and explorer then
explorer:reload_explorer()
end
end)
else
@@ -72,8 +74,8 @@ function M.remove(node)
end
events._dispatch_file_removed(node.absolute_path)
clear_buffer(node.absolute_path)
if not M.config.filesystem_watchers.enable then
reloaders.reload_explorer()
if not M.config.filesystem_watchers.enable and explorer then
explorer:reload_explorer()
end
end)
end

View File

@@ -1,12 +1,11 @@
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"
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.root = require("nvim-tree.actions.root")
M.tree = require("nvim-tree.actions.tree")
function M.setup(opts)
M.fs.setup(opts)

View File

@@ -1,7 +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"
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

@@ -1,9 +1,9 @@
local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view"
local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib"
local explorer_node = require "nvim-tree.explorer.node"
local diagnostics = require "nvim-tree.diagnostics"
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local explorer_node = require("nvim-tree.explorer.node")
local diagnostics = require("nvim-tree.diagnostics")
local M = {}
local MAX_DEPTH = 100
@@ -33,11 +33,15 @@ end
---@param what string type of status
---@param skip_gitignored boolean default false
local function move(where, what, skip_gitignored)
local node_cur = lib.get_node_at_cursor()
local first_node_line = core.get_nodes_starting_line()
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, first_node_line)
local iter_start, iter_end, iter_step, cur, first, nex
local cursor = lib.get_cursor_position()
if cursor and cursor[1] < first_node_line then
cur = cursor[1]
end
if where == "next" then
iter_start, iter_end, iter_step = first_node_line, #nodes_by_line, 1
elseif where == "prev" then
@@ -52,7 +56,7 @@ local function move(where, what, skip_gitignored)
first = line
end
if node == node_cur then
if cursor and line == cursor[1] then
cur = line
elseif valid and cur then
nex = line
@@ -61,9 +65,9 @@ local function move(where, what, skip_gitignored)
end
if nex then
view.set_cursor { nex, 0 }
view.set_cursor({ nex, 0 })
elseif vim.o.wrapscan and first then
view.set_cursor { first, 0 }
view.set_cursor({ first, 0 })
end
end
@@ -171,7 +175,7 @@ local function move_prev_recursive(what, skip_gitignored)
if
node_cur == nil
or node_cur == node_init -- we didn't move
or not node_cur.nodes -- node is a file
or not node_cur.nodes -- node is a file
then
return
end
@@ -182,13 +186,13 @@ local function move_prev_recursive(what, skip_gitignored)
-- 4.3)
if node_init.name == ".." then -- root node
view.set_cursor { 1, 0 } -- move to root node (position 1)
view.set_cursor({ 1, 0 }) -- move to root node (position 1)
else
local node_init_line = utils.find_node_line(node_init)
if node_init_line < 0 then
return
end
view.set_cursor { node_init_line, 0 }
view.set_cursor({ node_init_line, 0 })
end
-- 4.4)

View File

@@ -1,8 +1,7 @@
local renderer = require "nvim-tree.renderer"
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib"
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local M = {}
@@ -12,26 +11,32 @@ function M.fn(should_close)
should_close = should_close or false
return function(node)
local explorer = core.get_explorer()
node = lib.get_last_group_node(node)
if should_close and node.open then
node.open = false
return renderer.draw()
if explorer then
explorer.renderer:draw()
end
return
end
local parent = utils.get_parent_of_group(node).parent
if not parent or not parent.parent then
return view.set_cursor { 1, 0 }
return view.set_cursor({ 1, 0 })
end
local _, line = utils.find_node(core.get_explorer().nodes, function(n)
return n.absolute_path == parent.absolute_path
end)
view.set_cursor { line + 1, 0 }
view.set_cursor({ line + 1, 0 })
if should_close then
parent.open = false
renderer.draw()
if explorer then
explorer.renderer:draw()
end
end
end
end

View File

@@ -1,6 +1,6 @@
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local Iterator = require "nvim-tree.iterators.node-iterator"
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local Iterator = require("nvim-tree.iterators.node-iterator")
local M = {}

View File

@@ -1,4 +1,4 @@
local utils = require "nvim-tree.utils"
local utils = require("nvim-tree.utils")
local M = {}
@@ -57,7 +57,7 @@ end
function M.close_popup()
if current_popup ~= nil then
vim.api.nvim_win_close(current_popup.winnr, true)
vim.cmd "augroup NvimTreeRemoveFilePopup | au! CursorMoved | augroup END"
vim.cmd("augroup NvimTreeRemoveFilePopup | au! CursorMoved | augroup END")
current_popup = nil
end

View File

@@ -1,9 +1,9 @@
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"
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)

View File

@@ -1,8 +1,8 @@
-- Copyright 2019 Yazdani Kiyan under MIT License
local lib = require "nvim-tree.lib"
local notify = require "nvim-tree.notify"
local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view"
local lib = require("nvim-tree.lib")
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local M = {}
@@ -27,7 +27,7 @@ local function usable_win_ids()
local bufid = vim.api.nvim_win_get_buf(id)
for option, v in pairs(M.window_picker.exclude) do
local ok, option_value
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
ok, option_value = pcall(vim.api.nvim_get_option_value, option, { buf = bufid })
else
ok, option_value = pcall(vim.api.nvim_buf_get_option, bufid, option) ---@diagnostic disable-line: deprecated
@@ -91,7 +91,7 @@ local function pick_win_id()
for _, win_id in ipairs(not_selectable) do
local ok_status, statusline, ok_hl, winhl
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
ok_status, statusline = pcall(vim.api.nvim_get_option_value, "statusline", { win = win_id })
ok_hl, winhl = pcall(vim.api.nvim_get_option_value, "winhl", { win = win_id })
else
@@ -105,7 +105,7 @@ local function pick_win_id()
}
-- Clear statusline for windows not selectable
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("statusline", " ", { win = win_id })
else
vim.api.nvim_win_set_option(win_id, "statusline", " ") ---@diagnostic disable-line: deprecated
@@ -118,7 +118,7 @@ local function pick_win_id()
local char = M.window_picker.chars:sub(i, i)
local ok_status, statusline, ok_hl, winhl
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
ok_status, statusline = pcall(vim.api.nvim_get_option_value, "statusline", { win = id })
ok_hl, winhl = pcall(vim.api.nvim_get_option_value, "winhl", { win = id })
else
@@ -132,7 +132,7 @@ local function pick_win_id()
}
win_map[char] = id
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("statusline", "%=" .. char .. "%=", { win = id })
vim.api.nvim_set_option_value("winhl", "StatusLine:NvimTreeWindowPicker,StatusLineNC:NvimTreeWindowPicker", { win = id })
else
@@ -146,9 +146,9 @@ local function pick_win_id()
end
end
vim.cmd "redraw"
vim.cmd("redraw")
if vim.opt.cmdheight._value ~= 0 then
print "Pick window: "
print("Pick window: ")
end
local _, resp = pcall(get_user_input_char)
resp = (resp or ""):upper()
@@ -157,7 +157,7 @@ local function pick_win_id()
-- Restore window options
for _, id in ipairs(selectable) do
for opt, value in pairs(win_opts[id]) do
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value(opt, value, { win = id })
else
vim.api.nvim_win_set_option(id, opt, value) ---@diagnostic disable-line: deprecated
@@ -170,7 +170,7 @@ local function pick_win_id()
-- Ensure window still exists at this point
if vim.api.nvim_win_is_valid(id) then
for opt, value in pairs(win_opts[id]) do
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value(opt, value, { win = id })
else
vim.api.nvim_win_set_option(id, opt, value) ---@diagnostic disable-line: deprecated
@@ -300,7 +300,7 @@ local function open_in_new_window(filename, mode)
-- No need to split, as we created a new window.
create_new_window = false
if mode:match "split$" then
if mode:match("split$") then
mode = "edit"
end
elseif not vim.o.hidden then
@@ -309,14 +309,14 @@ local function open_in_new_window(filename, mode)
local target_bufid = vim.api.nvim_win_get_buf(target_winid)
local modified
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
modified = vim.api.nvim_get_option_value("modified", { buf = target_bufid })
else
modified = vim.api.nvim_buf_get_option(target_bufid, "modified") ---@diagnostic disable-line: deprecated
end
if modified then
if not mode:match "split$" then
if not mode:match("split$") then
mode = "vsplit"
end
end
@@ -333,16 +333,16 @@ local function open_in_new_window(filename, mode)
local fname
if M.relative_path then
fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd())))
fname = vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))
else
fname = utils.escape_special_chars(vim.fn.fnameescape(filename))
fname = vim.fn.fnameescape(filename)
end
local command
if create_new_window then
-- generated from vim.api.nvim_parse_cmd("belowright vsplit foo", {})
command = { cmd = "vsplit", mods = { split = new_window_side }, args = { fname } }
elseif mode:match "split$" then
elseif mode:match("split$") then
command = { cmd = mode, args = { fname } }
else
command = { cmd = "edit", args = { fname } }
@@ -372,27 +372,28 @@ end
---@param mode string
---@param filename string
function M.fn(mode, filename)
local fname = utils.escape_special_chars(filename)
if type(mode) ~= "string" then
mode = ""
end
if mode == "tabnew" then
return open_file_in_tab(filename)
return open_file_in_tab(fname)
end
if mode == "drop" then
return drop(filename)
return drop(fname)
end
if mode == "tab_drop" then
return tab_drop(filename)
return tab_drop(fname)
end
if mode == "edit_in_place" then
return edit_in_current_buf(filename)
return edit_in_current_buf(fname)
end
local buf_loaded = is_already_loaded(filename)
local buf_loaded = is_already_loaded(fname)
local found_win = utils.get_win_buf_from_path(filename)
if found_win and (mode == "preview" or mode == "preview_no_picker") then
@@ -400,7 +401,7 @@ function M.fn(mode, filename)
end
if not found_win then
open_in_new_window(filename, mode)
open_in_new_window(fname, mode)
else
vim.api.nvim_set_current_win(found_win)
vim.bo.bufhidden = ""

View File

@@ -1,5 +1,5 @@
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local M = {}

View File

@@ -1,12 +1,12 @@
local notify = require "nvim-tree.notify"
local utils = require "nvim-tree.utils"
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local M = {}
---@param node Node
function M.fn(node)
local function user(node)
if #M.config.system_open.cmd == 0 then
require("nvim-tree.utils").notify.warn "Cannot open file with system application. Unrecognized platform."
require("nvim-tree.utils").notify.warn("Cannot open file with system application. Unrecognized platform.")
return
end
@@ -49,20 +49,41 @@ function M.fn(node)
vim.loop.unref(process.handle)
end
---@param node Node
local function native(node)
local _, err = vim.ui.open(node.link_to or node.absolute_path)
-- err only provided on opener executable not found hence logging path is not useful
if err then
notify.warn(err)
end
end
---@param node Node
function M.fn(node)
M.open(node)
end
-- TODO always use native once 0.10 is the minimum neovim version
function M.setup(opts)
M.config = {}
M.config.system_open = opts.system_open or {}
if #M.config.system_open.cmd == 0 then
if utils.is_windows then
M.config.system_open = {
cmd = "cmd",
args = { "/c", "start", '""' },
}
elseif utils.is_macos then
M.config.system_open.cmd = "open"
elseif utils.is_unix then
M.config.system_open.cmd = "xdg-open"
if vim.fn.has("nvim-0.10") == 1 and #M.config.system_open.cmd == 0 then
M.open = native
else
M.open = user
if #M.config.system_open.cmd == 0 then
if utils.is_windows then
M.config.system_open = {
cmd = "cmd",
args = { "/c", "start", '""' },
}
elseif utils.is_macos then
M.config.system_open.cmd = "open"
elseif utils.is_unix then
M.config.system_open.cmd = "xdg-open"
end
end
end
end

View File

@@ -1,71 +0,0 @@
local git = require "nvim-tree.git"
local view = require "nvim-tree.view"
local renderer = require "nvim-tree.renderer"
local explorer_module = require "nvim-tree.explorer"
local core = require "nvim-tree.core"
local explorer_node = require "nvim-tree.explorer.node"
local Iterator = require "nvim-tree.iterators.node-iterator"
local M = {}
---@param node Explorer|nil
---@param projects table
local function refresh_nodes(node, projects)
Iterator.builder({ node })
:applier(function(n)
if n.nodes then
local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path)
explorer_module.reload(n, projects[toplevel] or {})
end
end)
:recursor(function(n)
return n.group_next and { n.group_next } or (n.open and n.nodes)
end)
:iterate()
end
---@param parent_node Node|nil
---@param projects table
function M.reload_node_status(parent_node, projects)
if parent_node == nil then
return
end
local toplevel = git.get_toplevel(parent_node.absolute_path)
local status = projects[toplevel] or {}
for _, node in ipairs(parent_node.nodes) do
explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status)
if node.nodes and #node.nodes > 0 then
M.reload_node_status(node, projects)
end
end
end
local event_running = false
function M.reload_explorer()
if event_running or not core.get_explorer() or vim.v.exiting ~= vim.NIL then
return
end
event_running = true
local projects = git.reload()
refresh_nodes(core.get_explorer(), projects)
if view.is_visible() then
renderer.draw()
end
event_running = false
end
function M.reload_git()
if not core.get_explorer() or not git.config.git.enable or event_running then
return
end
event_running = true
local projects = git.reload()
M.reload_node_status(core.get_explorer(), projects)
renderer.draw()
event_running = false
end
return M

View File

@@ -1,6 +1,6 @@
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local M = {
current_tab = vim.api.nvim_get_current_tabpage(),
@@ -91,7 +91,10 @@ M.force_dirchange = add_profiling_to(function(foldername, should_open_view)
if should_open_view then
require("nvim-tree.lib").open()
else
require("nvim-tree.renderer").draw()
local explorer = core.get_explorer()
if explorer then
explorer.renderer:draw()
end
end
end)

View File

@@ -1,12 +1,12 @@
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local M = {}
---@param node Node
function M.fn(node)
if not node or node.name == ".." then
require("nvim-tree.actions.root.change-dir").fn ".."
require("nvim-tree.actions.root.change-dir").fn("..")
else
local cwd = core.get_cwd()
if cwd == nil then

View File

@@ -1,7 +1,7 @@
local M = {}
M.change_dir = require "nvim-tree.actions.root.change-dir"
M.dir_up = require "nvim-tree.actions.root.dir-up"
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)

View File

@@ -1,7 +1,7 @@
local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib"
local view = require "nvim-tree.view"
local finders_find_file = require "nvim-tree.actions.finders.find-file"
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local view = require("nvim-tree.view")
local finders_find_file = require("nvim-tree.actions.finders.find-file")
local M = {}
@@ -49,9 +49,9 @@ function M.fn(opts)
end
elseif opts.open then
-- open
lib.open { current_window = opts.current_window, winid = opts.winid }
lib.open({ current_window = opts.current_window, winid = opts.winid })
if not opts.focus then
vim.cmd "noautocmd wincmd p"
vim.cmd("noautocmd wincmd p")
end
end

View File

@@ -1,10 +1,10 @@
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"
M.resize = require "nvim-tree.actions.tree.resize"
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")
M.resize = require("nvim-tree.actions.tree.resize")
function M.setup(opts)
M.find_file.setup(opts)

View File

@@ -1,8 +1,7 @@
local renderer = require "nvim-tree.renderer"
local utils = require "nvim-tree.utils"
local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib"
local Iterator = require "nvim-tree.iterators.node-iterator"
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local Iterator = require("nvim-tree.iterators.node-iterator")
local M = {}
@@ -46,7 +45,7 @@ function M.fn(keep_buffers)
end)
:iterate()
renderer.draw()
explorer.renderer:draw()
utils.focus_node_or_parent(node)
end

View File

@@ -1,8 +1,7 @@
local core = require "nvim-tree.core"
local renderer = require "nvim-tree.renderer"
local Iterator = require "nvim-tree.iterators.node-iterator"
local notify = require "nvim-tree.notify"
local lib = require "nvim-tree.lib"
local core = require("nvim-tree.core")
local Iterator = require("nvim-tree.iterators.node-iterator")
local notify = require("nvim-tree.notify")
local lib = require("nvim-tree.lib")
local M = {}
@@ -65,11 +64,14 @@ end
---@param base_node table
function M.fn(base_node)
local node = base_node.nodes and base_node or core.get_explorer()
local explorer = core.get_explorer()
local node = base_node.nodes and base_node or explorer
if gen_iterator()(node) then
notify.warn("expansion iteration was halted after " .. M.MAX_FOLDER_DISCOVERY .. " discovered folders")
end
renderer.draw()
if explorer then
explorer.renderer:draw()
end
end
function M.setup(opts)

View File

@@ -1,8 +1,8 @@
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"
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)

View File

@@ -1,12 +1,12 @@
local lib = require "nvim-tree.lib"
local utils = require "nvim-tree.utils"
local reloaders = require "nvim-tree.actions.reloaders"
local core = require "nvim-tree.core"
local lib = require("nvim-tree.lib")
local utils = require("nvim-tree.utils")
local core = require("nvim-tree.core")
local M = {}
local function reload()
---@param explorer Explorer
local function reload(explorer)
local node = lib.get_node_at_cursor()
reloaders.reload_explorer()
explorer:reload_explorer()
utils.focus_node_or_parent(node)
end
@@ -19,39 +19,46 @@ local function wrap_explorer(fn)
end
end
---@param explorer Explorer
local function custom(explorer)
explorer.filters.config.filter_custom = not explorer.filters.config.filter_custom
reload()
reload(explorer)
end
---@param explorer Explorer
local function git_ignored(explorer)
explorer.filters.config.filter_git_ignored = not explorer.filters.config.filter_git_ignored
reload()
reload(explorer)
end
---@param explorer Explorer
local function git_clean(explorer)
explorer.filters.config.filter_git_clean = not explorer.filters.config.filter_git_clean
reload()
reload(explorer)
end
---@param explorer Explorer
local function no_buffer(explorer)
explorer.filters.config.filter_no_buffer = not explorer.filters.config.filter_no_buffer
reload()
reload(explorer)
end
---@param explorer Explorer
local function no_bookmark(explorer)
explorer.filters.config.filter_no_bookmark = not explorer.filters.config.filter_no_bookmark
reload()
reload(explorer)
end
---@param explorer Explorer
local function dotfiles(explorer)
explorer.filters.config.filter_dotfiles = not explorer.filters.config.filter_dotfiles
reload()
reload(explorer)
end
---@param explorer Explorer
local function enable(explorer)
explorer.filters.config.enable = not explorer.filters.config.enable
reload()
reload(explorer)
end
M.custom = wrap_explorer(custom)

View File

@@ -1,6 +1,6 @@
local lib = require "nvim-tree.lib"
local view = require "nvim-tree.view"
local finders_find_file = require "nvim-tree.actions.finders.find-file"
local lib = require("nvim-tree.lib")
local view = require("nvim-tree.view")
local finders_find_file = require("nvim-tree.actions.finders.find-file")
local M = {}
@@ -29,11 +29,11 @@ function M.fn(opts)
view.focus()
else
-- open
lib.open {
lib.open({
path = opts.path,
current_window = opts.current_window,
winid = opts.winid,
}
})
end
-- find file

View File

@@ -1,4 +1,4 @@
local view = require "nvim-tree.view"
local view = require("nvim-tree.view")
local M = {}

View File

@@ -1,6 +1,6 @@
local lib = require "nvim-tree.lib"
local view = require "nvim-tree.view"
local finders_find_file = require "nvim-tree.actions.finders.find-file"
local lib = require("nvim-tree.lib")
local view = require("nvim-tree.view")
local finders_find_file = require("nvim-tree.actions.finders.find-file")
local M = {}
@@ -45,11 +45,11 @@ function M.fn(opts, no_focus, cwd, bang)
view.close()
else
-- open
lib.open {
lib.open({
path = opts.path,
current_window = opts.current_window,
winid = opts.winid,
}
})
-- find file
if M.config.update_focused_file.enable or opts.find_file then
@@ -64,7 +64,7 @@ function M.fn(opts, no_focus, cwd, bang)
-- restore focus
if not opts.focus then
vim.cmd "noautocmd wincmd p"
vim.cmd("noautocmd wincmd p")
end
end
end

View File

@@ -1,17 +1,13 @@
local lib = require "nvim-tree.lib"
local core = require "nvim-tree.core"
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local actions = require "nvim-tree.actions"
local appearance_diagnostics = require "nvim-tree.appearance.diagnostics"
local events = require "nvim-tree.events"
local help = require "nvim-tree.help"
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 lib = require("nvim-tree.lib")
local core = require("nvim-tree.core")
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local actions = require("nvim-tree.actions")
local appearance_diagnostics = require("nvim-tree.appearance.diagnostics")
local events = require("nvim-tree.events")
local help = require("nvim-tree.help")
local keymap = require("nvim-tree.keymap")
local notify = require("nvim-tree.notify")
local Api = {
tree = {},
@@ -51,7 +47,7 @@ local function wrap(f)
if vim.g.NvimTreeSetup == 1 then
return f(...)
else
notify.error "nvim-tree setup not called"
notify.error("nvim-tree setup not called")
end
end
end
@@ -76,16 +72,17 @@ local function wrap_node_or_nil(fn)
end
end
---Inject the explorer as the first argument if present otherwise do nothing.
---@param fn function function to invoke
---Invoke a method on the singleton explorer.
---Print error when setup not called.
---@param explorer_method string explorer method name
---@return fun(...) : any
local function wrap_explorer(fn)
return function(...)
local function wrap_explorer(explorer_method)
return wrap(function(...)
local explorer = core.get_explorer()
if explorer then
return fn(explorer, ...)
return explorer[explorer_method](explorer, ...)
end
end
end)
end
---Invoke a member's method on the singleton explorer.
@@ -124,7 +121,7 @@ Api.tree.toggle = wrap(actions.tree.toggle.fn)
Api.tree.close = wrap(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.reload = wrap(actions.reloaders.reload_explorer)
Api.tree.reload = wrap_explorer("reload_explorer")
---@class ApiTreeResizeOpts
---@field width string|function|number|table|nil
@@ -139,7 +136,7 @@ end)
Api.tree.change_root_to_node = wrap_node(function(node)
if node.name == ".." then
actions.root.change_dir.fn ".."
actions.root.change_dir.fn("..")
elseif node.nodes ~= nil then
actions.root.change_dir.fn(lib.get_last_group_node(node).absolute_path)
end
@@ -185,20 +182,20 @@ Api.tree.winid = wrap(view.winid)
Api.fs.create = wrap_node_or_nil(actions.fs.create_file.fn)
Api.fs.remove = wrap_node(actions.fs.remove_file.fn)
Api.fs.trash = wrap_node(actions.fs.trash.fn)
Api.fs.rename_node = wrap_node(actions.fs.rename_file.fn ":t")
Api.fs.rename = wrap_node(actions.fs.rename_file.fn ":t")
Api.fs.rename_sub = wrap_node(actions.fs.rename_file.fn ":p:h")
Api.fs.rename_basename = wrap_node(actions.fs.rename_file.fn ":t:r")
Api.fs.rename_full = wrap_node(actions.fs.rename_file.fn ":p")
Api.fs.cut = wrap_node(actions.fs.copy_paste.cut)
Api.fs.paste = wrap_node(actions.fs.copy_paste.paste)
Api.fs.clear_clipboard = wrap(actions.fs.copy_paste.clear_clipboard)
Api.fs.print_clipboard = wrap(actions.fs.copy_paste.print_clipboard)
Api.fs.copy.node = wrap_node(actions.fs.copy_paste.copy)
Api.fs.copy.absolute_path = wrap_node(actions.fs.copy_paste.copy_absolute_path)
Api.fs.copy.filename = wrap_node(actions.fs.copy_paste.copy_filename)
Api.fs.copy.basename = wrap_node(actions.fs.copy_paste.copy_basename)
Api.fs.copy.relative_path = wrap_node(actions.fs.copy_paste.copy_path)
Api.fs.rename_node = wrap_node(actions.fs.rename_file.fn(":t"))
Api.fs.rename = wrap_node(actions.fs.rename_file.fn(":t"))
Api.fs.rename_sub = wrap_node(actions.fs.rename_file.fn(":p:h"))
Api.fs.rename_basename = wrap_node(actions.fs.rename_file.fn(":t:r"))
Api.fs.rename_full = wrap_node(actions.fs.rename_file.fn(":p"))
Api.fs.cut = wrap_node(wrap_explorer_member("clipboard", "cut"))
Api.fs.paste = wrap_node(wrap_explorer_member("clipboard", "paste"))
Api.fs.clear_clipboard = wrap_explorer_member("clipboard", "clear_clipboard")
Api.fs.print_clipboard = wrap_explorer_member("clipboard", "print_clipboard")
Api.fs.copy.node = wrap_node(wrap_explorer_member("clipboard", "copy"))
Api.fs.copy.absolute_path = wrap_node(wrap_explorer_member("clipboard", "copy_absolute_path"))
Api.fs.copy.filename = wrap_node(wrap_explorer_member("clipboard", "copy_filename"))
Api.fs.copy.basename = wrap_node(wrap_explorer_member("clipboard", "copy_basename"))
Api.fs.copy.relative_path = wrap_node(wrap_explorer_member("clipboard", "copy_path"))
---@param mode string
---@param node table
@@ -215,7 +212,7 @@ end
local function open_or_expand_or_dir_up(mode, toggle_group)
return function(node)
if node.name == ".." then
actions.root.change_dir.fn ".."
actions.root.change_dir.fn("..")
elseif node.nodes then
lib.expand_or_collapse(node, toggle_group)
elseif not toggle_group then
@@ -224,42 +221,42 @@ local function open_or_expand_or_dir_up(mode, toggle_group)
end
end
Api.node.open.edit = wrap_node(open_or_expand_or_dir_up "edit")
Api.node.open.drop = wrap_node(open_or_expand_or_dir_up "drop")
Api.node.open.tab_drop = wrap_node(open_or_expand_or_dir_up "tab_drop")
Api.node.open.replace_tree_buffer = wrap_node(open_or_expand_or_dir_up "edit_in_place")
Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up "edit_no_picker")
Api.node.open.vertical = wrap_node(open_or_expand_or_dir_up "vsplit")
Api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up "split")
Api.node.open.tab = wrap_node(open_or_expand_or_dir_up "tabnew")
Api.node.open.edit = wrap_node(open_or_expand_or_dir_up("edit"))
Api.node.open.drop = wrap_node(open_or_expand_or_dir_up("drop"))
Api.node.open.tab_drop = wrap_node(open_or_expand_or_dir_up("tab_drop"))
Api.node.open.replace_tree_buffer = wrap_node(open_or_expand_or_dir_up("edit_in_place"))
Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up("edit_no_picker"))
Api.node.open.vertical = wrap_node(open_or_expand_or_dir_up("vsplit"))
Api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up("split"))
Api.node.open.tab = wrap_node(open_or_expand_or_dir_up("tabnew"))
Api.node.open.toggle_group_empty = wrap_node(open_or_expand_or_dir_up("toggle_group_empty", true))
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 = 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.show_info_popup = wrap_node(actions.node.file_popup.toggle_file_info)
Api.node.run.cmd = wrap_node(actions.node.run_command.run_file_command)
Api.node.run.system = wrap_node(actions.node.system_open.fn)
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.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.next_recursive = wrap_node(actions.moves.item.fn { where = "next", what = "git", recurse = 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.git.prev_recursive = wrap_node(actions.moves.item.fn { where = "prev", what = "git", recurse = true })
Api.node.navigate.diagnostics.next = wrap_node(actions.moves.item.fn { where = "next", what = "diag" })
Api.node.navigate.diagnostics.next_recursive = wrap_node(actions.moves.item.fn { where = "next", what = "diag", recurse = true })
Api.node.navigate.diagnostics.prev = wrap_node(actions.moves.item.fn { where = "prev", what = "diag" })
Api.node.navigate.diagnostics.prev_recursive = wrap_node(actions.moves.item.fn { where = "prev", what = "diag", recurse = true })
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.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.next_recursive = wrap_node(actions.moves.item.fn({ where = "next", what = "git", recurse = 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.git.prev_recursive = wrap_node(actions.moves.item.fn({ where = "prev", what = "git", recurse = true }))
Api.node.navigate.diagnostics.next = wrap_node(actions.moves.item.fn({ where = "next", what = "diag" }))
Api.node.navigate.diagnostics.next_recursive = wrap_node(actions.moves.item.fn({ where = "next", what = "diag", recurse = true }))
Api.node.navigate.diagnostics.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "diag" }))
Api.node.navigate.diagnostics.prev_recursive = wrap_node(actions.moves.item.fn({ where = "prev", what = "diag", recurse = true }))
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.git.reload = wrap(actions.reloaders.reload_git)
Api.git.reload = wrap_explorer("reload_git")
Api.events.subscribe = events.subscribe
Api.events.Event = events.Event
@@ -267,16 +264,16 @@ Api.events.Event = events.Event
Api.live_filter.start = wrap_explorer_member("live_filter", "start_filtering")
Api.live_filter.clear = wrap_explorer_member("live_filter", "clear_filter")
Api.marks.get = wrap_node(wrap_explorer_member("marks", "get_mark"))
Api.marks.list = wrap_explorer_member("marks", "get_marks")
Api.marks.toggle = wrap_node(wrap_explorer_member("marks", "toggle_mark"))
Api.marks.clear = wrap_explorer_member("marks", "clear_marks")
Api.marks.bulk.delete = wrap_explorer(marks_bulk_delete.bulk_delete)
Api.marks.bulk.trash = wrap_explorer(marks_bulk_trash.bulk_trash)
Api.marks.bulk.move = wrap_explorer(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.marks.get = wrap_node(wrap_explorer_member("marks", "get"))
Api.marks.list = wrap_explorer_member("marks", "list")
Api.marks.toggle = wrap_node(wrap_explorer_member("marks", "toggle"))
Api.marks.clear = wrap_explorer_member("marks", "clear")
Api.marks.bulk.delete = wrap_explorer_member("marks", "bulk_delete")
Api.marks.bulk.trash = wrap_explorer_member("marks", "bulk_trash")
Api.marks.bulk.move = wrap_explorer_member("marks", "bulk_move")
Api.marks.navigate.next = wrap_explorer_member("marks", "navigate_next")
Api.marks.navigate.prev = wrap_explorer_member("marks", "navigate_prev")
Api.marks.navigate.select = wrap_explorer_member("marks", "navigate_select")
Api.config.mappings.get_keymap = wrap(keymap.get_keymap)
Api.config.mappings.get_keymap_default = wrap(keymap.get_keymap_default)

View File

@@ -1,4 +1,4 @@
local appearance = require "nvim-tree.appearance"
local appearance = require("nvim-tree.appearance")
-- others with name and links less than this arbitrary value are short
local SHORT_LEN = 50
@@ -129,7 +129,7 @@ function M.hi_test()
render_displays("other, long", displays_long, bufnr, l)
-- finalise and focus the buffer
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", false, { buf = bufnr })
else
vim.api.nvim_buf_set_option(bufnr, "modifiable", false) ---@diagnostic disable-line: deprecated

View File

@@ -12,126 +12,126 @@ local M = {}
M.HIGHLIGHT_GROUPS = {
-- Standard
{ group = "NvimTreeNormal", link = "Normal" },
{ group = "NvimTreeNormalFloat", link = "NormalFloat" },
{ group = "NvimTreeNormalFloatBorder", link = "FloatBorder" },
{ group = "NvimTreeNormalNC", link = "NvimTreeNormal" },
{ group = "NvimTreeNormal", link = "Normal" },
{ group = "NvimTreeNormalFloat", link = "NormalFloat" },
{ group = "NvimTreeNormalFloatBorder", link = "FloatBorder" },
{ group = "NvimTreeNormalNC", link = "NvimTreeNormal" },
{ group = "NvimTreeLineNr", link = "LineNr" },
{ group = "NvimTreeWinSeparator", link = "WinSeparator" },
{ group = "NvimTreeEndOfBuffer", link = "EndOfBuffer" },
{ group = "NvimTreePopup", link = "Normal" },
{ group = "NvimTreeSignColumn", link = "NvimTreeNormal" },
{ group = "NvimTreeLineNr", link = "LineNr" },
{ group = "NvimTreeWinSeparator", link = "WinSeparator" },
{ group = "NvimTreeEndOfBuffer", link = "EndOfBuffer" },
{ group = "NvimTreePopup", link = "Normal" },
{ group = "NvimTreeSignColumn", link = "NvimTreeNormal" },
{ group = "NvimTreeCursorColumn", link = "CursorColumn" },
{ group = "NvimTreeCursorLine", link = "CursorLine" },
{ group = "NvimTreeCursorLineNr", link = "CursorLineNr" },
{ group = "NvimTreeCursorColumn", link = "CursorColumn" },
{ group = "NvimTreeCursorLine", link = "CursorLine" },
{ group = "NvimTreeCursorLineNr", link = "CursorLineNr" },
{ group = "NvimTreeStatusLine", link = "StatusLine" },
{ group = "NvimTreeStatusLineNC", link = "StatusLineNC" },
{ group = "NvimTreeStatusLine", link = "StatusLine" },
{ group = "NvimTreeStatusLineNC", link = "StatusLineNC" },
-- File Text
{ group = "NvimTreeExecFile", link = "Question" },
{ group = "NvimTreeImageFile", link = "Question" },
{ group = "NvimTreeSpecialFile", link = "Title" },
{ group = "NvimTreeSymlink", link = "Underlined" },
{ group = "NvimTreeExecFile", link = "Question" },
{ group = "NvimTreeImageFile", link = "Question" },
{ group = "NvimTreeSpecialFile", link = "Title" },
{ group = "NvimTreeSymlink", link = "Underlined" },
-- Folder Text
{ group = "NvimTreeRootFolder", link = "Title" },
{ group = "NvimTreeFolderName", link = "Directory" },
{ group = "NvimTreeEmptyFolderName", link = "Directory" },
{ group = "NvimTreeOpenedFolderName", link = "Directory" },
{ group = "NvimTreeSymlinkFolderName", link = "Directory" },
{ group = "NvimTreeRootFolder", link = "Title" },
{ group = "NvimTreeFolderName", link = "Directory" },
{ group = "NvimTreeEmptyFolderName", link = "Directory" },
{ group = "NvimTreeOpenedFolderName", link = "Directory" },
{ group = "NvimTreeSymlinkFolderName", link = "Directory" },
-- File Icons
{ group = "NvimTreeFileIcon", link = "NvimTreeNormal" },
{ group = "NvimTreeSymlinkIcon", link = "NvimTreeNormal" },
{ group = "NvimTreeFileIcon", link = "NvimTreeNormal" },
{ group = "NvimTreeSymlinkIcon", link = "NvimTreeNormal" },
-- Folder Icons
{ group = "NvimTreeFolderIcon", def = "guifg=#8094b4 ctermfg=Blue" },
{ group = "NvimTreeOpenedFolderIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeClosedFolderIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeFolderArrowClosed", link = "NvimTreeIndentMarker" },
{ group = "NvimTreeFolderArrowOpen", link = "NvimTreeIndentMarker" },
{ group = "NvimTreeFolderIcon", def = "guifg=#8094b4 ctermfg=Blue" },
{ group = "NvimTreeOpenedFolderIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeClosedFolderIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeFolderArrowClosed", link = "NvimTreeIndentMarker" },
{ group = "NvimTreeFolderArrowOpen", link = "NvimTreeIndentMarker" },
-- Indent
{ group = "NvimTreeIndentMarker", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeIndentMarker", link = "NvimTreeFolderIcon" },
-- Picker
{ group = "NvimTreeWindowPicker", def = "guifg=#ededed guibg=#4493c8 gui=bold ctermfg=White ctermbg=DarkBlue" },
{ group = "NvimTreeWindowPicker", def = "guifg=#ededed guibg=#4493c8 gui=bold ctermfg=White ctermbg=DarkBlue" },
-- LiveFilter
{ group = "NvimTreeLiveFilterPrefix", link = "PreProc" },
{ group = "NvimTreeLiveFilterValue", link = "ModeMsg" },
{ group = "NvimTreeLiveFilterPrefix", link = "PreProc" },
{ group = "NvimTreeLiveFilterValue", link = "ModeMsg" },
-- Clipboard
{ group = "NvimTreeCutHL", link = "SpellBad" },
{ group = "NvimTreeCopiedHL", link = "SpellRare" },
{ group = "NvimTreeCutHL", link = "SpellBad" },
{ group = "NvimTreeCopiedHL", link = "SpellRare" },
-- Bookmark
{ group = "NvimTreeBookmarkIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeBookmarkHL", link = "SpellLocal" },
{ group = "NvimTreeBookmarkIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeBookmarkHL", link = "SpellLocal" },
-- Modified
{ group = "NvimTreeModifiedIcon", link = "Type" },
{ group = "NvimTreeModifiedFileHL", link = "NvimTreeModifiedIcon" },
{ group = "NvimTreeModifiedFolderHL", link = "NvimTreeModifiedFileHL" },
{ group = "NvimTreeModifiedIcon", link = "Type" },
{ group = "NvimTreeModifiedFileHL", link = "NvimTreeModifiedIcon" },
{ group = "NvimTreeModifiedFolderHL", link = "NvimTreeModifiedFileHL" },
-- Hidden
{ group = "NvimTreeHiddenIcon", link = "Conceal" },
{ group = "NvimTreeHiddenFileHL", link = "NvimTreeHiddenIcon" },
{ group = "NvimTreeHiddenFolderHL", link = "NvimTreeHiddenFileHL" },
{ group = "NvimTreeHiddenIcon", link = "Conceal" },
{ group = "NvimTreeHiddenFileHL", link = "NvimTreeHiddenIcon" },
{ group = "NvimTreeHiddenFolderHL", link = "NvimTreeHiddenFileHL" },
-- Hidden Display
{ group = "NvimTreeHiddenDisplay", link = "Conceal" },
{ group = "NvimTreeHiddenDisplay", link = "Conceal" },
-- Opened
{ group = "NvimTreeOpenedHL", link = "Special" },
{ group = "NvimTreeOpenedHL", link = "Special" },
-- Git Icon
{ group = "NvimTreeGitDeletedIcon", link = "Statement" },
{ group = "NvimTreeGitDirtyIcon", link = "Statement" },
{ group = "NvimTreeGitIgnoredIcon", link = "Comment" },
{ group = "NvimTreeGitMergeIcon", link = "Constant" },
{ group = "NvimTreeGitNewIcon", link = "PreProc" },
{ group = "NvimTreeGitRenamedIcon", link = "PreProc" },
{ group = "NvimTreeGitStagedIcon", link = "Constant" },
{ group = "NvimTreeGitDeletedIcon", link = "Statement" },
{ group = "NvimTreeGitDirtyIcon", link = "Statement" },
{ group = "NvimTreeGitIgnoredIcon", link = "Comment" },
{ group = "NvimTreeGitMergeIcon", link = "Constant" },
{ group = "NvimTreeGitNewIcon", link = "PreProc" },
{ group = "NvimTreeGitRenamedIcon", link = "PreProc" },
{ group = "NvimTreeGitStagedIcon", link = "Constant" },
-- Git File Highlight
{ group = "NvimTreeGitFileDeletedHL", link = "NvimTreeGitDeletedIcon" },
{ group = "NvimTreeGitFileDirtyHL", link = "NvimTreeGitDirtyIcon" },
{ group = "NvimTreeGitFileIgnoredHL", link = "NvimTreeGitIgnoredIcon" },
{ group = "NvimTreeGitFileMergeHL", link = "NvimTreeGitMergeIcon" },
{ group = "NvimTreeGitFileNewHL", link = "NvimTreeGitNewIcon" },
{ group = "NvimTreeGitFileRenamedHL", link = "NvimTreeGitRenamedIcon" },
{ group = "NvimTreeGitFileStagedHL", link = "NvimTreeGitStagedIcon" },
{ group = "NvimTreeGitFileDeletedHL", link = "NvimTreeGitDeletedIcon" },
{ group = "NvimTreeGitFileDirtyHL", link = "NvimTreeGitDirtyIcon" },
{ group = "NvimTreeGitFileIgnoredHL", link = "NvimTreeGitIgnoredIcon" },
{ group = "NvimTreeGitFileMergeHL", link = "NvimTreeGitMergeIcon" },
{ group = "NvimTreeGitFileNewHL", link = "NvimTreeGitNewIcon" },
{ group = "NvimTreeGitFileRenamedHL", link = "NvimTreeGitRenamedIcon" },
{ group = "NvimTreeGitFileStagedHL", link = "NvimTreeGitStagedIcon" },
-- Git Folder Highlight
{ group = "NvimTreeGitFolderDeletedHL", link = "NvimTreeGitFileDeletedHL" },
{ group = "NvimTreeGitFolderDirtyHL", link = "NvimTreeGitFileDirtyHL" },
{ group = "NvimTreeGitFolderIgnoredHL", link = "NvimTreeGitFileIgnoredHL" },
{ group = "NvimTreeGitFolderMergeHL", link = "NvimTreeGitFileMergeHL" },
{ group = "NvimTreeGitFolderNewHL", link = "NvimTreeGitFileNewHL" },
{ group = "NvimTreeGitFolderRenamedHL", link = "NvimTreeGitFileRenamedHL" },
{ group = "NvimTreeGitFolderStagedHL", link = "NvimTreeGitFileStagedHL" },
{ group = "NvimTreeGitFolderDeletedHL", link = "NvimTreeGitFileDeletedHL" },
{ group = "NvimTreeGitFolderDirtyHL", link = "NvimTreeGitFileDirtyHL" },
{ group = "NvimTreeGitFolderIgnoredHL", link = "NvimTreeGitFileIgnoredHL" },
{ group = "NvimTreeGitFolderMergeHL", link = "NvimTreeGitFileMergeHL" },
{ group = "NvimTreeGitFolderNewHL", link = "NvimTreeGitFileNewHL" },
{ group = "NvimTreeGitFolderRenamedHL", link = "NvimTreeGitFileRenamedHL" },
{ group = "NvimTreeGitFolderStagedHL", link = "NvimTreeGitFileStagedHL" },
-- Diagnostics Icon
{ group = "NvimTreeDiagnosticErrorIcon", link = "DiagnosticError" },
{ group = "NvimTreeDiagnosticWarnIcon", link = "DiagnosticWarn" },
{ group = "NvimTreeDiagnosticInfoIcon", link = "DiagnosticInfo" },
{ group = "NvimTreeDiagnosticHintIcon", link = "DiagnosticHint" },
{ group = "NvimTreeDiagnosticErrorIcon", link = "DiagnosticError" },
{ group = "NvimTreeDiagnosticWarnIcon", link = "DiagnosticWarn" },
{ group = "NvimTreeDiagnosticInfoIcon", link = "DiagnosticInfo" },
{ group = "NvimTreeDiagnosticHintIcon", link = "DiagnosticHint" },
-- Diagnostics File Highlight
{ group = "NvimTreeDiagnosticErrorFileHL", link = "DiagnosticUnderlineError" },
{ group = "NvimTreeDiagnosticWarnFileHL", link = "DiagnosticUnderlineWarn" },
{ group = "NvimTreeDiagnosticInfoFileHL", link = "DiagnosticUnderlineInfo" },
{ group = "NvimTreeDiagnosticHintFileHL", link = "DiagnosticUnderlineHint" },
{ group = "NvimTreeDiagnosticErrorFileHL", link = "DiagnosticUnderlineError" },
{ group = "NvimTreeDiagnosticWarnFileHL", link = "DiagnosticUnderlineWarn" },
{ group = "NvimTreeDiagnosticInfoFileHL", link = "DiagnosticUnderlineInfo" },
{ group = "NvimTreeDiagnosticHintFileHL", link = "DiagnosticUnderlineHint" },
-- Diagnostics Folder Highlight
{ group = "NvimTreeDiagnosticErrorFolderHL", link = "NvimTreeDiagnosticErrorFileHL" },
{ group = "NvimTreeDiagnosticWarnFolderHL", link = "NvimTreeDiagnosticWarnFileHL" },
{ group = "NvimTreeDiagnosticInfoFolderHL", link = "NvimTreeDiagnosticInfoFileHL" },
{ group = "NvimTreeDiagnosticHintFolderHL", link = "NvimTreeDiagnosticHintFileHL" },
{ group = "NvimTreeDiagnosticWarnFolderHL", link = "NvimTreeDiagnosticWarnFileHL" },
{ group = "NvimTreeDiagnosticInfoFolderHL", link = "NvimTreeDiagnosticInfoFileHL" },
{ group = "NvimTreeDiagnosticHintFolderHL", link = "NvimTreeDiagnosticHintFileHL" },
}
-- nvim-tree highlight groups to legacy

View File

@@ -6,16 +6,14 @@ M._modified = {}
---refresh M._modified
function M.reload_modified()
M._modified = {}
local bufs = vim.fn.getbufinfo { bufmodified = 1, buflisted = 1 }
local bufs = vim.fn.getbufinfo({ bufmodified = 1, buflisted = 1 })
for _, buf in pairs(bufs) do
local path = buf.name
if path ~= "" then -- not a [No Name] buffer
-- mark all the parent as modified as well
while
M._modified[path] ~= true
while M._modified[path] ~= true do
-- no need to keep going if already recorded
-- This also prevents an infinite loop
do
M._modified[path] = true
path = vim.fn.fnamemodify(path, ":h")
end

View File

@@ -1,5 +1,5 @@
local api = require "nvim-tree.api"
local view = require "nvim-tree.view"
local api = require("nvim-tree.api")
local view = require("nvim-tree.view")
local M = {}
@@ -12,7 +12,7 @@ local CMDS = {
complete = "dir",
},
command = function(c)
api.tree.open { path = c.args }
api.tree.open({ path = c.args })
end,
},
{
@@ -33,12 +33,12 @@ local CMDS = {
complete = "dir",
},
command = function(c)
api.tree.toggle {
api.tree.toggle({
find_file = false,
focus = true,
path = c.args,
update_root = false,
}
})
end,
},
{
@@ -79,11 +79,11 @@ local CMDS = {
bar = true,
},
command = function(c)
api.tree.find_file {
api.tree.find_file({
open = true,
focus = true,
update_root = c.bang,
}
})
end,
},
{
@@ -95,12 +95,12 @@ local CMDS = {
complete = "dir",
},
command = function(c)
api.tree.toggle {
api.tree.toggle({
find_file = true,
focus = true,
path = c.args,
update_root = c.bang,
}
})
end,
},
{

View File

@@ -1,7 +1,6 @@
local events = require "nvim-tree.events"
local explorer = require "nvim-tree.explorer"
local view = require "nvim-tree.view"
local log = require "nvim-tree.log"
local events = require("nvim-tree.events")
local view = require("nvim-tree.view")
local log = require("nvim-tree.log")
local M = {}
@@ -16,7 +15,7 @@ function M.init(foldername)
if TreeExplorer then
TreeExplorer:destroy()
end
TreeExplorer = explorer.Explorer.new(foldername)
TreeExplorer = require("nvim-tree.explorer"):new(foldername)
if not first_init_done then
events._dispatch_ready()
first_init_done = true

View File

@@ -1,6 +1,7 @@
local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view"
local log = require "nvim-tree.log"
local core = require("nvim-tree.core")
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local log = require("nvim-tree.log")
local M = {}
@@ -41,7 +42,7 @@ local function from_nvim_lsp()
-- is_enabled is not present in all 0.10 builds/releases, see #2781
local is_enabled = false
if vim.fn.has "nvim-0.10" == 1 and type(vim.diagnostic.is_enabled) == "function" then
if vim.fn.has("nvim-0.10") == 1 and type(vim.diagnostic.is_enabled) == "function" then
is_enabled = vim.diagnostic.is_enabled()
elseif type(vim.diagnostic.is_disabled) == "function" then ---@diagnostic disable-line: deprecated
is_enabled = not vim.diagnostic.is_disabled() ---@diagnostic disable-line: deprecated
@@ -76,7 +77,7 @@ local function handle_coc_exception(err)
local notify = true
-- avoid distractions on interrupts (CTRL-C)
if err:find "Vim:Interrupt" or err:find "Keyboard interrupt" then
if err:find("Vim:Interrupt") or err:find("Keyboard interrupt") then
notify = false
end
@@ -99,7 +100,7 @@ local function from_coc()
end
local ok, diagnostic_list = xpcall(function()
return vim.fn.CocAction "diagnosticList"
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 {}
@@ -151,21 +152,24 @@ function M.update()
return
end
utils.debounce("diagnostics", M.debounce_delay, function()
local profile = log.profile_start "diagnostics update"
local profile = log.profile_start("diagnostics update")
if is_using_coc() then
NODE_SEVERITIES = from_coc()
else
NODE_SEVERITIES = from_nvim_lsp()
end
NODE_SEVERITIES_VERSION = NODE_SEVERITIES_VERSION + 1
if log.enabled "diagnostics" then
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
log.profile_end(profile)
if view.is_buf_valid(view.get_bufnr()) then
require("nvim-tree.renderer").draw()
local explorer = core.get_explorer()
if explorer then
explorer.renderer:draw()
end
end
end)
end

View File

@@ -1,4 +1,4 @@
local notify = require "nvim-tree.notify"
local notify = require("nvim-tree.notify")
local M = {}

View File

@@ -1,111 +0,0 @@
local utils = require "nvim-tree.utils"
local builders = require "nvim-tree.explorer.node-builders"
local explorer_node = require "nvim-tree.explorer.node"
local git = require "nvim-tree.git"
local log = require "nvim-tree.log"
local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON
local Watcher = require "nvim-tree.watcher"
local M = {}
---@param handle uv.uv_fs_t
---@param cwd string
---@param node Node
---@param git_status table
---@param parent Explorer
local function populate_children(handle, cwd, node, git_status, parent)
local node_ignored = explorer_node.is_git_ignored(node)
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
local filter_status = parent.filters:prepare(git_status)
node.hidden_stats = vim.tbl_deep_extend("force", node.hidden_stats or {}, {
git = 0,
buf = 0,
dotfile = 0,
custom = 0,
bookmark = 0,
})
while true do
local name, t = vim.loop.fs_scandir_next(handle)
if not name then
break
end
local abs = utils.path_join { cwd, name }
local profile = log.profile_start("explore populate_children %s", abs)
---@type uv.fs_stat.result|nil
local stat = vim.loop.fs_stat(abs)
local filter_reason = parent.filters:should_filter_as_reason(abs, stat, filter_status)
if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] and Watcher.is_fs_event_capable(abs) then
local child = nil
if t == "directory" and vim.loop.fs_access(abs, "R") then
child = builders.folder(node, abs, name, stat)
elseif t == "file" then
child = builders.file(node, abs, name, stat)
elseif t == "link" then
local link = builders.link(node, abs, name, stat)
if link.link_to ~= nil then
child = link
end
end
if child then
table.insert(node.nodes, child)
nodes_by_path[child.absolute_path] = true
explorer_node.update_git_status(child, node_ignored, git_status)
end
else
for reason, value in pairs(FILTER_REASON) do
if filter_reason == value then
node.hidden_stats[reason] = node.hidden_stats[reason] + 1
end
end
end
log.profile_end(profile)
end
end
---@param node Node
---@param status table
---@param parent Explorer
---@return Node[]|nil
function M.explore(node, status, parent)
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
return
end
local profile = log.profile_start("explore init %s", node.absolute_path)
populate_children(handle, cwd, node, status, parent)
local is_root = not node.parent
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
if M.config.group_empty and not is_root and child_folder_only then
local child_cwd = child_folder_only.link_to or child_folder_only.absolute_path
local child_status = git.load_project_status(child_cwd)
node.group_next = child_folder_only
local ns = M.explore(child_folder_only, child_status, parent)
node.nodes = ns or {}
log.profile_end(profile)
return ns
end
parent.sorters:sort(node.nodes)
parent.live_filter:apply_filter(node)
log.profile_end(profile)
return node.nodes
end
function M.setup(opts)
M.config = opts.renderer
end
return M

View File

@@ -1,4 +1,4 @@
local utils = require "nvim-tree.utils"
local utils = require("nvim-tree.utils")
local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON
---@class Filters to handle all opts.filters and related API
@@ -165,7 +165,7 @@ local function custom(self, path)
end
end
local idx = path:match ".+()%.[^.]+$"
local idx = path:match(".+()%.[^.]+$")
if idx then
if self.ignore_list["*" .. string.sub(path, idx)] == true then
return true
@@ -189,12 +189,12 @@ function Filters:prepare(git_status)
}
if self.config.filter_no_buffer then
status.bufinfo = vim.fn.getbufinfo { buflisted = 1 }
status.bufinfo = vim.fn.getbufinfo({ buflisted = 1 })
end
local explorer = require("nvim-tree.core").get_explorer()
if explorer then
for _, node in pairs(explorer.marks:get_marks()) do
for _, node in pairs(explorer.marks:list()) do
status.bookmarks[node.absolute_path] = node.type
end
end

View File

@@ -1,32 +1,44 @@
local git = require "nvim-tree.git"
local notify = require "nvim-tree.notify"
local watch = require "nvim-tree.explorer.watch"
local explorer_node = require "nvim-tree.explorer.node"
local Filters = require "nvim-tree.explorer.filters"
local Marks = require "nvim-tree.marks"
local LiveFilter = require "nvim-tree.explorer.live-filter"
local Sorters = require "nvim-tree.explorer.sorters"
local builders = require("nvim-tree.explorer.node-builders")
local git = require("nvim-tree.git")
local log = require("nvim-tree.log")
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local watch = require("nvim-tree.explorer.watch")
local explorer_node = require("nvim-tree.explorer.node")
local M = {}
local Iterator = require("nvim-tree.iterators.node-iterator")
local NodeIterator = require("nvim-tree.iterators.node-iterator")
local Watcher = require("nvim-tree.watcher")
M.explore = require("nvim-tree.explorer.explore").explore
M.reload = require("nvim-tree.explorer.reload").reload
local Filters = require("nvim-tree.explorer.filters")
local Marks = require("nvim-tree.marks")
local LiveFilter = require("nvim-tree.explorer.live-filter")
local Sorters = require("nvim-tree.explorer.sorters")
local Clipboard = require("nvim-tree.actions.fs.clipboard")
local Renderer = require("nvim-tree.renderer")
local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON
local config
---@class Explorer
---@field opts table user options
---@field absolute_path string
---@field nodes Node[]
---@field open boolean
---@field watcher Watcher|nil
---@field renderer Renderer
---@field filters Filters
---@field live_filter LiveFilter
---@field sorters Sorter
---@field marks Marks
---@field clipboard Clipboard
local Explorer = {}
Explorer.__index = Explorer
---@param path string|nil
---@return Explorer|nil
function Explorer.new(path)
function Explorer:new(path)
local err
if path then
@@ -39,27 +51,27 @@ function Explorer.new(path)
return
end
---@class Explorer
local explorer = setmetatable({
local o = {
opts = config,
absolute_path = path,
nodes = {},
open = true,
marks = Marks:new(),
sorters = Sorters:new(M.config),
}, Explorer)
explorer.watcher = watch.create_watcher(explorer)
explorer.filters = Filters:new(M.config, explorer)
explorer.live_filter = LiveFilter:new(M.config, explorer)
explorer:_load(explorer)
return explorer
end
sorters = Sorters:new(config),
}
---@private
---@param node Node
function Explorer:_load(node)
local cwd = node.link_to or node.absolute_path
local git_status = git.load_project_status(cwd)
M.explore(node, git_status, self)
setmetatable(o, self)
self.__index = self
o.watcher = watch.create_watcher(o)
o.renderer = Renderer:new(config, o)
o.filters = Filters:new(config, o)
o.live_filter = LiveFilter:new(config, o)
o.marks = Marks:new(config, o)
o.clipboard = Clipboard:new(config, o)
o:_load(o)
return o
end
---@param node Node
@@ -79,14 +91,397 @@ function Explorer:destroy()
iterate(self)
end
function M.setup(opts)
M.config = opts
---@param node Node
---@param git_status table|nil
function Explorer:reload(node, git_status)
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
return
end
local profile = log.profile_start("reload %s", node.absolute_path)
local filter_status = self.filters:prepare(git_status)
if node.group_next then
node.nodes = { node.group_next }
node.group_next = nil
end
local remain_childs = {}
local node_ignored = explorer_node.is_git_ignored(node)
---@type table<string, Node>
local nodes_by_path = utils.key_by(node.nodes, "absolute_path")
-- To reset we must 'zero' everything that we use
node.hidden_stats = vim.tbl_deep_extend("force", node.hidden_stats or {}, {
git = 0,
buf = 0,
dotfile = 0,
custom = 0,
bookmark = 0,
})
while true do
local name, _ = vim.loop.fs_scandir_next(handle)
if not name then
break
end
local abs = utils.path_join({ cwd, name })
---@type uv.fs_stat.result|nil
local stat = vim.loop.fs_lstat(abs)
local filter_reason = self.filters:should_filter_as_reason(abs, stat, filter_status)
if filter_reason == FILTER_REASON.none then
remain_childs[abs] = true
-- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility
local t = stat and stat.type or nil
-- Recreate node if type changes.
if nodes_by_path[abs] then
local n = nodes_by_path[abs]
if n.type ~= t then
utils.array_remove(node.nodes, n)
explorer_node.node_destroy(n)
nodes_by_path[abs] = nil
end
end
if not nodes_by_path[abs] then
local new_child = nil
if t == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then
new_child = builders.folder(node, abs, name, stat)
elseif t == "file" then
new_child = builders.file(node, abs, name, stat)
elseif t == "link" then
local link = builders.link(node, abs, name, stat)
if link.link_to ~= nil then
new_child = link
end
end
if new_child then
table.insert(node.nodes, new_child)
nodes_by_path[abs] = new_child
end
else
local n = nodes_by_path[abs]
if n then
n.executable = builders.is_executable(abs) or false
n.fs_stat = stat
end
end
else
for reason, value in pairs(FILTER_REASON) do
if filter_reason == value then
node.hidden_stats[reason] = node.hidden_stats[reason] + 1
end
end
end
end
node.nodes = vim.tbl_map(
self:update_status(nodes_by_path, node_ignored, git_status),
vim.tbl_filter(function(n)
if remain_childs[n.absolute_path] then
return remain_childs[n.absolute_path]
else
explorer_node.node_destroy(n)
return false
end
end, node.nodes)
)
local is_root = not node.parent
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
if config.renderer.group_empty and not is_root and child_folder_only then
node.group_next = child_folder_only
local ns = self:reload(child_folder_only, git_status)
node.nodes = ns or {}
log.profile_end(profile)
return ns
end
self.sorters:sort(node.nodes)
self.live_filter:apply_filter(node)
log.profile_end(profile)
return node.nodes
end
---TODO #2837 #2871 move this and similar to node
---Refresh contents and git status for a single node
---@param node Node
---@param callback function
function Explorer:refresh_node(node, callback)
if type(node) ~= "table" then
callback()
end
local parent_node = utils.get_parent_of_group(node)
self:reload_and_get_git_project(node.absolute_path, function(toplevel, project)
self:reload(parent_node, project)
self:update_parent_statuses(parent_node, project, toplevel)
callback()
end)
end
---Refresh contents of all nodes to a path: actual directory and links.
---Groups will be expanded if needed.
---@param path string absolute path
function Explorer:refresh_parent_nodes_for_path(path)
local profile = log.profile_start("refresh_parent_nodes_for_path %s", path)
-- collect parent nodes from the top down
local parent_nodes = {}
NodeIterator.builder({ self })
:recursor(function(node)
return node.nodes
end)
:applier(function(node)
local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1
local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1
if abs_contains or link_contains then
table.insert(parent_nodes, node)
end
end)
:iterate()
-- refresh in order; this will expand groups as needed
for _, node in ipairs(parent_nodes) do
local toplevel = git.get_toplevel(node.absolute_path)
local project = git.get_project(toplevel) or {}
self:reload(node, project)
self:update_parent_statuses(node, project, toplevel)
end
log.profile_end(profile)
end
---@private
---@param node Node
function Explorer:_load(node)
local cwd = node.link_to or node.absolute_path
local git_status = git.load_project_status(cwd)
self:explore(node, git_status, self)
end
---@private
---@param nodes_by_path table
---@param node_ignored boolean
---@param status table|nil
---@return fun(node: Node): table
function Explorer:update_status(nodes_by_path, node_ignored, status)
return function(node)
if nodes_by_path[node.absolute_path] then
explorer_node.update_git_status(node, node_ignored, status)
end
return node
end
end
---TODO #2837 #2871 move this and similar to node
---@private
---@param path string
---@param callback fun(toplevel: string|nil, project: table|nil)
function Explorer:reload_and_get_git_project(path, callback)
local toplevel = git.get_toplevel(path)
git.reload_project(toplevel, path, function()
callback(toplevel, git.get_project(toplevel) or {})
end)
end
---TODO #2837 #2871 move this and similar to node
---@private
---@param node Node
---@param project table|nil
---@param root string|nil
function Explorer:update_parent_statuses(node, project, root)
while project and node do
-- step up to the containing project
if node.absolute_path == root then
-- stop at the top of the tree
if not node.parent then
break
end
root = git.get_toplevel(node.parent.absolute_path)
-- stop when no more projects
if not root then
break
end
-- update the containing project
project = git.get_project(root)
git.reload_project(root, node.absolute_path, nil)
end
-- update status
explorer_node.update_git_status(node, explorer_node.is_git_ignored(node.parent), project)
-- maybe parent
node = node.parent
end
end
---@private
---@param handle uv.uv_fs_t
---@param cwd string
---@param node Node
---@param git_status table
---@param parent Explorer
function Explorer:populate_children(handle, cwd, node, git_status, parent)
local node_ignored = explorer_node.is_git_ignored(node)
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
local filter_status = parent.filters:prepare(git_status)
node.hidden_stats = vim.tbl_deep_extend("force", node.hidden_stats or {}, {
git = 0,
buf = 0,
dotfile = 0,
custom = 0,
bookmark = 0,
})
while true do
local name, _ = vim.loop.fs_scandir_next(handle)
if not name then
break
end
local abs = utils.path_join({ cwd, name })
if Watcher.is_fs_event_capable(abs) then
local profile = log.profile_start("populate_children %s", abs)
---@type uv.fs_stat.result|nil
local stat = vim.loop.fs_lstat(abs)
local filter_reason = parent.filters:should_filter_as_reason(abs, stat, filter_status)
if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] then
-- Type must come from fs_stat and not fs_scandir_next to maintain sshfs compatibility
local t = stat and stat.type or nil
local child = nil
if t == "directory" and vim.loop.fs_access(abs, "R") then
child = builders.folder(node, abs, name, stat)
elseif t == "file" then
child = builders.file(node, abs, name, stat)
elseif t == "link" then
local link = builders.link(node, abs, name, stat)
if link.link_to ~= nil then
child = link
end
end
if child then
table.insert(node.nodes, child)
nodes_by_path[child.absolute_path] = true
explorer_node.update_git_status(child, node_ignored, git_status)
end
else
for reason, value in pairs(FILTER_REASON) do
if filter_reason == value then
node.hidden_stats[reason] = node.hidden_stats[reason] + 1
end
end
end
log.profile_end(profile)
end
end
end
---@private
---@param node Node
---@param status table
---@param parent Explorer
---@return Node[]|nil
function Explorer:explore(node, status, parent)
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
return
end
local profile = log.profile_start("explore %s", node.absolute_path)
self:populate_children(handle, cwd, node, status, parent)
local is_root = not node.parent
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
if config.renderer.group_empty and not is_root and child_folder_only then
local child_cwd = child_folder_only.link_to or child_folder_only.absolute_path
local child_status = git.load_project_status(child_cwd)
node.group_next = child_folder_only
local ns = self:explore(child_folder_only, child_status, parent)
node.nodes = ns or {}
log.profile_end(profile)
return ns
end
parent.sorters:sort(node.nodes)
parent.live_filter:apply_filter(node)
log.profile_end(profile)
return node.nodes
end
---@private
---@param projects table
function Explorer:refresh_nodes(projects)
Iterator.builder({ self })
:applier(function(n)
if n.nodes then
local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path)
self:reload(n, projects[toplevel] or {})
end
end)
:recursor(function(n)
return n.group_next and { n.group_next } or (n.open and n.nodes)
end)
:iterate()
end
local event_running = false
function Explorer:reload_explorer()
if event_running or vim.v.exiting ~= vim.NIL then
return
end
event_running = true
local projects = git.reload()
self:refresh_nodes(projects)
if view.is_visible() then
self.renderer:draw()
end
event_running = false
end
function Explorer:reload_git()
if not git.config.git.enable or event_running then
return
end
event_running = true
local projects = git.reload()
explorer_node.reload_node_status(self, projects)
self.renderer:draw()
event_running = false
end
function Explorer.setup(opts)
config = opts
require("nvim-tree.explorer.node").setup(opts)
require("nvim-tree.explorer.explore").setup(opts)
require("nvim-tree.explorer.reload").setup(opts)
require("nvim-tree.explorer.watch").setup(opts)
end
M.Explorer = Explorer
return M
return Explorer

View File

@@ -1,6 +1,6 @@
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local Iterator = require "nvim-tree.iterators.node-iterator"
local view = require("nvim-tree.view")
local utils = require("nvim-tree.utils")
local Iterator = require("nvim-tree.iterators.node-iterator")
---@class LiveFilter
---@field explorer Explorer
@@ -23,10 +23,6 @@ function LiveFilter:new(opts, explorer)
return o
end
local function redraw()
require("nvim-tree.renderer").draw()
end
---@param node_ Node|nil
local function reset_filter(self, node_)
node_ = node_ or self.explorer
@@ -129,7 +125,7 @@ local function record_char(self)
vim.schedule(function()
self.filter = vim.api.nvim_buf_get_lines(overlay_bufnr, 0, -1, false)[1]
self:apply_filter()
redraw()
self.explorer.renderer:draw()
end)
end
@@ -166,11 +162,11 @@ end
local function create_overlay(self)
if view.View.float.enable then
-- don't close nvim-tree float when focus is changed to filter window
vim.api.nvim_clear_autocmds {
vim.api.nvim_clear_autocmds({
event = "WinLeave",
pattern = "NvimTree_*",
group = vim.api.nvim_create_augroup("NvimTree", { clear = false }),
}
})
end
configure_buffer_overlay(self)
@@ -184,14 +180,14 @@ local function create_overlay(self)
style = "minimal",
})
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", true, { buf = overlay_bufnr })
else
vim.api.nvim_buf_set_option(overlay_bufnr, "modifiable", true) ---@diagnostic disable-line: deprecated
end
vim.api.nvim_buf_set_lines(overlay_bufnr, 0, -1, false, { self.filter })
vim.cmd "startinsert"
vim.cmd("startinsert")
vim.api.nvim_win_set_cursor(overlay_winnr, { 1, #self.filter + 1 })
end
@@ -199,10 +195,10 @@ function LiveFilter:start_filtering()
view.View.live_filter.prev_focused_node = require("nvim-tree.lib").get_node_at_cursor()
self.filter = self.filter or ""
redraw()
self.explorer.renderer:draw()
local row = require("nvim-tree.core").get_nodes_starting_line() - 1
local col = #self.prefix > 0 and #self.prefix - 1 or 1
view.set_cursor { row, col }
view.set_cursor({ row, col })
-- needs scheduling to let the cursor move before initializing the window
vim.schedule(function()
return create_overlay(self)
@@ -215,7 +211,7 @@ function LiveFilter:clear_filter()
self.filter = nil
reset_filter(self)
redraw()
self.explorer.renderer:draw()
if node then
utils.focus_file(node.absolute_path)

View File

@@ -1,5 +1,5 @@
local utils = require "nvim-tree.utils"
local watch = require "nvim-tree.explorer.watch"
local utils = require("nvim-tree.utils")
local watch = require("nvim-tree.explorer.watch")
local M = {}

View File

@@ -1,3 +1,5 @@
local git = {} -- circular dependencies
local M = {}
---@class GitStatus
@@ -122,6 +124,23 @@ function M.get_git_status(node)
end
end
---@param parent_node Node|nil
---@param projects table
function M.reload_node_status(parent_node, projects)
if parent_node == nil then
return
end
local toplevel = git.get_toplevel(parent_node.absolute_path)
local status = projects[toplevel] or {}
for _, node in ipairs(parent_node.nodes) do
M.update_git_status(node, M.is_git_ignored(parent_node), status)
if node.nodes and #node.nodes > 0 then
M.reload_node_status(node, projects)
end
end
end
---@param node Node
---@return boolean
function M.is_git_ignored(node)
@@ -157,6 +176,8 @@ function M.setup(opts)
M.config = {
git = opts.git,
}
git = require("nvim-tree.git")
end
return M

View File

@@ -1,251 +0,0 @@
local utils = require "nvim-tree.utils"
local builders = require "nvim-tree.explorer.node-builders"
local explorer_node = require "nvim-tree.explorer.node"
local git = require "nvim-tree.git"
local log = require "nvim-tree.log"
local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON
local NodeIterator = require "nvim-tree.iterators.node-iterator"
local Watcher = require "nvim-tree.watcher"
local M = {}
---@param nodes_by_path table
---@param node_ignored boolean
---@param status table
---@return fun(node: Node): table
local function update_status(nodes_by_path, node_ignored, status)
return function(node)
if nodes_by_path[node.absolute_path] then
explorer_node.update_git_status(node, node_ignored, status)
end
return node
end
end
---@param path string
---@param callback fun(toplevel: string|nil, project: table|nil)
local function reload_and_get_git_project(path, callback)
local toplevel = git.get_toplevel(path)
git.reload_project(toplevel, path, function()
callback(toplevel, git.get_project(toplevel) or {})
end)
end
---@param node Node
---@param project table|nil
---@param root string|nil
local function update_parent_statuses(node, project, root)
while project and node do
-- step up to the containing project
if node.absolute_path == root then
-- stop at the top of the tree
if not node.parent then
break
end
root = git.get_toplevel(node.parent.absolute_path)
-- stop when no more projects
if not root then
break
end
-- update the containing project
project = git.get_project(root)
git.reload_project(root, node.absolute_path, nil)
end
-- update status
explorer_node.update_git_status(node, explorer_node.is_git_ignored(node.parent), project)
-- maybe parent
node = node.parent
end
end
---@param node Node
---@param git_status table
function M.reload(node, git_status)
local explorer = require("nvim-tree.core").get_explorer()
if not explorer then
return
end
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
return
end
local profile = log.profile_start("reload %s", node.absolute_path)
local filter_status = explorer.filters:prepare(git_status)
if node.group_next then
node.nodes = { node.group_next }
node.group_next = nil
end
local remain_childs = {}
local node_ignored = explorer_node.is_git_ignored(node)
---@type table<string, Node>
local nodes_by_path = utils.key_by(node.nodes, "absolute_path")
-- To reset we must 'zero' everything that we use
node.hidden_stats = vim.tbl_deep_extend("force", node.hidden_stats or {}, {
git = 0,
buf = 0,
dotfile = 0,
custom = 0,
bookmark = 0,
})
while true do
local name, t = vim.loop.fs_scandir_next(handle)
if not name then
break
end
local abs = utils.path_join { cwd, name }
---@type uv.fs_stat.result|nil
local stat = vim.loop.fs_stat(abs)
local filter_reason = explorer.filters:should_filter_as_reason(abs, stat, filter_status)
if filter_reason == FILTER_REASON.none then
remain_childs[abs] = true
-- Recreate node if type changes.
if nodes_by_path[abs] then
local n = nodes_by_path[abs]
if n.type ~= t then
utils.array_remove(node.nodes, n)
explorer_node.node_destroy(n)
nodes_by_path[abs] = nil
end
end
if not nodes_by_path[abs] then
local new_child = nil
if t == "directory" and vim.loop.fs_access(abs, "R") and Watcher.is_fs_event_capable(abs) then
new_child = builders.folder(node, abs, name, stat)
elseif t == "file" then
new_child = builders.file(node, abs, name, stat)
elseif t == "link" then
local link = builders.link(node, abs, name, stat)
if link.link_to ~= nil then
new_child = link
end
end
if new_child then
table.insert(node.nodes, new_child)
nodes_by_path[abs] = new_child
end
else
local n = nodes_by_path[abs]
if n then
n.executable = builders.is_executable(abs) or false
n.fs_stat = stat
end
end
else
for reason, value in pairs(FILTER_REASON) do
if filter_reason == value then
node.hidden_stats[reason] = node.hidden_stats[reason] + 1
end
end
end
end
node.nodes = vim.tbl_map(
update_status(nodes_by_path, node_ignored, git_status),
vim.tbl_filter(function(n)
if remain_childs[n.absolute_path] then
return remain_childs[n.absolute_path]
else
explorer_node.node_destroy(n)
return false
end
end, node.nodes)
)
local is_root = not node.parent
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
if M.config.group_empty and not is_root and child_folder_only then
node.group_next = child_folder_only
local ns = M.reload(child_folder_only, git_status)
node.nodes = ns or {}
log.profile_end(profile)
return ns
end
explorer.sorters:sort(node.nodes)
explorer.live_filter:apply_filter(node)
log.profile_end(profile)
return node.nodes
end
---Refresh contents and git status for a single node
---@param node Node
---@param callback function
function M.refresh_node(node, callback)
if type(node) ~= "table" then
callback()
end
local parent_node = utils.get_parent_of_group(node)
reload_and_get_git_project(node.absolute_path, function(toplevel, project)
require("nvim-tree.explorer.reload").reload(parent_node, project)
update_parent_statuses(parent_node, project, toplevel)
callback()
end)
end
---Refresh contents of all nodes to a path: actual directory and links.
---Groups will be expanded if needed.
---@param path string absolute path
function M.refresh_parent_nodes_for_path(path)
local explorer = require("nvim-tree.core").get_explorer()
if not explorer then
return
end
local profile = log.profile_start("refresh_parent_nodes_for_path %s", path)
-- collect parent nodes from the top down
local parent_nodes = {}
NodeIterator.builder({ explorer })
:recursor(function(node)
return node.nodes
end)
:applier(function(node)
local abs_contains = node.absolute_path and path:find(node.absolute_path, 1, true) == 1
local link_contains = node.link_to and path:find(node.link_to, 1, true) == 1
if abs_contains or link_contains then
table.insert(parent_nodes, node)
end
end)
:iterate()
-- refresh in order; this will expand groups as needed
for _, node in ipairs(parent_nodes) do
local toplevel = git.get_toplevel(node.absolute_path)
local project = git.get_project(toplevel) or {}
M.reload(node, project)
update_parent_statuses(node, project, toplevel)
end
log.profile_end(profile)
end
function M.setup(opts)
M.config = opts.renderer
end
return M

View File

@@ -122,7 +122,7 @@ function Sorter:sort(t)
absolute_path = n.absolute_path,
executable = n.executable,
extension = n.extension,
filetype = vim.filetype.match { filename = n.name },
filetype = vim.filetype.match({ filename = n.name }),
link_to = n.link_to,
name = n.name,
type = n.type,
@@ -237,8 +237,8 @@ function C.suffix(a, b, cfg)
end
-- unsuffixed go third
local a_suffix_ndx = a.name:find "%.%w+$"
local b_suffix_ndx = b.name:find "%.%w+$"
local a_suffix_ndx = a.name:find("%.%w+$")
local b_suffix_ndx = b.name:find("%.%w+$")
if not a_suffix_ndx and b_suffix_ndx then
return true
@@ -289,8 +289,8 @@ function C.extension(a, b, cfg)
end
function C.filetype(a, b, cfg)
local a_ft = vim.filetype.match { filename = a.name }
local b_ft = vim.filetype.match { filename = b.name }
local a_ft = vim.filetype.match({ filename = a.name })
local b_ft = vim.filetype.match({ filename = b.name })
-- directories first
local early_return = folders_or_files_first(a, b, cfg)

View File

@@ -1,5 +1,5 @@
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local Watcher = require("nvim-tree.watcher").Watcher
local M = {
@@ -76,9 +76,12 @@ function M.create_watcher(node)
else
log.line("watcher", "node event executing refresh '%s'", node.absolute_path)
end
require("nvim-tree.explorer.reload").refresh_node(node, function()
require("nvim-tree.renderer").draw()
end)
local explorer = require("nvim-tree.core").get_explorer()
if explorer then
explorer:refresh_node(node, function()
explorer.renderer:draw()
end)
end
end)
end

View File

@@ -1,10 +1,10 @@
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local git_utils = require "nvim-tree.git.utils"
local Runner = require "nvim-tree.git.runner"
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local git_utils = require("nvim-tree.git.utils")
local Runner = require("nvim-tree.git.runner")
local Watcher = require("nvim-tree.watcher").Watcher
local Iterator = require "nvim-tree.iterators.node-iterator"
local explorer_node = require "nvim-tree.explorer.node"
local Iterator = require("nvim-tree.iterators.node-iterator")
local explorer_node = require("nvim-tree.explorer.node")
local M = {
config = {},
@@ -23,10 +23,10 @@ local M = {
-- Utilities (like watchman) can also write to this directory (often) and aren't useful for us.
local WATCHED_FILES = {
"FETCH_HEAD", -- remote ref
"HEAD", -- local ref
"HEAD.lock", -- HEAD will not always be updated e.g. revert
"config", -- user config
"index", -- staging area
"HEAD", -- local ref
"HEAD.lock", -- HEAD will not always be updated e.g. revert
"config", -- user config
"index", -- staging area
}
---@param toplevel string|nil
@@ -216,7 +216,10 @@ local function reload_tree_at(toplevel)
end)
:iterate()
require("nvim-tree.renderer").draw()
local explorer = require("nvim-tree.core").get_explorer()
if explorer then
explorer.renderer:draw()
end
end)
end
@@ -240,12 +243,12 @@ function M.load_project_status(path)
return status
end
local git_status = Runner.run {
local git_status = Runner.run({
toplevel = toplevel,
list_untracked = git_utils.should_show_untracked(toplevel),
list_ignored = true,
timeout = M.config.git.timeout,
}
})
local watcher = nil
if M.config.filesystem_watchers.enable then
@@ -261,7 +264,7 @@ function M.load_project_status(path)
end)
end
local git_dir = vim.env.GIT_DIR or M._git_dirs_by_toplevel[toplevel] or utils.path_join { toplevel, ".git" }
local git_dir = vim.env.GIT_DIR or M._git_dirs_by_toplevel[toplevel] or utils.path_join({ toplevel, ".git" })
watcher = Watcher:new(git_dir, WATCHED_FILES, callback, {
toplevel = toplevel,
})

View File

@@ -1,6 +1,6 @@
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local notify = require "nvim-tree.notify"
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local notify = require("nvim-tree.notify")
---@class Runner
local Runner = {}
@@ -18,11 +18,11 @@ function Runner:_parse_status_output(status, path)
end
-- replacing slashes if on windows
if vim.fn.has "win32" == 1 then
if vim.fn.has("win32") == 1 then
path = path:gsub("/", "\\")
end
if #status > 0 and #path > 0 then
self.output[utils.path_remove_trailing(utils.path_join { self.toplevel, path })] = status
self.output[utils.path_remove_trailing(utils.path_join({ self.toplevel, path }))] = status
end
end
@@ -35,7 +35,7 @@ function Runner:_handle_incoming_data(prev_output, incoming)
local prev = prev_output .. incoming
local i = 1
local skip_next_line = false
for line in prev:gmatch "[^\n]*\n" do
for line in prev:gmatch("[^\n]*\n") do
if skip_next_line then
skip_next_line = false
else
@@ -57,7 +57,7 @@ function Runner:_handle_incoming_data(prev_output, incoming)
return prev_output .. incoming
end
for line in prev_output:gmatch "[^\n]*\n" do
for line in prev_output:gmatch("[^\n]*\n") do
self:_parse_status_output(line)
end
@@ -79,7 +79,7 @@ end
---@param output string
function Runner:_log_raw_output(output)
if log.enabled "git" and output and type(output) == "string" then
if log.enabled("git") and output and type(output) == "string" then
log.raw("git", "%s", output)
log.line("git", "done")
end

View File

@@ -1,5 +1,5 @@
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local M = {
use_cygpath = false,
@@ -21,30 +21,30 @@ function M.get_toplevel(cwd)
log.raw("git", out)
log.profile_end(profile)
if vim.v.shell_error ~= 0 or not out or #out == 0 or out:match "fatal" then
if vim.v.shell_error ~= 0 or not out or #out == 0 or out:match("fatal") then
return nil, nil
end
local toplevel, git_dir = out:match "([^\n]+)\n+([^\n]+)"
local toplevel, git_dir = out:match("([^\n]+)\n+([^\n]+)")
if not toplevel then
return nil, nil
end
if not git_dir then
git_dir = utils.path_join { toplevel, ".git" }
git_dir = utils.path_join({ toplevel, ".git" })
end
-- git always returns path with forward slashes
if vim.fn.has "win32" == 1 then
if vim.fn.has("win32") == 1 then
-- msys2 git support
-- cygpath calls must in array format to avoid shell compatibility issues
if M.use_cygpath then
toplevel = vim.fn.system { "cygpath", "-w", toplevel }
toplevel = vim.fn.system({ "cygpath", "-w", toplevel })
if vim.v.shell_error ~= 0 then
return nil, nil
end
-- remove trailing newline(\n) character added by vim.fn.system
toplevel = toplevel:gsub("\n", "")
git_dir = vim.fn.system { "cygpath", "-w", git_dir }
git_dir = vim.fn.system({ "cygpath", "-w", git_dir })
if vim.v.shell_error ~= 0 then
return nil, nil
end
@@ -128,7 +128,7 @@ end
function M.setup(opts)
if opts.git.cygwin_support then
M.use_cygpath = vim.fn.executable "cygpath" == 1
M.use_cygpath = vim.fn.executable("cygpath") == 1
end
end

View File

@@ -1,4 +1,5 @@
local keymap = require "nvim-tree.keymap"
local keymap = require("nvim-tree.keymap")
local api = {} -- circular dependency
local PAT_MOUSE = "^<.*Mouse"
local PAT_CTRL = "^<C%-"
@@ -26,12 +27,12 @@ local function tidy_lhs(lhs)
lhs = lhs:gsub("^<lt>", "<")
-- shorten ctrls
if lhs:lower():match "^<ctrl%-" then
if lhs:lower():match("^<ctrl%-") then
lhs = lhs:lower():gsub("^<ctrl%-", "<C%-")
end
-- uppercase ctrls
if lhs:lower():match "^<c%-" then
if lhs:lower():match("^<c%-") then
lhs = lhs:upper()
end
@@ -79,18 +80,19 @@ local function sort_lhs(a, b)
end
--- Compute all lines for the buffer
---@param map table keymap.get_keymap
---@return table strings of text
---@return table arrays of arguments 3-6 for nvim_buf_add_highlight()
---@return number maximum length of text
local function compute()
local function compute(map)
local head_lhs = "nvim-tree mappings"
local head_rhs1 = "exit: q"
local head_rhs2 = string.format("sort by %s: s", M.config.sort_by == "key" and "description" or "keymap")
-- formatted lhs and desc from active keymap
local mappings = vim.tbl_map(function(map)
return { lhs = tidy_lhs(map.lhs), desc = tidy_desc(map.desc) }
end, keymap.get_keymap())
local mappings = vim.tbl_map(function(m)
return { lhs = tidy_lhs(m.lhs), desc = tidy_desc(m.desc) }
end, map)
-- sorter function for mappings
local sort_fn
@@ -128,7 +130,7 @@ local function compute()
-- header highlight, assume one character keys
local hl = {
{ "NvimTreeFolderName", 0, 0, #head_lhs },
{ "NvimTreeFolderName", 0, 0, #head_lhs },
{ "NvimTreeFolderName", 0, width - 1, width },
{ "NvimTreeFolderName", 1, width - 1, width },
}
@@ -165,8 +167,11 @@ local function open()
-- close existing, shouldn't be necessary
close()
-- fetch all mappings
local map = keymap.get_keymap()
-- text and highlight
local lines, hl, width = compute()
local lines, hl, width = compute(map)
-- create the buffer
M.bufnr = vim.api.nvim_create_buf(false, true)
@@ -174,7 +179,7 @@ local function open()
-- populate it
vim.api.nvim_buf_set_lines(M.bufnr, 0, -1, false, lines)
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", false, { buf = M.bufnr })
else
vim.api.nvim_buf_set_option(M.bufnr, "modifiable", false) ---@diagnostic disable-line: deprecated
@@ -206,12 +211,21 @@ local function open()
open()
end
local keymaps = {
-- hardcoded
local help_keymaps = {
q = { fn = close, desc = "nvim-tree: exit help" },
["<Esc>"] = { fn = close, desc = "nvim-tree: exit help" }, -- hidden
s = { fn = toggle_sort, desc = "nvim-tree: toggle sorting method" },
}
for k, v in pairs(keymaps) do
-- api help binding closes
for _, m in ipairs(map) do
if m.callback == api.tree.toggle_help then
help_keymaps[m.lhs] = { fn = close, desc = "nvim-tree: exit help" }
end
end
for k, v in pairs(help_keymaps) do
vim.keymap.set("n", k, v.fn, {
desc = v.desc,
buffer = M.bufnr,
@@ -240,6 +254,8 @@ end
function M.setup(opts)
M.config.cursorline = opts.view.cursorline
M.config.sort_by = opts.help.sort_by
api = require("nvim-tree.api")
end
return M

View File

@@ -19,21 +19,40 @@ local function generate_keymap(fn)
return keymap
end
-- stylua: ignore start
---@return table
function M.get_keymap()
return generate_keymap(M.on_attach)
end
---@return table
function M.get_keymap_default()
return generate_keymap(M.default_on_attach)
end
function M.setup(opts)
if type(opts.on_attach) ~= "function" then
M.on_attach = M.default_on_attach
else
M.on_attach = opts.on_attach
end
end
---@param bufnr integer
function M.default_on_attach(bufnr)
local api = require('nvim-tree.api')
local api = require("nvim-tree.api")
local function opts(desc)
return {
desc = 'nvim-tree: ' .. desc,
desc = "nvim-tree: " .. desc,
buffer = bufnr,
noremap = true,
silent = true,
nowait = true,
}
}
end
-- formatting cannot be re-enabled, hence this is at the end
---@format disable
-- BEGIN_DEFAULT_ON_ATTACH
vim.keymap.set('n', '<C-]>', api.tree.change_root_to_node, opts('CD'))
vim.keymap.set('n', '<C-e>', api.node.open.replace_tree_buffer, opts('Open: In Place'))
@@ -95,24 +114,5 @@ function M.default_on_attach(bufnr)
vim.keymap.set('n', '<2-RightMouse>', api.tree.change_root_to_node, opts('CD'))
-- END_DEFAULT_ON_ATTACH
end
-- stylua: ignore end
---@return table
function M.get_keymap()
return generate_keymap(M.on_attach)
end
---@return table
function M.get_keymap_default()
return generate_keymap(M.default_on_attach)
end
function M.setup(opts)
if type(opts.on_attach) ~= "function" then
M.on_attach = M.default_on_attach
else
M.on_attach = opts.on_attach
end
end
return M

View File

@@ -1,5 +1,5 @@
local utils = require "nvim-tree.utils"
local notify = require "nvim-tree.notify"
local utils = require("nvim-tree.utils")
local notify = require("nvim-tree.notify")
local M = {}
@@ -64,23 +64,24 @@ end
local function deprecated(opts)
if type(opts.view) == "table" and opts.view.hide_root_folder then
notify.info "view.hide_root_folder is deprecated, please set renderer.root_folder_label = false"
notify.info("view.hide_root_folder is deprecated, please set renderer.root_folder_label = false")
end
end
local function removed(opts)
if opts.auto_close then
notify.warn "auto close feature has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Auto-Close"
notify.warn("auto close feature has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Auto-Close")
opts.auto_close = nil
end
if opts.focus_empty_on_setup then
notify.warn "focus_empty_on_setup has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup"
notify.warn("focus_empty_on_setup has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup")
opts.focus_empty_on_setup = nil
end
if opts.create_in_closed_folder then
notify.warn "create_in_closed_folder has been removed and is now the default behaviour. You may use api.fs.create to add a file under your desired node."
notify.warn(
"create_in_closed_folder has been removed and is now the default behaviour. You may use api.fs.create to add a file under your desired node.")
end
opts.create_in_closed_folder = nil
end

View File

@@ -1,10 +1,9 @@
local renderer = require "nvim-tree.renderer"
local view = require "nvim-tree.view"
local core = require "nvim-tree.core"
local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify"
local explorer_node = require "nvim-tree.explorer.node"
local view = require("nvim-tree.view")
local core = require("nvim-tree.core")
local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local explorer_node = require("nvim-tree.explorer.node")
---@class LibOpenOpts
---@field path string|nil path
@@ -15,25 +14,33 @@ local M = {
target_winid = nil,
}
---@return Node|nil
function M.get_node_at_cursor()
---Cursor position as per vim.api.nvim_win_get_cursor
---@return integer[]|nil
function M.get_cursor_position()
if not core.get_explorer() then
return
end
local winnr = view.get_winnr()
if not winnr then
if not winnr or not vim.api.nvim_win_is_valid(winnr) then
return
end
local cursor = vim.api.nvim_win_get_cursor(winnr)
local line = cursor[1]
return vim.api.nvim_win_get_cursor(winnr)
end
if line == 1 and view.is_root_folder_visible(core.get_cwd()) then
---@return Node|nil
function M.get_node_at_cursor()
local cursor = M.get_cursor_position()
if not cursor then
return
end
if cursor[1] == 1 and view.is_root_folder_visible(core.get_cwd()) then
return { name = ".." }
end
return utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())[line]
return utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())[cursor[1]]
end
---Create a sanitized partial copy of a node, populating children recursively.
@@ -142,13 +149,15 @@ end
---@param node Node
function M.expand_or_collapse(node, toggle_group)
local explorer = core.get_explorer()
toggle_group = toggle_group or false
if node.has_children then
node.has_children = false
end
if #node.nodes == 0 then
core.get_explorer():expand(node)
if #node.nodes == 0 and explorer then
explorer:expand(node)
end
local head_node = utils.get_parent_of_group(node)
@@ -167,7 +176,9 @@ function M.expand_or_collapse(node, toggle_group)
n.open = next_open
end
renderer.draw()
if explorer then
explorer.renderer:draw()
end
end
function M.set_target_win()
@@ -192,7 +203,11 @@ local function open_view_and_draw()
local cwd = vim.fn.getcwd()
view.open()
handle_buf_cwd(cwd)
renderer.draw()
local explorer = core.get_explorer()
if explorer then
explorer.renderer:draw()
end
end
local function should_hijack_current_buf()
@@ -200,7 +215,7 @@ local function should_hijack_current_buf()
local bufname = vim.api.nvim_buf_get_name(bufnr)
local bufmodified, ft
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
bufmodified = vim.api.nvim_get_option_value("modified", { buf = bufnr })
ft = vim.api.nvim_get_option_value("ft", { buf = bufnr })
else
@@ -261,16 +276,25 @@ function M.open(opts)
core.init(cwd)
end
end
local explorer = core.get_explorer()
if should_hijack_current_buf() then
view.close_this_tab_only()
view.open_in_win()
renderer.draw()
if explorer then
explorer.renderer:draw()
end
elseif opts.winid then
view.open_in_win { hijack_current_buf = false, resize = false, winid = opts.winid }
renderer.draw()
view.open_in_win({ hijack_current_buf = false, resize = false, winid = opts.winid })
if explorer then
explorer.renderer:draw()
end
elseif opts.current_window then
view.open_in_win { hijack_current_buf = false, resize = false }
renderer.draw()
view.open_in_win({ hijack_current_buf = false, resize = false })
if explorer then
explorer.renderer:draw()
end
else
open_view_and_draw()
end

View File

@@ -32,7 +32,7 @@ end
---@return Profile to pass to profile_end
function M.profile_start(fmt, ...)
local profile = {}
if M.enabled "profile" then
if M.enabled("profile") then
profile.start = vim.loop.hrtime()
profile.tag = string.format((fmt or "???"), ...)
M.line("profile", "START %s", profile.tag)
@@ -44,7 +44,7 @@ end
--- END is prefixed and duration in seconds is suffixed
---@param profile Profile returned from profile_start
function M.profile_end(profile)
if M.enabled "profile" and type(profile) == "table" then
if M.enabled("profile") and type(profile) == "table" then
local millis = profile.start and math.modf((vim.loop.hrtime() - profile.start) / 1000000) or -1
M.line("profile", "END %s %dms", profile.tag or "", millis)
end
@@ -57,7 +57,7 @@ end
---@param ... any arguments for string.format
function M.line(typ, fmt, ...)
if M.enabled(typ) then
M.raw(typ, string.format("[%s] [%s] %s\n", os.date "%Y-%m-%d %H:%M:%S", typ, (fmt or "???")), ...)
M.raw(typ, string.format("[%s] [%s] %s\n", os.date("%Y-%m-%d %H:%M:%S"), typ, (fmt or "???")), ...)
end
end
@@ -77,7 +77,7 @@ end
function M.node(typ, node, fmt, ...)
if M.enabled(typ) then
node = node or require("nvim-tree.lib").get_node_at_cursor()
M.raw(typ, string.format("[%s] [%s] %s\n%s\n", os.date "%Y-%m-%d %H:%M:%S", typ, (fmt or "???"), vim.inspect(node, inspect_opts)), ...)
M.raw(typ, string.format("[%s] [%s] %s\n%s\n", os.date("%Y-%m-%d %H:%M:%S"), typ, (fmt or "???"), vim.inspect(node, inspect_opts)), ...)
end
end
@@ -91,7 +91,7 @@ end
function M.setup(opts)
M.config = opts.log
if M.config and M.config.enable and M.config.types then
M.path = string.format("%s/nvim-tree.log", vim.fn.stdpath "log", os.date "%H:%M:%S", vim.env.USER)
M.path = string.format("%s/nvim-tree.log", vim.fn.stdpath("log"), os.date("%H:%M:%S"), vim.env.USER)
if M.config.truncate then
os.remove(M.path)
end

View File

@@ -1,59 +0,0 @@
local utils = require "nvim-tree.utils"
local remove_file = require "nvim-tree.actions.fs.remove-file"
local notify = require "nvim-tree.notify"
local lib = require "nvim-tree.lib"
local M = {
config = {},
}
--- Delete nodes; each removal will be optionally notified
---@param nodes Node[]
---@param marks Marks
local function do_delete(marks, nodes)
for _, node in pairs(nodes) do
remove_file.remove(node)
end
marks:clear_marks()
if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders").reload_explorer()
end
end
--- Delete marked nodes, optionally prompting
---@param explorer Explorer
function M.bulk_delete(explorer)
if not explorer then
return
end
local marks = explorer.marks
local nodes = marks:get_marks()
if not nodes or #nodes == 0 then
notify.warn "No bookmarksed to delete."
return
end
if M.config.ui.confirm.remove then
local prompt_select = "Remove bookmarked ?"
local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_delete", function(item_short)
utils.clear_prompt()
if item_short == "y" then
do_delete(marks, nodes)
end
end)
else
do_delete(marks, nodes)
end
end
function M.setup(opts)
M.config.ui = opts.ui
M.config.filesystem_watchers = opts.filesystem_watchers
end
return M

View File

@@ -1,67 +0,0 @@
local core = require "nvim-tree.core"
local utils = require "nvim-tree.utils"
local rename_file = require "nvim-tree.actions.fs.rename-file"
local notify = require "nvim-tree.notify"
local lib = require "nvim-tree.lib"
local M = {
config = {},
}
---@param explorer Explorer
function M.bulk_move(explorer)
if not explorer then
return
end
local marks = explorer.marks
if #marks:get_marks() == 0 then
notify.warn "No bookmarks to move."
return
end
local node_at_cursor = lib.get_node_at_cursor()
local default_path = core.get_cwd()
if node_at_cursor and node_at_cursor.type == "directory" then
default_path = node_at_cursor.absolute_path
elseif node_at_cursor and node_at_cursor.parent then
default_path = node_at_cursor.parent.absolute_path
end
local input_opts = {
prompt = "Move to: ",
default = default_path,
completion = "dir",
}
vim.ui.input(input_opts, function(location)
utils.clear_prompt()
if not location or location == "" then
return
end
if vim.fn.filewritable(location) ~= 2 then
notify.warn(location .. " is not writable, cannot move.")
return
end
local nodes = marks:get_marks()
for _, node in pairs(nodes) do
local head = vim.fn.fnamemodify(node.absolute_path, ":t")
local to = utils.path_join { location, head }
rename_file.rename(node, to)
end
marks:clear_marks()
if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders").reload_explorer()
end
end)
end
function M.setup(opts)
M.config.filesystem_watchers = opts.filesystem_watchers
end
return M

View File

@@ -1,53 +0,0 @@
local utils = require "nvim-tree.utils"
local remove_file = require "nvim-tree.actions.fs.trash"
local notify = require "nvim-tree.notify"
local lib = require "nvim-tree.lib"
local M = {
config = {},
}
--- Delete nodes; each removal will be optionally notified
---@param nodes Node[]
local function do_trash(nodes)
for _, node in pairs(nodes) do
remove_file.remove(node)
end
end
---@param explorer Explorer
function M.bulk_trash(explorer)
if not explorer then
return
end
local marks = explorer.marks
local nodes = marks:get_marks()
if not nodes or #nodes == 0 then
notify.warn "No bookmarks to trash."
return
end
if M.config.ui.confirm.trash then
local prompt_select = "Trash bookmarked ?"
local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_trash", function(item_short)
utils.clear_prompt()
if item_short == "y" then
do_trash(nodes)
marks:clear_marks()
end
end)
else
do_trash(nodes)
marks:clear_marks()
end
end
function M.setup(opts)
M.config.ui = opts.ui
M.config.filesystem_watchers = opts.filesystem_watchers
end
return M

View File

@@ -1,65 +1,81 @@
local renderer = {} -- circular dependency
local Iterator = require("nvim-tree.iterators.node-iterator")
local core = require("nvim-tree.core")
local lib = require("nvim-tree.lib")
local notify = require("nvim-tree.notify")
local open_file = require("nvim-tree.actions.node.open-file")
local remove_file = require("nvim-tree.actions.fs.remove-file")
local rename_file = require("nvim-tree.actions.fs.rename-file")
local trash = require("nvim-tree.actions.fs.trash")
local utils = require("nvim-tree.utils")
---@class Marks
---@field private marks Node[]
---@field config table hydrated user opts.filters
---@field private explorer Explorer
---@field private marks table<string, Node> by absolute path
local Marks = {}
---@return Marks
function Marks:new()
local o = {}
---@param opts table user options
---@param explorer Explorer
function Marks:new(opts, explorer)
local o = {
explorer = explorer,
config = {
ui = opts.ui,
filesystem_watchers = opts.filesystem_watchers,
},
marks = {},
}
setmetatable(o, self)
self.__index = self
o.marks = {}
return o
end
---Clear all marks and reload if watchers disabled
---@private
---@param node Node
function Marks:add_mark(node)
self.marks[node.absolute_path] = node
renderer.draw()
function Marks:clear_reload()
self:clear()
if not self.config.filesystem_watchers.enable then
self.explorer:reload_explorer()
end
end
---@private
---@param node Node
function Marks:remove_mark(node)
self.marks[node.absolute_path] = nil
renderer.draw()
---Clear all marks and redraw
---@public
function Marks:clear()
self.marks = {}
self.explorer.renderer:draw()
end
---@public
---@param node Node
function Marks:toggle_mark(node)
function Marks:toggle(node)
if node.absolute_path == nil then
return
end
if self:get_mark(node) then
self:remove_mark(node)
if self:get(node) then
self.marks[node.absolute_path] = nil
else
self:add_mark(node)
self.marks[node.absolute_path] = node
end
renderer.draw()
end
function Marks:clear_marks()
self.marks = {}
renderer.draw()
self.explorer.renderer:draw()
end
---Return node if marked
---@public
---@param node Node
---@return Node|nil
function Marks:get_mark(node)
function Marks:get(node)
return node and self.marks[node.absolute_path]
end
---List marked nodes
---@public
---@return Node[]
function Marks:get_marks()
function Marks:list()
local list = {}
for _, node in pairs(self.marks) do
table.insert(list, node)
@@ -67,12 +83,190 @@ function Marks:get_marks()
return list
end
function Marks.setup(opts)
renderer = require "nvim-tree.renderer"
---Delete marked; each removal will be optionally notified
---@public
function Marks:bulk_delete()
if not next(self.marks) then
notify.warn("No bookmarks to delete.")
return
end
require("nvim-tree.marks.bulk-delete").setup(opts)
require("nvim-tree.marks.bulk-trash").setup(opts)
require("nvim-tree.marks.bulk-move").setup(opts)
local function execute()
for _, node in pairs(self.marks) do
remove_file.remove(node)
end
self:clear_reload()
end
if self.config.ui.confirm.remove then
local prompt_select = "Remove bookmarked ?"
local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_delete", function(item_short)
utils.clear_prompt()
if item_short == "y" then
execute()
end
end)
else
execute()
end
end
---Trash marked; each removal will be optionally notified
---@public
function Marks:bulk_trash()
if not next(self.marks) then
notify.warn("No bookmarks to trash.")
return
end
local function execute()
for _, node in pairs(self.marks) do
trash.remove(node)
end
self:clear_reload()
end
if self.config.ui.confirm.trash then
local prompt_select = "Trash bookmarked ?"
local prompt_input = prompt_select .. " y/N: "
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_trash", function(item_short)
utils.clear_prompt()
if item_short == "y" then
execute()
end
end)
else
execute()
end
end
---Move marked
---@public
function Marks:bulk_move()
if not next(self.marks) then
notify.warn("No bookmarks to move.")
return
end
local node_at_cursor = lib.get_node_at_cursor()
local default_path = core.get_cwd()
if node_at_cursor and node_at_cursor.type == "directory" then
default_path = node_at_cursor.absolute_path
elseif node_at_cursor and node_at_cursor.parent then
default_path = node_at_cursor.parent.absolute_path
end
local input_opts = {
prompt = "Move to: ",
default = default_path,
completion = "dir",
}
vim.ui.input(input_opts, function(location)
utils.clear_prompt()
if not location or location == "" then
return
end
if vim.fn.filewritable(location) ~= 2 then
notify.warn(location .. " is not writable, cannot move.")
return
end
for _, node in pairs(self.marks) do
local head = vim.fn.fnamemodify(node.absolute_path, ":t")
local to = utils.path_join({ location, head })
rename_file.rename(node, to)
end
self:clear_reload()
end)
end
---Focus nearest marked node in direction.
---@private
---@param up boolean
function Marks:navigate(up)
local node = lib.get_node_at_cursor()
if not node then
return
end
local first, prev, next, last = nil, nil, nil, nil
local found = false
Iterator.builder(self.explorer.nodes)
:recursor(function(n)
return n.open and n.nodes
end)
:applier(function(n)
if n.absolute_path == node.absolute_path then
found = true
return
end
if not self:get(n) then
return
end
last = n
first = first or n
if found and not next then
next = n
end
if not found then
prev = n
end
end)
:iterate()
if not found then
return
end
if up then
utils.focus_node_or_parent(prev or last)
else
utils.focus_node_or_parent(next or first)
end
end
---@public
function Marks:navigate_prev()
self:navigate(true)
end
---@public
function Marks:navigate_next()
self:navigate(false)
end
---Prompts for selection of a marked node, sorted by absolute paths.
---A folder will be focused, a file will be opened.
---@public
function Marks:navigate_select()
local list = vim.tbl_map(function(n)
return n.absolute_path
end, self:list())
table.sort(list)
vim.ui.select(list, {
prompt = "Select a file to open or a folder to focus",
}, function(choice)
if not choice or choice == "" then
return
end
local node = self.marks[choice]
if node and not node.nodes 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)
end
end)
end
return Marks

View File

@@ -1,111 +0,0 @@
local Iterator = require "nvim-tree.iterators.node-iterator"
local core = require "nvim-tree.core"
local open_file = require "nvim-tree.actions.node.open-file"
local utils = require "nvim-tree.utils"
local lib = require "nvim-tree.lib"
---@param node table
---@param where string
---@return Node|nil
local function get_nearest(node, where)
local explorer = core.get_explorer()
if not explorer then
return
end
local first, prev, next, last = nil, nil, nil, nil
local found = false
Iterator.builder(explorer.nodes)
:recursor(function(n)
return n.open and n.nodes
end)
:applier(function(n)
if n.absolute_path == node.absolute_path then
found = true
return
end
if not explorer.marks:get_mark(n) then
return
end
last = n
first = first or n
if found and not next then
next = n
end
if not found then
prev = n
end
end)
:iterate()
if not found then
return
end
if where == "next" then
return next or first
else
return prev or last
end
end
---@param where string
---@param node table|nil
---@return Node|nil
local function get(where, node)
if node then
return get_nearest(node, where)
end
end
---@param node table|nil
local function open_or_focus(node)
if node and not node.nodes 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)
end
end
---@param where string
---@return function
local function navigate_to(where)
return function()
local node = lib.get_node_at_cursor()
local next = get(where, node)
open_or_focus(next)
end
end
local M = {}
M.next = navigate_to "next"
M.prev = navigate_to "prev"
function M.select()
local explorer = core.get_explorer()
if not explorer then
return
end
local list = vim.tbl_map(function(n)
return n.absolute_path
end, explorer.marks:get_marks())
vim.ui.select(list, {
prompt = "Select a file to open or a folder to focus",
}, function(choice)
if not choice or choice == "" then
return
end
local node = explorer.marks:get_mark { absolute_path = choice }
open_or_focus(node)
end)
end
return M

View File

@@ -9,9 +9,9 @@ local title_support
---@return boolean
function M.supports_title()
if title_support == nil then
title_support = (package.loaded.notify and (vim.notify == require "notify" or vim.notify == require("notify").notify))
title_support = (package.loaded.notify and (vim.notify == require("notify") or vim.notify == require("notify").notify))
or (package.loaded.noice and (vim.notify == require("noice").notify or vim.notify == require("noice.source.notify").notify))
or (package.loaded.notifier and require("notifier.config").has_component "nvim")
or (package.loaded.notifier and require("notifier.config").has_component("nvim"))
or false
end
@@ -21,8 +21,8 @@ end
local modes = {
{ name = "trace", level = vim.log.levels.TRACE },
{ name = "debug", level = vim.log.levels.DEBUG },
{ name = "info", level = vim.log.levels.INFO },
{ name = "warn", level = vim.log.levels.WARN },
{ name = "info", level = vim.log.levels.INFO },
{ name = "warn", level = vim.log.levels.WARN },
{ name = "error", level = vim.log.levels.ERROR },
}
@@ -35,7 +35,7 @@ do
vim.schedule(function()
if not M.supports_title() then
-- add title to the message, with a newline if the message is multiline
msg = string.format("[NvimTree]%s%s", (msg:match "\n" and "\n" or " "), msg)
msg = string.format("[NvimTree]%s%s", (msg:match("\n") and "\n" or " "), msg)
end
vim.notify(msg, level, { title = "NvimTree" })

View File

@@ -1,60 +1,62 @@
local core = require "nvim-tree.core"
local notify = require "nvim-tree.notify"
local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view"
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local DecoratorBookmarks = require "nvim-tree.renderer.decorator.bookmarks"
local DecoratorCopied = require "nvim-tree.renderer.decorator.copied"
local DecoratorCut = require "nvim-tree.renderer.decorator.cut"
local DecoratorDiagnostics = require "nvim-tree.renderer.decorator.diagnostics"
local DecoratorGit = require "nvim-tree.renderer.decorator.git"
local DecoratorModified = require "nvim-tree.renderer.decorator.modified"
local DecoratorHidden = require "nvim-tree.renderer.decorator.hidden"
local DecoratorOpened = require "nvim-tree.renderer.decorator.opened"
local DecoratorBookmarks = require("nvim-tree.renderer.decorator.bookmarks")
local DecoratorCopied = require("nvim-tree.renderer.decorator.copied")
local DecoratorCut = require("nvim-tree.renderer.decorator.cut")
local DecoratorDiagnostics = require("nvim-tree.renderer.decorator.diagnostics")
local DecoratorGit = require("nvim-tree.renderer.decorator.git")
local DecoratorModified = require("nvim-tree.renderer.decorator.modified")
local DecoratorHidden = require("nvim-tree.renderer.decorator.hidden")
local DecoratorOpened = require("nvim-tree.renderer.decorator.opened")
local pad = require "nvim-tree.renderer.components.padding"
local icons = require "nvim-tree.renderer.components.icons"
local pad = require("nvim-tree.renderer.components.padding")
local icons = require("nvim-tree.renderer.components.icons")
local M = {
opts = {},
decorators = {},
picture_map = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
},
local PICTURE_MAP = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
}
---@class HighlightedString
---@class (exact) HighlightedString
---@field str string
---@field hl string[]
---@class AddHighlightArgs
---@class (exact) AddHighlightArgs
---@field group string[]
---@field line number
---@field col_start number
---@field col_end number
---@class Builder
---@class (exact) Builder
---@field private __index? table
---@field lines string[] includes icons etc.
---@field hl_args AddHighlightArgs[] line highlights
---@field signs string[] line signs
---@field extmarks table[] extra marks for right icon placement
---@field virtual_lines table[] virtual lines for hidden count display
---@field private root_cwd string absolute path
---@field private explorer Explorer
---@field private index number
---@field private depth number
---@field private combined_groups table<string, boolean> combined group names
---@field private markers boolean[] indent markers
---@field private decorators Decorator[]
---@field private hidden_display fun(node: Node): string|nil
local Builder = {}
---@param opts table user options
---@param explorer Explorer
---@return Builder
function Builder:new()
function Builder:new(opts, explorer)
---@type Builder
local o = {
root_cwd = core.get_cwd(),
opts = opts,
explorer = explorer,
index = 0,
depth = 0,
hl_args = {},
@@ -64,7 +66,20 @@ function Builder:new()
signs = {},
extmarks = {},
virtual_lines = {},
decorators = {
-- priority order
DecoratorCut:new(opts, explorer),
DecoratorCopied:new(opts, explorer),
DecoratorDiagnostics:new(opts, explorer),
DecoratorBookmarks:new(opts, explorer),
DecoratorModified:new(opts, explorer),
DecoratorHidden:new(opts, explorer),
DecoratorOpened:new(opts, explorer),
DecoratorGit:new(opts, explorer),
},
hidden_display = Builder:setup_hidden_display_function(opts),
}
setmetatable(o, self)
self.__index = self
@@ -89,8 +104,8 @@ function Builder:get_folder_name(node)
next = next.group_next
end
if node.group_next and type(M.opts.renderer.group_empty) == "function" then
local new_name = M.opts.renderer.group_empty(name)
if node.group_next and type(self.opts.renderer.group_empty) == "function" then
local new_name = self.opts.renderer.group_empty(name)
if type(new_name) == "string" then
name = new_name
else
@@ -98,7 +113,7 @@ function Builder:get_folder_name(node)
end
end
return string.format("%s%s", name, M.opts.renderer.add_trailing and "/" or "")
return string.format("%s%s", name, self.opts.renderer.add_trailing and "/" or "")
end
---@private
@@ -139,13 +154,13 @@ function Builder:build_folder(node)
end
local foldername_hl = "NvimTreeFolderName"
if node.link_to and M.opts.renderer.symlink_destination then
if node.link_to and self.opts.renderer.symlink_destination then
local arrow = icons.i.symlink_arrow
local link_to = utils.path_relative(node.link_to, self.root_cwd)
local link_to = utils.path_relative(node.link_to, self.explorer.absolute_path)
foldername = string.format("%s%s%s", foldername, arrow, link_to)
foldername_hl = "NvimTreeSymlinkFolderName"
elseif
vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name)
vim.tbl_contains(self.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(self.opts.renderer.special_files, node.name)
then
foldername_hl = "NvimTreeSpecialFolderName"
elseif node.open then
@@ -165,8 +180,8 @@ function Builder:build_symlink(node)
local icon = icons.i.symlink
local arrow = icons.i.symlink_arrow
local symlink_formatted = node.name
if M.opts.renderer.symlink_destination then
local link_to = utils.path_relative(node.link_to, self.root_cwd)
if self.opts.renderer.symlink_destination then
local link_to = utils.path_relative(node.link_to, self.explorer.absolute_path)
symlink_formatted = string.format("%s%s%s", symlink_formatted, arrow, link_to)
end
@@ -179,11 +194,13 @@ end
---@return HighlightedString name
function Builder:build_file(node)
local hl
if vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name) then
if
vim.tbl_contains(self.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(self.opts.renderer.special_files, node.name)
then
hl = "NvimTreeSpecialFile"
elseif node.executable then
hl = "NvimTreeExecFile"
elseif M.picture_map[node.extension] then
elseif PICTURE_MAP[node.extension] then
hl = "NvimTreeImageFile"
end
@@ -206,7 +223,7 @@ function Builder:format_line(indent_markers, arrows, icon, name, node)
end
for _, v in ipairs(t2) do
if added_len > 0 then
table.insert(t1, { str = M.opts.renderer.icons.padding })
table.insert(t1, { str = self.opts.renderer.icons.padding })
end
table.insert(t1, v)
end
@@ -222,19 +239,19 @@ function Builder:format_line(indent_markers, arrows, icon, name, node)
local line = { indent_markers, arrows }
add_to_end(line, { icon })
for i = #M.decorators, 1, -1 do
add_to_end(line, M.decorators[i]:icons_before(node))
for i = #self.decorators, 1, -1 do
add_to_end(line, self.decorators[i]:icons_before(node))
end
add_to_end(line, { name })
for i = #M.decorators, 1, -1 do
add_to_end(line, M.decorators[i]:icons_after(node))
for i = #self.decorators, 1, -1 do
add_to_end(line, self.decorators[i]:icons_after(node))
end
local rights = {}
for i = #M.decorators, 1, -1 do
add_to_end(rights, M.decorators[i]:icons_right_align(node))
for i = #self.decorators, 1, -1 do
add_to_end(rights, self.decorators[i]:icons_right_align(node))
end
if #rights > 0 then
self.extmarks[self.index] = rights
@@ -248,7 +265,7 @@ end
function Builder:build_signs(node)
-- first in priority order
local sign_name
for _, d in ipairs(M.decorators) do
for _, d in ipairs(self.decorators) do
sign_name = d:sign_name(node)
if sign_name then
self.signs[self.index] = sign_name
@@ -300,8 +317,8 @@ function Builder:add_highlights(node)
local icon_groups = {}
local name_groups = {}
local d, icon, name
for i = #M.decorators, 1, -1 do
d = M.decorators[i]
for i = #self.decorators, 1, -1 do
d = self.decorators[i]
icon, name = d:groups_icon_name(node)
table.insert(icon_groups, icon)
table.insert(name_groups, name)
@@ -366,10 +383,10 @@ function Builder:add_hidden_count_string(node, idx, num_children)
if not node.open then
return
end
local hidden_count_string = M.opts.renderer.hidden_display(node.hidden_stats)
local hidden_count_string = self.hidden_display(node.hidden_stats)
if hidden_count_string and hidden_count_string ~= "" then
local indent_markers = pad.get_indent_markers(self.depth, idx or 0, num_children or 0, node, self.markers, 1)
local indent_width = M.opts.renderer.indent_width
local indent_width = self.opts.renderer.indent_width
local indent_padding = string.rep(" ", indent_width)
local indent_string = indent_padding .. indent_markers.str
@@ -380,7 +397,7 @@ function Builder:add_hidden_count_string(node, idx, num_children)
-- if we change the traversal, we might need to sort by depth before rendering `self.virtual_lines`
-- to maintain proper ordering of parent and child folder hidden count info.
table.insert(self.virtual_lines[line_nr], {
{ indent_string, indent_markers.hl },
{ indent_string, indent_markers.hl },
{ string.rep(indent_padding, (node.parent == nil and 0 or 1)) .. hidden_count_string, "NvimTreeHiddenDisplay" },
})
end
@@ -388,8 +405,7 @@ end
---@private
function Builder:get_nodes_number(nodes)
local explorer = core.get_explorer()
if not explorer or not explorer.live_filter.filter then
if not self.explorer.live_filter.filter then
return #nodes
end
@@ -405,7 +421,7 @@ end
---@private
function Builder:build_lines(node)
if not node then
node = core.get_explorer()
node = self.explorer
end
local num_children = self:get_nodes_number(node.nodes)
local idx = 1
@@ -424,30 +440,29 @@ end
---@return string
function Builder:format_root_name(root_label)
if type(root_label) == "function" then
local label = root_label(self.root_cwd)
local label = root_label(self.explorer.absolute_path)
if type(label) == "string" then
return label
end
elseif type(root_label) == "string" then
return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label))
return utils.path_remove_trailing(vim.fn.fnamemodify(self.explorer.absolute_path, root_label))
end
return "???"
end
---@private
function Builder:build_header()
local explorer = core.get_explorer()
if view.is_root_folder_visible(core.get_cwd()) then
local root_name = self:format_root_name(M.opts.renderer.root_folder_label)
if view.is_root_folder_visible(self.explorer.absolute_path) then
local root_name = self:format_root_name(self.opts.renderer.root_folder_label)
table.insert(self.lines, root_name)
self:insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name))
self.index = 1
end
if explorer and explorer.live_filter.filter then
local filter_line = string.format("%s/%s/", M.opts.live_filter.prefix, explorer.live_filter.filter)
if self.explorer.live_filter.filter then
local filter_line = string.format("%s/%s/", self.opts.live_filter.prefix, self.explorer.live_filter.filter)
table.insert(self.lines, filter_line)
local prefix_length = string.len(M.opts.live_filter.prefix)
local prefix_length = string.len(self.opts.live_filter.prefix)
self:insert_highlight({ "NvimTreeLiveFilterPrefix" }, 0, prefix_length)
self:insert_highlight({ "NvimTreeLiveFilterValue" }, prefix_length, string.len(filter_line))
self.index = self.index + 1
@@ -472,26 +487,28 @@ function Builder:build()
return self
end
---TODO refactor back to function; this was left here to reduce PR noise
---@param opts table
local setup_hidden_display_function = function(opts)
---@return fun(node: Node): string|nil
function Builder:setup_hidden_display_function(opts)
local hidden_display = opts.renderer.hidden_display
-- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then
if type(hidden_display) == "string" then
if hidden_display == "none" then
opts.renderer.hidden_display = function()
return function()
return nil
end
elseif hidden_display == "simple" then
opts.renderer.hidden_display = function(hidden_stats)
return function(hidden_stats)
return utils.default_format_hidden_count(hidden_stats, true)
end
elseif hidden_display == "all" then
opts.renderer.hidden_display = function(hidden_stats)
else -- "all"
return function(hidden_stats)
return utils.default_format_hidden_count(hidden_stats, false)
end
end
elseif type(hidden_display) == "function" then
local safe_render = function(hidden_stats)
else -- "function
return function(hidden_stats)
-- In case of missing field such as live_filter we zero it, otherwise keep field as is
hidden_stats = vim.tbl_deep_extend("force", {
live_filter = 0,
@@ -504,31 +521,13 @@ local setup_hidden_display_function = 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"
notify.warn(
"Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree")
return nil
end
return result
end
opts.renderer.hidden_display = safe_render
end
end
function Builder.setup(opts)
setup_hidden_display_function(opts)
M.opts = opts
-- priority order
M.decorators = {
DecoratorCut:new(opts),
DecoratorCopied:new(opts),
DecoratorDiagnostics:new(opts),
DecoratorBookmarks:new(opts),
DecoratorModified:new(opts),
DecoratorHidden:new(opts),
DecoratorOpened:new(opts),
DecoratorGit:new(opts),
}
end
return Builder

View File

@@ -1,5 +1,5 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local diagnostics = require "nvim-tree.diagnostics"
local diagnostics = require("nvim-tree.diagnostics")
local M = {
-- highlight strings for the icons

View File

@@ -1,6 +1,6 @@
local M = {}
local utils = require "nvim-tree.utils"
local utils = require("nvim-tree.utils")
local function hide(win)
if win then
@@ -42,7 +42,7 @@ local function show()
return
end
local line = vim.fn.getline "."
local line = vim.fn.getline(".")
local leftcol = vim.fn.winsaveview().leftcol
-- hide full name if left column of node in nvim-tree win is not zero
if leftcol ~= 0 then
@@ -81,7 +81,7 @@ local function show()
vim.api.nvim_buf_add_highlight(0, ns_id, details.hl_group, 0, col, details.end_col)
end
vim.cmd [[ setlocal nowrap cursorline noswapfile nobuflisted buftype=nofile bufhidden=hide ]]
vim.cmd([[ setlocal nowrap cursorline noswapfile nobuflisted buftype=nofile bufhidden=hide ]])
end)
end

View File

@@ -107,7 +107,7 @@ end
function M.setup(opts)
M.config = opts.renderer.icons
M.devicons = pcall(require, "nvim-web-devicons") and require "nvim-web-devicons" or nil
M.devicons = pcall(require, "nvim-web-devicons") and require("nvim-web-devicons") or nil
end
return M

View File

@@ -0,0 +1,15 @@
local M = {}
M.diagnostics = require("nvim-tree.renderer.components.diagnostics")
M.full_name = require("nvim-tree.renderer.components.full-name")
M.icons = require("nvim-tree.renderer.components.icons")
M.padding = require("nvim-tree.renderer.components.padding")
function M.setup(opts)
M.diagnostics.setup(opts)
M.full_name.setup(opts)
M.icons.setup(opts)
M.padding.setup(opts)
end
return M

View File

@@ -117,7 +117,7 @@ function M.setup(opts)
return " "
end
-- return the first character from the UTF-8 encoded string; we may use utf8.codes from Lua 5.3 when available
return symbol:match "[%z\1-\127\194-\244][\128-\191]*"
return symbol:match("[%z\1-\127\194-\244][\128-\191]*")
end
for k, v in pairs(M.config.indent_markers.icons) do

View File

@@ -1,18 +1,18 @@
local core = require "nvim-tree.core"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorBookmarks: Decorator
---@class (exact) DecoratorBookmarks: Decorator
---@field icon HighlightedString
local DecoratorBookmarks = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorBookmarks
function DecoratorBookmarks:new(opts)
function DecoratorBookmarks:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_bookmarks] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT[opts.renderer.icons.bookmarks_placement] or ICON_PLACEMENT.none,
@@ -34,7 +34,7 @@ end
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorBookmarks:calculate_icons(node)
if core.get_explorer() and core.get_explorer().marks:get_mark(node) then
if self.explorer.marks:get(node) then
return { self.icon }
end
end
@@ -43,7 +43,7 @@ end
---@param node Node
---@return string|nil group
function DecoratorBookmarks:calculate_highlight(node)
if self.hl_pos ~= HL_POSITION.none and core.get_explorer() and core.get_explorer().marks:get_mark(node) then
if self.hl_pos ~= HL_POSITION.none and self.explorer.marks:get(node) then
return "NvimTreeBookmarkHL"
end
end

View File

@@ -1,28 +1,25 @@
local copy_paste
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorCopied: Decorator
---@class (exact) DecoratorCopied: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorCopied = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorCopied
function DecoratorCopied:new(opts)
function DecoratorCopied:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT.none,
})
---@cast o DecoratorCopied
-- cyclic
copy_paste = copy_paste or require "nvim-tree.actions.fs.copy-paste"
return o
end
@@ -30,7 +27,7 @@ end
---@param node Node
---@return string|nil group
function DecoratorCopied:calculate_highlight(node)
if self.hl_pos ~= HL_POSITION.none and copy_paste.is_copied(node) then
if self.hl_pos ~= HL_POSITION.none and self.explorer.clipboard:is_copied(node) then
return "NvimTreeCopiedHL"
end
end

View File

@@ -1,28 +1,25 @@
local copy_paste
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorCut: Decorator
---@class (exact) DecoratorCut: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorCut = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorCut
function DecoratorCut:new(opts)
function DecoratorCut:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT.none,
})
---@cast o DecoratorCut
-- cyclic
copy_paste = copy_paste or require "nvim-tree.actions.fs.copy-paste"
return o
end
@@ -30,7 +27,7 @@ end
---@param node Node
---@return string|nil group
function DecoratorCut:calculate_highlight(node)
if self.hl_pos ~= HL_POSITION.none and copy_paste.is_cut(node) then
if self.hl_pos ~= HL_POSITION.none and self.explorer.clipboard:is_cut(node) then
return "NvimTreeCutHL"
end
end

View File

@@ -1,9 +1,9 @@
local diagnostics = require "nvim-tree.diagnostics"
local diagnostics = require("nvim-tree.diagnostics")
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
-- highlight groups by severity
local HG_ICON = {
@@ -32,14 +32,16 @@ local ICON_KEYS = {
["hint"] = vim.diagnostic.severity.HINT,
}
---@class DecoratorDiagnostics: Decorator
---@class (exact) DecoratorDiagnostics: Decorator
---@field icons HighlightedString[]
local DecoratorDiagnostics = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorDiagnostics
function DecoratorDiagnostics:new(opts)
function DecoratorDiagnostics:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = opts.diagnostics.enable,
hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT[opts.renderer.icons.diagnostics_placement] or ICON_PLACEMENT.none,

View File

@@ -1,15 +1,15 @@
local notify = require "nvim-tree.notify"
local explorer_node = require "nvim-tree.explorer.node"
local notify = require("nvim-tree.notify")
local explorer_node = require("nvim-tree.explorer.node")
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class HighlightedStringGit: HighlightedString
---@field ord number decreasing priority
---@class DecoratorGit: Decorator
---@class (exact) DecoratorGit: Decorator
---@field file_hl table<string, string> by porcelain status e.g. "AM"
---@field folder_hl table<string, string> by porcelain status
---@field icons_by_status HighlightedStringGit[] by human status
@@ -17,9 +17,11 @@ local Decorator = require "nvim-tree.renderer.decorator"
local DecoratorGit = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorGit
function DecoratorGit:new(opts)
function DecoratorGit:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = opts.git.enable,
hl_pos = HL_POSITION[opts.renderer.highlight_git] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT[opts.renderer.icons.git_placement] or ICON_PLACEMENT.none,

View File

@@ -1,16 +1,18 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local explorer_node = require "nvim-tree.explorer.node"
local Decorator = require "nvim-tree.renderer.decorator"
local explorer_node = require("nvim-tree.explorer.node")
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorHidden: Decorator
---@class (exact) DecoratorHidden: Decorator
---@field icon HighlightedString|nil
local DecoratorHidden = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorHidden
function DecoratorHidden:new(opts)
function DecoratorHidden:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_hidden] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT[opts.renderer.icons.hidden_placement] or ICON_PLACEMENT.none,
@@ -28,7 +30,7 @@ function DecoratorHidden:new(opts)
return o
end
---Hidden icon: hidden.enable, renderer.icons.show.hidden and node starts with `.` (dotfile).
---Hidden icon: renderer.icons.show.hidden and node starts with `.` (dotfile).
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorHidden:calculate_icons(node)
@@ -37,7 +39,7 @@ function DecoratorHidden:calculate_icons(node)
end
end
---Hidden highlight: hidden.enable, renderer.highlight_hidden and node starts with `.` (dotfile).
---Hidden highlight: renderer.highlight_hidden and node starts with `.` (dotfile).
---@param node Node
---@return string|nil group
function DecoratorHidden:calculate_highlight(node)

View File

@@ -1,7 +1,9 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
---@class Decorator
---@class (exact) Decorator
---@field private __index? table
---@field protected explorer Explorer
---@field protected enabled boolean
---@field protected hl_pos HL_POSITION
---@field protected icon_placement ICON_PLACEMENT
@@ -11,6 +13,7 @@ local Decorator = {}
---@return Decorator
function Decorator:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self

View File

@@ -1,18 +1,20 @@
local buffers = require "nvim-tree.buffers"
local buffers = require("nvim-tree.buffers")
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorModified: Decorator
---@class (exact) DecoratorModified: Decorator
---@field icon HighlightedString|nil
local DecoratorModified = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorModified
function DecoratorModified:new(opts)
function DecoratorModified:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = opts.modified.enable,
hl_pos = HL_POSITION[opts.renderer.highlight_modified] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT[opts.renderer.icons.modified_placement] or ICON_PLACEMENT.none,

View File

@@ -1,19 +1,21 @@
local buffers = require "nvim-tree.buffers"
local buffers = require("nvim-tree.buffers")
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
local Decorator = require "nvim-tree.renderer.decorator"
local Decorator = require("nvim-tree.renderer.decorator")
---@class DecoratorOpened: Decorator
---@class (exact) DecoratorOpened: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorOpened = Decorator:new()
---@param opts table
---@param explorer Explorer
---@return DecoratorOpened
function DecoratorOpened:new(opts)
function DecoratorOpened:new(opts, explorer)
local o = Decorator.new(self, {
explorer = explorer,
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_opened_files] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT.none,

View File

@@ -1,36 +1,57 @@
local core = require "nvim-tree.core"
local log = require "nvim-tree.log"
local view = require "nvim-tree.view"
local events = require "nvim-tree.events"
local log = require("nvim-tree.log")
local view = require("nvim-tree.view")
local events = require("nvim-tree.events")
local _padding = require "nvim-tree.renderer.components.padding"
local icon_component = require "nvim-tree.renderer.components.icons"
local full_name = require "nvim-tree.renderer.components.full-name"
local Builder = require "nvim-tree.renderer.builder"
local icon_component = require("nvim-tree.renderer.components.icons")
local M = {}
local Builder = require("nvim-tree.renderer.builder")
local SIGN_GROUP = "NvimTreeRendererSigns"
local namespace_highlights_id = vim.api.nvim_create_namespace "NvimTreeHighlights"
local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks"
local namespace_virtual_lines_id = vim.api.nvim_create_namespace "NvimTreeVirtualLines"
local namespace_highlights_id = vim.api.nvim_create_namespace("NvimTreeHighlights")
local namespace_extmarks_id = vim.api.nvim_create_namespace("NvimTreeExtmarks")
local namespace_virtual_lines_id = vim.api.nvim_create_namespace("NvimTreeVirtualLines")
---@class (exact) Renderer
---@field private __index? table
---@field private opts table user options
---@field private explorer Explorer
---@field private builder Builder
local Renderer = {}
---@param opts table user options
---@param explorer Explorer
---@return Renderer
function Renderer:new(opts, explorer)
---@type Renderer
local o = {
opts = opts,
explorer = explorer,
builder = Builder:new(opts, explorer),
}
setmetatable(o, self)
self.__index = self
return o
end
---@private
---@param bufnr number
---@param lines string[]
---@param hl_args AddHighlightArgs[]
---@param signs string[]
local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines)
if vim.fn.has "nvim-0.10" == 1 then
function Renderer:_draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines)
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", true, { buf = bufnr })
else
vim.api.nvim_buf_set_option(bufnr, "modifiable", true) ---@diagnostic disable-line: deprecated
end
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
M.render_hl(bufnr, hl_args)
self:render_hl(bufnr, hl_args)
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
vim.api.nvim_set_option_value("modifiable", false, { buf = bufnr })
else
vim.api.nvim_buf_set_option(bufnr, "modifiable", false) ---@diagnostic disable-line: deprecated
@@ -62,7 +83,8 @@ local function _draw(bufnr, lines, hl_args, signs, extmarks, virtual_lines)
end
end
function M.render_hl(bufnr, hl)
---@private
function Renderer:render_hl(bufnr, hl)
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
return
end
@@ -76,20 +98,20 @@ function M.render_hl(bufnr, hl)
end
end
function M.draw()
function Renderer:draw()
local bufnr = view.get_bufnr()
if not core.get_explorer() or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
return
end
local profile = log.profile_start "draw"
local profile = log.profile_start("draw")
local cursor = vim.api.nvim_win_get_cursor(view.get_winnr() or 0)
icon_component.reset_config()
local builder = Builder:new():build()
local builder = Builder:new(self.opts, self.explorer):build()
_draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines)
self:_draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks, builder.virtual_lines)
if cursor and #builder.lines >= cursor[1] then
vim.api.nvim_win_set_cursor(view.get_winnr() or 0, cursor)
@@ -102,14 +124,4 @@ function M.draw()
events._dispatch_on_tree_rendered(bufnr, view.get_winnr())
end
function M.setup(opts)
M.config = opts.renderer
_padding.setup(opts)
full_name.setup(opts)
icon_component.setup(opts)
Builder.setup(opts)
end
return M
return Renderer

View File

@@ -1,15 +1,15 @@
local Iterator = require "nvim-tree.iterators.node-iterator"
local notify = require "nvim-tree.notify"
local Iterator = require("nvim-tree.iterators.node-iterator")
local notify = require("nvim-tree.notify")
local M = {
debouncers = {},
}
M.is_unix = vim.fn.has "unix" == 1
M.is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1
M.is_wsl = vim.fn.has "wsl" == 1
M.is_unix = vim.fn.has("unix") == 1
M.is_macos = vim.fn.has("mac") == 1 or vim.fn.has("macunix") == 1
M.is_wsl = vim.fn.has("wsl") == 1
-- false for WSL
M.is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1
M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1
---@param haystack string
---@param needle string
@@ -250,7 +250,7 @@ function M.rename_loaded_buffers(old_path, new_path)
-- to avoid the 'overwrite existing file' error message on write for
-- normal files
local buftype
if vim.fn.has "nvim-0.10" == 1 then
if vim.fn.has("nvim-0.10") == 1 then
buftype = vim.api.nvim_get_option_value("buftype", { buf = buf })
else
buftype = vim.api.nvim_buf_get_option(buf, "buftype") ---@diagnostic disable-line: deprecated
@@ -258,8 +258,8 @@ function M.rename_loaded_buffers(old_path, new_path)
if buftype == "" then
vim.api.nvim_buf_call(buf, function()
vim.cmd "silent! write!"
vim.cmd "edit"
vim.cmd("silent! write!")
vim.cmd("edit")
end)
end
end
@@ -277,7 +277,7 @@ end
---@param path string
---@return string
function M.canonical_path(path)
if M.is_windows and path:match "^%a:" then
if M.is_windows and path:match("^%a:") then
return path:sub(1, 1):upper() .. path:sub(2)
end
return path
@@ -290,7 +290,7 @@ function M.escape_special_chars(path)
if path == nil then
return path
end
return M.is_windows and path:gsub("%(", "\\("):gsub("%)", "\\)") or path
return M.is_windows and path:gsub("\\", "/") or path
end
--- Create empty sub-tables if not present
@@ -467,7 +467,7 @@ 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 }
require("nvim-tree.view").set_cursor({ i + 1, 1 })
end
---Focus node passed as parameter if visible, otherwise focus first visible parent.
@@ -487,7 +487,7 @@ function M.focus_node_or_parent(node)
end)
if found_node or node.parent == nil then
require("nvim-tree.view").set_cursor { i + 1, 1 }
require("nvim-tree.view").set_cursor({ i + 1, 1 })
break
end
@@ -510,7 +510,7 @@ end
function M.clear_prompt()
if vim.opt.cmdheight._value ~= 0 then
vim.cmd "normal! :"
vim.cmd("normal! :")
end
end
@@ -567,7 +567,7 @@ function M.is_nvim_tree_buf(bufnr)
end
if vim.api.nvim_buf_is_valid(bufnr) then
local bufname = vim.api.nvim_buf_get_name(bufnr)
if vim.fn.fnamemodify(bufname, ":t"):match "^NvimTree_[0-9]+$" then
if vim.fn.fnamemodify(bufname, ":t"):match("^NvimTree_[0-9]+$") then
if vim.bo[bufnr].filetype == "NvimTree" then
return true
elseif vim.fn.filereadable(bufname) == 0 then

View File

@@ -1,6 +1,7 @@
local events = require "nvim-tree.events"
local utils = require "nvim-tree.utils"
local log = require "nvim-tree.log"
local events = require("nvim-tree.events")
local utils = require("nvim-tree.utils")
local log = require("nvim-tree.log")
local notify = require("nvim-tree.notify")
---@class OpenInWinOpts
---@field hijack_current_buf boolean|nil default true
@@ -166,7 +167,7 @@ local function open_window()
if M.View.float.enable then
vim.api.nvim_open_win(0, true, open_win_config())
else
vim.api.nvim_command "vsp"
vim.api.nvim_command("vsp")
M.reposition_window()
end
setup_tabpage(vim.api.nvim_get_current_tabpage())
@@ -181,7 +182,7 @@ end
---@return number|nil
local function get_alt_or_next_buf()
local alt_buf = vim.fn.bufnr "#"
local alt_buf = vim.fn.bufnr("#")
if is_buf_displayed(alt_buf) then
return alt_buf
end
@@ -199,7 +200,7 @@ local function switch_buf_if_last_buf()
if buf then
vim.cmd("sb" .. buf)
else
vim.cmd "new"
vim.cmd("new")
end
end
end
@@ -213,7 +214,7 @@ end
---@param tabpage integer
local function close(tabpage)
if not M.is_visible { tabpage = tabpage } then
if not M.is_visible({ tabpage = tabpage }) then
return
end
save_tab_state(tabpage)
@@ -222,12 +223,16 @@ local function close(tabpage)
local current_win = vim.api.nvim_get_current_win()
for _, win in pairs(vim.api.nvim_tabpage_list_wins(tabpage)) do
if vim.api.nvim_win_get_config(win).relative == "" then
local prev_win = vim.fn.winnr "#" -- this tab only
local prev_win = vim.fn.winnr("#") -- this tab only
if tree_win == current_win and prev_win > 0 then
vim.api.nvim_set_current_win(vim.fn.win_getid(prev_win))
end
if vim.api.nvim_win_is_valid(tree_win or 0) then
vim.api.nvim_win_close(tree_win or 0, true)
local success, error = pcall(vim.api.nvim_win_close, tree_win or 0, true)
if not success then
notify.debug("Failed to close window: " .. error)
return
end
end
events._dispatch_on_tree_close()
return
@@ -259,7 +264,7 @@ function M.open(options)
return
end
local profile = log.profile_start "view open"
local profile = log.profile_start("view open")
create_buffer()
open_window()
@@ -267,7 +272,7 @@ function M.open(options)
local opts = options or { focus_tree = true }
if not opts.focus_tree then
vim.cmd "wincmd p"
vim.cmd("wincmd p")
end
events._dispatch_on_tree_open()
@@ -346,14 +351,18 @@ function M.resize(size)
return
end
local winnr = M.get_winnr() or 0
local new_size = get_width()
vim.api.nvim_win_set_width(M.get_winnr() or 0, new_size)
if new_size ~= vim.api.nvim_win_get_width(winnr) then
vim.api.nvim_win_set_width(winnr, new_size)
if not M.View.preserve_window_proportions then
vim.cmd(":wincmd =")
end
end
events._dispatch_on_tree_resize(new_size)
if not M.View.preserve_window_proportions then
vim.cmd ":wincmd ="
end
end
function M.reposition_window()
@@ -456,7 +465,7 @@ function M.winid(opts)
if tabpage == 0 then
tabpage = vim.api.nvim_get_current_tabpage()
end
if M.is_visible { tabpage = tabpage } then
if M.is_visible({ tabpage = tabpage }) then
return M.get_winnr(tabpage)
else
return nil
@@ -505,7 +514,7 @@ function M._prevent_buffer_override()
local curbuf = vim.api.nvim_win_get_buf(curwin)
local bufname = vim.api.nvim_buf_get_name(curbuf)
if not bufname:match "NvimTree" then
if not bufname:match("NvimTree") then
for i, tabpage in ipairs(M.View.tabpages) do
if tabpage.winnr == view_winnr then
M.View.tabpages[i] = nil
@@ -519,10 +528,15 @@ function M._prevent_buffer_override()
-- patch to avoid the overriding window to be fixed in size
-- might need a better patch
vim.cmd "setlocal nowinfixwidth"
vim.cmd "setlocal nowinfixheight"
M.open { focus_tree = false }
require("nvim-tree.renderer").draw()
vim.cmd("setlocal nowinfixwidth")
vim.cmd("setlocal nowinfixheight")
M.open({ focus_tree = false })
local explorer = require("nvim-tree.core").get_explorer()
if explorer then
explorer.renderer:draw()
end
pcall(vim.api.nvim_win_close, curwin, { force = true })
-- to handle opening a file using :e when nvim-tree is on floating mode

View File

@@ -1,6 +1,6 @@
local notify = require "nvim-tree.notify"
local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local notify = require("nvim-tree.notify")
local log = require("nvim-tree.log")
local utils = require("nvim-tree.utils")
local M = {
config = {},
@@ -79,7 +79,7 @@ function Event:start()
rc, _, name = self._fs_event:start(self._path, FS_EVENT_FLAGS, event_cb)
if rc ~= 0 then
if name == "EMFILE" then
M.disable_watchers "fs.inotify.max_user_watches exceeded, see https://github.com/nvim-tree/nvim-tree.lua/wiki/Troubleshooting"
M.disable_watchers("fs.inotify.max_user_watches exceeded, see https://github.com/nvim-tree/nvim-tree.lua/wiki/Troubleshooting")
else
notify.warn(string.format("Could not start the fs_event watcher for path %s : %s", self._path, name))
end