Compare commits

..

1 Commits

Author SHA1 Message Date
github-actions[bot]
9525689aa3 Saving release notes 2023-12-09 00:36:31 +00:00
72 changed files with 1697 additions and 2664 deletions

View File

@@ -7,9 +7,6 @@ on:
push:
branches:
- master
- release-please--branches--master--components--nvim-tree
workflow_dispatch:
permissions:
contents: read
@@ -17,31 +14,22 @@ permissions:
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
lua_version: [ 5.1 ]
steps:
- uses: actions/checkout@v4
- uses: leafo/gh-actions-lua@v10
with:
luaVersion: ${{ matrix.lua_version }}
luaVersion: "5.1"
- uses: leafo/gh-actions-luarocks@v4
- run: luarocks install luacheck 1.1.1
- run: make lint
- name: luacheck
run: |
luarocks install luacheck 1.1.1
luacheck lua
style:
runs-on: ubuntu-latest
strategy:
matrix:
stylua_version: [ 0.19.1 ]
steps:
- uses: actions/checkout@v4
@@ -49,33 +37,6 @@ jobs:
uses: JohnnyMorganz/stylua-action@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ matrix.stylua_version }}
version: "0.19"
args: --check lua
- run: make style-doc
check:
runs-on: ubuntu-latest
strategy:
matrix:
nvim_version: [ v0.9.4 ]
luals_version: [ 3.7.3 ]
steps:
- uses: actions/checkout@v4
- uses: rhysd/action-setup-vim@v1
with:
neovim: true
version: ${{ matrix.nvim_version }}
- name: install luals
run: |
mkdir -p luals
curl -L "https://github.com/LuaLS/lua-language-server/releases/download/${{ matrix.luals_version }}/lua-language-server-${{ matrix.luals_version }}-linux-x64.tar.gz" | tar zx --directory luals
- name: make check
run: VIMRUNTIME=/home/runner/nvim-${{ matrix.nvim_version }}/share/nvim/runtime PATH="luals/bin:${PATH}" make check
- run: make help-check

View File

@@ -2,18 +2,17 @@ on:
push:
branches:
- master
workflow_dispatch:
name: release-please
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v4
id: release
with:
release-type: simple
package-name: nvim-tree
command: github-release
- uses: actions/checkout@v4
- name: tag major and minor versions
if: ${{ steps.release.outputs.release_created }}

View File

@@ -6,8 +6,6 @@ on:
- reopened
- edited
- synchronize
workflow_dispatch:
jobs:
semantic-pr-subject:
runs-on: ubuntu-latest

2
.gitignore vendored
View File

@@ -1,2 +0,0 @@
/luals-out/
/luals/

View File

@@ -1,3 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash
make
stylua . --check || exit 1
luacheck . || exit 1

View File

@@ -1,14 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
"runtime.version" : "Lua 5.1",
"workspace": {
"library": [
"$VIMRUNTIME/lua/vim/lsp",
"${3rd}/luv/library"
]
},
"diagnostics": {
"libraryFiles": "Disable",
"globals": [
"vim"
],

View File

@@ -1,3 +0,0 @@
{
".": "0.100.0"
}

View File

@@ -1,43 +0,0 @@
# Changelog
## [0.100.0](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v0.99.0...nvim-tree-v0.100.0) (2024-02-11)
### Features
* **#1389:** api: recursive node navigation for git and diagnostics ([#2525](https://github.com/nvim-tree/nvim-tree.lua/issues/2525)) ([5d13cc8](https://github.com/nvim-tree/nvim-tree.lua/commit/5d13cc8205bce4963866f73c50f6fdc18a515ffe))
* **#2415:** add :NvimTreeHiTest ([#2664](https://github.com/nvim-tree/nvim-tree.lua/issues/2664)) ([b278fc2](https://github.com/nvim-tree/nvim-tree.lua/commit/b278fc25ae0fc95e4808eb5618f07fc2522fd2b3))
* **#2415:** colour and highlight overhaul, see :help nvim-tree-highlight-overhaul ([#2455](https://github.com/nvim-tree/nvim-tree.lua/issues/2455)) ([e9c5abe](https://github.com/nvim-tree/nvim-tree.lua/commit/e9c5abe073a973f54d3ca10bfe30f253569f4405))
* add node.open.toggle_group_empty, default mapping L ([#2647](https://github.com/nvim-tree/nvim-tree.lua/issues/2647)) ([8cbb1db](https://github.com/nvim-tree/nvim-tree.lua/commit/8cbb1db8e90b62fc56f379992e622e9f919792ce))
### Bug Fixes
* **#2415:** disambiguate highlight groups, see :help nvim-tree-highlight-overhaul ([#2639](https://github.com/nvim-tree/nvim-tree.lua/issues/2639)) ([d9cb432](https://github.com/nvim-tree/nvim-tree.lua/commit/d9cb432d2c8d8fa9267ddbd7535d76fe4df89360))
* **#2415:** fix NvimTreeIndentMarker highlight group: FileIcon->FolderIcon ([e9ac136](https://github.com/nvim-tree/nvim-tree.lua/commit/e9ac136a3ab996aa8e4253253521dcf2cb66b81b))
* **#2415:** highlight help header and mappings ([#2669](https://github.com/nvim-tree/nvim-tree.lua/issues/2669)) ([39e6fef](https://github.com/nvim-tree/nvim-tree.lua/commit/39e6fef85ac3bb29532b877aa7c9c34911c661af))
* **#2415:** nvim 0.8 highlight overhaul support, limited to only show highest highlight precedence ([#2642](https://github.com/nvim-tree/nvim-tree.lua/issues/2642)) ([f39f7b6](https://github.com/nvim-tree/nvim-tree.lua/commit/f39f7b6fcd3865ac2146de4cb4045286308f2935))
* **#2415:** NvimTreeIndentMarker highlight group: FileIcon->FolderIcon ([#2656](https://github.com/nvim-tree/nvim-tree.lua/issues/2656)) ([e9ac136](https://github.com/nvim-tree/nvim-tree.lua/commit/e9ac136a3ab996aa8e4253253521dcf2cb66b81b))
* **#2624:** open file from docked floating window ([#2627](https://github.com/nvim-tree/nvim-tree.lua/issues/2627)) ([f24afa2](https://github.com/nvim-tree/nvim-tree.lua/commit/f24afa2cef551122b8bd53bb2e4a7df42343ce2e))
* **#2632:** occasional error stack when locating nvim-tree window ([#2633](https://github.com/nvim-tree/nvim-tree.lua/issues/2633)) ([48b1d86](https://github.com/nvim-tree/nvim-tree.lua/commit/48b1d8638fa3726236ae22e0e48a74ac8ea6592a))
* **#2637:** show buffer modified icons and highlights ([#2638](https://github.com/nvim-tree/nvim-tree.lua/issues/2638)) ([7bdb220](https://github.com/nvim-tree/nvim-tree.lua/commit/7bdb220d0fe604a77361e92cdbc7af1b8a412126))
* **#2643:** correctly apply linked highlight groups in tree window ([#2653](https://github.com/nvim-tree/nvim-tree.lua/issues/2653)) ([fbee8a6](https://github.com/nvim-tree/nvim-tree.lua/commit/fbee8a69a46f558d29ab84e96301425b0501c668))
* allow highlight overrides for DEFAULT_DEFS: NvimTreeFolderIcon, NvimTreeWindowPicker ([#2636](https://github.com/nvim-tree/nvim-tree.lua/issues/2636)) ([74525ac](https://github.com/nvim-tree/nvim-tree.lua/commit/74525ac04760bf0d9fec2bf51474d2b05f36048e))
* bad column offset when using full_name ([#2629](https://github.com/nvim-tree/nvim-tree.lua/issues/2629)) ([75ff64e](https://github.com/nvim-tree/nvim-tree.lua/commit/75ff64e6663fc3b23c72dca32b2f838acefe7c8a))
* passing nil as window handle in view.get_winnr ([48b1d86](https://github.com/nvim-tree/nvim-tree.lua/commit/48b1d8638fa3726236ae22e0e48a74ac8ea6592a))
## 0.99.0 (2024-01-01)
### Features
* **#1850:** add "no bookmark" filter ([#2571](https://github.com/nvim-tree/nvim-tree.lua/issues/2571)) ([8f92e1e](https://github.com/nvim-tree/nvim-tree.lua/commit/8f92e1edd399f839a23776dcc6eee4ba18030370))
* add kind param to vim.ui.select function calls ([#2602](https://github.com/nvim-tree/nvim-tree.lua/issues/2602)) ([dc839a7](https://github.com/nvim-tree/nvim-tree.lua/commit/dc839a72a6496ce22ebd3dd959115cf97c1b20a0))
* add option to skip gitignored files on git navigation ([#2583](https://github.com/nvim-tree/nvim-tree.lua/issues/2583)) ([50f30bc](https://github.com/nvim-tree/nvim-tree.lua/commit/50f30bcd8c62ac4a83d133d738f268279f2c2ce2))
### Bug Fixes
* **#2519:** Diagnostics Not Updated When Tree Not Visible ([#2597](https://github.com/nvim-tree/nvim-tree.lua/issues/2597)) ([96a783f](https://github.com/nvim-tree/nvim-tree.lua/commit/96a783fbd606a458bcce2ef8041240a8b94510ce))
* **#2609:** help toggle ([#2611](https://github.com/nvim-tree/nvim-tree.lua/issues/2611)) ([fac4900](https://github.com/nvim-tree/nvim-tree.lua/commit/fac4900bd18a9fa15be3d104645d9bdef7b3dcec))
* hijack_cursor on update focused file and vim search ([#2600](https://github.com/nvim-tree/nvim-tree.lua/issues/2600)) ([02ae523](https://github.com/nvim-tree/nvim-tree.lua/commit/02ae52357ba4da77a4c120390791584a81d15340))

View File

@@ -4,76 +4,31 @@ Thank you for contributing.
See [Development](https://github.com/nvim-tree/nvim-tree.lua/wiki/Development) for environment setup, tips and tools.
# Tools
## Styling and formatting
Following are used during CI and strongly recommended during local development.
Code is formatted using luacheck, and linted using stylua.
You can install these with:
Lint: [luacheck](https://github.com/lunarmodules/luacheck/)
Style: [StyLua](https://github.com/JohnnyMorganz/StyLua)
Language server: [luals](https://luals.github.io)
You can install them via you OS package manager e.g. `pacman`, `brew` or other via other package managers such as `cargo` or `luarocks`
# Quality
The following quality checks are mandatory and are performed during CI. They run on the entire `lua` directory and return 1 on any failure.
You can run them all via `make` or `make all`
You can setup git hooks to run all checks by running `scripts/setup-hooks.sh`
## lint
1. Runs luacheck quietly using `.luacheck` settings
```sh
make lint
```bash
luarocks install luacheck
cargo install stylua
```
## style
You can setup the git hooks by running `scripts/setup-hooks.sh`.
1. Runs stylua using `.stylua.toml` settings
1. Runs `scripts/doc-comments.sh` to validate annotated documentation
```sh
make style
```
You can automatically fix stylua issues via:
```sh
make style-fix
```
## check
1. Runs the checks that the LSP lua language server runs inside nvim using `.luarc.json` via `scripts/luals-check.sh`
```sh
make check
```
Assumes `$VIMRUNTIME` is `/usr/share/nvim/runtime`. Adjust as necessary e.g.
```sh
VIMRUNTIME="/my/path/to/runtime" make check
```
# Adding New Actions
## Adding new actions
To add a new action, add a file in `actions/name-of-the-action.lua`. You should export a `setup` function if some configuration is needed.
Once you did, you should run the `scripts/update-help.sh`.
Once you did, you should run `make help-update`
# Documentation
## Documentation
When adding new options, you should declare the defaults in the main `nvim-tree.lua` file.
Once you did, you should run the `scripts/update-help.sh`.
Documentation for options should also be added to `nvim-tree-opts` in `doc/nvim-tree-lua.txt`
# Pull Request
## Pull Request
Please reference any issues in the description e.g. "resolves #1234".

View File

@@ -1,47 +0,0 @@
all: lint style check
#
# mandatory checks
#
lint: luacheck
style: stylua style-doc
check: luals
#
# subtasks
#
luacheck:
luacheck -q lua
stylua:
stylua lua --check
style-doc:
scripts/doc-comments.sh
luals:
scripts/luals-check.sh
#
# fixes
#
style-fix:
stylua lua
#
# utility
#
help-update:
scripts/help-update.sh
#
# CI
#
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

View File

@@ -53,7 +53,7 @@ Setup the plugin in your `init.lua`
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- optionally enable 24-bit colour
-- set termguicolors to enable highlight groups
vim.opt.termguicolors = true
-- empty setup using defaults

View File

@@ -10,7 +10,6 @@ CONTENTS *nvim-tree*
2.1 Quickstart: Setup |nvim-tree-quickstart-setup|
2.2 Quickstart: Help |nvim-tree-quickstart-help|
2.3 Quickstart: Custom Mappings |nvim-tree-quickstart-custom-mappings|
2.4 Quickstart: Highlight |nvim-tree-quickstart-highlight|
3. Commands |nvim-tree-commands|
4. Setup |nvim-tree-setup|
5. Opts |nvim-tree-opts|
@@ -44,16 +43,12 @@ CONTENTS *nvim-tree*
6.7 API Marks |nvim-tree-api.marks|
6.8 API Config |nvim-tree-api.config|
6.9 API Commands |nvim-tree-api.commands|
6.10 API Diagnostics |nvim-tree-api.diagnostics|
7. Mappings |nvim-tree-mappings|
7.1 Mappings: Default |nvim-tree-mappings-default|
8. Highlight |nvim-tree-highlight|
8.1 Highlight Default |nvim-tree-highlight-default|
8.2 Highlight Overhaul |nvim-tree-highlight-overhaul|
9. Events |nvim-tree-events|
10. Prompts |nvim-tree-prompts|
11. OS Specific Restrictions |nvim-tree-os-specific|
12. Netrw |nvim-tree-netrw|
10. OS Specific Restrictions |nvim-tree-os-specific|
11. Netrw |nvim-tree-netrw|
==============================================================================
1. INTRODUCTION *nvim-tree-introduction*
@@ -117,7 +112,7 @@ Setup the plugin in your `init.lua` >
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- optionally enable 24-bit colour
-- set termguicolors to enable highlight groups
vim.opt.termguicolors = true
-- empty setup using defaults
@@ -175,16 +170,14 @@ Show the mappings: `g?`
`e` Rename: Basename |nvim-tree-api.fs.rename_basename()|
`]e` Next Diagnostic |nvim-tree-api.node.navigate.diagnostics.next()|
`[e` Prev Diagnostic |nvim-tree-api.node.navigate.diagnostics.prev()|
`F` Live Filter: Clear |nvim-tree-api.live_filter.clear()|
`f` Live Filter: Start |nvim-tree-api.live_filter.start()|
`F` Clean Filter |nvim-tree-api.live_filter.clear()|
`f` Filter |nvim-tree-api.live_filter.start()|
`g?` Help |nvim-tree-api.tree.toggle_help()|
`gy` Copy Absolute Path |nvim-tree-api.fs.copy.absolute_path()|
`H` Toggle Filter: Dotfiles |nvim-tree-api.tree.toggle_hidden_filter()|
`I` Toggle Filter: Git Ignore |nvim-tree-api.tree.toggle_gitignore_filter()|
`J` Last Sibling |nvim-tree-api.node.navigate.sibling.last()|
`K` First Sibling |nvim-tree-api.node.navigate.sibling.first()|
`L` Toggle Group Empty |nvim-tree-api.node.open.toggle_group_empty()|
`M` Toggle Filter: No Bookmark |nvim-tree-api.tree.toggle_no_bookmark_filter()|
`m` Toggle Bookmark |nvim-tree-api.marks.toggle()|
`o` Open |nvim-tree-api.node.open.edit()|
`O` Open: No Window Picker |nvim-tree-api.node.open.no_window_picker()|
@@ -232,16 +225,6 @@ via |nvim-tree.on_attach| e.g. >
---
}
<
==============================================================================
2.4 QUICKSTART: HIGHLIGHT *nvim-tree-quickstart-highlight*
Run |:NvimTreeHiTest| to show all the highlights that nvim-tree uses.
They can be customised before or after setup is called and will be immediately
applied at runtime.
See |nvim-tree-highlight| for details.
==============================================================================
3. COMMANDS *nvim-tree-commands*
@@ -336,14 +319,6 @@ See |nvim-tree-highlight| for details.
Calls: `api.tree.collapse_all(true)`
*:NvimTreeHiTest*
Show nvim-tree highlight groups similar to `:so $VIMRUNTIME/syntax/hitest.vim`
See |nvim-tree-api.diagnostics.hi_test()|
Calls: `api.diagnostics.hi_test()`
==============================================================================
4. SETUP *nvim-tree-setup*
@@ -410,8 +385,8 @@ Following is the default configuration. See |nvim-tree-opts| for details.
indent_width = 2,
special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
symlink_destination = true,
highlight_git = "none",
highlight_diagnostics = "none",
highlight_git = false,
highlight_diagnostics = false,
highlight_opened_files = "none",
highlight_modified = "none",
highlight_bookmarks = "none",
@@ -527,7 +502,6 @@ Following is the default configuration. See |nvim-tree-opts| for details.
dotfiles = false,
git_clean = false,
no_buffer = false,
no_bookmark = false,
custom = {},
exclude = {},
},
@@ -812,9 +786,8 @@ Use nvim-tree in a floating window.
==============================================================================
5.3 OPTS: RENDERER *nvim-tree-opts-renderer*
Highlight precedence, additive:
git < opened < modified < bookmarked < diagnostics < copied < cut
Neovim <= 0.8 will only show the highest.
Highlight precedence:
clipboard > diagnostics > bookmarked > modified > opened > git
*nvim-tree.renderer.add_trailing*
Appends a trailing slash to folder names.
@@ -856,20 +829,18 @@ Whether to show the destination of the symlink.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.highlight_git*
Enable highlight for git attributes using `NvimTreeGit*HL` highlight groups.
Enable highlight for git attributes using `NvimTreeGit*` highlight groups.
Requires |nvim-tree.git.enable|
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`
Type: `boolean`, Default: `false`
*nvim-tree.renderer.highlight_diagnostics*
Enable highlight for diagnostics using `NvimTreeDiagnostic*HL` highlight groups.
Enable highlight for diagnostics using `LspDiagnosticsError*Text` highlight groups.
Requires |nvim-tree.diagnostics.enable|
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`
Type: `boolean`, Default: `false`
*nvim-tree.renderer.highlight_opened_files*
Highlight icons and/or names for |bufloaded()| files using the
`NvimTreeOpenedHL` highlight group.
`NvimTreeOpenedFile` highlight group.
See |nvim-tree-api.navigate.opened.next()| and |nvim-tree-api.navigate.opened.prev()|
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`
@@ -918,8 +889,8 @@ Configuration options for tree indent markers.
*nvim-tree.renderer.icons*
Configuration options for icons.
Icon order and sign column precedence:
git < modified < bookmarked < diagnostics
Icon sign column precedence:
diagnostics > modified > git > bookmarked
*nvim-tree.renderer.icons.web_devicons*
Configure optional plugin `"nvim-tree/nvim-web-devicons"`
@@ -933,7 +904,7 @@ Icon order and sign column precedence:
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.web_devicons.file.color*
Use icon colors for files. Overrides highlight groups.
Use icon colors for files.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.web_devicons.folder*
@@ -945,7 +916,7 @@ Icon order and sign column precedence:
Type: `boolean`, Default: `false`
*nvim-tree.renderer.icons.web_devicons.folder.color*
Use icon colors for folders. Overrides highlight groups.
Use icon colors for folders.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.git_placement*
@@ -1252,12 +1223,6 @@ For performance reasons this may not immediately update on buffer
delete/wipe. A reload or filesystem event will result in an update.
Type: `boolean`, Default: `false`
*nvim-tree.filters.no_bookmark*
Do not show files that are not bookarked.
Toggle via |nvim-tree-api.tree.toggle_no_bookmark_filter()|, default `M`
Enabling this is not useful as there is no means yet to persist bookmarks.
Type: `boolean`, Default: `false`
*nvim-tree.filters.custom*
Custom list of vim regex for file/directory names that will not be shown.
Backslashes must be escaped e.g. "^\\.git". See |string-match|.
@@ -1701,10 +1666,6 @@ tree.toggle_git_clean_filter()
tree.toggle_no_buffer_filter()
Toggle |nvim-tree.filters.no_buffer| filter.
*nvim-tree-api.tree.toggle_no_bookmark_filter()*
tree.toggle_no_bookmark_filter()
Toggle |nvim-tree.filters.no_bookmark| filter.
*nvim-tree-api.tree.toggle_custom_filter()*
tree.toggle_custom_filter()
Toggle |nvim-tree.filters.custom| filter.
@@ -1869,12 +1830,6 @@ node.open.vertical() *nvim-tree-api.node.open.vertical()*
node.open.horizontal() *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()
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()*
Switch to window with selected file if it exists.
Open file otherwise.
@@ -1907,49 +1862,17 @@ node.open.preview_no_picker() *nvim-tree-api.node.open.preview_no_picker()*
node.navigate.git.next() *nvim-tree-api.node.navigate.git.next()*
Navigate to the next item showing git status.
*nvim-tree-api.node.navigate.git.next_recursive()*
node.navigate.git.next_recursive()
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()
Same as |node.navigate.git.next()|, but skips gitignored files.
node.navigate.git.prev() *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()
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()
Same as |node.navigate.git.prev()|, but skips gitignored files.
*nvim-tree-api.node.navigate.diagnostics.next()*
node.navigate.diagnostics.next()
Navigate to the next item showing diagnostic status.
*nvim-tree-api.node.navigate.diagnostics.next_recursive()*
node.navigate.diagnostics.next_recursive()
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()
Navigate to the next item showing diagnostic status.
*nvim-tree-api.node.navigate.diagnostics.prev_recursive()*
node.navigate.diagnostics.prev_recursive()
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()
Navigate to the next |bufloaded()| item.
@@ -2097,7 +2020,7 @@ config.mappings.get_keymap_default()
(table) as per |nvim_buf_get_keymap()|
==============================================================================
6.9 API COMMANDS *nvim-tree-api.commands*
6.8 API COMMANDS *nvim-tree-api.commands*
commands.get() *nvim-tree-api.commands.get()*
Retrieve all commands, see |nvim-tree-commands|
@@ -2108,15 +2031,6 @@ commands.get() *nvim-tree-api.commands.get()*
• {command} (function)
• {opts} (table)
==============================================================================
6.10 DIAGNOSTICS *nvim-tree-api.diagnostics*
diagnostics.hi_test() *nvim-tree-api.diagnostics.hi_test()*
Open a new buffer displaying all nvim-tree highlight groups, their link
chain and concrete definition.
Similar to `:so $VIMRUNTIME/syntax/hitest.vim` as per |:highlight|
==============================================================================
7. MAPPINGS *nvim-tree-mappings*
@@ -2224,16 +2138,14 @@ You are encouraged to copy these to your own |nvim-tree.on_attach| function.
vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename'))
vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic'))
vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic'))
vim.keymap.set('n', 'F', api.live_filter.clear, opts('Live Filter: Clear'))
vim.keymap.set('n', 'f', api.live_filter.start, opts('Live Filter: Start'))
vim.keymap.set('n', 'F', api.live_filter.clear, opts('Clean Filter'))
vim.keymap.set('n', 'f', api.live_filter.start, opts('Filter'))
vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles'))
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
vim.keymap.set('n', 'L', api.node.open.toggle_group_empty, opts('Toggle Group Empty'))
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker'))
@@ -2279,32 +2191,42 @@ groups.
Example |:highlight| >
:hi NvimTreeSymlink guifg=blue gui=bold,underline
<
It is recommended to enable 'termguicolors' for the more pleasant 24-bit
colours.
You should have 'termguicolors' enabled, otherwise, colors will not be
applied.
To view the nvim-tree highlight groups run |:NvimTreeHiTest|
To view all active highlight groups run `:so $VIMRUNTIME/syntax/hitest.vim`
To view the active highlight groups run `:so $VIMRUNTIME/syntax/hitest.vim`
as per |:highlight|
The `*HL` groups are additive as per |nvim-tree-opts-renderer| precedence.
Only present attributes will clobber each other.
In this example a modified, opened file will have magenta text, with cyan
undercurl: >
:hi NvimTreeOpenedHL guifg=magenta guisp=red gui=underline
:hi NvimTreeModifiedFileHL guisp=cyan gui=undercurl
Default linked group follows name.
File Text: >
NvimTreeSymlink
NvimTreeExecFile
NvimTreeOpenedFile
NvimTreeModifiedFile
NvimTreeSpecialFile
NvimTreeImageFile
<
Folder Text: >
NvimTreeFolderName Directory
NvimTreeEmptyFolderName Directory
NvimTreeOpenedFolderName Directory
NvimTreeSymlinkFolderName Directory
NvimTreeRootFolder
<
Icon: >
NvimTreeFileIcon
NvimTreeOpenedFileIcon NvimTreeOpenedFile
NvimTreeSymlinkIcon
NvimTreeFolderIcon
NvimTreeOpenedFolderIcon NvimTreeFolderIcon
NvimTreeClosedFolderIcon NvimTreeFolderIcon
NvimTreeFolderArrowClosed NvimTreeIndentMarker
NvimTreeFolderArrowOpen NvimTreeIndentMarker
<
Indent: >
NvimTreeIndentMarker
<
To prevent usage of a highlight:
- Before setup: link the group to `Normal` e.g.
`:hi NvimTreeExecFile Normal`
- After setup: link it to `NONE`, to override the default link e.g.
`:hi! link NvimTreeExecFile NONE`
==============================================================================
8.1 HIGHLIGHT DEFAULT *nvim-tree-highlight-default*
|:highlight-link| `default` or |:highlight-default| define the groups on setup:
Standard: >
NvimTreeNormal Normal
NvimTreeNormalFloat NormalFloat
@@ -2323,172 +2245,67 @@ Standard: >
NvimTreeStatusLine StatusLine
NvimTreeStatusLineNC StatusLineNC
<
File Text: >
NvimTreeExecFile SpellCap
NvimTreeImageFile SpellCap
NvimTreeSpecialFile SpellCap
NvimTreeSymlink SpellCap
<
Folder Text: >
NvimTreeRootFolder Title
NvimTreeFolderName Directory
NvimTreeEmptyFolderName Directory
NvimTreeOpenedFolderName Directory
NvimTreeSymlinkFolderName Directory
<
File Icons: >
NvimTreeFileIcon NvimTreeNormal
NvimTreeSymlinkIcon NvimTreeNormal
<
Folder Icons: >
NvimTreeFolderIcon guifg=#8094b4 ctermfg=Blue
NvimTreeOpenedFolderIcon NvimTreeFolderIcon
NvimTreeClosedFolderIcon NvimTreeFolderIcon
NvimTreeFolderArrowClosed NvimTreeIndentMarker
NvimTreeFolderArrowOpen NvimTreeIndentMarker
<
Indent: >
NvimTreeIndentMarker NvimTreeFileIcon
<
Picker: >
NvimTreeWindowPicker guifg=#ededed guibg=#4493c8 gui=bold ctermfg=White ctermbg=Cyan
<
Live Filter: >
NvimTreeLiveFilterPrefix PreProc
NvimTreeLiveFilterValue ModeMsg
<
Clipboard: >
NvimTreeCopiedHL SpellRare
NvimTreeCutHL SpellBad
<
Bookmarks: >
NvimTreeBookmarkIcon NvimTreeFolderIcon
Bookmark Icon: >
NvimTreeBookmark
<
Bookmark Highlight: >
NvimTreeBookmarkHL SpellLocal
<
Modified: >
NvimTreeModifiedIcon Type
NvimTreeModifiedFileHL NvimTreeModifiedIcon
NvimTreeModifiedFolderHL NvimTreeModifiedIcon
Picker: >
NvimTreeWindowPicker
<
Opened: >
NvimTreeOpenedHL Special
Live Filter: >
NvimTreeLiveFilterPrefix
NvimTreeLiveFilterValue
<
Git Icon: >
NvimTreeGitDeletedIcon Statement
NvimTreeGitDirtyIcon Statement
NvimTreeGitIgnoredIcon Comment
NvimTreeGitMergeIcon Constant
NvimTreeGitNewIcon PreProc
NvimTreeGitRenamedIcon PreProc
NvimTreeGitStagedIcon Constant
NvimTreeGitDirty
NvimTreeGitStaged
NvimTreeGitMerge
NvimTreeGitRenamed
NvimTreeGitNew
NvimTreeGitDeleted
NvimTreeGitIgnored Comment
<
Git File File Highlight: >
NvimTreeGitFileDeletedHL NvimTreeGitDeletedIcon
NvimTreeGitFileDirtyHL NvimTreeGitDirtyIcon
NvimTreeGitFileIgnoredHL NvimTreeGitIgnoredIcon
NvimTreeGitFileMergeHL NvimTreeGitMergeIcon
NvimTreeGitFileNewHL NvimTreeGitNewIcon
NvimTreeGitFileRenamedHL NvimTreeGitRenamedIcon
NvimTreeGitFileStagedHL NvimTreeGitStagedIcon
Git File Text: >
NvimTreeFileDirty NvimTreeGitDirty
NvimTreeFileStaged NvimTreeGitStaged
NvimTreeFileMerge NvimTreeGitMerge
NvimTreeFileRenamed NvimTreeGitRenamed
NvimTreeFileNew NvimTreeGitNew
NvimTreeFileDeleted NvimTreeGitDeleted
NvimTreeFileIgnored NvimTreeGitIgnored
<
Git Folder Folder Highlight: >
NvimTreeGitFolderDeletedHL NvimTreeGitFileDeletedHL
NvimTreeGitFolderDirtyHL NvimTreeGitFileDirtyHL
NvimTreeGitFolderIgnoredHL NvimTreeGitFileIgnoredHL
NvimTreeGitFolderMergeHL NvimTreeGitFileMergeHL
NvimTreeGitFolderNewHL NvimTreeGitFileNewHL
NvimTreeGitFolderRenamedHL NvimTreeGitFileRenamedHL
NvimTreeGitFolderStagedHL NvimTreeGitFileStagedHL
Git Folder Text: >
NvimTreeFolderDirty NvimTreeFileDirty
NvimTreeFolderStaged NvimTreeFileStaged
NvimTreeFolderMerge NvimTreeFileMerge
NvimTreeFolderRenamed NvimTreeFileRenamed
NvimTreeFolderNew NvimTreeFileNew
NvimTreeFolderDeleted NvimTreeFileDeleted
NvimTreeFolderIgnored NvimTreeFileIgnored
<
Diagnostics Icon: >
NvimTreeDiagnosticErrorIcon DiagnosticError
NvimTreeDiagnosticWarnIcon DiagnosticWarn
NvimTreeDiagnosticInfoIcon DiagnosticInfo
NvimTreeDiagnosticHintIcon DiagnosticHint
NvimTreeLspDiagnosticsError DiagnosticError
NvimTreeLspDiagnosticsWarning DiagnosticWarn
NvimTreeLspDiagnosticsInformation DiagnosticInfo
NvimTreeLspDiagnosticsHint DiagnosticHint
<
Diagnostics File Highlight: >
NvimTreeDiagnosticErrorFileHL DiagnosticUnderlineError
NvimTreeDiagnosticWarnFileHL DiagnosticUnderlineWarn
NvimTreeDiagnosticInfoFileHL DiagnosticUnderlineInfo
NvimTreeDiagnosticHintFileHL DiagnosticUnderlineHint
Diagnostics File Text: >
NvimTreeLspDiagnosticsErrorText NvimTreeLspDiagnosticsError
NvimTreeLspDiagnosticsWarningText NvimTreeLspDiagnosticsWarning
NvimTreeLspDiagnosticsInfoText NvimTreeLspDiagnosticsInformation
NvimTreeLspDiagnosticsHintText NvimTreeLspDiagnosticsHint
<
Diagnostics Folder Highlight: >
NvimTreeDiagnosticErrorFolderHL NvimTreeDiagnosticErrorFileHL
NvimTreeDiagnosticWarnFolderHL NvimTreeDiagnosticWarnFileHL
NvimTreeDiagnosticInfoFolderHL NvimTreeDiagnosticInfoFileHL
NvimTreeDiagnosticHintFolderHL NvimTreeDiagnosticHintFileHL
<
==============================================================================
8.1 HIGHLIGHT OVERHAUL *nvim-tree-highlight-overhaul*
2024-01-20: significant highlighting changes, some breaking:
- Full cterm support.
- Standard vim highlight groups such |DiagnosticUnderlineError| are now the
defaults.
- Highlight groups named consistently.
- All `highlight_xxx` e.g. |nvim-tree.renderer.highlight_git| are granular,
allowing `"none"`, `"icon"`, `"name"` or `"all"`
- `highlight_xxx` has highlight groups for both File and Folder
- `highlight_xxx` is additive instead of overwriting. See
|nvim-tree-opts-renderer| for precedence.
2024-01-29: disambiguate default highlights sharing groups:
- NvimTreeRootFolder PreProc -> Title
- NvimTreeModified* Constant -> Type
- NvimTreeOpenedHL Constant -> Special
- NvimTreeBookmarkIcon Constant -> NvimTreeFolderIcon
- NvimTreeExecFile Constant -> SpellCap
- NvimTreeImageFile PreProc -> SpellCap
- NvimTreeSpecialFile PreProc -> SpellCap
- NvimTreeSymlink Statement -> SpellCap
Legacy highlight group are still obeyed when they are defined and the current
highlight group is not, hard linking as follows: >
NvimTreeModifiedIcon NvimTreeModifiedFile
NvimTreeOpenedHL NvimTreeOpenedFile
NvimTreeBookmarkIcon NvimTreeBookmark
NvimTreeGitDeletedIcon NvimTreeGitDeleted
NvimTreeGitDirtyIcon NvimTreeGitDirty
NvimTreeGitIgnoredIcon NvimTreeGitIgnored
NvimTreeGitMergeIcon NvimTreeGitMerge
NvimTreeGitNewIcon NvimTreeGitNew
NvimTreeGitRenamedIcon NvimTreeGitRenamed
NvimTreeGitStagedIcon NvimTreeGitStaged
NvimTreeGitFileDeletedHL NvimTreeFileDeleted
NvimTreeGitFileDirtyHL NvimTreeFileDirty
NvimTreeGitFileIgnoredHL NvimTreeFileIgnored
NvimTreeGitFileMergeHL NvimTreeFileMerge
NvimTreeGitFileNewHL NvimTreeFileNew
NvimTreeGitFileRenamedHL NvimTreeFileRenamed
NvimTreeGitFileStagedHL NvimTreeFileStaged
NvimTreeGitFolderDeletedHL NvimTreeFolderDeleted
NvimTreeGitFolderDirtyHL NvimTreeFolderDirty
NvimTreeGitFolderIgnoredHL NvimTreeFolderIgnored
NvimTreeGitFolderMergeHL NvimTreeFolderMerge
NvimTreeGitFolderNewHL NvimTreeFolderNew
NvimTreeGitFolderRenamedHL NvimTreeFolderRenamed
NvimTreeGitFolderStagedHL NvimTreeFolderStaged
NvimTreeLspDiagnosticsError NvimTreeDiagnosticErrorIcon
NvimTreeLspDiagnosticsWarning NvimTreeDiagnosticWarnIcon
NvimTreeLspDiagnosticsInformation NvimTreeDiagnosticInfoIcon
NvimTreeLspDiagnosticsHint NvimTreeDiagnosticHintIcon
NvimTreeLspDiagnosticsErrorText NvimTreeDiagnosticErrorFileHL
NvimTreeLspDiagnosticsWarningText NvimTreeDiagnosticWarnFileHL
NvimTreeLspDiagnosticsInformationText NvimTreeDiagnosticInfoFileHL
NvimTreeLspDiagnosticsHintText NvimTreeDiagnosticHintFileHL
NvimTreeLspDiagnosticsErrorFolderText NvimTreeDiagnosticErrorFolderHL
NvimTreeLspDiagnosticsWarningFolderText NvimTreeDiagnosticWarnFolderHL
NvimTreeLspDiagnosticsInformationFolderText NvimTreeDiagnosticInfoFolderHL
NvimTreeLspDiagnosticsHintFolderText NvimTreeDiagnosticHintFolderHL
Diagnostics Folder Text: >
NvimTreeLspDiagnosticsErrorFolderText NvimTreeLspDiagnosticsErrorText
NvimTreeLspDiagnosticsWarningFolderText NvimTreeLspDiagnosticsWarningText
NvimTreeLspDiagnosticsInfoFolderText NvimTreeLspDiagnosticsInfoText
NvimTreeLspDiagnosticsHintFolderText NvimTreeLspDiagnosticsHintText
<
==============================================================================
9. EVENTS *nvim-tree-events*
@@ -2604,32 +2421,7 @@ Example subscription: >
})
<
==============================================================================
10. PROMPTS *nvim-tree-prompts*
Some NvimTree actions use the builtin |vim.ui.select| prompt API for
confirmations when the |nvim_tree.select_prompts| option is set.
The API accepts the optional `kind` key as part of the {opts} parameter, which
can can be used to identify the type of prompt, to allow user side
configurations for different types of prompts.
- `nvimtree_overwrite_rename`
overwrite or rename during |nvim-tree-api.fs.paste()|
- `nvimtree_remove`
delete during |nvim-tree-api.fs.remove()|
- `nvimtree_trash`
send to trash during |nvim-tree-api.fs.trash()|
- `nvimtree_bulk_delete`
delete all bookmarked during |nvim-tree-api.marks.bulk.delete()|
- `nvimtree_bulk_trash`
send all bookmarked to trash during |nvim-tree-api.marks.bulk.trash()|
==============================================================================
11. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific*
10. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific*
macOS
- Rename to different case is not possible when using a case insensitive file
@@ -2642,7 +2434,7 @@ Windows WSL and PowerShell
- Some filesystem watcher error related to permissions will not be reported
==============================================================================
12. NETRW *nvim-tree-netrw*
11. NETRW *nvim-tree-netrw*
|netrw| is a standard neovim plugin that is enabled by default. It provides,
amongst other functionality, a file/directory browser.

View File

@@ -1,16 +1,18 @@
local lib = require "nvim-tree.lib"
local log = require "nvim-tree.log"
local appearance = require "nvim-tree.appearance"
local colors = require "nvim-tree.colors"
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 change_dir = require "nvim-tree.actions.root.change-dir"
local legacy = require "nvim-tree.legacy"
local core = require "nvim-tree.core"
local reloaders = require "nvim-tree.actions.reloaders.reloaders"
local git = require "nvim-tree.git"
local filters = require "nvim-tree.explorer.filters"
local buffers = require "nvim-tree.buffers"
local modified = require "nvim-tree.modified"
local find_file = require "nvim-tree.actions.tree.find-file"
local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify"
@@ -49,7 +51,7 @@ function M.change_root(path, bufnr)
-- test if in vim_cwd
if utils.path_relative(path, vim_cwd) ~= path then
if vim_cwd ~= cwd then
actions.root.change_dir.fn(vim_cwd)
change_dir.fn(vim_cwd)
end
return
end
@@ -60,19 +62,43 @@ function M.change_root(path, bufnr)
-- otherwise test M.init_root
if _config.prefer_startup_root and utils.path_relative(path, M.init_root) ~= path then
actions.root.change_dir.fn(M.init_root)
change_dir.fn(M.init_root)
return
end
-- otherwise root_dirs
for _, dir in pairs(_config.root_dirs) do
dir = vim.fn.fnamemodify(dir, ":p")
if utils.path_relative(path, dir) ~= path then
actions.root.change_dir.fn(dir)
change_dir.fn(dir)
return
end
end
-- finally fall back to the folder containing the file
actions.root.change_dir.fn(vim.fn.fnamemodify(path, ":p:h"))
change_dir.fn(vim.fn.fnamemodify(path, ":p:h"))
end
---@param cwd string|nil
function M.open_replacing_current_buffer(cwd)
if view.is_visible() then
return
end
local buf = vim.api.nvim_get_current_buf()
local bufname = vim.api.nvim_buf_get_name(buf)
if bufname == "" or vim.loop.fs_stat(bufname) == nil then
return
end
if cwd == "" or cwd == nil then
cwd = vim.fn.fnamemodify(bufname, ":p:h")
end
if not core.get_explorer() or cwd ~= core.get_cwd() then
core.init(cwd)
end
view.open_in_win { hijack_current_buf = false, resize = false }
require("nvim-tree.renderer").draw()
require("nvim-tree.actions.finders.find-file").fn(bufname)
end
function M.tab_enter()
@@ -85,7 +111,7 @@ function M.tab_enter()
end
end
view.open { focus_tree = false }
renderer.draw()
require("nvim-tree.renderer").draw()
end
end
@@ -101,20 +127,27 @@ function M.open_on_directory()
return
end
actions.root.change_dir.force_dirchange(bufname, true)
change_dir.force_dirchange(bufname, true)
end
function M.reset_highlight()
colors.setup()
view.reset_winhl()
renderer.render_hl(view.get_bufnr())
end
local prev_line
function M.place_cursor_on_node()
local search = vim.fn.searchcount()
if search and search.exact_match == 1 then
local l = vim.api.nvim_win_get_cursor(0)[1]
if l == prev_line then
return
end
prev_line = l
local node = lib.get_node_at_cursor()
if not node or node.name == ".." then
return
end
node = utils.get_parent_of_group(node)
local line = vim.api.nvim_get_current_line()
local cursor = vim.api.nvim_win_get_cursor(0)
@@ -146,11 +179,11 @@ end
---@param name string|nil
function M.change_dir(name)
if name then
actions.root.change_dir.fn(name)
change_dir.fn(name)
end
if _config.update_focused_file.enable then
actions.tree.find_file.fn()
find_file.fn()
end
end
@@ -162,14 +195,8 @@ local function setup_autocommands(opts)
vim.api.nvim_create_autocmd(name, vim.tbl_extend("force", default_opts, custom_opts))
end
-- reset and draw (highlights) when colorscheme is changed
create_nvim_tree_autocmd("ColorScheme", {
callback = function()
appearance.setup()
view.reset_winhl()
renderer.draw()
end,
})
-- reset highlights when colorscheme is changed
create_nvim_tree_autocmd("ColorScheme", { callback = M.reset_highlight })
-- prevent new opened file from opening in the same window as nvim-tree
create_nvim_tree_autocmd("BufWipeout", {
@@ -189,7 +216,7 @@ 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()
reloaders.reload_explorer()
end
end,
})
@@ -199,7 +226,7 @@ local function setup_autocommands(opts)
-- update opened file buffers
if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
actions.reloaders.reload_explorer()
reloaders.reload_explorer()
end)
end
end,
@@ -210,7 +237,7 @@ local function setup_autocommands(opts)
-- update opened file buffers
if (filters.config.filter_no_buffer or renderer.config.highlight_opened_files ~= "none") and vim.bo[data.buf].buftype == "" then
utils.debounce("Buf:filter_buffer", opts.view.debounce_delay, function()
actions.reloaders.reload_explorer()
reloaders.reload_explorer(nil, data.buf)
end)
end
end,
@@ -220,7 +247,7 @@ 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()
reloaders.reload_git()
end
end,
})
@@ -249,7 +276,7 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd("BufEnter", {
callback = function()
utils.debounce("BufEnter:find_file", opts.view.debounce_delay, function()
actions.tree.find_file.fn()
find_file.fn()
end)
end,
})
@@ -264,7 +291,7 @@ 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()
reloaders.reload_explorer()
end
end
end,
@@ -314,8 +341,8 @@ 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()
modified.reload()
reloaders.reload_explorer()
end)
end,
})
@@ -386,8 +413,8 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
indent_width = 2,
special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
symlink_destination = true,
highlight_git = "none",
highlight_diagnostics = "none",
highlight_git = false,
highlight_diagnostics = false,
highlight_opened_files = "none",
highlight_modified = "none",
highlight_bookmarks = "none",
@@ -503,7 +530,6 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
dotfiles = false,
git_clean = false,
no_buffer = false,
no_bookmark = false,
custom = {},
exclude = {},
},
@@ -641,11 +667,9 @@ local ACCEPTED_STRINGS = {
signcolumn = { "yes", "no", "auto" },
},
renderer = {
highlight_git = { "none", "icon", "name", "all" },
highlight_opened_files = { "none", "icon", "name", "all" },
highlight_modified = { "none", "icon", "name", "all" },
highlight_bookmarks = { "none", "icon", "name", "all" },
highlight_diagnostics = { "none", "icon", "name", "all" },
highlight_clipboard = { "none", "icon", "name", "all" },
icons = {
git_placement = { "before", "after", "signcolumn" },
@@ -788,7 +812,7 @@ function M.setup(conf)
require("nvim-tree.actions").setup(opts)
require("nvim-tree.keymap").setup(opts)
require("nvim-tree.appearance").setup()
require("nvim-tree.colors").setup()
require("nvim-tree.diagnostics").setup(opts)
require("nvim-tree.explorer").setup(opts)
require("nvim-tree.git").setup(opts)
@@ -798,7 +822,7 @@ function M.setup(conf)
require("nvim-tree.renderer").setup(opts)
require("nvim-tree.live-filter").setup(opts)
require("nvim-tree.marks").setup(opts)
require("nvim-tree.buffers").setup(opts)
require("nvim-tree.modified").setup(opts)
require("nvim-tree.help").setup(opts)
require("nvim-tree.watcher").setup(opts)
if M.config.renderer.icons.show.file and pcall(require, "nvim-web-devicons") then

View File

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

View File

@@ -5,7 +5,9 @@ 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 reloaders = require "nvim-tree.actions.reloaders.reloaders"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local find_file = require("nvim-tree.actions.finders.find-file").fn
@@ -129,7 +131,7 @@ local function do_single_paste(source, dest, action_type, action_fn)
else
local prompt_select = "Overwrite " .. dest .. " ?"
local prompt_input = prompt_select .. " R(ename)/y/n: "
lib.prompt(prompt_input, prompt_select, { "", "y", "n" }, { "Rename", "Yes", "No" }, "nvimtree_overwrite_rename", function(item_short)
lib.prompt(prompt_input, prompt_select, { "", "y", "n" }, { "Rename", "Yes", "No" }, function(item_short)
utils.clear_prompt()
if item_short == "y" then
on_process()
@@ -315,23 +317,34 @@ function M.copy_absolute_path(node)
copy_to_clipboard(content)
end
---Node is cut. Will not be copied.
--- Clipboard text highlight group and position when highlight_clipboard.
---@param node Node
---@return boolean
function M.is_cut(node)
return vim.tbl_contains(clipboard.cut, node)
---@return HL_POSITION position none when clipboard empty
---@return string|nil group only when node present in clipboard
function M.get_highlight(node)
if M.hl_pos == HL_POSITION.none then
return HL_POSITION.none, nil
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)
for _, n in ipairs(clipboard.cut) do
if node == n then
return M.hl_pos, "NvimTreeCutHL"
end
end
for _, n in ipairs(clipboard.copy) do
if node == n then
return M.hl_pos, "NvimTreeCopiedHL"
end
end
return HL_POSITION.none, nil
end
function M.setup(opts)
M.config.filesystem_watchers = opts.filesystem_watchers
M.config.actions = opts.actions
M.hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none
end
return M

View File

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

View File

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

View File

@@ -102,7 +102,7 @@ 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()
require("nvim-tree.actions.reloaders.reloaders").reload_explorer()
end
find_file(utils.path_remove_trailing(new_file_path))

View File

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

View File

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

View File

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

View File

@@ -3,36 +3,14 @@ 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
---Return the status of the node or nil if no status, depending on the type of
---status.
---@param node table node to inspect
---@param what string type of status
---@param skip_gitignored boolean default false
---@return boolean
local function status_is_valid(node, what, skip_gitignored)
if what == "git" then
local git_status = explorer_node.get_git_status(node)
return git_status ~= nil and (not skip_gitignored or git_status[1] ~= "!!")
elseif what == "diag" then
local diag_status = diagnostics.get_diag_status(node)
return diag_status ~= nil and diag_status.value ~= nil
elseif what == "opened" then
return vim.fn.bufloaded(node.absolute_path) ~= 0
end
return false
end
---Move to the next node that has a valid status. If none found, don't move.
---@param where string where to move (forwards or backwards)
---@param what string type of status
---@param skip_gitignored boolean default false
local function move(where, what, skip_gitignored)
---@param where string
---@param what string
---@return fun()
function M.fn(where, what)
return function()
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)
@@ -46,7 +24,15 @@ local function move(where, what, skip_gitignored)
for line = iter_start, iter_end, iter_step do
local node = nodes_by_line[line]
local valid = status_is_valid(node, what, skip_gitignored)
local valid = false
if what == "git" then
valid = explorer_node.get_git_status(node) ~= nil
elseif what == "diag" then
valid = node.diag_status ~= nil
elseif what == "opened" then
valid = vim.fn.bufloaded(node.absolute_path) ~= 0
end
if not first and valid then
first = line
@@ -66,173 +52,6 @@ local function move(where, what, skip_gitignored)
view.set_cursor { first, 0 }
end
end
local function expand_node(node)
if not node.open then
-- Expand the node.
-- Should never collapse since we checked open.
lib.expand_or_collapse(node)
end
end
--- Move to the next node recursively.
---@param what string type of status
---@param skip_gitignored boolean default false
local function move_next_recursive(what, skip_gitignored)
-- If the current node:
-- * is a directory
-- * and is not the root node
-- * and has a git/diag status
-- * and is not opened
-- expand it.
local node_init = lib.get_node_at_cursor()
if not node_init then
return
end
local valid = false
if node_init.name ~= ".." then -- root node cannot have a status
valid = status_is_valid(node_init, what, skip_gitignored)
end
if node_init.nodes ~= nil and valid and not node_init.open then
lib.expand_or_collapse(node_init)
end
move("next", what, skip_gitignored)
local node_cur = lib.get_node_at_cursor()
if not node_cur then
return
end
-- If we haven't moved at all at this point, return.
if node_init == node_cur then
return
end
-- i is used to limit iterations.
local i = 0
local is_dir = node_cur.nodes ~= nil
while is_dir and i < MAX_DEPTH do
expand_node(node_cur)
move("next", what, skip_gitignored)
-- Save current node.
node_cur = lib.get_node_at_cursor()
-- Update is_dir.
if node_cur then
is_dir = node_cur.nodes ~= nil
else
is_dir = false
end
i = i + 1
end
end
--- Move to the previous node recursively.
---
--- move_prev_recursive:
---
--- 1) Save current as node_init.
-- 2) Call a non-recursive prev.
--- 3) If current node is node_init's parent, call move_prev_recursive.
--- 4) Else:
--- 4.1) If current node is nil, is node_init (we didn't move), or is a file, return.
--- 4.2) The current file is a directory, expand it.
--- 4.3) Find node_init in current window, and move to it (if not found, return).
--- If node_init is the root node (name = ".."), directly move to position 1.
--- 4.4) Call a non-recursive prev.
--- 4.5) Save the current node and start back from 4.1.
---
---@param what string type of status
---@param skip_gitignored boolean default false
local function move_prev_recursive(what, skip_gitignored)
local node_init, node_cur
-- 1)
node_init = lib.get_node_at_cursor()
if node_init == nil then
return
end
-- 2)
move("prev", what, skip_gitignored)
node_cur = lib.get_node_at_cursor()
if node_cur == node_init.parent then
-- 3)
move_prev_recursive(what, skip_gitignored)
else
-- i is used to limit iterations.
local i = 0
while i < MAX_DEPTH do
-- 4.1)
if
node_cur == nil
or node_cur == node_init -- we didn't move
or not node_cur.nodes -- node is a file
then
return
end
-- 4.2)
local node_dir = node_cur
expand_node(node_dir)
-- 4.3)
if node_init.name == ".." then -- root node
view.set_cursor { 1, 0 } -- move to root node (position 1)
else
local node_init_line = utils.find_node_line(node_init)
if node_init_line < 0 then
return
end
view.set_cursor { node_init_line, 0 }
end
-- 4.4)
move("prev", what, skip_gitignored)
-- 4.5)
node_cur = lib.get_node_at_cursor()
i = i + 1
end
end
end
---@class NavigationItemOpts
---@field where string
---@field what string
---@param opts NavigationItemOpts
---@return fun()
function M.fn(opts)
return function()
local recurse = false
local skip_gitignored = false
-- recurse only valid for git and diag moves.
if (opts.what == "git" or opts.what == "diag") and opts.recurse ~= nil then
recurse = opts.recurse
end
if opts.skip_gitignored ~= nil then
skip_gitignored = opts.skip_gitignored
end
if not recurse then
move(opts.where, opts.what, skip_gitignored)
return
end
if opts.where == "next" then
move_next_recursive(opts.what, skip_gitignored)
elseif opts.where == "prev" then
move_prev_recursive(opts.what, skip_gitignored)
end
end
end
return M

View File

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

View File

@@ -10,12 +10,13 @@ local M = {}
---@param node Explorer|nil
---@param projects table
local function refresh_nodes(node, projects)
---@param unloaded_bufnr number|nil
local function refresh_nodes(node, projects, unloaded_bufnr)
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 {})
explorer_module.reload(n, projects[toplevel] or {}, unloaded_bufnr)
end
end)
:recursor(function(n)
@@ -42,16 +43,18 @@ function M.reload_node_status(parent_node, projects)
end
local event_running = false
function M.reload_explorer()
---@param _ table|nil unused node passed by action
---@param unloaded_bufnr number|nil optional bufnr recently unloaded via BufUnload event
function M.reload_explorer(_, unloaded_bufnr)
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)
refresh_nodes(core.get_explorer(), projects, unloaded_bufnr)
if view.is_visible() then
renderer.draw()
renderer.draw(unloaded_bufnr)
end
event_running = false
end

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,17 +1,3 @@
local lib = require "nvim-tree.lib"
local view = require "nvim-tree.view"
local utils = require "nvim-tree.utils"
local actions = require "nvim-tree.actions"
local appearance_diagnostics = require "nvim-tree.appearance.diagnostics"
local events = require "nvim-tree.events"
local help = require "nvim-tree.help"
local live_filter = require "nvim-tree.live-filter"
local marks = require "nvim-tree.marks"
local marks_navigation = require "nvim-tree.marks.navigation"
local marks_bulk_delete = require "nvim-tree.marks.bulk-delete"
local marks_bulk_trash = require "nvim-tree.marks.bulk-trash"
local marks_bulk_move = require "nvim-tree.marks.bulk-move"
local keymap = require "nvim-tree.keymap"
local notify = require "nvim-tree.notify"
local Api = {
@@ -40,7 +26,6 @@ local Api = {
mappings = {},
},
commands = {},
diagnostics = {},
}
--- Do nothing when setup not called.
@@ -60,7 +45,7 @@ end
---@param fn function function to invoke
local function wrap_node(fn)
return function(node, ...)
node = node or lib.get_node_at_cursor()
node = node or require("nvim-tree.lib").get_node_at_cursor()
if node then
fn(node, ...)
end
@@ -71,7 +56,7 @@ end
---@param fn function function to invoke
local function wrap_node_or_nil(fn)
return function(node, ...)
node = node or lib.get_node_at_cursor()
node = node or require("nvim-tree.lib").get_node_at_cursor()
fn(node, ...)
end
end
@@ -83,8 +68,7 @@ end
---@field find_file boolean|nil default false
---@field update_root boolean|nil default false
Api.tree.open = wrap(actions.tree.open.fn)
Api.tree.focus = Api.tree.open
Api.tree.open = wrap(require("nvim-tree.actions.tree.open").fn)
---@class ApiTreeToggleOpts
---@field path string|nil
@@ -94,11 +78,19 @@ Api.tree.focus = Api.tree.open
---@field update_root boolean|nil default false
---@field focus boolean|nil default true
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.toggle = wrap(require("nvim-tree.actions.tree.toggle").fn)
Api.tree.close = wrap(require("nvim-tree.view").close)
Api.tree.close_in_this_tab = wrap(require("nvim-tree.view").close_this_tab_only)
Api.tree.close_in_all_tabs = wrap(require("nvim-tree.view").close_all_tabs)
Api.tree.focus = wrap(function()
Api.tree.open()
end)
Api.tree.reload = wrap(require("nvim-tree.actions.reloaders.reloaders").reload_explorer)
Api.tree.change_root = wrap(function(...)
require("nvim-tree").change_dir(...)
@@ -106,15 +98,17 @@ end)
Api.tree.change_root_to_node = wrap_node(function(node)
if node.name == ".." then
actions.root.change_dir.fn ".."
require("nvim-tree.actions.root.change-dir").fn ".."
elseif node.nodes ~= nil then
actions.root.change_dir.fn(lib.get_last_group_node(node).absolute_path)
require("nvim-tree.actions.root.change-dir").fn(require("nvim-tree.lib").get_last_group_node(node).absolute_path)
end
end)
Api.tree.change_root_to_parent = wrap_node(actions.root.dir_up.fn)
Api.tree.get_node_under_cursor = wrap(lib.get_node_at_cursor)
Api.tree.get_nodes = wrap(lib.get_nodes)
Api.tree.change_root_to_parent = wrap_node(require("nvim-tree.actions.root.dir-up").fn)
Api.tree.get_node_under_cursor = wrap(require("nvim-tree.lib").get_node_at_cursor)
Api.tree.get_nodes = wrap(require("nvim-tree.lib").get_nodes)
---@class ApiTreeFindFileOpts
---@field buf string|number|nil
@@ -124,46 +118,55 @@ Api.tree.get_nodes = wrap(lib.get_nodes)
---@field update_root boolean|nil default false
---@field focus boolean|nil default false
Api.tree.find_file = wrap(actions.tree.find_file.fn)
Api.tree.search_node = wrap(actions.finders.search_node.fn)
Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse_all.fn)
Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand_all.fn)
Api.tree.toggle_gitignore_filter = wrap(actions.tree.modifiers.toggles.git_ignored)
Api.tree.toggle_git_clean_filter = wrap(actions.tree.modifiers.toggles.git_clean)
Api.tree.toggle_no_buffer_filter = wrap(actions.tree.modifiers.toggles.no_buffer)
Api.tree.toggle_custom_filter = wrap(actions.tree.modifiers.toggles.custom)
Api.tree.toggle_hidden_filter = wrap(actions.tree.modifiers.toggles.dotfiles)
Api.tree.toggle_no_bookmark_filter = wrap(actions.tree.modifiers.toggles.no_bookmark)
Api.tree.toggle_help = wrap(help.toggle)
Api.tree.is_tree_buf = wrap(utils.is_nvim_tree_buf)
Api.tree.find_file = wrap(require("nvim-tree.actions.tree.find-file").fn)
Api.tree.search_node = wrap(require("nvim-tree.actions.finders.search-node").fn)
Api.tree.collapse_all = wrap(require("nvim-tree.actions.tree-modifiers.collapse-all").fn)
Api.tree.expand_all = wrap_node(require("nvim-tree.actions.tree-modifiers.expand-all").fn)
Api.tree.toggle_gitignore_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").git_ignored)
Api.tree.toggle_git_clean_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").git_clean)
Api.tree.toggle_no_buffer_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").no_buffer)
Api.tree.toggle_custom_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").custom)
Api.tree.toggle_hidden_filter = wrap(require("nvim-tree.actions.tree-modifiers.toggles").dotfiles)
Api.tree.toggle_help = wrap(require("nvim-tree.help").toggle)
Api.tree.is_tree_buf = wrap(require("nvim-tree.utils").is_nvim_tree_buf)
---@class ApiTreeIsVisibleOpts
---@field tabpage number|nil
---@field any_tabpage boolean|nil default false
Api.tree.is_visible = wrap(view.is_visible)
Api.tree.is_visible = wrap(require("nvim-tree.view").is_visible)
---@class ApiTreeWinIdOpts
---@field tabpage number|nil default nil
Api.tree.winid = wrap(view.winid)
Api.tree.winid = wrap(require("nvim-tree.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.relative_path = wrap_node(actions.fs.copy_paste.copy_path)
Api.fs.create = wrap_node_or_nil(require("nvim-tree.actions.fs.create-file").fn)
Api.fs.remove = wrap_node(require("nvim-tree.actions.fs.remove-file").fn)
Api.fs.trash = wrap_node(require("nvim-tree.actions.fs.trash").fn)
Api.fs.rename_node = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t")
Api.fs.rename = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t")
Api.fs.rename_sub = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":p:h")
Api.fs.rename_basename = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":t:r")
Api.fs.rename_full = wrap_node(require("nvim-tree.actions.fs.rename-file").fn ":p")
Api.fs.cut = wrap_node(require("nvim-tree.actions.fs.copy-paste").cut)
Api.fs.paste = wrap_node(require("nvim-tree.actions.fs.copy-paste").paste)
Api.fs.clear_clipboard = wrap(require("nvim-tree.actions.fs.copy-paste").clear_clipboard)
Api.fs.print_clipboard = wrap(require("nvim-tree.actions.fs.copy-paste").print_clipboard)
Api.fs.copy.node = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy)
Api.fs.copy.absolute_path = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_absolute_path)
Api.fs.copy.filename = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_filename)
Api.fs.copy.relative_path = wrap_node(require("nvim-tree.actions.fs.copy-paste").copy_path)
---@param mode string
---@param node table
@@ -172,18 +175,18 @@ local function edit(mode, node)
if node.link_to and not node.nodes then
path = node.link_to
end
actions.node.open_file.fn(mode, path)
require("nvim-tree.actions.node.open-file").fn(mode, path)
end
---@param mode string
---@return fun(node: table)
local function open_or_expand_or_dir_up(mode, toggle_group)
local function open_or_expand_or_dir_up(mode)
return function(node)
if node.name == ".." then
actions.root.change_dir.fn ".."
require("nvim-tree.actions.root.change-dir").fn ".."
elseif node.nodes then
lib.expand_or_collapse(node, toggle_group)
elseif not toggle_group then
require("nvim-tree.lib").expand_or_collapse(node)
else
edit(mode, node)
end
end
@@ -197,57 +200,53 @@ Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up "edit_no_pic
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.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.show_info_popup = wrap_node(require("nvim-tree.actions.node.file-popup").toggle_file_info)
Api.node.run.cmd = wrap_node(require("nvim-tree.actions.node.run-command").run_file_command)
Api.node.run.system = wrap_node(require("nvim-tree.actions.node.system-open").fn)
Api.node.navigate.sibling.next = wrap_node(require("nvim-tree.actions.moves.sibling").fn "next")
Api.node.navigate.sibling.prev = wrap_node(require("nvim-tree.actions.moves.sibling").fn "prev")
Api.node.navigate.sibling.first = wrap_node(require("nvim-tree.actions.moves.sibling").fn "first")
Api.node.navigate.sibling.last = wrap_node(require("nvim-tree.actions.moves.sibling").fn "last")
Api.node.navigate.parent = wrap_node(require("nvim-tree.actions.moves.parent").fn(false))
Api.node.navigate.parent_close = wrap_node(require("nvim-tree.actions.moves.parent").fn(true))
Api.node.navigate.git.next = wrap_node(require("nvim-tree.actions.moves.item").fn("next", "git"))
Api.node.navigate.git.prev = wrap_node(require("nvim-tree.actions.moves.item").fn("prev", "git"))
Api.node.navigate.diagnostics.next = wrap_node(require("nvim-tree.actions.moves.item").fn("next", "diag"))
Api.node.navigate.diagnostics.prev = wrap_node(require("nvim-tree.actions.moves.item").fn("prev", "diag"))
Api.node.navigate.opened.next = wrap_node(require("nvim-tree.actions.moves.item").fn("next", "opened"))
Api.node.navigate.opened.prev = wrap_node(require("nvim-tree.actions.moves.item").fn("prev", "opened"))
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.git.reload = wrap(require("nvim-tree.actions.reloaders.reloaders").reload_git)
Api.git.reload = wrap(actions.reloaders.reload_git)
Api.events.subscribe = require("nvim-tree.events").subscribe
Api.events.Event = require("nvim-tree.events").Event
Api.events.subscribe = events.subscribe
Api.events.Event = events.Event
Api.live_filter.start = wrap(require("nvim-tree.live-filter").start_filtering)
Api.live_filter.clear = wrap(require("nvim-tree.live-filter").clear_filter)
Api.live_filter.start = wrap(live_filter.start_filtering)
Api.live_filter.clear = wrap(live_filter.clear_filter)
Api.marks.get = wrap_node(require("nvim-tree.marks").get_mark)
Api.marks.list = wrap(require("nvim-tree.marks").get_marks)
Api.marks.toggle = wrap_node(require("nvim-tree.marks").toggle_mark)
Api.marks.clear = wrap(require("nvim-tree.marks").clear_marks)
Api.marks.bulk.delete = wrap(require("nvim-tree.marks.bulk-delete").bulk_delete)
Api.marks.bulk.trash = wrap(require("nvim-tree.marks.bulk-trash").bulk_trash)
Api.marks.bulk.move = wrap(require("nvim-tree.marks.bulk-move").bulk_move)
Api.marks.navigate.next = wrap(require("nvim-tree.marks.navigation").next)
Api.marks.navigate.prev = wrap(require("nvim-tree.marks.navigation").prev)
Api.marks.navigate.select = wrap(require("nvim-tree.marks.navigation").select)
Api.marks.get = wrap_node(marks.get_mark)
Api.marks.list = wrap(marks.get_marks)
Api.marks.toggle = wrap_node(marks.toggle_mark)
Api.marks.clear = wrap(marks.clear_marks)
Api.marks.bulk.delete = wrap(marks_bulk_delete.bulk_delete)
Api.marks.bulk.trash = wrap(marks_bulk_trash.bulk_trash)
Api.marks.bulk.move = wrap(marks_bulk_move.bulk_move)
Api.marks.navigate.next = wrap(marks_navigation.next)
Api.marks.navigate.prev = wrap(marks_navigation.prev)
Api.marks.navigate.select = wrap(marks_navigation.select)
Api.config.mappings.default_on_attach = require("nvim-tree.keymap").default_on_attach
Api.config.mappings.get_keymap = wrap(keymap.get_keymap)
Api.config.mappings.get_keymap_default = wrap(keymap.get_keymap_default)
Api.config.mappings.default_on_attach = keymap.default_on_attach
Api.config.mappings.get_keymap = wrap(function()
return require("nvim-tree.keymap").get_keymap()
end)
Api.diagnostics.hi_test = wrap(appearance_diagnostics.hi_test)
Api.config.mappings.get_keymap_default = wrap(function()
return require("nvim-tree.keymap").get_keymap_default()
end)
Api.commands.get = wrap(function()
return require("nvim-tree.commands").get()

View File

@@ -1,80 +0,0 @@
local appearance = require "nvim-tree.appearance"
local M = {}
---@class HighlightDisplay for :NvimTreeHiTest
---@field group string nvim-tree highlight group name
---@field links string link chain to a concretely defined group
---@field def string :hi concrete definition after following any links
local HighlightDisplay = {}
---@param group string nvim-tree highlight group
---@return HighlightDisplay
function HighlightDisplay:new(group)
local o = {}
setmetatable(o, self)
self.__index = self
o.group = group
local concrete = o.group
-- maybe follow links
local links = {}
local link = vim.api.nvim_get_hl(0, { name = o.group }).link
while link do
table.insert(links, link)
concrete = link
link = vim.api.nvim_get_hl(0, { name = link }).link
end
o.links = table.concat(links, " ")
-- concrete definition
local ok, res = pcall(vim.api.nvim_cmd, { cmd = "highlight", args = { concrete } }, { output = true })
if ok and type(res) == "string" then
o.def = res:gsub(".*xxx *", "")
else
o.def = ""
end
return o
end
function HighlightDisplay:render(bufnr, fmt, l)
local text = string.format(fmt, self.group, self.links, self.def)
vim.api.nvim_buf_set_lines(bufnr, l, -1, true, { text })
vim.api.nvim_buf_add_highlight(bufnr, -1, self.group, l, 0, #self.group)
end
---Run a test similar to :so $VIMRUNTIME/syntax/hitest.vim
---Display all nvim-tree highlight groups, their link chain and actual definition
function M.hi_test()
local displays = {}
local max_group_len = 0
local max_links_len = 0
-- build all highlight groups, name only
for _, highlight_group in ipairs(appearance.HIGHLIGHT_GROUPS) do
local display = HighlightDisplay:new(highlight_group.group)
table.insert(displays, display)
max_group_len = math.max(max_group_len, #display.group)
max_links_len = math.max(max_links_len, #display.links)
end
-- create a buffer
local bufnr = vim.api.nvim_create_buf(false, true)
-- render and highlight
local l = 0
local fmt = string.format("%%-%d.%ds %%-%d.%ds %%s", max_group_len, max_group_len, max_links_len, max_links_len)
for _, display in ipairs(displays) do
display:render(bufnr, fmt, l)
l = l + 1
end
-- finalise and focus the buffer
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.cmd.buffer(bufnr)
end
return M

View File

@@ -1,202 +0,0 @@
local M = {}
-- All highlight groups: linked or directly defined.
-- Please add new groups to help and preserve order.
-- Please avoid directly defined groups to preserve accessibility for TUI.
M.HIGHLIGHT_GROUPS = {
-- Standard
{ group = "NvimTreeNormal", link = "Normal" },
{ group = "NvimTreeNormalFloat", link = "NormalFloat" },
{ 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 = "NvimTreeCursorColumn", link = "CursorColumn" },
{ group = "NvimTreeCursorLine", link = "CursorLine" },
{ group = "NvimTreeCursorLineNr", link = "CursorLineNr" },
{ group = "NvimTreeStatusLine", link = "StatusLine" },
{ group = "NvimTreeStatusLineNC", link = "StatusLineNC" },
-- File Text
{ group = "NvimTreeExecFile", link = "SpellCap" },
{ group = "NvimTreeImageFile", link = "SpellCap" },
{ group = "NvimTreeSpecialFile", link = "SpellCap" },
{ group = "NvimTreeSymlink", link = "SpellCap" },
-- Folder Text
{ 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" },
-- 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" },
-- Indent
{ group = "NvimTreeIndentMarker", link = "NvimTreeFolderIcon" },
-- Picker
{ group = "NvimTreeWindowPicker", def = "guifg=#ededed guibg=#4493c8 gui=bold ctermfg=White ctermbg=Cyan" },
-- LiveFilter
{ group = "NvimTreeLiveFilterPrefix", link = "PreProc" },
{ group = "NvimTreeLiveFilterValue", link = "ModeMsg" },
-- Clipboard
{ group = "NvimTreeCutHL", link = "SpellBad" },
{ group = "NvimTreeCopiedHL", link = "SpellRare" },
-- Bookmark
{ group = "NvimTreeBookmarkIcon", link = "NvimTreeFolderIcon" },
{ group = "NvimTreeBookmarkHL", link = "SpellLocal" },
-- Modified
{ group = "NvimTreeModifiedIcon", link = "Type" },
{ group = "NvimTreeModifiedFileHL", link = "NvimTreeModifiedIcon" },
{ group = "NvimTreeModifiedFolderHL", link = "NvimTreeModifiedFileHL" },
-- Opened
{ 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" },
-- 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" },
-- 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" },
-- Diagnostics Icon
{ 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" },
-- Diagnostics Folder Highlight
{ group = "NvimTreeDiagnosticErrorFolderHL", link = "NvimTreeDiagnosticErrorFileHL" },
{ group = "NvimTreeDiagnosticWarnFolderHL", link = "NvimTreeDiagnosticWarnFileHL" },
{ group = "NvimTreeDiagnosticInfoFolderHL", link = "NvimTreeDiagnosticInfoFileHL" },
{ group = "NvimTreeDiagnosticHintFolderHL", link = "NvimTreeDiagnosticHintFileHL" },
}
-- nvim-tree highlight groups to legacy
M.LEGACY_LINKS = {
NvimTreeModifiedIcon = "NvimTreeModifiedFile",
NvimTreeOpenedHL = "NvimTreeOpenedFile",
NvimTreeBookmarkIcon = "NvimTreeBookmark",
NvimTreeGitDeletedIcon = "NvimTreeGitDeleted",
NvimTreeGitDirtyIcon = "NvimTreeGitDirty",
NvimTreeGitIgnoredIcon = "NvimTreeGitIgnored",
NvimTreeGitMergeIcon = "NvimTreeGitMerge",
NvimTreeGitNewIcon = "NvimTreeGitNew",
NvimTreeGitRenamedIcon = "NvimTreeGitRenamed",
NvimTreeGitStagedIcon = "NvimTreeGitStaged",
NvimTreeGitFileDeletedHL = "NvimTreeFileDeleted",
NvimTreeGitFileDirtyHL = "NvimTreeFileDirty",
NvimTreeGitFileIgnoredHL = "NvimTreeFileIgnored",
NvimTreeGitFileMergeHL = "NvimTreeFileMerge",
NvimTreeGitFileNewHL = "NvimTreeFileNew",
NvimTreeGitFileRenamedHL = "NvimTreeFileRenamed",
NvimTreeGitFileStagedHL = "NvimTreeFileStaged",
NvimTreeGitFolderDeletedHL = "NvimTreeFolderDeleted",
NvimTreeGitFolderDirtyHL = "NvimTreeFolderDirty",
NvimTreeGitFolderIgnoredHL = "NvimTreeFolderIgnored",
NvimTreeGitFolderMergeHL = "NvimTreeFolderMerge",
NvimTreeGitFolderNewHL = "NvimTreeFolderNew",
NvimTreeGitFolderRenamedHL = "NvimTreeFolderRenamed",
NvimTreeGitFolderStagedHL = "NvimTreeFolderStaged",
NvimTreeDiagnosticErrorIcon = "NvimTreeLspDiagnosticsError",
NvimTreeDiagnosticWarnIcon = "NvimTreeLspDiagnosticsWarning",
NvimTreeDiagnosticInfoIcon = "NvimTreeLspDiagnosticsInformation",
NvimTreeDiagnosticHintIcon = "NvimTreeLspDiagnosticsHint",
NvimTreeDiagnosticErrorFileHL = "NvimTreeLspDiagnosticsErrorText",
NvimTreeDiagnosticWarnFileHL = "NvimTreeLspDiagnosticsWarningText",
NvimTreeDiagnosticInfoFileHL = "NvimTreeLspDiagnosticsInformationText",
NvimTreeDiagnosticHintFileHL = "NvimTreeLspDiagnosticsHintText",
NvimTreeDiagnosticErrorFolderHL = "NvimTreeLspDiagnosticsErrorFolderText",
NvimTreeDiagnosticWarnFolderHL = "NvimTreeLspDiagnosticsWarningFolderText",
NvimTreeDiagnosticInfoFolderHL = "NvimTreeLspDiagnosticsInformationFolderText",
NvimTreeDiagnosticHintFolderHL = "NvimTreeLspDiagnosticsHintFolderText",
}
function M.setup()
-- non-linked
for _, g in ipairs(M.HIGHLIGHT_GROUPS) do
if g.def then
vim.api.nvim_command("hi def " .. g.group .. " " .. g.def)
end
end
-- hard link override when legacy only is present
for from, to in pairs(M.LEGACY_LINKS) do
local hl_from
local hl_to
if vim.fn.has "nvim-0.9" == 1 then
hl_from = vim.api.nvim_get_hl(0, { name = from })
hl_to = vim.api.nvim_get_hl(0, { name = to })
else
hl_from = vim.api.nvim__get_hl_defs(0)[from] or {}
hl_to = vim.api.nvim__get_hl_defs(0)[to] or {}
end
if vim.tbl_isempty(hl_from) and not vim.tbl_isempty(hl_to) then
vim.api.nvim_command("hi link " .. from .. " " .. to)
end
end
-- default links
for _, g in ipairs(M.HIGHLIGHT_GROUPS) do
if g.link then
vim.api.nvim_command("hi def link " .. g.group .. " " .. g.link)
end
end
end
return M

130
lua/nvim-tree/colors.lua Normal file
View File

@@ -0,0 +1,130 @@
local M = {}
local function get_color_from_hl(hl_name, fallback)
local id = vim.api.nvim_get_hl_id_by_name(hl_name)
if not id then
return fallback
end
local foreground = vim.fn.synIDattr(vim.fn.synIDtrans(id), "fg")
if not foreground or foreground == "" then
return fallback
end
return foreground
end
local function get_colors()
return {
red = vim.g.terminal_color_1 or get_color_from_hl("Keyword", "Red"),
green = vim.g.terminal_color_2 or get_color_from_hl("Character", "Green"),
yellow = vim.g.terminal_color_3 or get_color_from_hl("PreProc", "Yellow"),
blue = vim.g.terminal_color_4 or get_color_from_hl("Include", "Blue"),
purple = vim.g.terminal_color_5 or get_color_from_hl("Define", "Purple"),
cyan = vim.g.terminal_color_6 or get_color_from_hl("Conditional", "Cyan"),
dark_red = vim.g.terminal_color_9 or get_color_from_hl("Keyword", "DarkRed"),
orange = vim.g.terminal_color_11 or get_color_from_hl("Number", "Orange"),
}
end
local function get_hl_groups()
local colors = get_colors()
return {
IndentMarker = { fg = "#8094b4" },
Symlink = { gui = "bold", fg = colors.cyan },
FolderIcon = { fg = "#8094b4" },
RootFolder = { fg = colors.purple },
ExecFile = { gui = "bold", fg = colors.green },
SpecialFile = { gui = "bold,underline", fg = colors.yellow },
ImageFile = { gui = "bold", fg = colors.purple },
OpenedFile = { gui = "bold", fg = colors.green },
ModifiedFile = { fg = colors.green },
GitDirty = { fg = colors.dark_red },
GitDeleted = { fg = colors.dark_red },
GitStaged = { fg = colors.green },
GitMerge = { fg = colors.orange },
GitRenamed = { fg = colors.purple },
GitNew = { fg = colors.yellow },
WindowPicker = { gui = "bold", fg = "#ededed", bg = "#4493c8" },
LiveFilterPrefix = { gui = "bold", fg = colors.purple },
LiveFilterValue = { gui = "bold", fg = "#fff" },
Bookmark = { fg = colors.green },
}
end
local function get_links()
return {
FolderName = "Directory",
EmptyFolderName = "Directory",
OpenedFolderName = "Directory",
SymlinkFolderName = "Directory",
OpenedFolderIcon = "NvimTreeFolderIcon",
ClosedFolderIcon = "NvimTreeFolderIcon",
OpenedFileIcon = "NvimTreeOpenedFile",
Normal = "Normal",
NormalFloat = "NormalFloat",
NormalNC = "NvimTreeNormal",
EndOfBuffer = "EndOfBuffer",
CursorLineNr = "CursorLineNr",
LineNr = "LineNr",
CursorLine = "CursorLine",
WinSeparator = "WinSeparator",
CursorColumn = "CursorColumn",
FileDirty = "NvimTreeGitDirty",
FileNew = "NvimTreeGitNew",
FileRenamed = "NvimTreeGitRenamed",
FileMerge = "NvimTreeGitMerge",
FileStaged = "NvimTreeGitStaged",
FileDeleted = "NvimTreeGitDeleted",
FileIgnored = "NvimTreeGitIgnored",
FolderDirty = "NvimTreeFileDirty",
FolderNew = "NvimTreeFileNew",
FolderRenamed = "NvimTreeFileRenamed",
FolderMerge = "NvimTreeFileMerge",
FolderStaged = "NvimTreeFileStaged",
FolderDeleted = "NvimTreeFileDeleted",
FolderIgnored = "NvimTreeFileIgnored",
LspDiagnosticsError = "DiagnosticError",
LspDiagnosticsWarning = "DiagnosticWarn",
LspDiagnosticsInformation = "DiagnosticInfo",
LspDiagnosticsHint = "DiagnosticHint",
LspDiagnosticsErrorText = "NvimTreeLspDiagnosticsError",
LspDiagnosticsWarningText = "NvimTreeLspDiagnosticsWarning",
LspDiagnosticsInformationText = "NvimTreeLspDiagnosticsInformation",
LspDiagnosticsHintText = "NvimTreeLspDiagnosticsHintFile",
LspDiagnosticsErrorFolderText = "NvimTreeLspDiagnosticsErrorText",
LspDiagnosticsWarningFolderText = "NvimTreeLspDiagnosticsWarningText",
LspDiagnosticsInformationFolderText = "NvimTreeLspDiagnosticsInformationText",
LspDiagnosticsHintFolderText = "NvimTreeLspDiagnosticsHintFileText",
Popup = "Normal",
GitIgnored = "Comment",
StatusLine = "StatusLine",
StatusLineNC = "StatusLineNC",
SignColumn = "NvimTreeNormal",
CutHL = "SpellBad",
CopiedHL = "SpellRare",
BookmarkHL = "SpellLocal",
}
end
function M.setup()
local highlight_groups = get_hl_groups()
for k, d in pairs(highlight_groups) do
local gui = d.gui and " gui=" .. d.gui or ""
local fg = d.fg and " guifg=" .. d.fg or ""
local bg = d.bg and " guibg=" .. d.bg or ""
vim.api.nvim_command("hi def NvimTree" .. k .. gui .. fg .. bg)
end
local links = get_links()
for k, d in pairs(links) do
vim.api.nvim_command("hi def link NvimTree" .. k .. " " .. d)
end
end
return M

View File

@@ -134,13 +134,6 @@ local CMDS = {
api.tree.collapse_all(true)
end,
},
{
name = "NvimTreeHiTest",
opts = {
desc = "nvim-tree: highlight test",
},
command = api.diagnostics.hi_test,
},
}
function M.get()

View File

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

View File

@@ -12,10 +12,9 @@ M.HL_POSITION = {
---Setup options for "*_placement"
---@enum ICON_PLACEMENT
M.ICON_PLACEMENT = {
none = 0,
signcolumn = 1,
before = 2,
after = 3,
signcolumn = 0,
before = 1,
after = 2,
}
return M

View File

@@ -1,5 +1,4 @@
local utils = require "nvim-tree.utils"
local marks = require "nvim-tree.marks"
local M = {
ignore_list = {},
@@ -47,15 +46,16 @@ end
---Check if the given path has no listed buffer
---@param path string Absolute path
---@param bufinfo table vim.fn.getbufinfo { buflisted = 1 }
---@param unloaded_bufnr number optional bufnr recently unloaded via BufUnload event
---@return boolean
local function buf(path, bufinfo)
local function buf(path, bufinfo, unloaded_bufnr)
if not M.config.filter_no_buffer or type(bufinfo) ~= "table" then
return false
end
-- filter files with no open buffer and directories containing no open buffers
for _, b in ipairs(bufinfo) do
if b.name == path or b.name:find(path .. "/", 1, true) then
if b.name == path or b.name:find(path .. "/", 1, true) and b.bufnr ~= unloaded_bufnr then
return false
end
end
@@ -69,12 +69,6 @@ local function dotfile(path)
return M.config.filter_dotfiles and utils.path_basename(path):sub(1, 1) == "."
end
---@param path string
---@param bookmarks table<string, boolean> absolute paths bookmarked
local function bookmark(path, bookmarks)
return M.config.filter_no_bookmark and not bookmarks[path]
end
---@param path string
---@return boolean
local function custom(path)
@@ -104,25 +98,22 @@ end
---Prepare arguments for should_filter. This is done prior to should_filter for efficiency reasons.
---@param git_status table|nil optional results of git.load_project_status(...)
---@param unloaded_bufnr number|nil optional bufnr recently unloaded via BufUnload event
---@return table
--- git_status: reference
--- unloaded_bufnr: copy
--- bufinfo: empty unless no_buffer set: vim.fn.getbufinfo { buflisted = 1 }
--- bookmarks: absolute paths to boolean
function M.prepare(git_status)
function M.prepare(git_status, unloaded_bufnr)
local status = {
git_status = git_status or {},
unloaded_bufnr = unloaded_bufnr,
bufinfo = {},
bookmarks = {},
}
if M.config.filter_no_buffer then
status.bufinfo = vim.fn.getbufinfo { buflisted = 1 }
end
for _, node in pairs(marks.get_marks()) do
status.bookmarks[node.absolute_path] = true
end
return status
end
@@ -136,7 +127,7 @@ function M.should_filter(path, status)
return false
end
return git(path, status.git_status) or buf(path, status.bufinfo) or dotfile(path) or custom(path) or bookmark(path, status.bookmarks)
return git(path, status.git_status) or buf(path, status.bufinfo, status.unloaded_bufnr) or dotfile(path) or custom(path)
end
function M.setup(opts)
@@ -146,7 +137,6 @@ function M.setup(opts)
filter_git_ignored = opts.filters.git_ignored,
filter_git_clean = opts.filters.git_clean,
filter_no_buffer = opts.filters.no_buffer,
filter_no_bookmark = opts.filters.no_bookmark,
}
M.ignore_list = {}

View File

@@ -69,7 +69,8 @@ end
---@param node Node
---@param git_status table
function M.reload(node, git_status)
---@param unloaded_bufnr number|nil
function M.reload(node, git_status, unloaded_bufnr)
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
@@ -78,7 +79,7 @@ function M.reload(node, git_status)
local profile = log.profile_start("reload %s", node.absolute_path)
local filter_status = filters.prepare(git_status)
local filter_status = filters.prepare(git_status, unloaded_bufnr)
if node.group_next then
node.nodes = { node.group_next }

View File

@@ -2,6 +2,11 @@ local log = require "nvim-tree.log"
local utils = require "nvim-tree.utils"
local notify = require "nvim-tree.notify"
-- TODO add "${3rd}/luv/library" to "workspace.library"
---@class uv.uv_handle_t: table
---@class uv.uv_stream_t: uv.uv_handle_t
---@class uv.uv_pipe_t: uv.uv_stream_t
---@class Runner
local Runner = {}
Runner.__index = Runner

View File

@@ -119,20 +119,14 @@ local function compute()
-- increase desc if lines are shorter than the header
max_desc = math.max(max_desc, #head_lhs + #head_rhs1 - max_lhs)
-- header text, not padded
-- header, not padded
local hl = { { "NvimTreeRootFolder", 0, 0, #head_lhs } }
local lines = {
head_lhs .. string.rep(" ", max_desc + max_lhs - #head_lhs - #head_rhs1 + 2) .. head_rhs1,
string.rep(" ", max_desc + max_lhs - #head_rhs2 + 2) .. head_rhs2,
}
local width = #lines[1]
-- header highlight, assume one character keys
local hl = {
{ "NvimTreeFolderName", 0, 0, #head_lhs },
{ "NvimTreeFolderName", 0, width - 1, width },
{ "NvimTreeFolderName", 1, width - 1, width },
}
-- mappings, left padded 1
local fmt = string.format(" %%-%ds %%-%ds", max_lhs, max_desc)
for i, l in ipairs(mappings) do

View File

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

View File

@@ -41,16 +41,6 @@ local function refactored(opts)
-- 2023/08/26
utils.move_missing_val(opts, "renderer.icons", "webdev_colors", opts, "renderer.icons.web_devicons.file", "color", true)
-- 2023/10/08
if type(opts.renderer) == "table" and type(opts.renderer.highlight_diagnostics) == "boolean" then
opts.renderer.highlight_diagnostics = opts.renderer.highlight_diagnostics and "name" or "none"
end
-- 2023/10/21
if type(opts.renderer) == "table" and type(opts.renderer.highlight_git) == "boolean" then
opts.renderer.highlight_git = opts.renderer.highlight_git and "name" or "none"
end
end
local function deprecated(opts)

View File

@@ -3,7 +3,6 @@ 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 explorer_node = require "nvim-tree.explorer.node"
---@class LibOpenOpts
---@field path string|nil path
@@ -25,7 +24,7 @@ function M.get_node_at_cursor()
return
end
local cursor = vim.api.nvim_win_get_cursor(winnr)
local cursor = vim.api.nvim_win_get_cursor(view.get_winnr())
local line = cursor[1]
if line == 1 and view.is_root_folder_visible(core.get_cwd()) then
@@ -87,34 +86,6 @@ function M.get_last_group_node(node)
return node
end
---Group empty folders
-- Recursively group nodes
---@param node Node
---@return Node[]
function M.group_empty_folders(node)
local is_root = not node.parent
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
if M.group_empty and not is_root and child_folder_only then
node.group_next = child_folder_only
local ns = M.group_empty_folders(child_folder_only)
node.nodes = ns or {}
return ns
end
return node.nodes
end
---Ungroup empty folders
-- If a node is grouped, ungroup it: put node.group_next to the node.nodes and set node.group_next to nil
---@param node Node
function M.ungroup_empty_folders(node)
local cur = node
while cur and cur.group_next do
cur.nodes = { cur.group_next }
cur.group_next = nil
cur = cur.nodes[1]
end
end
---@param node Node
---@return Node[]
function M.get_all_nodes_in_group(node)
@@ -127,21 +98,8 @@ function M.get_all_nodes_in_group(node)
return nodes
end
-- Toggle group empty folders
---@param head_node Node
local function toggle_group_folders(head_node)
local is_grouped = head_node.group_next ~= nil
if is_grouped then
M.ungroup_empty_folders(head_node)
else
M.group_empty_folders(head_node)
end
end
---@param node Node
function M.expand_or_collapse(node, toggle_group)
toggle_group = toggle_group or false
function M.expand_or_collapse(node)
if node.has_children then
node.has_children = false
end
@@ -150,20 +108,9 @@ function M.expand_or_collapse(node, toggle_group)
core.get_explorer():expand(node)
end
local head_node = utils.get_parent_of_group(node)
if toggle_group then
toggle_group_folders(head_node)
end
local open = M.get_last_group_node(node).open
local next_open
if toggle_group then
next_open = open
else
next_open = not open
end
for _, n in ipairs(M.get_all_nodes_in_group(head_node)) do
n.open = next_open
local open = not M.get_last_group_node(node).open
for _, n in ipairs(M.get_all_nodes_in_group(node)) do
n.open = open
end
renderer.draw()
@@ -210,9 +157,8 @@ end
---@param prompt_select string
---@param items_short string[]
---@param items_long string[]
---@param kind string|nil
---@param callback fun(item_short: string)
function M.prompt(prompt_input, prompt_select, items_short, items_long, kind, callback)
function M.prompt(prompt_input, prompt_select, items_short, items_long, callback)
local function format_item(short)
for i, s in ipairs(items_short) do
if short == s then
@@ -223,7 +169,7 @@ function M.prompt(prompt_input, prompt_select, items_short, items_long, kind, ca
end
if M.select_prompts then
vim.ui.select(items_short, { prompt = prompt_select, kind = kind, format_item = format_item }, function(item_short)
vim.ui.select(items_short, { prompt = prompt_select, format_item = format_item }, function(item_short)
callback(item_short)
end)
else
@@ -266,7 +212,6 @@ function M.setup(opts)
M.hijack_directories = opts.hijack_directories
M.respect_buf_cwd = opts.respect_buf_cwd
M.select_prompts = opts.select_prompts
M.group_empty = opts.renderer.group_empty
end
return M

View File

@@ -18,7 +18,7 @@ local function do_delete(nodes)
marks.clear_marks()
if not M.config.filesystem_watchers.enable then
require("nvim-tree.actions.reloaders").reload_explorer()
require("nvim-tree.actions.reloaders.reloaders").reload_explorer()
end
end
@@ -33,7 +33,7 @@ function M.bulk_delete()
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)
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, function(item_short)
utils.clear_prompt()
if item_short == "y" then
do_delete(nodes)

View File

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

View File

@@ -28,7 +28,7 @@ function M.bulk_trash()
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)
lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, function(item_short)
utils.clear_prompt()
if item_short == "y" then
do_trash(nodes)

View File

@@ -45,7 +45,7 @@ end
---@param node Node|MinimalNode
---@return table|nil
function M.get_mark(node)
return node and NvimTreeMarks[node.absolute_path]
return NvimTreeMarks[node.absolute_path]
end
---@return table

View File

@@ -1,50 +1,40 @@
local M = {}
---@type table<string, boolean> record of which file is modified
M._modified = {}
M._record = {}
---refresh M._modified
function M.reload_modified()
M._modified = {}
---refresh M.record
function M.reload()
M._record = {}
local bufs = vim.fn.getbufinfo { bufmodified = true, buflisted = true }
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
M._record[path] ~= true
-- no need to keep going if already recorded
-- This also prevents an infinite loop
do
M._modified[path] = true
M._record[path] = true
path = vim.fn.fnamemodify(path, ":h")
end
end
end
end
---@param node table
---@param node Node
---@return boolean
function M.is_modified(node)
return node
and M.config.modified.enable
and M._modified[node.absolute_path]
and (not node.nodes or M.config.modified.show_on_dirs)
and (not node.open or M.config.modified.show_on_open_dirs)
end
---A buffer exists for the node's absolute path
---@param node table
---@return boolean
function M.is_opened(node)
return node and vim.fn.bufloaded(node.absolute_path) > 0
return M.config.enable
and M._record[node.absolute_path]
and (not node.nodes or M.config.show_on_dirs)
and (not node.open or M.config.show_on_open_dirs)
end
---@param opts table
function M.setup(opts)
M.config = {
modified = opts.modified,
}
M.config = opts.modified
end
return M

View File

@@ -1,5 +1,9 @@
---@meta
-- TODO add "${3rd}/luv/library" to "workspace.library"
---@class uv.uv_req_t: table
---@class uv.uv_fs_t: uv.uv_req_t
---@class ParentNode
---@field name string
@@ -13,7 +17,6 @@
---@field parent DirNode
---@field type string
---@field watcher function|nil
---@field diag_status DiagStatus|nil
---@class DirNode: BaseNode
---@field has_children boolean

View File

@@ -1,92 +1,136 @@
local core = require "nvim-tree.core"
local live_filter = require "nvim-tree.live-filter"
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 DecoratorOpened = require "nvim-tree.renderer.decorator.opened"
local core = require "nvim-tree.core"
local notify = require "nvim-tree.notify"
local git = require "nvim-tree.renderer.components.git"
local pad = require "nvim-tree.renderer.components.padding"
local icons = require "nvim-tree.renderer.components.icons"
local modified = require "nvim-tree.renderer.components.modified"
local diagnostics = require "nvim-tree.renderer.components.diagnostics"
local bookmarks = require "nvim-tree.renderer.components.bookmarks"
local M = {
opts = {},
decorators = {},
picture_map = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
},
}
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
---@class HighlightedString
---@field str string
---@field hl string[]
---@class AddHighlightArgs
---@field group string[]
---@field line number
---@field col_start number
---@field col_end number
---@class Builder
---@field lines string[] includes icons etc.
---@field hl_args AddHighlightArgs[] line highlights
---@field signs string[] line signs
---@field private root_cwd string absolute path
---@field private index number
---@field private depth number
---@field private combined_groups table<string, boolean> combined group names
---@field private markers boolean[] indent markers
local Builder = {}
Builder.__index = Builder
---@return Builder
function Builder:new()
local o = {
root_cwd = core.get_cwd(),
local DEFAULT_ROOT_FOLDER_LABEL = ":~:s?$?/..?"
function Builder.new(root_cwd)
return setmetatable({
index = 0,
depth = 0,
hl_args = {},
combined_groups = {},
highlights = {},
lines = {},
markers = {},
signs = {},
}
setmetatable(o, self)
self.__index = self
return o
root_cwd = root_cwd,
}, Builder)
end
---Insert ranged highlight groups into self.highlights
---@private
---@param groups string[]
---@param start number
---@param end_ number|nil
function Builder:insert_highlight(groups, start, end_)
table.insert(self.hl_args, { groups, self.index, start, end_ or -1 })
function Builder:configure_root_label(root_folder_label)
self.root_folder_label = root_folder_label or DEFAULT_ROOT_FOLDER_LABEL
return self
end
---@private
function Builder:get_folder_name(node)
function Builder:configure_trailing_slash(with_trailing)
self.trailing_slash = with_trailing and "/" or ""
return self
end
function Builder:configure_special_files(special_files)
self.special_files = special_files
return self
end
function Builder:configure_picture_map(picture_map)
self.picture_map = picture_map
return self
end
function Builder:configure_filter(filter, prefix)
self.filter_prefix = prefix
self.filter = filter
return self
end
function Builder:configure_opened_file_highlighting(highlight_opened_files)
self.highlight_opened_files = highlight_opened_files
return self
end
function Builder:configure_modified_highlighting(highlight_modified)
self.highlight_modified = highlight_modified
return self
end
function Builder:configure_icon_padding(padding)
self.icon_padding = padding or " "
return self
end
function Builder:configure_git_icons_placement(where)
if where ~= "after" and where ~= "before" and where ~= "signcolumn" then
where = "before" -- default before
end
self.git_placement = where
return self
end
function Builder:configure_diagnostics_icon_placement(where)
if where ~= "after" and where ~= "before" and where ~= "signcolumn" then
where = "before" -- default before
end
self.diagnostics_placement = where
return self
end
function Builder:configure_bookmark_icon_placement(where)
if where ~= "after" and where ~= "before" and where ~= "signcolumn" then
where = "before" -- default before
end
self.bookmarks_placement = where
return self
end
function Builder:configure_modified_placement(where)
if where ~= "after" and where ~= "before" and where ~= "signcolumn" then
where = "after" -- default after
end
self.modified_placement = where
return self
end
function Builder:configure_symlink_destination(show)
self.symlink_destination = show
return self
end
function Builder:configure_group_name_modifier(group_name_modifier)
if type(group_name_modifier) == "function" then
self.group_name_modifier = group_name_modifier
end
return self
end
function Builder:_insert_highlight(group, start, end_)
table.insert(self.highlights, { group, self.index, start, end_ or -1 })
end
function Builder:_insert_line(line)
table.insert(self.lines, line)
end
function Builder:_get_folder_name(node)
local name = node.name
local next = node.group_next
while next do
name = string.format("%s/%s", name, next.name)
name = name .. "/" .. next.name
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 self.group_name_modifier then
local new_name = self.group_name_modifier(name)
if type(new_name) == "string" then
name = new_name
else
@@ -94,13 +138,16 @@ function Builder:get_folder_name(node)
end
end
return string.format("%s%s", name, M.opts.renderer.add_trailing and "/" or "")
return name .. self.trailing_slash
end
---@private
---@class HighlightedString
---@field str string
---@field hl string[]
---@param highlighted_strings HighlightedString[]
---@return string
function Builder:unwrap_highlighted_strings(highlighted_strings)
function Builder:_unwrap_highlighted_strings(highlighted_strings)
if not highlighted_strings then
return ""
end
@@ -109,22 +156,21 @@ function Builder:unwrap_highlighted_strings(highlighted_strings)
for _, v in ipairs(highlighted_strings) do
if #v.str > 0 then
if v.hl and type(v.hl) == "table" then
self:insert_highlight(v.hl, #string, #string + #v.str)
self:_insert_highlight(v.hl, #string, #string + #v.str)
end
string = string.format("%s%s", string, v.str)
string = string .. v.str
end
end
return string
end
---@private
---@param node table
---@return HighlightedString icon
---@return HighlightedString name
function Builder:build_folder(node)
function Builder:_build_folder(node)
local has_children = #node.nodes ~= 0 or node.has_children
local icon, icon_hl = icons.get_folder_icon(node, has_children)
local foldername = self:get_folder_name(node)
local foldername = self:_get_folder_name(node)
if #icon > 0 and icon_hl == nil then
if node.open then
@@ -135,14 +181,12 @@ 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.symlink_destination then
local arrow = icons.i.symlink_arrow
local link_to = utils.path_relative(node.link_to, self.root_cwd)
foldername = string.format("%s%s%s", foldername, arrow, link_to)
local link_to = utils.path_relative(node.link_to, core.get_cwd())
foldername = 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)
then
elseif vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then
foldername_hl = "NvimTreeSpecialFolderName"
elseif node.open then
foldername_hl = "NvimTreeOpenedFolderName"
@@ -153,56 +197,174 @@ function Builder:build_folder(node)
return { str = icon, hl = { icon_hl } }, { str = foldername, hl = { foldername_hl } }
end
---@private
---@param node table
---@return HighlightedString icon
---@return HighlightedString name
function Builder:build_symlink(node)
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)
symlink_formatted = string.format("%s%s%s", symlink_formatted, arrow, link_to)
if self.symlink_destination then
local link_to = utils.path_relative(node.link_to, core.get_cwd())
symlink_formatted = symlink_formatted .. arrow .. link_to
end
return { str = icon, hl = { "NvimTreeSymlinkIcon" } }, { str = symlink_formatted, hl = { "NvimTreeSymlink" } }
end
---@private
---@param node table
---@return HighlightedString icon
function Builder:_build_file_icon(node)
local icon, hl_group = icons.get_file_icon(node.name, node.extension)
return { str = icon, hl = { hl_group } }
end
---@param node table
---@return HighlightedString icon
---@return HighlightedString name
function Builder:build_file(node)
function Builder:_build_file(node)
local icon = self:_build_file_icon(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.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then
hl = "NvimTreeSpecialFile"
elseif node.executable then
hl = "NvimTreeExecFile"
elseif M.picture_map[node.extension] then
elseif self.picture_map[node.extension] then
hl = "NvimTreeImageFile"
end
local icon, hl_group = icons.get_file_icon(node.name, node.extension)
return { str = icon, hl = { hl_group } }, { str = node.name, hl = { hl } }
return icon, { str = node.name, hl = { hl } }
end
---@param node table
---@return HighlightedString[]|nil icon
function Builder:_get_git_icons(node)
local git_icons = git.get_icons(node)
if git_icons and #git_icons > 0 and self.git_placement == "signcolumn" then
table.insert(self.signs, {
sign = git_icons[1].hl[1],
lnum = self.index + 1,
priority = 1,
})
git_icons = nil
end
return git_icons
end
---@param node table
---@return HighlightedString[]|nil icon
function Builder:_get_diagnostics_icon(node)
local diagnostics_icon = diagnostics.get_icon(node)
if diagnostics_icon and self.diagnostics_placement == "signcolumn" then
table.insert(self.signs, {
sign = diagnostics_icon.hl[1],
lnum = self.index + 1,
priority = 2,
})
diagnostics_icon = nil
end
return diagnostics_icon
end
---@param node table
---@return HighlightedString|nil icon
function Builder:_get_modified_icon(node)
local modified_icon = modified.get_icon(node)
if modified_icon and self.modified_placement == "signcolumn" then
table.insert(self.signs, {
sign = modified_icon.hl[1],
lnum = self.index + 1,
priority = 3,
})
modified_icon = nil
end
return modified_icon
end
---@param node table
---@return HighlightedString[]|nil icon
function Builder:_get_bookmark_icon(node)
local bookmark_icon = bookmarks.get_icon(node)
if bookmark_icon and self.bookmarks_placement == "signcolumn" then
table.insert(self.signs, {
sign = bookmark_icon.hl[1],
lnum = self.index + 1,
priority = 4,
})
bookmark_icon = nil
end
return bookmark_icon
end
---@param node table
---@return string|nil icon_hl
---@return string|nil name_hl
function Builder:_get_highlight_override(node, unloaded_bufnr)
local name_hl, icon_hl
-- git
local git_highlight = git.get_highlight(node)
if git_highlight then
name_hl = git_highlight
end
-- opened file
if self.highlight_opened_files and vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.bufnr(node.absolute_path) ~= unloaded_bufnr then
if self.highlight_opened_files == "all" or self.highlight_opened_files == "name" then
name_hl = "NvimTreeOpenedFile"
end
if self.highlight_opened_files == "all" or self.highlight_opened_files == "icon" then
icon_hl = "NvimTreeOpenedFileIcon"
end
end
-- modified file
local modified_highlight = modified.get_highlight(node)
if modified_highlight then
if self.highlight_modified == "all" or self.highlight_modified == "name" then
name_hl = modified_highlight
end
if self.highlight_modified == "all" or self.highlight_modified == "icon" then
icon_hl = modified_highlight
end
end
return icon_hl, name_hl
end
---Append optional highlighting to icon or name.
---@param node table
---@param get_hl fun(node: table): HL_POSITION, string
---@param icon_hl string[] icons to append to
---@param name_hl string[] names to append to
function Builder:_append_highlight(node, get_hl, icon_hl, name_hl)
local pos, hl = get_hl(node)
if pos ~= HL_POSITION.none and hl then
if pos == HL_POSITION.all or pos == HL_POSITION.icon then
table.insert(icon_hl, hl)
end
if pos == HL_POSITION.all or pos == HL_POSITION.name then
table.insert(name_hl, hl)
end
end
end
---@private
---@param indent_markers HighlightedString[]
---@param arrows HighlightedString[]|nil
---@param icon HighlightedString
---@param name HighlightedString
---@param node table
---@param git_icons HighlightedString[]|nil
---@param diagnostics_icon HighlightedString|nil
---@param modified_icon HighlightedString|nil
---@param bookmark_icon HighlightedString|nil
---@return HighlightedString[]
function Builder:format_line(indent_markers, arrows, icon, name, node)
function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon, bookmark_icon)
local added_len = 0
local function add_to_end(t1, t2)
if not t2 then
return
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.icon_padding })
end
table.insert(t1, v)
end
@@ -217,134 +379,78 @@ 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))
if git_icons and self.git_placement == "before" then
add_to_end(line, git_icons)
end
if modified_icon and self.modified_placement == "before" then
add_to_end(line, { modified_icon })
end
if diagnostics_icon and self.diagnostics_placement == "before" then
add_to_end(line, { diagnostics_icon })
end
if bookmark_icon and self.bookmarks_placement == "before" then
add_to_end(line, { bookmark_icon })
end
add_to_end(line, { name })
for i = #M.decorators, 1, -1 do
add_to_end(line, M.decorators[i]:icons_after(node))
if git_icons and self.git_placement == "after" then
add_to_end(line, git_icons)
end
if modified_icon and self.modified_placement == "after" then
add_to_end(line, { modified_icon })
end
if diagnostics_icon and self.diagnostics_placement == "after" then
add_to_end(line, { diagnostics_icon })
end
if bookmark_icon and self.bookmarks_placement == "after" then
add_to_end(line, { bookmark_icon })
end
return line
end
---@private
---@param node Node
function Builder:build_signs(node)
-- first in priority order
local sign_name
for _, d in ipairs(M.decorators) do
sign_name = d:sign_name(node)
if sign_name then
self.signs[self.index] = sign_name
break
end
end
end
function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
local copy_paste = require "nvim-tree.actions.fs.copy-paste"
---Create a highlight group for groups with later groups overriding previous.
---Combined group name is less than the 200 byte limit of highlight group names
---@private
---@param groups string[] highlight group names
---@return string group_name "NvimTreeCombinedHL" .. sha256
function Builder:create_combined_group(groups)
local combined_name = string.format("NvimTreeCombinedHL%s", vim.fn.sha256(table.concat(groups)))
-- only create if necessary
if not self.combined_groups[combined_name] then
self.combined_groups[combined_name] = true
local combined_hl = {}
-- build the highlight, overriding values
for _, group in ipairs(groups) do
local hl = vim.api.nvim_get_hl(0, { name = group, link = false })
combined_hl = vim.tbl_extend("force", combined_hl, hl)
end
-- add highlights to the global namespace
vim.api.nvim_set_hl(0, combined_name, combined_hl)
table.insert(self.combined_groups, combined_name)
end
return combined_name
end
---Calculate highlight group for icon and name. A combined highlight group will be created
---when there is more than one highlight.
---A highlight group is always calculated and upserted for the case of highlights changing.
---@private
---@param node Node
---@return string|nil icon_hl_group
---@return string|nil name_hl_group
function Builder:add_highlights(node)
-- result
local icon_hl_group, name_hl_group
-- calculate all groups
local icon_groups = {}
local name_groups = {}
local d, icon, name
for i = #M.decorators, 1, -1 do
d = M.decorators[i]
icon, name = d:groups_icon_name(node)
table.insert(icon_groups, icon)
table.insert(name_groups, name)
end
-- one or many icon groups; <= 0.8 always uses highest due to lack of a practical nvim_get_hl equivalent
if #icon_groups > 1 then
if vim.fn.has "nvim-0.9" == 1 then
icon_hl_group = self:create_combined_group(icon_groups)
else
icon_hl_group = icon_groups[#icon_groups]
end
else
icon_hl_group = icon_groups[1]
end
-- one or many name groups; <= 0.8 always uses highest due to lack of a practical nvim_get_hl equivalent
if #name_groups > 1 then
if vim.fn.has "nvim-0.9" == 1 then
name_hl_group = self:create_combined_group(name_groups)
else
name_hl_group = name_groups[#name_groups]
end
else
name_hl_group = name_groups[1]
end
return icon_hl_group, name_hl_group
end
---@private
function Builder:build_line(node, idx, num_children)
-- various components
local indent_markers = pad.get_indent_markers(self.depth, idx, num_children, node, self.markers)
local arrows = pad.get_arrows(node)
-- adds icons to signcolumn
local bookmark_icon = self:_get_bookmark_icon(node)
local git_icons = self:_get_git_icons(node)
local modified_icon = self:_get_modified_icon(node)
local diagnostics_icon = self:_get_diagnostics_icon(node)
-- main components
local is_folder = node.nodes ~= nil
local is_symlink = node.link_to ~= nil
local icon, name
if is_folder then
icon, name = self:build_folder(node)
icon, name = self:_build_folder(node)
elseif is_symlink then
icon, name = self:build_symlink(node)
icon, name = self:_build_symlink(node)
else
icon, name = self:build_file(node)
icon, name = self:_build_file(node)
end
-- highighting
local icon_hl_group, name_hl_group = self:add_highlights(node)
table.insert(icon.hl, icon_hl_group)
table.insert(name.hl, name_hl_group)
-- highlight override
local icon_hl_override, name_hl_override = self:_get_highlight_override(node, unloaded_bufnr)
if icon_hl_override then
icon.hl = { icon_hl_override }
end
if name_hl_override then
name.hl = { name_hl_override }
end
local line = self:format_line(indent_markers, arrows, icon, name, node)
table.insert(self.lines, self:unwrap_highlighted_strings(line))
-- extra highighting
self:_append_highlight(node, bookmarks.get_highlight, icon.hl, name.hl)
self:_append_highlight(node, diagnostics.get_highlight, icon.hl, name.hl)
self:_append_highlight(node, copy_paste.get_highlight, icon.hl, name.hl)
local line = self:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon, bookmark_icon)
self:_insert_line(self:_unwrap_highlighted_strings(line))
self.index = self.index + 1
@@ -352,14 +458,13 @@ function Builder:build_line(node, idx, num_children)
if node.open then
self.depth = self.depth + 1
self:build_lines(node)
self:build(node, unloaded_bufnr)
self.depth = self.depth - 1
end
end
---@private
function Builder:get_nodes_number(nodes)
if not live_filter.filter then
function Builder:_get_nodes_number(nodes)
if not self.filter then
return #nodes
end
@@ -372,77 +477,53 @@ function Builder:get_nodes_number(nodes)
return i
end
---@private
function Builder:build_lines(node)
if not node then
node = core.get_explorer()
end
local num_children = self:get_nodes_number(node.nodes)
function Builder:build(tree, unloaded_bufnr)
local num_children = self:_get_nodes_number(tree.nodes)
local idx = 1
for _, n in ipairs(node.nodes) do
if not n.hidden then
self:build_signs(n)
self:build_line(n, idx, num_children)
for _, node in ipairs(tree.nodes) do
if not node.hidden then
self:_build_line(node, idx, num_children, unloaded_bufnr)
idx = idx + 1
end
end
end
---@private
---@param root_label function|string
---@return string
function Builder:format_root_name(root_label)
if type(root_label) == "function" then
local label = root_label(self.root_cwd)
if type(label) == "string" then
return label
else
return "???"
end
end
return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label))
end
---@private
function Builder:build_header()
if view.is_root_folder_visible(core.get_cwd()) then
local root_name = self:format_root_name(M.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 live_filter.filter then
local filter_line = string.format("%s/%s/", M.opts.live_filter.prefix, live_filter.filter)
table.insert(self.lines, filter_line)
local prefix_length = string.len(M.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
end
end
---Build all lines with highlights and signs
---@return Builder
function Builder:build()
self:build_header()
self:build_lines()
return self
end
function Builder.setup(opts)
M.opts = opts
local function format_root_name(root_cwd, root_label)
if type(root_label) == "function" then
local label = root_label(root_cwd)
if type(label) == "string" then
return label
else
root_label = DEFAULT_ROOT_FOLDER_LABEL
end
end
return utils.path_remove_trailing(vim.fn.fnamemodify(root_cwd, root_label))
end
-- priority order
M.decorators = {
DecoratorCut:new(opts),
DecoratorCopied:new(opts),
DecoratorDiagnostics:new(opts),
DecoratorBookmarks:new(opts),
DecoratorModified:new(opts),
DecoratorOpened:new(opts),
DecoratorGit:new(opts),
}
function Builder:build_header(show_header)
if show_header then
local root_name = format_root_name(self.root_cwd, self.root_folder_label)
self:_insert_line(root_name)
self:_insert_highlight({ "NvimTreeRootFolder" }, 0, string.len(root_name))
self.index = 1
end
if self.filter then
local filter_line = self.filter_prefix .. "/" .. self.filter .. "/"
self:_insert_line(filter_line)
local prefix_length = string.len(self.filter_prefix)
self:_insert_highlight({ "NvimTreeLiveFilterPrefix" }, 0, prefix_length)
self:_insert_highlight({ "NvimTreeLiveFilterValue" }, prefix_length, string.len(filter_line))
self.index = self.index + 1
end
return self
end
function Builder:unwrap()
return self.lines, self.highlights, self.signs
end
return Builder

View File

@@ -0,0 +1,51 @@
local marks = require "nvim-tree.marks"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local M = {
ICON = {},
hl_pos = HL_POSITION.none,
}
---Bookmark highlight group and position when highlight_bookmark.
---@param node table
---@return HL_POSITION position none when clipboard empty
---@return string|nil group only when node present in clipboard
function M.get_highlight(node)
if M.hl_pos == HL_POSITION.none then
return HL_POSITION.none, nil
end
local mark = marks.get_mark(node)
if mark then
return M.hl_pos, "NvimTreeBookmarkHL"
else
return HL_POSITION.none, nil
end
end
---bookmark icon if marked
---@param node table
---@return HighlightedString|nil bookmark icon
function M.get_icon(node)
if M.config.renderer.icons.show.bookmarks and marks.get_mark(node) then
return M.ICON
end
end
function M.setup(opts)
M.config = {
renderer = opts.renderer,
}
M.hl_pos = HL_POSITION[opts.renderer.highlight_bookmarks] or HL_POSITION.none
M.ICON = {
str = opts.renderer.icons.glyphs.bookmark,
hl = { "NvimTreeBookmark" },
}
vim.fn.sign_define(M.ICON.hl[1], { text = M.ICON.str, texthl = M.ICON.hl[1] })
end
return M

View File

@@ -1,37 +1,30 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local diagnostics = require "nvim-tree.diagnostics"
local M = {
-- highlight strings for the icons
HS_ICON = {},
-- highlight groups for HL
HG_FILE = {},
HG_FOLDER = {},
-- position for HL
HL_POS = HL_POSITION.none,
HS_FILE = {},
HS_FOLDER = {},
ICON = {},
hl_pos = HL_POSITION.none,
}
---Diagnostics highlight group and position when highlight_diagnostics.
---Diagnostics text highlight group when highlight_diagnostics.
---@param node table
---@return HL_POSITION position none when no status
---@return string|nil group only when status
function M.get_highlight(node)
if not node or M.HL_POS == HL_POSITION.none then
if not node or M.hl_pos == HL_POSITION.none then
return HL_POSITION.none, nil
end
local group
local diag_status = diagnostics.get_diag_status(node)
if node.nodes then
group = M.HS_FOLDER[diag_status and diag_status.value]
group = M.HS_FOLDER[node.diag_status]
else
group = M.HS_FILE[diag_status and diag_status.value]
group = M.HS_FILE[node.diag_status]
end
if group then
return M.HL_POS, group
return M.hl_pos, group
else
return HL_POSITION.none, nil
end
@@ -42,8 +35,7 @@ end
---@return HighlightedString|nil modified icon
function M.get_icon(node)
if node and M.config.diagnostics.enable and M.config.renderer.icons.show.diagnostics then
local diag_status = diagnostics.get_diag_status(node)
return M.ICON[diag_status and diag_status.value]
return M.ICON[node.diag_status]
end
end
@@ -54,38 +46,40 @@ function M.setup(opts)
}
if opts.diagnostics.enable and opts.renderer.highlight_diagnostics then
M.HL_POS = HL_POSITION[opts.renderer.highlight_diagnostics]
-- TODO add a HL_POSITION
-- M.hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics]
M.hl_pos = HL_POSITION.name
end
M.HG_FILE[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFileHL"
M.HG_FILE[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarningFileHL"
M.HG_FILE[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFileHL"
M.HG_FILE[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFileHL"
M.HS_FILE[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorText"
M.HS_FILE[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningText"
M.HS_FILE[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoText"
M.HS_FILE[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintText"
M.HG_FOLDER[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFolderHL"
M.HG_FOLDER[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarningFolderHL"
M.HG_FOLDER[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFolderHL"
M.HG_FOLDER[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFolderHL"
M.HS_FOLDER[vim.diagnostic.severity.ERROR] = "NvimTreeLspDiagnosticsErrorFolderText"
M.HS_FOLDER[vim.diagnostic.severity.WARN] = "NvimTreeLspDiagnosticsWarningFolderText"
M.HS_FOLDER[vim.diagnostic.severity.INFO] = "NvimTreeLspDiagnosticsInfoFolderText"
M.HS_FOLDER[vim.diagnostic.severity.HINT] = "NvimTreeLspDiagnosticsHintFolderText"
M.HS_ICON[vim.diagnostic.severity.ERROR] = {
M.ICON[vim.diagnostic.severity.ERROR] = {
str = M.config.diagnostics.icons.error,
hl = { "NvimTreeDiagnosticErrorIcon" },
hl = { "NvimTreeLspDiagnosticsError" },
}
M.HS_ICON[vim.diagnostic.severity.WARN] = {
M.ICON[vim.diagnostic.severity.WARN] = {
str = M.config.diagnostics.icons.warning,
hl = { "NvimTreeDiagnosticWarningIcon" },
hl = { "NvimTreeLspDiagnosticsWarning" },
}
M.HS_ICON[vim.diagnostic.severity.INFO] = {
M.ICON[vim.diagnostic.severity.INFO] = {
str = M.config.diagnostics.icons.info,
hl = { "NvimTreeDiagnosticInfoIcon" },
hl = { "NvimTreeLspDiagnosticsInformation" },
}
M.HS_ICON[vim.diagnostic.severity.HINT] = {
M.ICON[vim.diagnostic.severity.HINT] = {
str = M.config.diagnostics.icons.hint,
hl = { "NvimTreeDiagnosticHintIcon" },
hl = { "NvimTreeLspDiagnosticsHint" },
}
for _, i in ipairs(M.HS_ICON) do
for _, i in ipairs(M.ICON) do
vim.fn.sign_define(i.hl[1], { text = i.str, texthl = i.hl[1] })
end
end

View File

@@ -57,9 +57,9 @@ local function show()
end
M.popup_win = vim.api.nvim_open_win(vim.api.nvim_create_buf(false, false), false, {
relative = "win",
relative = "cursor",
row = 0,
bufpos = { vim.api.nvim_win_get_cursor(0)[1] - 1, 0 },
col = 1 - vim.fn.getcursorcharpos()[3],
width = math.min(text_width, vim.o.columns - 2),
height = 1,
noautocmd = true,

View File

@@ -0,0 +1,191 @@
local notify = require "nvim-tree.notify"
local explorer_node = require "nvim-tree.explorer.node"
local M = {}
local function build_icons_table(i)
local icons = {
staged = { str = i.staged, hl = { "NvimTreeGitStaged" }, ord = 1 },
unstaged = { str = i.unstaged, hl = { "NvimTreeGitDirty" }, ord = 2 },
renamed = { str = i.renamed, hl = { "NvimTreeGitRenamed" }, ord = 3 },
deleted = { str = i.deleted, hl = { "NvimTreeGitDeleted" }, ord = 4 },
unmerged = { str = i.unmerged, hl = { "NvimTreeGitMerge" }, ord = 5 },
untracked = { str = i.untracked, hl = { "NvimTreeGitNew" }, ord = 6 },
ignored = { str = i.ignored, hl = { "NvimTreeGitIgnored" }, ord = 7 },
}
return {
["M "] = { icons.staged },
[" M"] = { icons.unstaged },
["C "] = { icons.staged },
[" C"] = { icons.unstaged },
["CM"] = { icons.unstaged },
[" T"] = { icons.unstaged },
["T "] = { icons.staged },
["TM"] = { icons.staged, icons.unstaged },
["MM"] = { icons.staged, icons.unstaged },
["MD"] = { icons.staged },
["A "] = { icons.staged },
["AD"] = { icons.staged },
[" A"] = { icons.untracked },
-- not sure about this one
["AA"] = { icons.unmerged, icons.untracked },
["AU"] = { icons.unmerged, icons.untracked },
["AM"] = { icons.staged, icons.unstaged },
["??"] = { icons.untracked },
["R "] = { icons.renamed },
[" R"] = { icons.renamed },
["RM"] = { icons.unstaged, icons.renamed },
["UU"] = { icons.unmerged },
["UD"] = { icons.unmerged },
["UA"] = { icons.unmerged },
[" D"] = { icons.deleted },
["D "] = { icons.deleted },
["DA"] = { icons.unstaged },
["RD"] = { icons.deleted },
["DD"] = { icons.deleted },
["DU"] = { icons.deleted, icons.unmerged },
["!!"] = { icons.ignored },
dirty = { icons.unstaged },
}
end
local function build_hl_table()
local file = {
["M "] = "NvimTreeFileStaged",
["C "] = "NvimTreeFileStaged",
["AA"] = "NvimTreeFileStaged",
["AD"] = "NvimTreeFileStaged",
["MD"] = "NvimTreeFileStaged",
["T "] = "NvimTreeFileStaged",
["TT"] = "NvimTreeFileStaged",
[" M"] = "NvimTreeFileDirty",
["CM"] = "NvimTreeFileDirty",
[" C"] = "NvimTreeFileDirty",
[" T"] = "NvimTreeFileDirty",
["MM"] = "NvimTreeFileDirty",
["AM"] = "NvimTreeFileDirty",
dirty = "NvimTreeFileDirty",
["A "] = "NvimTreeFileStaged",
["??"] = "NvimTreeFileNew",
["AU"] = "NvimTreeFileMerge",
["UU"] = "NvimTreeFileMerge",
["UD"] = "NvimTreeFileMerge",
["DU"] = "NvimTreeFileMerge",
["UA"] = "NvimTreeFileMerge",
[" D"] = "NvimTreeFileDeleted",
["DD"] = "NvimTreeFileDeleted",
["RD"] = "NvimTreeFileDeleted",
["D "] = "NvimTreeFileDeleted",
["R "] = "NvimTreeFileRenamed",
["RM"] = "NvimTreeFileRenamed",
[" R"] = "NvimTreeFileRenamed",
["!!"] = "NvimTreeFileIgnored",
[" A"] = "none",
}
local folder = {}
for k, v in pairs(file) do
folder[k] = v:gsub("File", "Folder")
end
return file, folder
end
local function nil_() end
local function warn_status(git_status)
notify.warn(string.format("Unrecognized git state '%s'", git_status))
end
---@param node table
---@return HighlightedString[]|nil
local function get_icons_(node)
local git_status = explorer_node.get_git_status(node)
if git_status == nil then
return nil
end
local inserted = {}
local iconss = {}
for _, s in pairs(git_status) do
local icons = M.git_icons[s]
if not icons then
if not M.config.highlight_git then
warn_status(s)
end
return nil
end
for _, icon in pairs(icons) do
if #icon.str > 0 then
if not inserted[icon] then
table.insert(iconss, icon)
inserted[icon] = true
end
end
end
end
if #iconss == 0 then
return nil
end
-- sort icons so it looks slightly better
table.sort(iconss, function(a, b)
return a.ord < b.ord
end)
return iconss
end
function M.setup_signs(i)
vim.fn.sign_define("NvimTreeGitDirty", { text = i.unstaged, texthl = "NvimTreeGitDirty" })
vim.fn.sign_define("NvimTreeGitStaged", { text = i.staged, texthl = "NvimTreeGitStaged" })
vim.fn.sign_define("NvimTreeGitMerge", { text = i.unmerged, texthl = "NvimTreeGitMerge" })
vim.fn.sign_define("NvimTreeGitRenamed", { text = i.renamed, texthl = "NvimTreeGitRenamed" })
vim.fn.sign_define("NvimTreeGitNew", { text = i.untracked, texthl = "NvimTreeGitNew" })
vim.fn.sign_define("NvimTreeGitDeleted", { text = i.deleted, texthl = "NvimTreeGitDeleted" })
vim.fn.sign_define("NvimTreeGitIgnored", { text = i.ignored, texthl = "NvimTreeGitIgnored" })
end
local function get_highlight_(node)
local git_status = explorer_node.get_git_status(node)
if git_status == nil then
return
end
if node.nodes then
return M.folder_hl[git_status[1]]
else
return M.file_hl[git_status[1]]
end
end
function M.setup(opts)
M.config = opts.renderer
M.git_icons = build_icons_table(opts.renderer.icons.glyphs.git)
M.file_hl, M.folder_hl = build_hl_table()
if opts.renderer.icons.git_placement == "signcolumn" then
M.setup_signs(opts.renderer.icons.glyphs.git)
end
if opts.renderer.icons.show.git then
M.get_icons = get_icons_
else
M.get_icons = nil_
end
if opts.renderer.highlight_git then
M.get_highlight = get_highlight_
else
M.get_highlight = nil_
end
M.git_show_on_open_dirs = opts.git.show_on_open_dirs
end
return M

View File

@@ -0,0 +1,41 @@
local modified = require "nvim-tree.modified"
local M = {}
local HIGHLIGHT = "NvimTreeModifiedFile"
---return modified icon if node is modified, otherwise return empty string
---@param node table
---@return HighlightedString|nil modified icon
function M.get_icon(node)
if not modified.is_modified(node) or not M.show_icon then
return nil
end
return { str = M.icon, hl = { HIGHLIGHT } }
end
function M.setup_signs()
vim.fn.sign_define(HIGHLIGHT, { text = M.icon, texthl = HIGHLIGHT })
end
---@param node table
---@return string|nil
function M.get_highlight(node)
if not modified.is_modified(node) then
return nil
end
return HIGHLIGHT
end
function M.setup(opts)
M.icon = opts.renderer.icons.glyphs.modified
M.show_icon = opts.renderer.icons.show.modified
if opts.renderer.icons.modified_placement == "signcolumn" then
M.setup_signs()
end
end
return M

View File

@@ -1,51 +0,0 @@
local marks = require "nvim-tree.marks"
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"
---@class DecoratorBookmarks: Decorator
---@field icon HighlightedString
local DecoratorBookmarks = Decorator:new()
---@param opts table
---@return DecoratorBookmarks
function DecoratorBookmarks:new(opts)
local o = Decorator.new(self, {
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,
})
---@cast o DecoratorBookmarks
if opts.renderer.icons.show.bookmarks then
o.icon = {
str = opts.renderer.icons.glyphs.bookmark,
hl = { "NvimTreeBookmarkIcon" },
}
o:define_sign(o.icon)
end
return o
end
---Bookmark icon: renderer.icons.show.bookmarks and node is marked
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorBookmarks:calculate_icons(node)
if marks.get_mark(node) then
return { self.icon }
end
end
---Bookmark highlight: renderer.highlight_bookmarks and node is marked
---@param node Node
---@return string|nil group
function DecoratorBookmarks:calculate_highlight(node)
if self.hl_pos ~= HL_POSITION.none and marks.get_mark(node) then
return "NvimTreeBookmarkHL"
end
end
return DecoratorBookmarks

View File

@@ -1,38 +0,0 @@
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"
---@class DecoratorCopied: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorCopied = Decorator:new()
---@param opts table
---@return DecoratorCopied
function DecoratorCopied:new(opts)
local o = Decorator.new(self, {
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
---Copied highlight: renderer.highlight_clipboard and node is copied
---@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
return "NvimTreeCopiedHL"
end
end
return DecoratorCopied

View File

@@ -1,38 +0,0 @@
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"
---@class DecoratorCut: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorCut = Decorator:new()
---@param opts table
---@return DecoratorCut
function DecoratorCut:new(opts)
local o = Decorator.new(self, {
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
---Cut highlight: renderer.highlight_clipboard and node is cut
---@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
return "NvimTreeCutHL"
end
end
return DecoratorCut

View File

@@ -1,110 +0,0 @@
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"
-- highlight groups by severity
local HG_ICON = {
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorIcon",
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnIcon",
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoIcon",
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintIcon",
}
local HG_FILE = {
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFileHL",
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnFileHL",
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFileHL",
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFileHL",
}
local HG_FOLDER = {
[vim.diagnostic.severity.ERROR] = "NvimTreeDiagnosticErrorFolderHL",
[vim.diagnostic.severity.WARN] = "NvimTreeDiagnosticWarnFolderHL",
[vim.diagnostic.severity.INFO] = "NvimTreeDiagnosticInfoFolderHL",
[vim.diagnostic.severity.HINT] = "NvimTreeDiagnosticHintFolderHL",
}
-- opts.diagnostics.icons.
local ICON_KEYS = {
["error"] = vim.diagnostic.severity.ERROR,
["warning"] = vim.diagnostic.severity.WARN,
["info"] = vim.diagnostic.severity.INFO,
["hint"] = vim.diagnostic.severity.HINT,
}
---@class DecoratorDiagnostics: Decorator
---@field icons HighlightedString[]
local DecoratorDiagnostics = Decorator:new()
---@param opts table
---@return DecoratorDiagnostics
function DecoratorDiagnostics:new(opts)
local o = Decorator.new(self, {
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,
})
---@cast o DecoratorDiagnostics
if not o.enabled then
return o
end
if opts.renderer.icons.show.diagnostics then
o.icons = {}
for name, sev in pairs(ICON_KEYS) do
o.icons[sev] = {
str = opts.diagnostics.icons[name],
hl = { HG_ICON[sev] },
}
o:define_sign(o.icons[sev])
end
end
return o
end
---Diagnostic icon: diagnostics.enable, renderer.icons.show.diagnostics and node has status
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorDiagnostics:calculate_icons(node)
if node and self.enabled and self.icons then
local diag_status = diagnostics.get_diag_status(node)
local diag_value = diag_status and diag_status.value
if diag_value then
return { self.icons[diag_value] }
end
end
end
---Diagnostic highlight: diagnostics.enable, renderer.highlight_diagnostics and node has status
---@param node Node
---@return string|nil group
function DecoratorDiagnostics:calculate_highlight(node)
if not node or not self.enabled or self.hl_pos == HL_POSITION.none then
return nil
end
local diag_status = diagnostics.get_diag_status(node)
local diag_value = diag_status and diag_status.value
if not diag_value then
return nil
end
local group
if node.nodes then
group = HG_FOLDER[diag_value]
else
group = HG_FILE[diag_value]
end
if group then
return group
else
return nil
end
end
return DecoratorDiagnostics

View File

@@ -1,221 +0,0 @@
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"
---@class HighlightedStringGit: HighlightedString
---@field ord number decreasing priority
---@class 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
---@field icons_by_xy table<string, HighlightedStringGit[]> by porcelain status
local DecoratorGit = Decorator:new()
---@param opts table
---@return DecoratorGit
function DecoratorGit:new(opts)
local o = Decorator.new(self, {
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,
})
---@cast o DecoratorGit
if not o.enabled then
return o
end
if o.hl_pos ~= HL_POSITION.none then
o:build_hl_table()
end
if opts.renderer.icons.show.git then
o:build_icons_by_status(opts.renderer.icons.glyphs.git)
o:build_icons_by_xy(o.icons_by_status)
for _, icon in pairs(o.icons_by_status) do
self:define_sign(icon)
end
end
return o
end
---@param glyphs table<string, string> user glyps
function DecoratorGit:build_icons_by_status(glyphs)
self.icons_by_status = {
staged = { str = glyphs.staged, hl = { "NvimTreeGitStagedIcon" }, ord = 1 },
unstaged = { str = glyphs.unstaged, hl = { "NvimTreeGitDirtyIcon" }, ord = 2 },
renamed = { str = glyphs.renamed, hl = { "NvimTreeGitRenamedIcon" }, ord = 3 },
deleted = { str = glyphs.deleted, hl = { "NvimTreeGitDeletedIcon" }, ord = 4 },
unmerged = { str = glyphs.unmerged, hl = { "NvimTreeGitMergeIcon" }, ord = 5 },
untracked = { str = glyphs.untracked, hl = { "NvimTreeGitNewIcon" }, ord = 6 },
ignored = { str = glyphs.ignored, hl = { "NvimTreeGitIgnoredIcon" }, ord = 7 },
}
end
---@param icons HighlightedStringGit[]
function DecoratorGit:build_icons_by_xy(icons)
self.icons_by_xy = {
["M "] = { icons.staged },
[" M"] = { icons.unstaged },
["C "] = { icons.staged },
[" C"] = { icons.unstaged },
["CM"] = { icons.unstaged },
[" T"] = { icons.unstaged },
["T "] = { icons.staged },
["TM"] = { icons.staged, icons.unstaged },
["MM"] = { icons.staged, icons.unstaged },
["MD"] = { icons.staged },
["A "] = { icons.staged },
["AD"] = { icons.staged },
[" A"] = { icons.untracked },
-- not sure about this one
["AA"] = { icons.unmerged, icons.untracked },
["AU"] = { icons.unmerged, icons.untracked },
["AM"] = { icons.staged, icons.unstaged },
["??"] = { icons.untracked },
["R "] = { icons.renamed },
[" R"] = { icons.renamed },
["RM"] = { icons.unstaged, icons.renamed },
["UU"] = { icons.unmerged },
["UD"] = { icons.unmerged },
["UA"] = { icons.unmerged },
[" D"] = { icons.deleted },
["D "] = { icons.deleted },
["DA"] = { icons.unstaged },
["RD"] = { icons.deleted },
["DD"] = { icons.deleted },
["DU"] = { icons.deleted, icons.unmerged },
["!!"] = { icons.ignored },
dirty = { icons.unstaged },
}
end
function DecoratorGit:build_hl_table()
self.file_hl = {
["M "] = "NvimTreeGitFileStagedHL",
["C "] = "NvimTreeGitFileStagedHL",
["AA"] = "NvimTreeGitFileStagedHL",
["AD"] = "NvimTreeGitFileStagedHL",
["MD"] = "NvimTreeGitFileStagedHL",
["T "] = "NvimTreeGitFileStagedHL",
["TT"] = "NvimTreeGitFileStagedHL",
[" M"] = "NvimTreeGitFileDirtyHL",
["CM"] = "NvimTreeGitFileDirtyHL",
[" C"] = "NvimTreeGitFileDirtyHL",
[" T"] = "NvimTreeGitFileDirtyHL",
["MM"] = "NvimTreeGitFileDirtyHL",
["AM"] = "NvimTreeGitFileDirtyHL",
dirty = "NvimTreeGitFileDirtyHL",
["A "] = "NvimTreeGitFileStagedHL",
["??"] = "NvimTreeGitFileNewHL",
["AU"] = "NvimTreeGitFileMergeHL",
["UU"] = "NvimTreeGitFileMergeHL",
["UD"] = "NvimTreeGitFileMergeHL",
["DU"] = "NvimTreeGitFileMergeHL",
["UA"] = "NvimTreeGitFileMergeHL",
[" D"] = "NvimTreeGitFileDeletedHL",
["DD"] = "NvimTreeGitFileDeletedHL",
["RD"] = "NvimTreeGitFileDeletedHL",
["D "] = "NvimTreeGitFileDeletedHL",
["R "] = "NvimTreeGitFileRenamedHL",
["RM"] = "NvimTreeGitFileRenamedHL",
[" R"] = "NvimTreeGitFileRenamedHL",
["!!"] = "NvimTreeGitFileIgnoredHL",
[" A"] = "none",
}
self.folder_hl = {}
for k, v in pairs(self.file_hl) do
self.folder_hl[k] = v:gsub("File", "Folder")
end
end
---Git icons: git.enable, renderer.icons.show.git and node has status
---@param node Node
---@return HighlightedString[]|nil modified icon
function DecoratorGit:calculate_icons(node)
if not node or not self.enabled or not self.icons_by_xy then
return nil
end
local git_status = explorer_node.get_git_status(node)
if git_status == nil then
return nil
end
local inserted = {}
local iconss = {}
for _, s in pairs(git_status) do
local icons = self.icons_by_xy[s]
if not icons then
if self.hl_pos == HL_POSITION.none then
notify.warn(string.format("Unrecognized git state '%s'", git_status))
end
return nil
end
for _, icon in pairs(icons) do
if #icon.str > 0 then
if not inserted[icon] then
table.insert(iconss, icon)
inserted[icon] = true
end
end
end
end
if #iconss == 0 then
return nil
end
-- sort icons so it looks slightly better
table.sort(iconss, function(a, b)
return a.ord < b.ord
end)
return iconss
end
---Get the first icon as the sign if appropriate
---@param node Node
---@return string|nil name
function DecoratorGit:sign_name(node)
if self.icon_placement ~= ICON_PLACEMENT.signcolumn then
return
end
local icons = self:calculate_icons(node)
if icons and #icons > 0 then
return icons[1].hl[1]
end
end
---Git highlight: git.enable, renderer.highlight_git and node has status
---@param node Node
---@return string|nil group
function DecoratorGit:calculate_highlight(node)
if not node or not self.enabled or self.hl_pos == HL_POSITION.none then
return nil
end
local git_status = explorer_node.get_git_status(node)
if not git_status then
return nil
end
if node.nodes then
return self.folder_hl[git_status[1]]
else
return self.file_hl[git_status[1]]
end
end
return DecoratorGit

View File

@@ -1,122 +0,0 @@
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local ICON_PLACEMENT = require("nvim-tree.enum").ICON_PLACEMENT
---@class Decorator
---@field protected enabled boolean
---@field protected hl_pos HL_POSITION
---@field protected icon_placement ICON_PLACEMENT
local Decorator = {}
---@param o Decorator|nil
---@return Decorator
function Decorator:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
---Maybe highlight groups
---@param node Node
---@return string|nil icon highlight group
---@return string|nil name highlight group
function Decorator:groups_icon_name(node)
local icon_hl, name_hl
if self.enabled and self.hl_pos ~= HL_POSITION.none then
local hl = self:calculate_highlight(node)
if self.hl_pos == HL_POSITION.all or self.hl_pos == HL_POSITION.icon then
icon_hl = hl
end
if self.hl_pos == HL_POSITION.all or self.hl_pos == HL_POSITION.name then
name_hl = hl
end
end
return icon_hl, name_hl
end
---Maybe icon sign
---@param node Node
---@return string|nil name
function Decorator:sign_name(node)
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.signcolumn then
return
end
local icons = self:calculate_icons(node)
if icons and #icons > 0 then
return icons[1].hl[1]
end
end
---Icons when ICON_PLACEMENT.before
---@param node Node
---@return HighlightedString[]|nil icons
function Decorator:icons_before(node)
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.before then
return
end
return self:calculate_icons(node)
end
---Icons when ICON_PLACEMENT.after
---@param node Node
---@return HighlightedString[]|nil icons
function Decorator:icons_after(node)
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.after then
return
end
return self:calculate_icons(node)
end
---Maybe icons, optionally implemented
---@protected
---@param _ Node
---@return HighlightedString[]|nil icons
function Decorator:calculate_icons(_)
return nil
end
---Maybe highlight group, optionally implemented
---@protected
---@param _ Node
---@return string|nil group
function Decorator:calculate_highlight(_)
return nil
end
---Define a sign
---@protected
---@param icon HighlightedString|nil
function Decorator:define_sign(icon)
if icon and #icon.hl > 0 then
local name = icon.hl[1]
if not vim.tbl_isempty(vim.fn.sign_getdefined(name)) then
vim.fn.sign_undefine(name)
end
-- don't use sign if not defined
if #icon.str < 1 then
self.icon_placement = ICON_PLACEMENT.none
return
end
-- byte index of the next character, allowing for wide
local bi = vim.fn.byteidx(icon.str, 1)
-- first (wide) character, falls back to empty string
local text = string.sub(icon.str, 1, bi)
vim.fn.sign_define(name, {
text = text,
texthl = name,
})
end
end
return Decorator

View File

@@ -1,61 +0,0 @@
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"
---@class DecoratorModified: Decorator
---@field icon HighlightedString|nil
local DecoratorModified = Decorator:new()
---@param opts table
---@return DecoratorModified
function DecoratorModified:new(opts)
local o = Decorator.new(self, {
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,
})
---@cast o DecoratorModified
if not o.enabled then
return o
end
if opts.renderer.icons.show.modified then
o.icon = {
str = opts.renderer.icons.glyphs.modified,
hl = { "NvimTreeModifiedIcon" },
}
o:define_sign(o.icon)
end
return o
end
---Modified icon: modified.enable, renderer.icons.show.modified and node is modified
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorModified:calculate_icons(node)
if self.enabled and buffers.is_modified(node) then
return { self.icon }
end
end
---Modified highlight: modified.enable, renderer.highlight_modified and node is modified
---@param node Node
---@return string|nil group
function DecoratorModified:calculate_highlight(node)
if not self.enabled or self.hl_pos == HL_POSITION.none or not buffers.is_modified(node) then
return nil
end
if node.nodes then
return "NvimTreeModifiedFolderHL"
else
return "NvimTreeModifiedFileHL"
end
end
return DecoratorModified

View File

@@ -1,35 +0,0 @@
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"
---@class DecoratorOpened: Decorator
---@field enabled boolean
---@field icon HighlightedString|nil
local DecoratorOpened = Decorator:new()
---@param opts table
---@return DecoratorOpened
function DecoratorOpened:new(opts)
local o = Decorator.new(self, {
enabled = true,
hl_pos = HL_POSITION[opts.renderer.highlight_opened_files] or HL_POSITION.none,
icon_placement = ICON_PLACEMENT.none,
})
---@cast o DecoratorOpened
return o
end
---Opened highlight: renderer.highlight_opened_files and node has an open buffer
---@param node Node
---@return string|nil group
function DecoratorOpened:calculate_highlight(node)
if self.hl_pos ~= HL_POSITION.none and buffers.is_opened(node) then
return "NvimTreeOpenedHL"
end
end
return DecoratorOpened

View File

@@ -2,30 +2,33 @@ 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 modified = require "nvim-tree.renderer.components.modified"
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 git = require "nvim-tree.renderer.components.git"
local diagnostics = require "nvim-tree.renderer.components.diagnostics"
local Builder = require "nvim-tree.renderer.builder"
local live_filter = require "nvim-tree.live-filter"
local bookmarks = require "nvim-tree.renderer.components.bookmarks"
local M = {}
local M = {
last_highlights = {},
}
local SIGN_GROUP = "NvimTreeRendererSigns"
local namespace_id = vim.api.nvim_create_namespace "NvimTreeHighlights"
---@param bufnr number
---@param lines string[]
---@param hl_args AddHighlightArgs[]
---@param signs string[]
local function _draw(bufnr, lines, hl_args, signs)
local function _draw(bufnr, lines, hl, signs)
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
M.render_hl(bufnr, hl_args)
M.render_hl(bufnr, hl)
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.fn.sign_unplace(SIGN_GROUP)
for i, sign_name in pairs(signs) do
vim.fn.sign_place(0, SIGN_GROUP, sign_name, bufnr, { lnum = i + 1 })
for _, sign in pairs(signs) do
vim.fn.sign_place(0, SIGN_GROUP, sign.sign, bufnr, { lnum = sign.lnum, priority = sign.priority })
end
end
@@ -34,7 +37,7 @@ function M.render_hl(bufnr, hl)
return
end
vim.api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1)
for _, data in ipairs(hl) do
for _, data in ipairs(hl or M.last_highlights) do
if type(data[1]) == "table" then
for _, group in ipairs(data[1]) do
vim.api.nvim_buf_add_highlight(bufnr, namespace_id, group, data[2], data[3], data[4])
@@ -43,7 +46,16 @@ function M.render_hl(bufnr, hl)
end
end
function M.draw()
local picture_map = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
}
function M.draw(unloaded_bufnr)
local bufnr = view.get_bufnr()
if not core.get_explorer() or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
return
@@ -54,11 +66,30 @@ function M.draw()
local cursor = vim.api.nvim_win_get_cursor(view.get_winnr())
icon_component.reset_config()
local builder = Builder:new():build()
local lines, hl, signs = Builder.new(core.get_cwd())
:configure_root_label(M.config.root_folder_label)
:configure_trailing_slash(M.config.add_trailing)
:configure_special_files(M.config.special_files)
:configure_picture_map(picture_map)
:configure_opened_file_highlighting(M.config.highlight_opened_files)
:configure_modified_highlighting(M.config.highlight_modified)
:configure_icon_padding(M.config.icons.padding)
:configure_git_icons_placement(M.config.icons.git_placement)
:configure_diagnostics_icon_placement(M.config.icons.diagnostics_placement)
:configure_bookmark_icon_placement(M.config.icons.bookmarks_placement)
:configure_modified_placement(M.config.icons.modified_placement)
:configure_symlink_destination(M.config.symlink_destination)
:configure_filter(live_filter.filter, live_filter.prefix)
:configure_group_name_modifier(M.config.group_empty)
:build_header(view.is_root_folder_visible(core.get_cwd()))
:build(core.get_explorer(), unloaded_bufnr)
:unwrap()
_draw(bufnr, builder.lines, builder.hl_args, builder.signs)
_draw(bufnr, lines, hl, signs)
if cursor and #builder.lines >= cursor[1] then
M.last_highlights = hl
if cursor and #lines >= cursor[1] then
vim.api.nvim_win_set_cursor(view.get_winnr(), cursor)
end
@@ -71,12 +102,15 @@ end
function M.setup(opts)
M.config = opts.renderer
M.config.modified = opts.modified
_padding.setup(opts)
full_name.setup(opts)
git.setup(opts)
modified.setup(opts)
diagnostics.setup(opts)
bookmarks.setup(opts)
icon_component.setup(opts)
Builder.setup(opts)
end
return M

View File

@@ -116,28 +116,6 @@ function M.find_node(nodes, fn)
return node, i
end
-- Find the line number of a node.
-- Return -1 is node is nil or not found.
---@param node Node|nil
---@return integer
function M.find_node_line(node)
if not node then
return -1
end
local first_node_line = require("nvim-tree.core").get_nodes_starting_line()
local nodes_by_line = M.get_nodes_by_line(require("nvim-tree.core").get_explorer().nodes, first_node_line)
local iter_start, iter_end = first_node_line, #nodes_by_line
for line = iter_start, iter_end, 1 do
if nodes_by_line[line] == node then
return line
end
end
return -1
end
-- get the node in the tree state depending on the absolute path of the node
-- (grouped or hidden too)
---@param path string
@@ -172,10 +150,11 @@ function M.get_node_from_path(path)
end
--- Get the highest parent of grouped nodes
---@param node Node
---@return Node node or parent
function M.get_parent_of_group(node)
while node and node.parent and node.parent.group_next do
---@param node_ Node
---@return table
function M.get_parent_of_group(node_)
local node = node_
while node.parent and node.parent.group_next do
node = node.parent
end
return node

View File

@@ -473,7 +473,7 @@ end
function M.get_winnr(tabpage)
tabpage = tabpage or vim.api.nvim_get_current_tabpage()
local tabinfo = M.View.tabpages[tabpage]
if tabinfo and tabinfo.winnr and vim.api.nvim_win_is_valid(tabinfo.winnr) then
if tabinfo ~= nil then
return tabinfo.winnr
end
end

355
release-notes.md Normal file
View File

@@ -0,0 +1,355 @@
:robot: I have created a release *beep* *boop*
---
## 1.0.0 (2023-12-09)
### Features
* **#1079:** add renderer.highlight_clipboard default name, defaults to undercurls ([#2410](https://github.com/nvim-tree/nvim-tree.lua/issues/2410)) ([a3aa3b4](https://github.com/nvim-tree/nvim-tree.lua/commit/a3aa3b47eac8b6289f028743bef4ce9eb0f6782e))
* **#1245:** add next_diag_item and prev_diag_item actions ([80d4f28](https://github.com/nvim-tree/nvim-tree.lua/commit/80d4f2838353915cc1567f3547d535276af9ab4c))
* **#1389:** add git.show_on_dirs ([#1390](https://github.com/nvim-tree/nvim-tree.lua/issues/1390)) ([736cc84](https://github.com/nvim-tree/nvim-tree.lua/commit/736cc843e1294f7877a1f418860650dcc8e6f1c2))
* **#1669:** remove deprecated open_on_setup mechanisms ([#2122](https://github.com/nvim-tree/nvim-tree.lua/issues/2122)) ([48d53a5](https://github.com/nvim-tree/nvim-tree.lua/commit/48d53a5934fbd51b655d03db7dad35551838f2c9))
* **#1804:** add api.marks.bulk.delete with default bd mapping ([#2276](https://github.com/nvim-tree/nvim-tree.lua/issues/2276)) ([bdceaf5](https://github.com/nvim-tree/nvim-tree.lua/commit/bdceaf50966f5f4a2602eb54bfe8a3e52748a42b))
* **#1837:** add git.disable_for_dirs ([#2239](https://github.com/nvim-tree/nvim-tree.lua/issues/2239)) ([6306140](https://github.com/nvim-tree/nvim-tree.lua/commit/63061404f4686267673707c4baffed740b2cad6a))
* **#1917:** add diagnostic highlighting and icon placement ([#2396](https://github.com/nvim-tree/nvim-tree.lua/issues/2396)) ([323f65c](https://github.com/nvim-tree/nvim-tree.lua/commit/323f65cb9c6a4eae7a0b15e136fa668aeb7fde9b))
* **#1974:** enable experimental.git.async by default, see https://github.com/nvim-tree/nvim-tree.lua/issues/2104 ([#2158](https://github.com/nvim-tree/nvim-tree.lua/issues/2158)) ([f8bb6b4](https://github.com/nvim-tree/nvim-tree.lua/commit/f8bb6b4c76e03156fac38c45f9feea84632c65c4))
* **#1974:** experimental.git.async see https://github.com/nvim-tree/nvim-tree.lua/issues/2104 ([#2094](https://github.com/nvim-tree/nvim-tree.lua/issues/2094)) ([0ef3d46](https://github.com/nvim-tree/nvim-tree.lua/commit/0ef3d4613f90d8e92c1407ddf397b9ee61995526))
* **#2079:** sort_by may return predefined sort ([#2123](https://github.com/nvim-tree/nvim-tree.lua/issues/2123)) ([6ad5c26](https://github.com/nvim-tree/nvim-tree.lua/commit/6ad5c26f4d44791699c5538d9773cb141ba033e7))
* **#2092:** add api.node.navigate.open.next, prev ([#2093](https://github.com/nvim-tree/nvim-tree.lua/issues/2093)) ([0c9bfe7](https://github.com/nvim-tree/nvim-tree.lua/commit/0c9bfe7225156c54dd7c79292d6d6468fd1cb2a6))
* **#2148:** api.fs.rename_full ([#2461](https://github.com/nvim-tree/nvim-tree.lua/issues/2461)) ([0882354](https://github.com/nvim-tree/nvim-tree.lua/commit/08823545171eea269943c7e414cb266abffd0b1b))
* **#2197:** git and diagnostics folder highlight groups ([#2409](https://github.com/nvim-tree/nvim-tree.lua/issues/2409)) ([b7f6600](https://github.com/nvim-tree/nvim-tree.lua/commit/b7f6600bc2b4e48e4af45f1e77d2bf170685a542))
* **#2270:** add notify.absolute_path - show file or absolute path (default) names with notifications ([#2286](https://github.com/nvim-tree/nvim-tree.lua/issues/2286)) ([3cc698b](https://github.com/nvim-tree/nvim-tree.lua/commit/3cc698b35b0a67792c61e1726830bb9ecfc4c9f4))
* **#2277:** skip overwrite prompt when copy/cut paste into same directory ([#2278](https://github.com/nvim-tree/nvim-tree.lua/issues/2278)) ([7aff29d](https://github.com/nvim-tree/nvim-tree.lua/commit/7aff29d755c5b3932af3ea6b69b27df4f3b64bfe))
* **#2305:** find file refreshes up the tree when node is not present ([#2358](https://github.com/nvim-tree/nvim-tree.lua/issues/2358)) ([ace6422](https://github.com/nvim-tree/nvim-tree.lua/commit/ace64228ad5d89035fbe6f85e7f45a1f7b9e29c1))
* **#2312:** fire `TextYankPost` event on path copy ([#2489](https://github.com/nvim-tree/nvim-tree.lua/issues/2489)) ([c2194e9](https://github.com/nvim-tree/nvim-tree.lua/commit/c2194e940cf50033bbd05d6a31d8f1b5109bd280))
* **#2313:** sort_by -&gt; sort.sorter, add sort.folders_first default true ([#2314](https://github.com/nvim-tree/nvim-tree.lua/issues/2314)) ([ef305a8](https://github.com/nvim-tree/nvim-tree.lua/commit/ef305a888be2b9a0627369f00ccebbad88e6e3ce))
* **#2316:** add NvimTreeFolderArrowClosed NvimTreeFolderArrowOpen ([#2408](https://github.com/nvim-tree/nvim-tree.lua/issues/2408)) ([8f48426](https://github.com/nvim-tree/nvim-tree.lua/commit/8f48426c88cd91aa33610c96ad649f378d7bf718))
* **#2364:** add option to sort files first ([#2366](https://github.com/nvim-tree/nvim-tree.lua/issues/2366)) ([d11d701](https://github.com/nvim-tree/nvim-tree.lua/commit/d11d701857f4a520a0ee6f4d82d3bef155976be3))
* **#2369:** add full renderer.icons.web_devicons options for file and folder ([#2375](https://github.com/nvim-tree/nvim-tree.lua/issues/2375)) ([b144b33](https://github.com/nvim-tree/nvim-tree.lua/commit/b144b333901a8429311215c78ee0297aa899b80f))
* **#2398:** add NvimTreeOpenedFileIcon ([#2407](https://github.com/nvim-tree/nvim-tree.lua/issues/2407)) ([33c3bc5](https://github.com/nvim-tree/nvim-tree.lua/commit/33c3bc562b2ff3c6f5324af94054fc1f21b3c9f7))
* **#2411:** add renderer.highlight_bookmarks, renderer.icons.bookmarks_placement ([#2412](https://github.com/nvim-tree/nvim-tree.lua/issues/2412)) ([d49a284](https://github.com/nvim-tree/nvim-tree.lua/commit/d49a2842365e425971cd27ae31d73985b0ccc0bc))
* **#2498:** delete, trash prompts default N, added ui.confirm.default_yes option to override this behaviour ([#2500](https://github.com/nvim-tree/nvim-tree.lua/issues/2500)) ([c156856](https://github.com/nvim-tree/nvim-tree.lua/commit/c1568568b3f58d5cab87cf6a2a84717afe09d11d))
* **#2515:** add option to change grouped folders name with custom function ([#2521](https://github.com/nvim-tree/nvim-tree.lua/issues/2521)) ([a2aaf8b](https://github.com/nvim-tree/nvim-tree.lua/commit/a2aaf8b430c11af36b869cf1c0ad2f7c8ceeaf2c))
* **#2530:** keep alt filename on node.open.replace_tree_buffer ([#2531](https://github.com/nvim-tree/nvim-tree.lua/issues/2531)) ([52a1c99](https://github.com/nvim-tree/nvim-tree.lua/commit/52a1c99bf0bedb781ce4817c6ec3ebfe3af90f81))
* **#2544:** add api.tree.winid ([#2545](https://github.com/nvim-tree/nvim-tree.lua/issues/2545)) ([8c53482](https://github.com/nvim-tree/nvim-tree.lua/commit/8c534822a7d16c83cf69928c53e1d8a13bd2734a))
* **actions:** expand_all 'exclude' option ([#1388](https://github.com/nvim-tree/nvim-tree.lua/issues/1388)) ([21516f4](https://github.com/nvim-tree/nvim-tree.lua/commit/21516f447baf42f6f11421a017cd69306d5d5ff3))
* add -bar option to command definitions ([#1422](https://github.com/nvim-tree/nvim-tree.lua/issues/1422)) ([c231933](https://github.com/nvim-tree/nvim-tree.lua/commit/c231933fcdc8855c813f368e48025a368864a636))
* add actions.open_file.eject ([#2341](https://github.com/nvim-tree/nvim-tree.lua/issues/2341)) ([4bd30f0](https://github.com/nvim-tree/nvim-tree.lua/commit/4bd30f0137e44dcf3e74cc1164efb568f78f2b02))
* add confirmation kind to select y/n ([ba5c18d](https://github.com/nvim-tree/nvim-tree.lua/commit/ba5c18dc2b43599067d999933469098073e1941c))
* add cwd arg to open_replacing_current_buffer ([#1348](https://github.com/nvim-tree/nvim-tree.lua/issues/1348)) ([6b7b1b3](https://github.com/nvim-tree/nvim-tree.lua/commit/6b7b1b34fa6c4851a7b06a9ce4a1a703de7fd0ed))
* add cwd arg to open_replacing_current_buffer: retain existing valid buffer check ([6548287](https://github.com/nvim-tree/nvim-tree.lua/commit/6548287e8b84552d40d28f9e122f7eedf1f331bd))
* add diagnostics.show_on_open_dirs git.show_on_open_dirs ([#1778](https://github.com/nvim-tree/nvim-tree.lua/issues/1778)) ([829e9f6](https://github.com/nvim-tree/nvim-tree.lua/commit/829e9f68e10a998198e17bf5b348a6947f9d3c2e))
* add filters.git_ignored (prev git.ignore), apply "Toggle Filter:" prefix to mapping descriptions ([#2325](https://github.com/nvim-tree/nvim-tree.lua/issues/2325)) ([697bfac](https://github.com/nvim-tree/nvim-tree.lua/commit/697bfaccac4a4843449ce7a7b14adb0e7989befe))
* add NvimTreeCursorLineNr ([#1616](https://github.com/nvim-tree/nvim-tree.lua/issues/1616)) ([7282f7d](https://github.com/nvim-tree/nvim-tree.lua/commit/7282f7de8aedf861fe0162a559fc2b214383c51c))
* add NvimTreeFindFile!, root_dirs and prefer_startup_root ([b08003f](https://github.com/nvim-tree/nvim-tree.lua/commit/b08003f54640f2015e54dfcd39685862908bfc6a))
* add NvimTreeNormalFloat ([#2167](https://github.com/nvim-tree/nvim-tree.lua/issues/2167)) ([98b76ff](https://github.com/nvim-tree/nvim-tree.lua/commit/98b76ff0a2f2725b6c0d1b7491ec85ca760c9f3f))
* add NvimTreeSymlinkIcon ([#2198](https://github.com/nvim-tree/nvim-tree.lua/issues/2198)) ([736c7ff](https://github.com/nvim-tree/nvim-tree.lua/commit/736c7ff59065275f0483af4b7f07a9bc41449ad0))
* add on_tree_resize event ([c847354](https://github.com/nvim-tree/nvim-tree.lua/commit/c84735483f20b692ffaffb2b889a8956a9a425a4))
* add option for folder arrows to be inline with indent markers ([#1468](https://github.com/nvim-tree/nvim-tree.lua/issues/1468)) ([7fcb48c](https://github.com/nvim-tree/nvim-tree.lua/commit/7fcb48c852b9d58709169a4dc1ec634fa9ea56f9))
* add sort_by "filetype" ([#2302](https://github.com/nvim-tree/nvim-tree.lua/issues/2302)) ([3d2fd90](https://github.com/nvim-tree/nvim-tree.lua/commit/3d2fd90b2869f2b4679d540dd0145d002d9688c3))
* add sort_by "suffix" ([#2307](https://github.com/nvim-tree/nvim-tree.lua/issues/2307)) ([a708bd2](https://github.com/nvim-tree/nvim-tree.lua/commit/a708bd2413d467929b5019ec1bce7b1f428438bc))
* add ui.confirm.remove and ui.confirm.trash, deprecate trash.require_confirm ([#1887](https://github.com/nvim-tree/nvim-tree.lua/issues/1887)) ([ccb6d8a](https://github.com/nvim-tree/nvim-tree.lua/commit/ccb6d8a518d32e22bf5874f90e6c22661a5d8b46))
* add winid parameter for api.tree.open, toggle, find_file ([#2213](https://github.com/nvim-tree/nvim-tree.lua/issues/2213)) ([b1e074d](https://github.com/nvim-tree/nvim-tree.lua/commit/b1e074d2b52d45c8327b5b43a498b3d7e6c93b97))
* allow cycling on git/diagnostic/opened files navigation ([#2506](https://github.com/nvim-tree/nvim-tree.lua/issues/2506)) ([0a99c4a](https://github.com/nvim-tree/nvim-tree.lua/commit/0a99c4a23eae8e25285a30d08439aee8da4f5c16))
* api.marks.bulk.trash ([#2391](https://github.com/nvim-tree/nvim-tree.lua/issues/2391)) ([7f7665a](https://github.com/nvim-tree/nvim-tree.lua/commit/7f7665a17b60d80533b7a69cfad3b6875f2dd453))
* api.node.open.preview_no_picker with default mapping &lt;S-Tab&gt; ([#2464](https://github.com/nvim-tree/nvim-tree.lua/issues/2464)) ([aaee4cd](https://github.com/nvim-tree/nvim-tree.lua/commit/aaee4cd896b74f85a81bed7eef2db7869960c4d0))
* **api:** add `node.open.drop()` ([#2164](https://github.com/nvim-tree/nvim-tree.lua/issues/2164)) ([0df384b](https://github.com/nvim-tree/nvim-tree.lua/commit/0df384b6c0fa62ff1333634d56ee4df0be5d34e1))
* **api:** add api.commands.get ([#2083](https://github.com/nvim-tree/nvim-tree.lua/issues/2083)) ([45400cd](https://github.com/nvim-tree/nvim-tree.lua/commit/45400cd7e02027937cd5e49845545e606ecf5a1f))
* **api:** add api.config.mappings.active, api.config.mappings.default ([#1876](https://github.com/nvim-tree/nvim-tree.lua/issues/1876)) ([bac962c](https://github.com/nvim-tree/nvim-tree.lua/commit/bac962caf472a4404ed3ce1ba2fcaf32f8002951))
* **api:** add api.config.mappings.default_on_attach ([#2037](https://github.com/nvim-tree/nvim-tree.lua/issues/2037)) ([bbb6d48](https://github.com/nvim-tree/nvim-tree.lua/commit/bbb6d4891009de7dab05ad8fc2d39f272d7a751c))
* **api:** add api.config.mappings.get_keymap and get_keymap_default ([#2056](https://github.com/nvim-tree/nvim-tree.lua/issues/2056)) ([4f03634](https://github.com/nvim-tree/nvim-tree.lua/commit/4f036342f14378b53ac5d7c6ae8d8f6d1bf9a0f8))
* **api:** add api.fs.clear_clipboard ([#1706](https://github.com/nvim-tree/nvim-tree.lua/issues/1706)) ([cbb5313](https://github.com/nvim-tree/nvim-tree.lua/commit/cbb5313f9044a2ccf0b3e0f85a9e6a4e0fd0dd40))
* **api:** add api.marks.clear ([#1708](https://github.com/nvim-tree/nvim-tree.lua/issues/1708)) ([cd2f756](https://github.com/nvim-tree/nvim-tree.lua/commit/cd2f7569dbf19ae989fcc0c1906df079b8247797))
* **api:** add api.tree.get_nodes ([e38e061](https://github.com/nvim-tree/nvim-tree.lua/commit/e38e061710c593d9b88c8ebb2c48f2842c89dc31))
* **api:** Add new node selection action based on tab :drop command ([#2161](https://github.com/nvim-tree/nvim-tree.lua/issues/2161)) ([d68b00a](https://github.com/nvim-tree/nvim-tree.lua/commit/d68b00a63e98ee02a415e27b3f40cb802b8f1906))
* **api:** add public API module ([#1432](https://github.com/nvim-tree/nvim-tree.lua/issues/1432)) ([e783278](https://github.com/nvim-tree/nvim-tree.lua/commit/e7832785d2abfc3b8dd67655076eeffddb3141e9))
* **api:** add tree.is_visible, tree.is_tree_buf ([#2150](https://github.com/nvim-tree/nvim-tree.lua/issues/2150)) ([a774fa1](https://github.com/nvim-tree/nvim-tree.lua/commit/a774fa186c19945d2a594de80922da2cbb4a0139))
* **api:** api.tree.find_file feature parity with open/toggle, convert all commands to API, document commands ([#2039](https://github.com/nvim-tree/nvim-tree.lua/issues/2039)) ([fe980ba](https://github.com/nvim-tree/nvim-tree.lua/commit/fe980baa945100d92f77fe55e2ca113cae1b1bd3))
* **api:** api.tree.open feature parity with api.tree.toggle ([#1955](https://github.com/nvim-tree/nvim-tree.lua/issues/1955)) ([215b29b](https://github.com/nvim-tree/nvim-tree.lua/commit/215b29bfad74518442621b9d0483a621483b066b))
* **api:** api.tree.open/toggle: add current_window option ([#1935](https://github.com/nvim-tree/nvim-tree.lua/issues/1935)) ([f1c2d6d](https://github.com/nvim-tree/nvim-tree.lua/commit/f1c2d6d3723947d822930e66cd4d3351a3c0370a))
* **api:** rename_basename API and action ([#1791](https://github.com/nvim-tree/nvim-tree.lua/issues/1791)) ([949913f](https://github.com/nvim-tree/nvim-tree.lua/commit/949913f1860eb85024fa1967dbd89ac797777b0d))
* automated migration from view.mappings.list to on_attach, see https://github.com/nvim-tree/nvim-tree.lua/wiki/Migrating-To-on_attach ([#1579](https://github.com/nvim-tree/nvim-tree.lua/issues/1579)) ([7495975](https://github.com/nvim-tree/nvim-tree.lua/commit/74959750f7823d6e069d3948a645f3c7a4c00638))
* **bookmarks:** add bookmark feature ([#1412](https://github.com/nvim-tree/nvim-tree.lua/issues/1412)) ([df92f15](https://github.com/nvim-tree/nvim-tree.lua/commit/df92f1527f30d19fbf3474af2badc0636a2d70bf))
* **copy-paste:** use vim.ui from prompting ([69aec67](https://github.com/nvim-tree/nvim-tree.lua/commit/69aec67edb046aa94c6a2a7aef7ec83bbcfb36b5))
* **create-file:** use vim.ui.select for confirmation ([1ee6a3e](https://github.com/nvim-tree/nvim-tree.lua/commit/1ee6a3ea65764bee4ca8114652308ee48d789031)), closes [#1434](https://github.com/nvim-tree/nvim-tree.lua/issues/1434) [#1294](https://github.com/nvim-tree/nvim-tree.lua/issues/1294)
* deprecate view.mappings, see https://github.com/nvim-tree/nvim-tree.lua/wiki/Migrating-To-on_attach ([#2143](https://github.com/nvim-tree/nvim-tree.lua/issues/2143)) ([5aa318c](https://github.com/nvim-tree/nvim-tree.lua/commit/5aa318c15934efa03d2ac86b493e89792e06c7b6))
* **diagnostics:** add diagnostics.severity ([#1755](https://github.com/nvim-tree/nvim-tree.lua/issues/1755)) ([68a2a09](https://github.com/nvim-tree/nvim-tree.lua/commit/68a2a0971eb50f13e4d54498a2add73f131b9a85))
* **event:** add au, global: NvimTreeRequired, NvimTreeSetup ([#1912](https://github.com/nvim-tree/nvim-tree.lua/issues/1912)) ([1f0fc8d](https://github.com/nvim-tree/nvim-tree.lua/commit/1f0fc8d6e8c7900533b78b467e37710e9c813ae8))
* **event:** add TreeAttachedPost ([#1877](https://github.com/nvim-tree/nvim-tree.lua/issues/1877)) ([f43f311](https://github.com/nvim-tree/nvim-tree.lua/commit/f43f3110a570512a4a4ff76a1103d734f02f6b32))
* **event:** add TreeRendered ([#2324](https://github.com/nvim-tree/nvim-tree.lua/issues/2324)) ([3b62c6b](https://github.com/nvim-tree/nvim-tree.lua/commit/3b62c6bf2c3f2973036aed609d02fd0ca9c3af35))
* **event:** add WillCreateFile, WillRemoveFile ([#2273](https://github.com/nvim-tree/nvim-tree.lua/issues/2273)) ([c3c6544](https://github.com/nvim-tree/nvim-tree.lua/commit/c3c6544ee00333b0f1d6a13735d0dd302dba4f70))
* **event:** add WillRenameNode ([#1821](https://github.com/nvim-tree/nvim-tree.lua/issues/1821)) ([a2c7556](https://github.com/nvim-tree/nvim-tree.lua/commit/a2c75567add11a0f76cd61f4dfc86df8cbd4b017))
* **event:** dispatch Event.NodeRenamed on cut-paste ([#1817](https://github.com/nvim-tree/nvim-tree.lua/issues/1817)) ([e49fa4e](https://github.com/nvim-tree/nvim-tree.lua/commit/e49fa4e52900ddc218cfaa6d7e3345c97a086d40))
* **file-popup:** add actions.file_popup.open_win_config ([a73d0d4](https://github.com/nvim-tree/nvim-tree.lua/commit/a73d0d4800d517f737d5d6d69283426b48bdf7f3))
* focus_empty_on_setup ([0417d91](https://github.com/nvim-tree/nvim-tree.lua/commit/0417d9148b6546bf4883b6e9750f992f980afbfe))
* **git:** add TM git status ([#2045](https://github.com/nvim-tree/nvim-tree.lua/issues/2045)) ([1830e5e](https://github.com/nvim-tree/nvim-tree.lua/commit/1830e5e8a46b32575130bf04bbe0a773999ccb73))
* **git:** support `DA` state, fix([#1822](https://github.com/nvim-tree/nvim-tree.lua/issues/1822)): test directory capable of watching before presenting it ([#1905](https://github.com/nvim-tree/nvim-tree.lua/issues/1905)) ([3ce0a8e](https://github.com/nvim-tree/nvim-tree.lua/commit/3ce0a8e770f70a135ef969e0a640bd8d05baf42c))
* **log:** add node inspection function ([#2541](https://github.com/nvim-tree/nvim-tree.lua/issues/2541)) ([5231562](https://github.com/nvim-tree/nvim-tree.lua/commit/5231562cafd7044c827c8b5cfd7b1391894761cc))
* mapping and options to sort entries in help window ([#2482](https://github.com/nvim-tree/nvim-tree.lua/issues/2482)) ([78a9ca5](https://github.com/nvim-tree/nvim-tree.lua/commit/78a9ca5ed6557f29cd0ce203df44213e54bfabb9))
* **mapping:** deprecate user mappings and add on_attach ([#1424](https://github.com/nvim-tree/nvim-tree.lua/issues/1424)) ([64cc3c1](https://github.com/nvim-tree/nvim-tree.lua/commit/64cc3c17e1a8d00d0fafcb61349b2a7d57234e53))
* **marks:** add bulk move action ([#1419](https://github.com/nvim-tree/nvim-tree.lua/issues/1419)) ([26512c3](https://github.com/nvim-tree/nvim-tree.lua/commit/26512c369fdb8b1e2bd80d0039dffac2088f85d8))
* **marks:** add navigation (next, previous, select) ([#1415](https://github.com/nvim-tree/nvim-tree.lua/issues/1415)) ([89becc7](https://github.com/nvim-tree/nvim-tree.lua/commit/89becc7604719a6d81e7a31e4b4221affa145e89))
* **movement:** allow circular movement for sibling next and prev ([#1416](https://github.com/nvim-tree/nvim-tree.lua/issues/1416)) ([b32c883](https://github.com/nvim-tree/nvim-tree.lua/commit/b32c88333f8e19685da5f301bb63a30ba685d0cb))
* notify [NvimTree] prefix is multiline only if the message is multiline ([#2453](https://github.com/nvim-tree/nvim-tree.lua/issues/2453)) ([e64a498](https://github.com/nvim-tree/nvim-tree.lua/commit/e64a498a5eb9169ff9673ef6a409005040d29c4c))
* **notify:** add notify.threshold ([#1693](https://github.com/nvim-tree/nvim-tree.lua/issues/1693)) ([6ca6f99](https://github.com/nvim-tree/nvim-tree.lua/commit/6ca6f99e7689c68679e8f0a58b421545ff52931f))
* **notify:** switch all print/nvim_*write statements to utils.notify ([1844713](https://github.com/nvim-tree/nvim-tree.lua/commit/18447132fce62dad87624efdb395fd6b2bebbc35))
* paste and create always target closed folder, remove create_in_closed_folder ([#1802](https://github.com/nvim-tree/nvim-tree.lua/issues/1802)) ([7177d95](https://github.com/nvim-tree/nvim-tree.lua/commit/7177d95ac0f46bf02ff3f8375e135149a3fc79b8))
* **picker:** allow custom function actions.open_file.window_picker.picker ([#1782](https://github.com/nvim-tree/nvim-tree.lua/issues/1782)) ([d85b671](https://github.com/nvim-tree/nvim-tree.lua/commit/d85b6718cef7f27c603cf170fb5154d90356e90b))
* **remove-file:** use vim.ui.select ([2d629ca](https://github.com/nvim-tree/nvim-tree.lua/commit/2d629cab78e6e25374037982531aee95c6e89b10))
* renderer.full_name includes root node ([#2502](https://github.com/nvim-tree/nvim-tree.lua/issues/2502)) ([7e3c0be](https://github.com/nvim-tree/nvim-tree.lua/commit/7e3c0bee7b246ca835d5f7453db6fa19de359bab))
* **renderer:** add NvimTreeOpenedFolderIcon NvimTreeClosedFolderIcon ([#1768](https://github.com/nvim-tree/nvim-tree.lua/issues/1768)) ([0b319a1](https://github.com/nvim-tree/nvim-tree.lua/commit/0b319a1b284a2e75faa46107d2cda31a30e946bc))
* **renderer:** add NvimTreeSymlinkFolderName ([#2000](https://github.com/nvim-tree/nvim-tree.lua/issues/2000)) ([f3dbddf](https://github.com/nvim-tree/nvim-tree.lua/commit/f3dbddf8b3fbd5de7c8838eafc1b3b72cd30c73e))
* **renderer:** add renderer.indent_width ([#1505](https://github.com/nvim-tree/nvim-tree.lua/issues/1505)) ([e8bf3d7](https://github.com/nvim-tree/nvim-tree.lua/commit/e8bf3d778a74882d748f55d67af206fa8b321d99))
* **renderer:** add renderer.root_folder_label ([#1746](https://github.com/nvim-tree/nvim-tree.lua/issues/1746)) ([99d7136](https://github.com/nvim-tree/nvim-tree.lua/commit/99d713644d44b573d076812ee5bfcaa5290aaa25))
* **renderer:** show symlink folder destination ([ad1f3ef](https://github.com/nvim-tree/nvim-tree.lua/commit/ad1f3ef3bc86ca43ebf488569aadf6f56e448575))
* **search-node:** use vim.ui.input ([1b667bc](https://github.com/nvim-tree/nvim-tree.lua/commit/1b667bc99e1e2cf090362579726fa2a55a4e1acc))
* **sorters:** allow user sort_by ([3676e0b](https://github.com/nvim-tree/nvim-tree.lua/commit/3676e0b124c2a132857e2bbcf7f48f05228f1052))
* split startup warning messages into multiple lines ([#2436](https://github.com/nvim-tree/nvim-tree.lua/issues/2436)) ([113e095](https://github.com/nvim-tree/nvim-tree.lua/commit/113e0950c88b81b01d253d8f3da17bbd0e6716bb))
* support custom $GIT_DIR ([#2263](https://github.com/nvim-tree/nvim-tree.lua/issues/2263)) ([a6daf50](https://github.com/nvim-tree/nvim-tree.lua/commit/a6daf50b9d1aa426f557e51b37ee854b99782d3f))
* support vim.diagnostic.is_disabled() ([#2232](https://github.com/nvim-tree/nvim-tree.lua/issues/2232)) ([8d82c4d](https://github.com/nvim-tree/nvim-tree.lua/commit/8d82c4dbe15913655b509dcf1179b2ac7c69f9c5))
* **tab_change:** introduce new option to filter buffer by bufname or ft ([79434c2](https://github.com/nvim-tree/nvim-tree.lua/commit/79434c2b3cd86aebc652db042c17f3b433bfd47c))
* **tabs:** add tab.sync options ([#1698](https://github.com/nvim-tree/nvim-tree.lua/issues/1698)) ([c494994](https://github.com/nvim-tree/nvim-tree.lua/commit/c49499413a875fc99ce8594cfe6474ed684e51eb))
* **trash:** add synchronized trash support for windows ([#2335](https://github.com/nvim-tree/nvim-tree.lua/issues/2335)) ([75c0574](https://github.com/nvim-tree/nvim-tree.lua/commit/75c05742bc1f96d9606ee315b3c649973c4fb1cd))
* **trash:** use vim.ui.select for confirmation ([7cffe14](https://github.com/nvim-tree/nvim-tree.lua/commit/7cffe14743279a7fa05dcd21a09a575e777c55f6))
* use IEC binary size prefixes ([#2483](https://github.com/nvim-tree/nvim-tree.lua/issues/2483)) ([83b6995](https://github.com/nvim-tree/nvim-tree.lua/commit/83b699533b279af6d207d6c3860d4301556d65b4))
* use virtual title in notifications if title is not supported ([#2439](https://github.com/nvim-tree/nvim-tree.lua/issues/2439)) ([85abe29](https://github.com/nvim-tree/nvim-tree.lua/commit/85abe2939620fe63b73ec97d3e2e0c7f2ec4fe23))
* validate all option types ([#2414](https://github.com/nvim-tree/nvim-tree.lua/issues/2414)) ([ea14741](https://github.com/nvim-tree/nvim-tree.lua/commit/ea147418e07e1ca7a867c753c906d27c39863273))
* validate some option string values ([#2404](https://github.com/nvim-tree/nvim-tree.lua/issues/2404)) ([51f0236](https://github.com/nvim-tree/nvim-tree.lua/commit/51f02366deed1f21153c564b546fed813acfd6d8))
* **view:** add filters.git_clean, filters.no_buffer ([#1784](https://github.com/nvim-tree/nvim-tree.lua/issues/1784)) ([c5dc80c](https://github.com/nvim-tree/nvim-tree.lua/commit/c5dc80c36b6855cb30bff8e743838b9da97219b3))
* **view:** add float.quit_on_focus_loss, float respects actions.open_file.quit_on_open ([#1621](https://github.com/nvim-tree/nvim-tree.lua/issues/1621)) ([79f631b](https://github.com/nvim-tree/nvim-tree.lua/commit/79f631bc1d52b387f4ae59fad1291d894afa97f5))
* **view:** add view.cursorline ([#1859](https://github.com/nvim-tree/nvim-tree.lua/issues/1859)) ([9ad93b6](https://github.com/nvim-tree/nvim-tree.lua/commit/9ad93b6ac062acca6d50563bf3984b287e10f721))
* **view:** add view.width.min/max replacing adaptive_size, allowing upper bound ([#1915](https://github.com/nvim-tree/nvim-tree.lua/issues/1915)) ([96506fe](https://github.com/nvim-tree/nvim-tree.lua/commit/96506fee49542f3aedab76368d400a147fea344e))
* **view:** add view.width.padding ([#1941](https://github.com/nvim-tree/nvim-tree.lua/issues/1941)) ([e05ed6a](https://github.com/nvim-tree/nvim-tree.lua/commit/e05ed6a60ff4fa70063f74edbf07ef8365eaabae))
* **view:** allow function for view.float.open_win_config ([#1538](https://github.com/nvim-tree/nvim-tree.lua/issues/1538)) ([c3ea264](https://github.com/nvim-tree/nvim-tree.lua/commit/c3ea264947671f44d836af5b7587e12c4b4611f9))
* **view:** always enable cursorline, users may change this behaviour via Event.TreeOpen ([#1814](https://github.com/nvim-tree/nvim-tree.lua/issues/1814)) ([69a07d1](https://github.com/nvim-tree/nvim-tree.lua/commit/69a07d169ae8c1de90904bd5fb9e1dd27eff6d30))
* **view:** deprecate open_on_setup.* in favour of https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup ([#1951](https://github.com/nvim-tree/nvim-tree.lua/issues/1951)) ([fb775b3](https://github.com/nvim-tree/nvim-tree.lua/commit/fb775b335389590f96ba22097b6a36a7c2f161ab))
* **view:** float.quit_on_focus_loss documentation clarification ([4a01f90](https://github.com/nvim-tree/nvim-tree.lua/commit/4a01f90d111d8a85a79502478f6f4e9ef13df74d))
* **view:** Floating nvim tree window [#1377](https://github.com/nvim-tree/nvim-tree.lua/issues/1377) ([#1462](https://github.com/nvim-tree/nvim-tree.lua/issues/1462)) ([7323c81](https://github.com/nvim-tree/nvim-tree.lua/commit/7323c81bd6209c247248244b12682cc345630301))
* **view:** floating window's optional adaptive size specification ([#1559](https://github.com/nvim-tree/nvim-tree.lua/issues/1559)) ([757951b](https://github.com/nvim-tree/nvim-tree.lua/commit/757951ba6b3ee6b0f502c4bd4a23c53b382305c2))
* **view:** indicate modified buffers ([#1835](https://github.com/nvim-tree/nvim-tree.lua/issues/1835)) ([dcc344c](https://github.com/nvim-tree/nvim-tree.lua/commit/dcc344cc72a617ff01db950aedfd3b3430ba5b59))
* **watcher:** add filesystem_watchers.ignore_dirs ([#1705](https://github.com/nvim-tree/nvim-tree.lua/issues/1705)) ([ed9db63](https://github.com/nvim-tree/nvim-tree.lua/commit/ed9db632a89ff2712c48e32774d68a715553510f))
* **watcher:** debounce FS watchers ([e401a4c](https://github.com/nvim-tree/nvim-tree.lua/commit/e401a4c9570f433053604fd9d98833376d5982fe))
* **watcher:** partial git refresh ([#1373](https://github.com/nvim-tree/nvim-tree.lua/issues/1373)) ([7a795d7](https://github.com/nvim-tree/nvim-tree.lua/commit/7a795d78fa2a102de197e81b85f5b1e6b5f366a3))
* **watcher:** tear down watcher on failue, warning the user ([#1707](https://github.com/nvim-tree/nvim-tree.lua/issues/1707)) ([a0f3e99](https://github.com/nvim-tree/nvim-tree.lua/commit/a0f3e99b2dc46b441c1a1db09eaf6338f1c5298a))
### Bug Fixes
* **#1270:** ensure explorer exists at startup before propagating FS changes ([55aa006](https://github.com/nvim-tree/nvim-tree.lua/commit/55aa0062b974e1fc29b4462c745271ae40009eda))
* **#1270:** open_on_setup_file does not override open_on_setup, hijack_directories does not override startup behaviour ([#1618](https://github.com/nvim-tree/nvim-tree.lua/issues/1618)) ([c5536db](https://github.com/nvim-tree/nvim-tree.lua/commit/c5536db0b7a9e13709af16a0ffe1ab20137f8a48))
* **#1354:** add missing :hi NvimTreeFileIgnored ([#1358](https://github.com/nvim-tree/nvim-tree.lua/issues/1358)) ([1fc0eee](https://github.com/nvim-tree/nvim-tree.lua/commit/1fc0eee9465f764bd3c8fab1900efe13318b28c9))
* **#1356:** view.close switch_buf_if_last_buf prefers alt buf ([#1357](https://github.com/nvim-tree/nvim-tree.lua/issues/1357)) ([d9aaa2f](https://github.com/nvim-tree/nvim-tree.lua/commit/d9aaa2f985c69ae1452e067e33e8a11ec84196a1))
* **#1366:** warn when trash cmd missing ([#1378](https://github.com/nvim-tree/nvim-tree.lua/issues/1378)) ([7285898](https://github.com/nvim-tree/nvim-tree.lua/commit/72858986f9de019dc0e151c76090de29954081f0))
* **#1406:** allow nvim-tree.renderer.icons.show.folder_arrow ([fd562ed](https://github.com/nvim-tree/nvim-tree.lua/commit/fd562ede63c6dac8938276f901e1e6d46ac8b293))
* **#1479:** apply remove_keymaps to default mappings ([cfc4692](https://github.com/nvim-tree/nvim-tree.lua/commit/cfc4692a3fd5e5afa7321b878eb8364e7617d7b7))
* **#1480:** break symlink cycle on find-file, search-node ([#1482](https://github.com/nvim-tree/nvim-tree.lua/issues/1482)) ([261a5c3](https://github.com/nvim-tree/nvim-tree.lua/commit/261a5c380c000e23c4a23dcd55b984c856cdb113))
* **#1484:** better error handling in git utils get_toplevel ([ff6e796](https://github.com/nvim-tree/nvim-tree.lua/commit/ff6e7966f39a897ac4d1358f4d022cfecdc88ff1))
* **#1494:** git showUntracked value and log ([#1504](https://github.com/nvim-tree/nvim-tree.lua/issues/1504)) ([09a5126](https://github.com/nvim-tree/nvim-tree.lua/commit/09a51266bca28dd87febd63c66bdbd74f7764a63))
* **#1500:** focusing directories with a trailing slash in their path doesn't work ([#1501](https://github.com/nvim-tree/nvim-tree.lua/issues/1501)) ([b314b3a](https://github.com/nvim-tree/nvim-tree.lua/commit/b314b3a6992f07f7af5c58521d1e219b032d309e))
* **#1503:** focus last win before close ([#1509](https://github.com/nvim-tree/nvim-tree.lua/issues/1509)) ([d9edddb](https://github.com/nvim-tree/nvim-tree.lua/commit/d9edddb84931ca73c350922d76f6c6825b694248))
* **#1514:** inverted git navigation keymaps ([#1515](https://github.com/nvim-tree/nvim-tree.lua/issues/1515)) ([9fd7b7a](https://github.com/nvim-tree/nvim-tree.lua/commit/9fd7b7ae2920cc349644b5d45785e2a655ffdfe9))
* **#1518:** sort_by=modification_time not reordering on refresh. ([#1519](https://github.com/nvim-tree/nvim-tree.lua/issues/1519)) ([049cdd3](https://github.com/nvim-tree/nvim-tree.lua/commit/049cdd3073faab064d93f7d6397c9d292d8a3cab))
* **#1520:** file type changes are not detected. ([#1521](https://github.com/nvim-tree/nvim-tree.lua/issues/1521)) ([c5fba1e](https://github.com/nvim-tree/nvim-tree.lua/commit/c5fba1ec1861525a8d2d9773f7983ecf77b588dc))
* **#1529:** ensure tree window exists before closing ([#1537](https://github.com/nvim-tree/nvim-tree.lua/issues/1537)) ([e3353c4](https://github.com/nvim-tree/nvim-tree.lua/commit/e3353c4cb40baef335e1a21d8b9c21b9cde919be))
* **#1533:** make `toggle_mark` ignore non-togglable nodes. ([#1534](https://github.com/nvim-tree/nvim-tree.lua/issues/1534)) ([90dcf42](https://github.com/nvim-tree/nvim-tree.lua/commit/90dcf42bba4b9c07e1d590592035fdec5d8e07d8))
* **#1539:** Fix closing nvim-tree float when file is removed ([#1546](https://github.com/nvim-tree/nvim-tree.lua/issues/1546)) ([07f59e7](https://github.com/nvim-tree/nvim-tree.lua/commit/07f59e7450c767c674cc53f5930b2d73af60b9c1))
* **#1540:** watcher ignore directories with name exactly '.git' ([259efee](https://github.com/nvim-tree/nvim-tree.lua/commit/259efeee62c7fb51abf299c2570cacbf4806e98a))
* **#1543:** Do not resize nvim-tree window if float is enabled ([#1556](https://github.com/nvim-tree/nvim-tree.lua/issues/1556)) ([ce5d0a6](https://github.com/nvim-tree/nvim-tree.lua/commit/ce5d0a6b7ddfec622554943d2ebcc739b1d74567))
* **#1545:** dispatch Event.Resize on all window resizes, requires nvim 0.9+ ([#2238](https://github.com/nvim-tree/nvim-tree.lua/issues/2238)) ([0345117](https://github.com/nvim-tree/nvim-tree.lua/commit/034511714bacfadc5008e49f73fcef67e5613840))
* **#1547:** pass explicit system arguments to for git toplevel and untracked actions ([9914780](https://github.com/nvim-tree/nvim-tree.lua/commit/9914780cbabdffe3cd030867f0bc34c6e51bcb95))
* **#1551:** handle git status TT as staged ([c272c88](https://github.com/nvim-tree/nvim-tree.lua/commit/c272c88dafa5d2e8bf0554f4d687396f843714c5))
* **#1553:** set correct side on vim open directory ([#1594](https://github.com/nvim-tree/nvim-tree.lua/issues/1594)) ([5cb87c0](https://github.com/nvim-tree/nvim-tree.lua/commit/5cb87c037d92b71a3a6f2bc342e2a38456b8870e))
* **#1555:** incorrect exe highlight in Windows filesystem from WSL ([#1557](https://github.com/nvim-tree/nvim-tree.lua/issues/1557)) ([4a725c0](https://github.com/nvim-tree/nvim-tree.lua/commit/4a725c0ca501d81002aad77418f1edafdd01a0ba))
* **#1564:** reset &bufhidden when opening an existing (maybe previewed) buffer ([#1573](https://github.com/nvim-tree/nvim-tree.lua/issues/1573)) ([e282420](https://github.com/nvim-tree/nvim-tree.lua/commit/e282420111929e2af2efca6f3fe31f95985d4a5b))
* **#1568:** show relative path of symlink destination ([#1569](https://github.com/nvim-tree/nvim-tree.lua/issues/1569)) ([951e10a](https://github.com/nvim-tree/nvim-tree.lua/commit/951e10a64e0b03069f0f50ddc79d6a8ed8d23dec))
* **#1615:** focus created file when command line prompt requires confirmation ([#1622](https://github.com/nvim-tree/nvim-tree.lua/issues/1622)) ([be2b4f5](https://github.com/nvim-tree/nvim-tree.lua/commit/be2b4f58e66ec48a8597246331c0c76f85171b4d))
* **#1626:** obey splitright/below when splitting existing windows ([#1641](https://github.com/nvim-tree/nvim-tree.lua/issues/1641)) ([c4ac723](https://github.com/nvim-tree/nvim-tree.lua/commit/c4ac723a833b6d78b8a6403ad37efd56a67ee0c4))
* **#1628:** quit_on_open e: do not open in the tree's window ([#1637](https://github.com/nvim-tree/nvim-tree.lua/issues/1637)) ([b01e7be](https://github.com/nvim-tree/nvim-tree.lua/commit/b01e7beaa6f0dbbf5df775cf4ecc829a23f0be54))
* **#1629:** nvim start with file named *NvimTree* opens tree instead of buffer ([#1634](https://github.com/nvim-tree/nvim-tree.lua/issues/1634)) ([c66cbdf](https://github.com/nvim-tree/nvim-tree.lua/commit/c66cbdfc25ce115db50cfe3dca8b96a8a1e9b931))
* **#1632:** autocenter: avoid use of feedkeys ([#1632](https://github.com/nvim-tree/nvim-tree.lua/issues/1632)) ([187388b](https://github.com/nvim-tree/nvim-tree.lua/commit/187388b7f5ea7b38888c9af9c02cb2f9040aea1f))
* **#1639:** ensure tree autocommands match filetype as well as name ([#1640](https://github.com/nvim-tree/nvim-tree.lua/issues/1640)) ([48992fd](https://github.com/nvim-tree/nvim-tree.lua/commit/48992fd3e82fa0f2ca22679f909823d8b37171d4))
* **#1643:** preview on floating window ([#1648](https://github.com/nvim-tree/nvim-tree.lua/issues/1648)) ([c995ce0](https://github.com/nvim-tree/nvim-tree.lua/commit/c995ce087875ec5d4df51520b1e9cb09a4b51725))
* **#1664:** respect hijack_directories.enable on startup when not open_on_setup ([#1665](https://github.com/nvim-tree/nvim-tree.lua/issues/1665)) ([4e24505](https://github.com/nvim-tree/nvim-tree.lua/commit/4e24505e2b30c4a8c35a3dfb4f564f14f6d9bfd4))
* **#1668:** revert all startup behaviour changes back to 540055b ([3a2f68b](https://github.com/nvim-tree/nvim-tree.lua/commit/3a2f68b9d53fdf360beba222022868c527ae4d8a))
* **#1668:** update issue link ([2b97063](https://github.com/nvim-tree/nvim-tree.lua/commit/2b970635d1ef531355a380258372411576ecad4d))
* **#1671:** split with no window picker will always find an available window ([#1677](https://github.com/nvim-tree/nvim-tree.lua/issues/1677)) ([dd90bfa](https://github.com/nvim-tree/nvim-tree.lua/commit/dd90bfa155be7fa5371a32cb8b95d4f76d379161))
* **#1675:** open-file sanity check mode ([e94f517](https://github.com/nvim-tree/nvim-tree.lua/commit/e94f5177983c033aad340b5351bf65ef1fa9737a))
* **#1679:** renderer.full_name correctly shows for one character outside ([#1688](https://github.com/nvim-tree/nvim-tree.lua/issues/1688)) ([fba9751](https://github.com/nvim-tree/nvim-tree.lua/commit/fba97517bb570702be98718c9f841ae9b359133e))
* **#1697:** remove notify plugin auto-detection ([#2135](https://github.com/nvim-tree/nvim-tree.lua/issues/2135)) ([68f485b](https://github.com/nvim-tree/nvim-tree.lua/commit/68f485b4542abd3912299b40b9ff39a834365567))
* **#1711:** open in a new window when no window picker and no available window ([#1715](https://github.com/nvim-tree/nvim-tree.lua/issues/1715)) ([33ce8e3](https://github.com/nvim-tree/nvim-tree.lua/commit/33ce8e3c733a9fd949dabb96896eef3e24d01e54))
* **#1712:** invalid window ID on colorscheme ([#1714](https://github.com/nvim-tree/nvim-tree.lua/issues/1714)) ([ada2c64](https://github.com/nvim-tree/nvim-tree.lua/commit/ada2c6441d0844cc1995b5def24fd3e90cfa8032))
* **#1716:** focus file/directory when created in a sub-directory, don't dispatch FolderCreated on file creation ([#1722](https://github.com/nvim-tree/nvim-tree.lua/issues/1722)) ([bdc4ec6](https://github.com/nvim-tree/nvim-tree.lua/commit/bdc4ec6abd3e6c78eb5dea5f8b94c2698c3aad51))
* **#1720:** .git watch only FETCH_HEAD, HEAD, HEAD.lock, config, index ([#1732](https://github.com/nvim-tree/nvim-tree.lua/issues/1732)) ([bcb2a5a](https://github.com/nvim-tree/nvim-tree.lua/commit/bcb2a5a80ddfe44dd9f4361800a54baafd7f6f18))
* **#1723:** find_file for externally created new file results in folder unable to be opened ([be2ccd4](https://github.com/nvim-tree/nvim-tree.lua/commit/be2ccd4b1a6077b53f8bfabf1e5c1775ca6dfbdc))
* **#1728:** escape cwd changes to prevent environment variable expansion ([#1729](https://github.com/nvim-tree/nvim-tree.lua/issues/1729)) ([e204a7d](https://github.com/nvim-tree/nvim-tree.lua/commit/e204a7d819a9a065d5b1cdc6f59d2d2777d14a0f))
* **#1731 #1723 #1716:** handle all external file system changes ([#1757](https://github.com/nvim-tree/nvim-tree.lua/issues/1757)) ([b17358f](https://github.com/nvim-tree/nvim-tree.lua/commit/b17358ff4d822deeb42b97919065800f8f91cb55))
* **#1740:** Error while running :NvimTreeCollapseKeepBuffers ([#1741](https://github.com/nvim-tree/nvim-tree.lua/issues/1741)) ([cf90837](https://github.com/nvim-tree/nvim-tree.lua/commit/cf908370fb046641e3aaaa6a6177c1b5d165f186))
* **#1785:** retain focused node on filter toggles ([#2202](https://github.com/nvim-tree/nvim-tree.lua/issues/2202)) ([d5d6950](https://github.com/nvim-tree/nvim-tree.lua/commit/d5d6950a0d0cc2692dfce9a1251b42f4da69136f))
* **#1804:** do not refresh watched nodes that have been destroyed (deleted) ([d949af7](https://github.com/nvim-tree/nvim-tree.lua/commit/d949af7245c04018e0b5ed3409c4e82c1303d2ea))
* **#1815:** don't schedule find_file calls, debounce update_focused_file with 15ms default ([#1820](https://github.com/nvim-tree/nvim-tree.lua/issues/1820)) ([623cecb](https://github.com/nvim-tree/nvim-tree.lua/commit/623cecb809c6ec35b8ddd47a57732ee2c57446f5))
* **#1815:** don't schedule find_file calls, debounce update_focused_file with 15ms default ([#1828](https://github.com/nvim-tree/nvim-tree.lua/issues/1828)) ([87409bb](https://github.com/nvim-tree/nvim-tree.lua/commit/87409bb4afd0093193e1364faa47327fbfdfca87))
* **#1824:** Don't modify jumplist when `edit_in_place`. ([#1825](https://github.com/nvim-tree/nvim-tree.lua/issues/1825)) ([e8ea62c](https://github.com/nvim-tree/nvim-tree.lua/commit/e8ea62c198f6e91197072350c119e8cc8e7f963a))
* **#1831:** improve fs_scandir error handling, add profiling ([89c79cb](https://github.com/nvim-tree/nvim-tree.lua/commit/89c79cb33bc4867ccf9ee4810697da76ac59fdba))
* **#1831:** remove error messages that were previously unreachable and add no value ([547db6e](https://github.com/nvim-tree/nvim-tree.lua/commit/547db6e9297ca9b0da95965d1760461b33b44687))
* **#1831:** remove instrumentation ([#1968](https://github.com/nvim-tree/nvim-tree.lua/issues/1968)) ([e0166d1](https://github.com/nvim-tree/nvim-tree.lua/commit/e0166d146923fdf5df9e26b47fc164ef30ccb548))
* **#1831:** remove instrumentation ([#1969](https://github.com/nvim-tree/nvim-tree.lua/issues/1969)) ([7eb33d2](https://github.com/nvim-tree/nvim-tree.lua/commit/7eb33d2a6d5d574a43159da90e0eac2445367393))
* **#1831:** remove windows executable functionality due to occasional vim freeze and performance concerns ([#1868](https://github.com/nvim-tree/nvim-tree.lua/issues/1868)) ([3c4958a](https://github.com/nvim-tree/nvim-tree.lua/commit/3c4958ab3dd0e5fa470fb50b6b9cc6df48229a2e))
* **#1833:** do not find file when view is not visible on the current tab ([#1845](https://github.com/nvim-tree/nvim-tree.lua/issues/1845)) ([9e4c395](https://github.com/nvim-tree/nvim-tree.lua/commit/9e4c39572f631bb60ee15cb9d46e1daa9927a45e))
* **#1836:** add view.debounce_delay ([#1871](https://github.com/nvim-tree/nvim-tree.lua/issues/1871)) ([951b6e7](https://github.com/nvim-tree/nvim-tree.lua/commit/951b6e7e55da8aee9566cc0b17c11f9451cec349))
* **#1841:** do not refresh on buffer events when highlight_opened_files is none ([4fc74ca](https://github.com/nvim-tree/nvim-tree.lua/commit/4fc74ca32157ecb275e62647fbe9cff0b8e9b9c8))
* **#1841:** do not refresh on buffer events when not a file buffer ([#1843](https://github.com/nvim-tree/nvim-tree.lua/issues/1843)) ([e14c289](https://github.com/nvim-tree/nvim-tree.lua/commit/e14c2895b4f36a22001f7773244041c173dcf867))
* **#1858:** deprecation warning for config.mappings.active and default ([#2084](https://github.com/nvim-tree/nvim-tree.lua/issues/2084)) ([886d852](https://github.com/nvim-tree/nvim-tree.lua/commit/886d852f6e8b73ae0ed6793bb09601b22d1f2fee))
* **#1858:** fire TreeAttachedPost event following on_attach call ([f0a1c6a](https://github.com/nvim-tree/nvim-tree.lua/commit/f0a1c6ae2eeaefcb693dc1a319150c52e64397b0))
* **#1878:** nvim frozen on no name buffer when modified.enable ([#1879](https://github.com/nvim-tree/nvim-tree.lua/issues/1879)) ([cdbd7da](https://github.com/nvim-tree/nvim-tree.lua/commit/cdbd7daf29db09e58a4ddc181c1be91c07184f4e))
* **#1916:** suppress EPERM watcher failures on windows ([#1919](https://github.com/nvim-tree/nvim-tree.lua/issues/1919)) ([1b13a49](https://github.com/nvim-tree/nvim-tree.lua/commit/1b13a49f913b58a5f1792ea81c13947a7988db8e))
* **#1923:** handle empty git icons ([#1952](https://github.com/nvim-tree/nvim-tree.lua/issues/1952)) ([8505b6e](https://github.com/nvim-tree/nvim-tree.lua/commit/8505b6ecd828e8fccb00ea59e789999311391210))
* **#1923:** handle empty git icons ([#1987](https://github.com/nvim-tree/nvim-tree.lua/issues/1987)) ([ba1778e](https://github.com/nvim-tree/nvim-tree.lua/commit/ba1778e061f25814bc5940be886a7f41d7d7736e))
* **#1931:** do not execute git status in git ignored directories ([#2326](https://github.com/nvim-tree/nvim-tree.lua/issues/2326)) ([273c170](https://github.com/nvim-tree/nvim-tree.lua/commit/273c1700eb68c27dce4e518efafc8144fd7ce4ab))
* **#1940:** NvimTreeFindFileToggle focus tree ([9e87ee2](https://github.com/nvim-tree/nvim-tree.lua/commit/9e87ee2d6e86f37ff09cb74ec7dcf2ac984a01e9))
* **#1942:** nvim-tree window options do not trigger OptionSet event ([#1945](https://github.com/nvim-tree/nvim-tree.lua/issues/1945)) ([55028e3](https://github.com/nvim-tree/nvim-tree.lua/commit/55028e30d7f897711c6469ea93a316f0f12223d4))
* **#1946:** only change vim's global cwd on startup when opening the tree ([#1947](https://github.com/nvim-tree/nvim-tree.lua/issues/1947)) ([8567841](https://github.com/nvim-tree/nvim-tree.lua/commit/8567841b87a664e47118b178190acc364d6730f9))
* **#1950:** disable most API until nvim-tree setup has been called ([#2125](https://github.com/nvim-tree/nvim-tree.lua/issues/2125)) ([56cdb58](https://github.com/nvim-tree/nvim-tree.lua/commit/56cdb5827d7c79611ccbe10ae6a720ee11fbde65))
* **#1961:** cycle detection on refresh, preventing infinite loop ([#1996](https://github.com/nvim-tree/nvim-tree.lua/issues/1996)) ([4222bb8](https://github.com/nvim-tree/nvim-tree.lua/commit/4222bb875d86a2a53069c75c4833e27f58e26d90))
* **#1961:** harden profiling functions ([#1986](https://github.com/nvim-tree/nvim-tree.lua/issues/1986)) ([b712b82](https://github.com/nvim-tree/nvim-tree.lua/commit/b712b82b0ca4eb402ced2d83f8082366989e43e0))
* **#1961:** stop unnecessary find file refreshes, avoid find file refresh cycles ([#2010](https://github.com/nvim-tree/nvim-tree.lua/issues/2010)) ([9c97e64](https://github.com/nvim-tree/nvim-tree.lua/commit/9c97e6449b0b0269bd44e1fd4857184dfa57bb4c))
* **#1970:** additional log function gating for efficiency when not logging ([#1971](https://github.com/nvim-tree/nvim-tree.lua/issues/1971)) ([02fdc26](https://github.com/nvim-tree/nvim-tree.lua/commit/02fdc262eba188198a7deb2117b3b996e6763d65))
* **#1970:** disable git integration after 5 timeouts ([#1990](https://github.com/nvim-tree/nvim-tree.lua/issues/1990)) ([36e29c3](https://github.com/nvim-tree/nvim-tree.lua/commit/36e29c3a95ae606449f6616a0d8ab7247af807dc))
* **#1976:** support non-standard `$GIT_DIR` ([#2012](https://github.com/nvim-tree/nvim-tree.lua/issues/2012)) ([517dee6](https://github.com/nvim-tree/nvim-tree.lua/commit/517dee64c150821efdc1d5adcd4285fdf9c30371))
* **#1989:** cut/paste over open buffer ([#2279](https://github.com/nvim-tree/nvim-tree.lua/issues/2279)) ([4af5722](https://github.com/nvim-tree/nvim-tree.lua/commit/4af572246ce49883e2a52c49203a19984454f2e0))
* **#1993:** always fire TreeOpen event ([#1994](https://github.com/nvim-tree/nvim-tree.lua/issues/1994)) ([8b8d457](https://github.com/nvim-tree/nvim-tree.lua/commit/8b8d457e07d279976a9baac6bbff5aa036afdc5f))
* **#2003:** obey user split command for modified buffers when hidden not set ([#2008](https://github.com/nvim-tree/nvim-tree.lua/issues/2008)) ([04f99f1](https://github.com/nvim-tree/nvim-tree.lua/commit/04f99f14b5f662df722badf78c3cae7b17dc4571))
* **#2004:** relative path detection handles regex magic ([#2005](https://github.com/nvim-tree/nvim-tree.lua/issues/2005)) ([66c15af](https://github.com/nvim-tree/nvim-tree.lua/commit/66c15afd13da5f86de52b82f38cd9d3f418d0dc3))
* **#2024:** help handles empty mapping description ([59bcb01](https://github.com/nvim-tree/nvim-tree.lua/commit/59bcb01d3bf58b810b9c48db56e558f3857110ad))
* **#2024:** revert removal of deprecated nvim-tree.config nvim_tree_callback ([362ecbe](https://github.com/nvim-tree/nvim-tree.lua/commit/362ecbeed69fae91a287004619decadcb6f7c113))
* **#2057:** update focused file on new terminal ([#2060](https://github.com/nvim-tree/nvim-tree.lua/issues/2060)) ([31d8e24](https://github.com/nvim-tree/nvim-tree.lua/commit/31d8e2446025f619bbabe5289815a9f464a2d144))
* **#2078:** :NvimTreeFindFile focuses tree ([#2080](https://github.com/nvim-tree/nvim-tree.lua/issues/2080)) ([6319ad9](https://github.com/nvim-tree/nvim-tree.lua/commit/6319ad94050c4489951ad34b6535c134a3efa455))
* **#2081:** do not change root for inexistent files ([#2082](https://github.com/nvim-tree/nvim-tree.lua/issues/2082)) ([6515a1e](https://github.com/nvim-tree/nvim-tree.lua/commit/6515a1e1a9c0187e4fa81998a02732bf681a9103))
* **#2086:** "Rename: Omit Filename" not removing file name ([#2087](https://github.com/nvim-tree/nvim-tree.lua/issues/2087)) ([a38f9a5](https://github.com/nvim-tree/nvim-tree.lua/commit/a38f9a55a4b55b0aa18af7abfde2c17a30959bdf))
* **#2088:** actions change dir enable false does not update tree root ([#2095](https://github.com/nvim-tree/nvim-tree.lua/issues/2095)) ([3e9509e](https://github.com/nvim-tree/nvim-tree.lua/commit/3e9509ec1b86f2352af85dd87ed77200488471b6))
* **#2104:** remove experimental.git.async, always used ([#2234](https://github.com/nvim-tree/nvim-tree.lua/issues/2234)) ([164eb10](https://github.com/nvim-tree/nvim-tree.lua/commit/164eb10cbd7363cbedbad768be0f98e8595c322d))
* **#2109:** floating help window ([#2120](https://github.com/nvim-tree/nvim-tree.lua/issues/2120)) ([0a144ba](https://github.com/nvim-tree/nvim-tree.lua/commit/0a144ba50af3ef585d3d5170efea64f3d465219c))
* **#2114:** remove deprecated non-API from lib, events ([#2121](https://github.com/nvim-tree/nvim-tree.lua/issues/2121)) ([920d5c8](https://github.com/nvim-tree/nvim-tree.lua/commit/920d5c8f7e4afebfc8e9a25ab36f7da915908838))
* **#2126:** custom window pickers may create windows ([#2140](https://github.com/nvim-tree/nvim-tree.lua/issues/2140)) ([8f392fa](https://github.com/nvim-tree/nvim-tree.lua/commit/8f392fa763b7ee80a48c714b630acaf6d1fe1854))
* **#2132:** focus file after rename and paste ([#2151](https://github.com/nvim-tree/nvim-tree.lua/issues/2151)) ([061a05b](https://github.com/nvim-tree/nvim-tree.lua/commit/061a05bfd91475a1001f2c972e5331b166e2a437))
* **#2133:** harden hide_root_folder deprecation ([#2134](https://github.com/nvim-tree/nvim-tree.lua/issues/2134)) ([b601b5a](https://github.com/nvim-tree/nvim-tree.lua/commit/b601b5aa25627f68d3d73ba9269b49e4f04ce126))
* **#2139:** API functions not passing arguments ([#2141](https://github.com/nvim-tree/nvim-tree.lua/issues/2141)) ([a8a4834](https://github.com/nvim-tree/nvim-tree.lua/commit/a8a4834e1af9fb85710bc1307298a45fae4e561c))
* **#2154:** `find_file` doesn't work when `group_empty` option is enabled ([#2100](https://github.com/nvim-tree/nvim-tree.lua/issues/2100)) ([d8b154c](https://github.com/nvim-tree/nvim-tree.lua/commit/d8b154c5f0981886fc2b0f1e52d6172e7fdd13e4))
* **#2154:** selection incorrect after find-file when renderer.group_empty ([#2437](https://github.com/nvim-tree/nvim-tree.lua/issues/2437)) ([d8e495b](https://github.com/nvim-tree/nvim-tree.lua/commit/d8e495b2354058276cad6dd32e3efdd1d02f4da6))
* **#2157:** use stdpath cache for nvim-tree-on-attach.lua ([#2159](https://github.com/nvim-tree/nvim-tree.lua/issues/2159)) ([13c7146](https://github.com/nvim-tree/nvim-tree.lua/commit/13c714681f44fb712ccc2519030a33c4ad925f3f))
* **#2175:** check number of actions.open_file.window_picker.chars before picking window ([#2177](https://github.com/nvim-tree/nvim-tree.lua/issues/2177)) ([9c60947](https://github.com/nvim-tree/nvim-tree.lua/commit/9c60947926e5fb8a04f9fb8d798a1a7ff9126992))
* **#2191:** edit: disregard floating windows ([#2209](https://github.com/nvim-tree/nvim-tree.lua/issues/2209)) ([89816ac](https://github.com/nvim-tree/nvim-tree.lua/commit/89816ace70642e9d3db0dab3dc68918f8979ec31))
* **#2191:** edit: disregard floating windows ([#2212](https://github.com/nvim-tree/nvim-tree.lua/issues/2212)) ([b657405](https://github.com/nvim-tree/nvim-tree.lua/commit/b6574056b52f18cbb987910c72c30f295a80318b))
* **#2240:** disable watchers following EMFILE ([#2268](https://github.com/nvim-tree/nvim-tree.lua/issues/2268)) ([d4f6d33](https://github.com/nvim-tree/nvim-tree.lua/commit/d4f6d33496ef09018ab96e48e4f4a852d3334caf))
* **#2293:** remove unnecessary git status during find file ([#2294](https://github.com/nvim-tree/nvim-tree.lua/issues/2294)) ([1fe3228](https://github.com/nvim-tree/nvim-tree.lua/commit/1fe32286db79719dd6e52236f82c5b52df3ccaa9))
* **#2301:** do not show git status on grouped dirs when show_on_open_dirs ([#2303](https://github.com/nvim-tree/nvim-tree.lua/issues/2303)) ([d17389c](https://github.com/nvim-tree/nvim-tree.lua/commit/d17389ce53929cf9a1e209727121e4388dc3e013))
* **#2301:** various git folder status fixes ([#2373](https://github.com/nvim-tree/nvim-tree.lua/issues/2373)) ([4e36850](https://github.com/nvim-tree/nvim-tree.lua/commit/4e36850811e219faf649fa68682c7699ca36007d))
* **#2327:** set parent folder git ignore status following file update ([#2328](https://github.com/nvim-tree/nvim-tree.lua/issues/2328)) ([c1466f9](https://github.com/nvim-tree/nvim-tree.lua/commit/c1466f991a3c4cbf77f44282e3baddd4b7432f8c))
* **#2343:** tree is now correctly abandoned upon an in-place open with eject=false ([#2344](https://github.com/nvim-tree/nvim-tree.lua/issues/2344)) ([0a89dcb](https://github.com/nvim-tree/nvim-tree.lua/commit/0a89dcb464b433d2d7b97a8f15d0b608c718dc13))
* **#2352:** windows: escape special filename characters on edit ([#2374](https://github.com/nvim-tree/nvim-tree.lua/issues/2374)) ([7c4c7e4](https://github.com/nvim-tree/nvim-tree.lua/commit/7c4c7e4e984db6ec012b0e3df11791a118d638aa))
* **#2370:** Better "y/N" prompts ([#2377](https://github.com/nvim-tree/nvim-tree.lua/issues/2377)) ([920868d](https://github.com/nvim-tree/nvim-tree.lua/commit/920868dba13466586897a8f40220eca6b2caac41))
* **#2382:** git watcher handles worktrees and submodules, via --absolute-git-dir when it is available ([#2389](https://github.com/nvim-tree/nvim-tree.lua/issues/2389)) ([28c3980](https://github.com/nvim-tree/nvim-tree.lua/commit/28c3980b25e50e9ede39df55427151cb11be46f9))
* **#2386:** kill git zombies ([#2401](https://github.com/nvim-tree/nvim-tree.lua/issues/2401)) ([5897b36](https://github.com/nvim-tree/nvim-tree.lua/commit/5897b3622f033b1f3ea6adf8eb1c165e9f20554f))
* **#2392:** bookmarks icon placement when group_empty ([#2402](https://github.com/nvim-tree/nvim-tree.lua/issues/2402)) ([b856d0a](https://github.com/nvim-tree/nvim-tree.lua/commit/b856d0a0c3238e49d6385d830ea8c7785b1eccc8))
* **#2440:** `view.width.padding` may be a number or function returning a number ([#2442](https://github.com/nvim-tree/nvim-tree.lua/issues/2442)) ([e153d9f](https://github.com/nvim-tree/nvim-tree.lua/commit/e153d9f5991ef275df46161a5100949847229538))
* **#2450:** apply NvimTreeImageFile for webp and jxl files ([#2451](https://github.com/nvim-tree/nvim-tree.lua/issues/2451)) ([94e572e](https://github.com/nvim-tree/nvim-tree.lua/commit/94e572e14190c47378f3afe9b60865ace7fa933e))
* **#2459:** disable cygwin git support by default, see :help nvim-tree.git.cygwin_support to enable ([#2486](https://github.com/nvim-tree/nvim-tree.lua/issues/2486)) ([db8145c](https://github.com/nvim-tree/nvim-tree.lua/commit/db8145c27d7a1489b5a0d4fcdd6291d0fbd55a09))
* **#2467:** remove newline in git paths when using cygwin_support ([#2478](https://github.com/nvim-tree/nvim-tree.lua/issues/2478)) ([7c5c074](https://github.com/nvim-tree/nvim-tree.lua/commit/7c5c0743541e8ffb8874fee732adcc400fa652f4))
* **#2468:** always apply filters to subdirectories ([#2537](https://github.com/nvim-tree/nvim-tree.lua/issues/2537)) ([fb89297](https://github.com/nvim-tree/nvim-tree.lua/commit/fb892973477e131042d737c9fc822c7c2ace5076))
* **#2473:** remove problematic &lt;S-Tab&gt; default mapping ([#2475](https://github.com/nvim-tree/nvim-tree.lua/issues/2475)) ([40b9b88](https://github.com/nvim-tree/nvim-tree.lua/commit/40b9b887d090d5da89a84689b4ca0304a9649f62))
* **#2495:** skip API action if node == nil ([#2499](https://github.com/nvim-tree/nvim-tree.lua/issues/2499)) ([7630cf4](https://github.com/nvim-tree/nvim-tree.lua/commit/7630cf4a92b69cc22347894c81cc03966b2a7bcf))
* **#2507:** icon in message after rename-file ([#2510](https://github.com/nvim-tree/nvim-tree.lua/issues/2510)) ([20a0707](https://github.com/nvim-tree/nvim-tree.lua/commit/20a0707e0ffa301eb7ef682664f37e2955354f7a))
* **#2512:** file creation in empty folder without root_folder_label ([#2514](https://github.com/nvim-tree/nvim-tree.lua/issues/2514)) ([4ee6366](https://github.com/nvim-tree/nvim-tree.lua/commit/4ee6366ff1fc5d66231516ed05beffb50004261b))
* **#2516:** diagnostics icon highlight group matches the documentation: NvimTreeLspDiagnosticsInfo -&gt; Information ([#2518](https://github.com/nvim-tree/nvim-tree.lua/issues/2518)) ([46e1f77](https://github.com/nvim-tree/nvim-tree.lua/commit/46e1f776f0a714099b9160604fbb62fba2540376))
* **#2523:** live filter overlay width calculation ([#2524](https://github.com/nvim-tree/nvim-tree.lua/issues/2524)) ([80cfead](https://github.com/nvim-tree/nvim-tree.lua/commit/80cfeadf179d5cba76f0f502c71dbcff1b515cd8))
* **#549:** add more profiling ~tree init ([95ed588](https://github.com/nvim-tree/nvim-tree.lua/commit/95ed5882114ab481e93362aa74c0f3c65dc4aade))
* `api.node.open.preview` should toggle directories ([#2099](https://github.com/nvim-tree/nvim-tree.lua/issues/2099)) ([7ad1c20](https://github.com/nvim-tree/nvim-tree.lua/commit/7ad1c204c4113b5ce4cc9244ff93a406db810a64))
* **actions:** change_dir to wrong directory ([#1398](https://github.com/nvim-tree/nvim-tree.lua/issues/1398)) ([269820e](https://github.com/nvim-tree/nvim-tree.lua/commit/269820e800f6652fac3e0ff66a1463121f2f0ff4))
* **actions:** close_node doesn't close for grouped node ([#1385](https://github.com/nvim-tree/nvim-tree.lua/issues/1385)) ([ec09b80](https://github.com/nvim-tree/nvim-tree.lua/commit/ec09b80c7bbf8a34c82b6de5f0a67ff78cbc8ae0))
* **actions:** create file should defer more to focus ([0fa2ec1](https://github.com/nvim-tree/nvim-tree.lua/commit/0fa2ec1950a5ef20b692781f18ad9185987bb705))
* **actions:** dispatching filter should not match for "live" keyword ([0f96e32](https://github.com/nvim-tree/nvim-tree.lua/commit/0f96e32326a842798b6b8e638a91464521e4ef71)), closes [#1420](https://github.com/nvim-tree/nvim-tree.lua/issues/1420)
* add legacy options safety ([f742b86](https://github.com/nvim-tree/nvim-tree.lua/commit/f742b86852948f11dcca5735d2af17b75dafee5f))
* **api:** copy is a table, copy -&gt; copy.name ([a044818](https://github.com/nvim-tree/nvim-tree.lua/commit/a0448184af1fe374779d103ab0aed47431ab75e8)), closes [#1461](https://github.com/nvim-tree/nvim-tree.lua/issues/1461)
* **api:** use copy.node instead of copy.name ([e95bfbf](https://github.com/nvim-tree/nvim-tree.lua/commit/e95bfbfc2d1c5bd2684c4607e4bc1b27399416e7)), closes [#1461](https://github.com/nvim-tree/nvim-tree.lua/issues/1461)
* **change-dir:** cd command concatenation ([eb6dde4](https://github.com/nvim-tree/nvim-tree.lua/commit/eb6dde4733a27c87b42d74f962e62f33730365c6))
* **ci:** stylua action version number ([43fd138](https://github.com/nvim-tree/nvim-tree.lua/commit/43fd13854423666c53439536892a5fbc4a66044c))
* cleanup live filter scratch buffers ([#2522](https://github.com/nvim-tree/nvim-tree.lua/issues/2522)) ([74ddb8f](https://github.com/nvim-tree/nvim-tree.lua/commit/74ddb8f2bb5d0a0f4952afb4356ed954f18d5e9e))
* close view before hijacking current window ([28c4bb0](https://github.com/nvim-tree/nvim-tree.lua/commit/28c4bb01f64a4f806c66781375b47767225ec94c))
* **colorscheme:** update winhl on colorscheme change ([65c2ba8](https://github.com/nvim-tree/nvim-tree.lua/commit/65c2ba895213c3641fc58dd33bc7a44423a6cdbe)), closes [#1696](https://github.com/nvim-tree/nvim-tree.lua/issues/1696)
* **copy-paste:** fix message on clipboard clear ([#1838](https://github.com/nvim-tree/nvim-tree.lua/issues/1838)) ([e0cfbbb](https://github.com/nvim-tree/nvim-tree.lua/commit/e0cfbbb93dc66ea51a148f206a49e82ae6bb0368))
* count unicode codepoints instead of bytes ([#1445](https://github.com/nvim-tree/nvim-tree.lua/issues/1445)) ([1e3c578](https://github.com/nvim-tree/nvim-tree.lua/commit/1e3c578eebc854029a7bd6d67dd20a67e3edc38b))
* **create-file:** pass file in parameter ([1018a83](https://github.com/nvim-tree/nvim-tree.lua/commit/1018a83e10c112efc38b11123d74f9f6c9ea16b6))
* **create-file:** when node is nil, create the file at root ([e632ac7](https://github.com/nvim-tree/nvim-tree.lua/commit/e632ac7c8116ed0ed2e865b4b3e0a17a78de8081)), closes [#1467](https://github.com/nvim-tree/nvim-tree.lua/issues/1467)
* **diagnostics:** coc obey diagnostics.severity ([#2072](https://github.com/nvim-tree/nvim-tree.lua/issues/2072)) ([874b7be](https://github.com/nvim-tree/nvim-tree.lua/commit/874b7be5d053f1b31f545099d6fcbe8ae81e9e03))
* **diagnostics:** do not show on file/dir with same prefix ([fee6801](https://github.com/nvim-tree/nvim-tree.lua/commit/fee68013931b1a208118498d8f7f77858c5f26e0))
* **diagnostics:** do not show on file/dir with same prefix ([#1832](https://github.com/nvim-tree/nvim-tree.lua/issues/1832)) ([3000797](https://github.com/nvim-tree/nvim-tree.lua/commit/3000797e53bab88b9e427655c6164ad1216f68be))
* **dispatch:** dispatch help toggle when its not shown ([95c57e0](https://github.com/nvim-tree/nvim-tree.lua/commit/95c57e034a1921dc1e0dab2f43f8ff87596e0979)), closes [#1411](https://github.com/nvim-tree/nvim-tree.lua/issues/1411)
* **doc:** duplicate help tag in README ([#2066](https://github.com/nvim-tree/nvim-tree.lua/issues/2066)) ([a50723e](https://github.com/nvim-tree/nvim-tree.lua/commit/a50723e35f57f89fb67019127a16d90f16edfef8))
* **docs:** typos ([#1470](https://github.com/nvim-tree/nvim-tree.lua/issues/1470)) ([2928f8f](https://github.com/nvim-tree/nvim-tree.lua/commit/2928f8fe31bacc287a988e02b7fe930f19c6a972))
* ensure startup warnings are visible with a multiline message, to work around https://github.com/neovim/neovim/issues/17832 planned for fix in nvim 0.10 ([#2387](https://github.com/nvim-tree/nvim-tree.lua/issues/2387)) ([807dc05](https://github.com/nvim-tree/nvim-tree.lua/commit/807dc051560afda30956320ed718def878f655f0))
* error when deleting opened file from floating window ([#2503](https://github.com/nvim-tree/nvim-tree.lua/issues/2503)) ([24bb0ed](https://github.com/nvim-tree/nvim-tree.lua/commit/24bb0ed806f0984906fc65940b31cd0107229946))
* **executable:** prevent nil extensions in executable check ([630305c](https://github.com/nvim-tree/nvim-tree.lua/commit/630305c233b815464d57bc253444610eb327d255)), closes [#1444](https://github.com/nvim-tree/nvim-tree.lua/issues/1444)
* expand and collapse whole folder groups ([#2380](https://github.com/nvim-tree/nvim-tree.lua/issues/2380)) ([0074120](https://github.com/nvim-tree/nvim-tree.lua/commit/00741206c2df9c4b538055def19b99790f0c95c8))
* **explorer:** reload `executable` stat ([#1427](https://github.com/nvim-tree/nvim-tree.lua/issues/1427)) ([b754eb8](https://github.com/nvim-tree/nvim-tree.lua/commit/b754eb8359837900044ea414d2edeff495e6bdb1))
* **file rename:** edit buffer when renaming to reset filetype ([90bf140](https://github.com/nvim-tree/nvim-tree.lua/commit/90bf14014e8b31c1a96c23a9583bf89028da13e2))
* **find-file:** do not recurse on closed nodes ([9d3602e](https://github.com/nvim-tree/nvim-tree.lua/commit/9d3602e8eab27ffb88cb89f2a938a127acd86c42))
* focus visible parent on collapse all ([#2261](https://github.com/nvim-tree/nvim-tree.lua/issues/2261)) ([f873625](https://github.com/nvim-tree/nvim-tree.lua/commit/f873625d0636889af4cd47a01e486beb865db205))
* fs_watcher not started for .git folders (windows) ([#2265](https://github.com/nvim-tree/nvim-tree.lua/issues/2265)) ([f5804ce](https://github.com/nvim-tree/nvim-tree.lua/commit/f5804ce94e06966e0fc1aba9c697c178fc7cb210))
* **fs:** create file failure when reloading watch path for node ([3d58a9b](https://github.com/nvim-tree/nvim-tree.lua/commit/3d58a9b2cfd7146e2f38b101bbc860e4c80a0ceb)), closes [#1633](https://github.com/nvim-tree/nvim-tree.lua/issues/1633)
* **get-node-from-path:** group dirs should be returned before nodes ([4bd919a](https://github.com/nvim-tree/nvim-tree.lua/commit/4bd919a75f37c7127ccfc746fc59a71068db3ceb))
* git highlight for new staged files ([#2534](https://github.com/nvim-tree/nvim-tree.lua/issues/2534)) ([8f9169a](https://github.com/nvim-tree/nvim-tree.lua/commit/8f9169a05931041aad1a0719e82eb02cea528881))
* **git:** fix inverted condition logic introduced in [#1433](https://github.com/nvim-tree/nvim-tree.lua/issues/1433) ([#1443](https://github.com/nvim-tree/nvim-tree.lua/issues/1443)) ([c964fa2](https://github.com/nvim-tree/nvim-tree.lua/commit/c964fa24d0e6cc7d77d46e29c03f6f004af1578c))
* **git:** git folder fixes and improvements ([#1809](https://github.com/nvim-tree/nvim-tree.lua/issues/1809)) ([29788cc](https://github.com/nvim-tree/nvim-tree.lua/commit/29788cc32a153e42b2fe48344d315da8367fc6fa))
* **git:** git rename not showing up for the renamed file ([#1783](https://github.com/nvim-tree/nvim-tree.lua/issues/1783)) ([f8489c9](https://github.com/nvim-tree/nvim-tree.lua/commit/f8489c992998e1e1b45aec65bdb9615e5cd59a61))
* **git:** prevent execution of git commands when git integration is disabled ([#1433](https://github.com/nvim-tree/nvim-tree.lua/issues/1433)) ([203bb7e](https://github.com/nvim-tree/nvim-tree.lua/commit/203bb7e176fc0d00fddceabf12bebfe87bb8da02))
* harden git status updates ([#2533](https://github.com/nvim-tree/nvim-tree.lua/issues/2533)) ([633811c](https://github.com/nvim-tree/nvim-tree.lua/commit/633811c53d3b7856cab8e96b91c6a5d2cf9eb8ae))
* harden tree root cwd fetch ([#2557](https://github.com/nvim-tree/nvim-tree.lua/issues/2557)) ([5e4475d](https://github.com/nvim-tree/nvim-tree.lua/commit/5e4475d8bf7a3646164e01d9b65ef68369b17e3c))
* help window header is minimum width ([#2149](https://github.com/nvim-tree/nvim-tree.lua/issues/2149)) ([5b53732](https://github.com/nvim-tree/nvim-tree.lua/commit/5b5373254f572de1fb65a7046fbd61bbffe6da05))
* **help:** clear git signs before draw ([b81ab19](https://github.com/nvim-tree/nvim-tree.lua/commit/b81ab199a513f0c5c099f7be3f230ce796f5ad12))
* Implicit current buf on centralize selection ([#1792](https://github.com/nvim-tree/nvim-tree.lua/issues/1792)) ([0cd8ac4](https://github.com/nvim-tree/nvim-tree.lua/commit/0cd8ac4751c39440a1c28c6be4704f3597807d29))
* info size suffix and formatting ([#2492](https://github.com/nvim-tree/nvim-tree.lua/issues/2492)) ([a31dfad](https://github.com/nvim-tree/nvim-tree.lua/commit/a31dfada1d0d177f88bc0b7e27365b08446788bb))
* inverted diagnostic navigation keymaps ([81eb718](https://github.com/nvim-tree/nvim-tree.lua/commit/81eb718394e489d2aebbffa730d2517d72ec7f9c))
* **iterators:** the index does not increase ([#1399](https://github.com/nvim-tree/nvim-tree.lua/issues/1399)) ([418fc97](https://github.com/nvim-tree/nvim-tree.lua/commit/418fc971fc22a501cbc09b5f7425129b7c95130d))
* **keymaps:** get_keymaps takes remove_keymaps as parameter ([9bbf95e](https://github.com/nvim-tree/nvim-tree.lua/commit/9bbf95e61691feb6696880701cdb1b6cafa97d41))
* **keypress:** use &lt;cmd&gt; instead of `:` to avoid triggering CmdLineEnter ([7087af8](https://github.com/nvim-tree/nvim-tree.lua/commit/7087af83f3a003913ed280eb3bdffe3a46a601c6)), closes [#1417](https://github.com/nvim-tree/nvim-tree.lua/issues/1417)
* nerd font 3 bookmark icon ([#2203](https://github.com/nvim-tree/nvim-tree.lua/issues/2203)) ([498e879](https://github.com/nvim-tree/nvim-tree.lua/commit/498e8793bbe73ab5235b3ee8f0aee32f5d01649f))
* **notify:** log file notice info-&gt;debug ([cc18122](https://github.com/nvim-tree/nvim-tree.lua/commit/cc18122be1c53e6736f4f7a75a32429b3bbca2a0))
* **notify:** remove unused varargs, log file notice debug-&gt;info ([a65063c](https://github.com/nvim-tree/nvim-tree.lua/commit/a65063cb0a67c0794da9aa6fc8ac0e64f614daf7))
* **open-file:** focus file if already opened ([4900d66](https://github.com/nvim-tree/nvim-tree.lua/commit/4900d66370988108dbe0f57cb8a2fc090878f73d))
* **open-file:** vim.op -&gt; vim.opt ([2edbe75](https://github.com/nvim-tree/nvim-tree.lua/commit/2edbe759cd45d4a7a3ae0c6e05f5b54860775f98))
* **paste:** allow pasting into empty root directory ([1837751](https://github.com/nvim-tree/nvim-tree.lua/commit/1837751efb5fcfc584cb0ee900f09ff911cd6c0b)), closes [#1736](https://github.com/nvim-tree/nvim-tree.lua/issues/1736)
* **paste:** paste into empty root directory ([059e4ca](https://github.com/nvim-tree/nvim-tree.lua/commit/059e4cadd658229ff7a5f9b56064be87f52cc6cd))
* **perf:** explorer was creating new table for each new entry ([665813b](https://github.com/nvim-tree/nvim-tree.lua/commit/665813b9e6e247c633346b861e08f03e44e3ac91))
* prompt uses first character of response - allow "yy" ([#2357](https://github.com/nvim-tree/nvim-tree.lua/issues/2357)) ([904f95c](https://github.com/nvim-tree/nvim-tree.lua/commit/904f95cd9db31d1800998fa428e78e418a50181d))
* **prompt:** add select_prompts to suit UI decorator plugins such as dressing and telescope ([ac8d259](https://github.com/nvim-tree/nvim-tree.lua/commit/ac8d259badf915cd9aaad406503d116230296c44))
* reload tree on `BufEnter` if cwd is different ([#2527](https://github.com/nvim-tree/nvim-tree.lua/issues/2527)) ([874ae6e](https://github.com/nvim-tree/nvim-tree.lua/commit/874ae6e9445a5eb5ba430e5fd10212450a261ad7))
* remove redundant file existence check in create file operation ([#1936](https://github.com/nvim-tree/nvim-tree.lua/issues/1936)) ([16f2806](https://github.com/nvim-tree/nvim-tree.lua/commit/16f2806d5968157fd6f76542c9ac358c684a3a03))
* remove unnecessary conditions ([#1614](https://github.com/nvim-tree/nvim-tree.lua/issues/1614)) ([45d386a](https://github.com/nvim-tree/nvim-tree.lua/commit/45d386a3591f87390390c0d718a81e05895465ca))
* **renderer:** indent markers + folder arrows should offset ([8632ac2](https://github.com/nvim-tree/nvim-tree.lua/commit/8632ac273979d5ec22ecee9c23aba18a73345584)), closes [#1421](https://github.com/nvim-tree/nvim-tree.lua/issues/1421)
* **renderer:** indent markers with arrows ([9a02ded](https://github.com/nvim-tree/nvim-tree.lua/commit/9a02dedd92fad67b04b2a3fee2de20555956b089))
* **renderer:** padding indent with folders only ([449b5bd](https://github.com/nvim-tree/nvim-tree.lua/commit/449b5bd0cbe08192ded83b2bce8cbec4764da63d))
* replace vim.* "requires" with explicit calls to vim functions ([#1701](https://github.com/nvim-tree/nvim-tree.lua/issues/1701)) ([8cc3696](https://github.com/nvim-tree/nvim-tree.lua/commit/8cc369695b3a0ae3ddf9538bc1f87bbf8cdbecca))
* restore eventignore ([#1612](https://github.com/nvim-tree/nvim-tree.lua/issues/1612)) ([11b5248](https://github.com/nvim-tree/nvim-tree.lua/commit/11b524899fc4d9a79e1b5632bd84dcc5b06da3aa))
* schedule notifications to avoid UI freeze on startup ([#2432](https://github.com/nvim-tree/nvim-tree.lua/issues/2432)) ([ce3495b](https://github.com/nvim-tree/nvim-tree.lua/commit/ce3495bd4c9a7d8e8a64fac9cc3c252dac19a994))
* **scripts:** default mappings should put a comma at the end of each line ([08ab346](https://github.com/nvim-tree/nvim-tree.lua/commit/08ab346f0312433b3f10a4a10f4b69d98138d38f))
* sort_by "extension" falls back to name ([#2306](https://github.com/nvim-tree/nvim-tree.lua/issues/2306)) ([04b2c1e](https://github.com/nvim-tree/nvim-tree.lua/commit/04b2c1e08c32cf1620b9404d8417f415b6ec7aad))
* **styling:** empty line ([4aef454](https://github.com/nvim-tree/nvim-tree.lua/commit/4aef454cd29bc69ae7d6c4737ba8570149d92f4f))
* **system-open:** use notify for system-open failures and tidy messages ([9d241e5](https://github.com/nvim-tree/nvim-tree.lua/commit/9d241e5f5889cf8d37c3a8054b3e55157549c283))
* trash.cmd defaults to 'trash' on macos and windows, document option ([#2336](https://github.com/nvim-tree/nvim-tree.lua/issues/2336)) ([0a54dcb](https://github.com/nvim-tree/nvim-tree.lua/commit/0a54dcb76b02f3a4e2da370c7a3f6f2b7b43ef01))
* **trash:** do not run trash command when trash is not executable ([cbbc799](https://github.com/nvim-tree/nvim-tree.lua/commit/cbbc799e6c5784fba9b6a842000caaebf07fa122))
* type annotations for utils.is_nvim_tree_buf ([#2180](https://github.com/nvim-tree/nvim-tree.lua/issues/2180)) ([270c955](https://github.com/nvim-tree/nvim-tree.lua/commit/270c95556cad96d18ca547d86ae65927334b108b))
* typo on clipboard notify ([#2032](https://github.com/nvim-tree/nvim-tree.lua/issues/2032)) ([6117582](https://github.com/nvim-tree/nvim-tree.lua/commit/6117582578d2e5b81212f04db4ad206836bcd24a))
* use pcall to prevent live-filter regex errors ([#1689](https://github.com/nvim-tree/nvim-tree.lua/issues/1689)) ([3845039](https://github.com/nvim-tree/nvim-tree.lua/commit/3845039c1a47ad0759a1ec7deb6f2ffb4421d175))
* **view:** do not close window when NvimTree buffer is replaced ([#1391](https://github.com/nvim-tree/nvim-tree.lua/issues/1391)) ([40e515d](https://github.com/nvim-tree/nvim-tree.lua/commit/40e515df87e164454b4df12b7c97a805dd8d2bb8))
* **view:** file filter and info popup above floating view ([d753a1d](https://github.com/nvim-tree/nvim-tree.lua/commit/d753a1da9a58339f1751db96d37e9b318be91825))
* **view:** prevent buffer override when actions.open_file.quit_on_open ([e82a921](https://github.com/nvim-tree/nvim-tree.lua/commit/e82a921baab36e9220b31c315b3dc816d6b892c9))
* **view:** refresh opened files highlight on buffer read, unload ([#1827](https://github.com/nvim-tree/nvim-tree.lua/issues/1827)) ([18272f8](https://github.com/nvim-tree/nvim-tree.lua/commit/18272f8df3aac2f59dfa31b268c62e0611fbc6c3))
* **watcher:** failure on watcher teardown message ([#1726](https://github.com/nvim-tree/nvim-tree.lua/issues/1726)) ([6d6a446](https://github.com/nvim-tree/nvim-tree.lua/commit/6d6a44626d4dec58bb61bd40d5bd63d69818c540))
* **watcher:** only purge on subsequent setup calls, add git_purge log ([899ed45](https://github.com/nvim-tree/nvim-tree.lua/commit/899ed45602090ec9f61a2ed69d218d246e7e035a))
* **watchers:** disable watchers on kernel filesystems ([ac90664](https://github.com/nvim-tree/nvim-tree.lua/commit/ac906640011df013ca3dd19b6dc71a4fec67cf85)), closes [#1465](https://github.com/nvim-tree/nvim-tree.lua/issues/1465)
* window picker can't be correctly rendered when cmdheight = 0 ([#1349](https://github.com/nvim-tree/nvim-tree.lua/issues/1349)) ([79258f1](https://github.com/nvim-tree/nvim-tree.lua/commit/79258f1d670277016523e13c0a88daa25070879f))
* **wipe:** wipe all nvim-tree rogue buffers ([ec530e7](https://github.com/nvim-tree/nvim-tree.lua/commit/ec530e73beec547e04efb11a4f17c912d750c626)), closes [#1438](https://github.com/nvim-tree/nvim-tree.lua/issues/1438)
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).

View File

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

View File

@@ -1,16 +0,0 @@
#!/bin/bash
out=$(grep -nr "^--- @" lua)
if [ "$out" ]; then
last_file=""
while read -r line; do
file="$(echo "$line" | cut -d: -f1)"
if [[ "$file" != "$last_file" ]]; then
echo "$file:" >&2
last_file="$file"
fi
echo "$line" | awk -F: '{ printf(" line %s: %s\n", $2, $3) }' >&2
done <<< "$out"
exit 1
fi

View File

@@ -1,44 +0,0 @@
#!/bin/sh
# Performs a lua-language-server check on all files.
# luals-out/check.json will be produced on any issues, returning 1.
# Outputs only check.json to stdout, all other messages to stderr, to allow jq etc.
# $VIMRUNTIME specifies neovim runtime path, defaults to "/usr/share/nvim/runtime" if unset.
if [ -z "${VIMRUNTIME}" ]; then
export VIMRUNTIME="/usr/share/nvim/runtime"
fi
DIR_SRC="lua"
DIR_OUT="luals-out"
# clear output
rm -rf "${DIR_OUT}"
mkdir "${DIR_OUT}"
# execute inside lua to prevent luals itself from being checked
OUT=$(lua-language-server --check="${DIR_SRC}" --configpath="${PWD}/.luarc.json" --checklevel=Information --logpath="${DIR_OUT}" --loglevel=error)
RC=$?
echo "${OUT}" >&2
if [ $RC -ne 0 ]; then
echo "failed with RC=$RC"
exit $RC
fi
# any output is a fail
case "${OUT}" in
*Diagnosis\ complete*)
if [ -f "${DIR_OUT}/check.json" ]; then
cat "${DIR_OUT}/check.json"
exit 1
else
exit 0
fi
;;
*)
exit 1
;;
esac

View File

@@ -2,7 +2,7 @@
# run after changing nvim-tree.lua DEFAULT_OPTS or keymap.lua M.default_on_attach
# scrapes and updates nvim-tree-lua.txt
# run from repository root: scripts/help-update.sh OR make help-update
# run from repository root: scripts/update-help.sh
#
@@ -38,7 +38,7 @@ sed -i -e "/${begin}/,/${end}/{ /${begin}/{p; r /tmp/DEFAULT_ON_ATTACH.lua
# help human
echo > /tmp/DEFAULT_ON_ATTACH.help
sed -E "s/^ *vim.keymap.set\('n', '(.*)',.*api(.*),.*opts\('(.*)'.*$/'\`\1\`' '\3' '|nvim-tree-api\2()|'/g
" /tmp/DEFAULT_ON_ATTACH.lua | while read -r line
" /tmp/DEFAULT_ON_ATTACH.lua | while read line
do
eval "printf '%-17.17s %-26.26s %s\n' ${line}" >> /tmp/DEFAULT_ON_ATTACH.help
done