Compare commits

...

38 Commits
v0.99 ... v1.1

Author SHA1 Message Date
github-actions[bot]
707b24af91 chore(master): release nvim-tree 1.1.1 (#2709)
* chore(master): release nvim-tree 1.1.1

* doc: remove duplicate bug fix entry

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-03-15 12:26:28 +11:00
remvn
76b98109f6 fix: bookmark filter should include parent directory (#2704)
* fix: bookmark filter should include parent directory

* fix: dont match mark's siblings

* fix: match mark from the start

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-03-15 12:21:04 +11:00
Asman Umbetov
cfea5bd080 fix(#2395): marks.bulk.move defaults to directory at cursor (#2688)
* fix(#2395): marks.bulk.move defaults to directory at cursor

* fix(#2395): adds check if node_at_cursor.parent is nil

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-03-15 12:03:06 +11:00
Alexander Courtis
1fd9c98960 fix(#2705): change NvimTreeWindowPicker cterm background from Cyan to more visible DarkBlue (#2708)
fix(#2705): change NvimTreeWindowPicker from Cyan to the more visible DarkBlue
2024-03-15 10:58:40 +11:00
github-actions[bot]
164f11db4f chore(master): release nvim-tree 1.1.0 (#2691)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-14 12:10:17 +02:00
Rami Elwan
8f2a50f1cd feat: add api.fs.copy.basename, default mapping ge (#2698)
* feat: add copy basename

* fix: change keymap for copy basename

* fix: use double quotes

* fix: add missing help

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-03-14 16:57:46 +11:00
gegoune
c64becf80c ci: set concurrency and trigger ci on master (#2701) 2024-03-14 07:36:22 +02:00
Alexander Courtis
3c4267eb50 fix(#2695): git toplevel guard against missing paths (#2696) 2024-03-14 16:23:58 +11:00
DB
041dbd18f4 fix: searchcount exception on invalid search regex (#2693)
* fix: wrap searchcount in pcall to avoid error

* fix: searchcount in pcall

---------

Co-authored-by: xVermillionx <xVermillionx@notvalid>
2024-03-09 13:27:23 +11:00
Mohamed Arish
efafd73efa feat(#2630): file renames can now create directories (#2657)
* Added creating of directories when renaming files

* Style check error? fixed

* Forgot, I added back the line of code that creates a directory named as the file and forgot to remove it

* Added a check for file already exists and also switched the is_error values as they were mismatched

* I don't know how but this somehow fixed the creation of a directory?
2024-03-03 12:25:17 +11:00
Alexander Courtis
d52fdeb0a3 docs: add help indexes (#2684)
* docs: add nvim-tree-index-api

* docs: add nvim-tree-index-opts

* docs: add nvim-tree-index-api

* docs: sort indices

* docs: less verbose

* docs: use dictionary sort for indices
2024-02-24 17:53:25 +11:00
Alexander Courtis
7efaa339d3 docs: :help nvim-tree-legacy (#2679)
doc: add help nvim-tree-legacy
2024-02-24 15:50:10 +11:00
Alexander Courtis
030defdb65 docs: add highlight examples to quickstart, document pre-overhaul SpellCap groups (#2680)
* docs: add highlight examples to quickstart, document pre-overhaul SpellLocal groups

* docs: add highlight examples to quickstart

* docs: document pre-overhaul SpellCap groups

* docs: document pre-overhaul SpellCap groups
2024-02-20 13:24:37 +11:00
github-actions[bot]
d35a8d5ec6 chore(master): release nvim-tree 1.0.0 (#2670)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-18 17:28:24 +11:00
Alexander Courtis
d16246a757 chore: release 1.0.0 (#2678)
Release-As: 1.0.0
2024-02-18 17:24:05 +11:00
gegoune
863cf832ce ci: triggers, nvim stable version & env vars (#2671) 2024-02-12 09:49:39 +01:00
dependabot[bot]
c7d4650c38 chore(deps): bump JohnnyMorganz/stylua-action from 3 to 4 (#2672)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-12 09:48:00 +01:00
darcy
4a87b8b46b feat(#2654): filters.custom may be a function (#2655)
* feat(#2654): add `binaries` field to `filters`

* feat(#2648): allow functions in `filters.custom`

* ci: fix: stylua check

* ci: fix: add new keybind and config to docs

* fix: replace os-specific binary filter with `vim.fn.executable`

* fix: remove function and mapping for `binaries` filter

* fix: add `node` parameter to custom filter function

* fix: update doc for custom filter function signature

* fix: add custom filter to `ACCEPTED_TYPES`

* fix: accept single function for custom filter

* fix: change custom filter on `ACCEPTED_TYPES`

* fix: revert to using `path` for custom filter function

* fix: use `function` type for custom filter

* fix: type for custom filter in help

* fix: custom filter single function no longer mutates `M.config.filter_custom`

* fix: remove dead `if` statement in custom filter

* fix: separate custom filter function from `M.ignore_list`

* doc nit

---------

Co-authored-by: darcy <44690813+darccyy@users.noreply.github.com>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-02-11 17:18:40 +11:00
github-actions[bot]
2dbe4ea2b5 chore(master): release nvim-tree 0.100.0 (#2635)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-11 15:49:27 +11:00
Alexander Courtis
39e6fef85a fix(#2415): highlight help header and mappings (#2669) 2024-02-11 15:40:21 +11:00
Alexander Courtis
b278fc25ae feat(#2415): add :NvimTreeHiTest (#2664)
* feat(#2415): add :NvimTreeHiTest

* feat(#2415): split out appearance diagnostics
2024-02-11 14:41:40 +11:00
Zeta
8cbb1db8e9 feat: add node.open.toggle_group_empty, default mapping L (#2647)
* feat: ungrouping empty directories

* add a new api to toggle empty folders

* solve comments

* solve comments

* update help

---------

Co-authored-by: juefei yan <juefeiyan@juefeis-MacBook-Air.local>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-02-04 16:48:56 +11:00
Confidenceman02
f39f7b6fcd fix(#2415): nvim 0.8 highlight overhaul support, limited to only show highest highlight precedence (#2642)
* fix: Add support for get_hl_defs in nvim 0.8

nvim-tree is using `nvim_get_hl` which was introduced in nvim 0.9 to
replace the unstable `get_hl_defs` in the following [commit](https://github.com/neovim/neovim/pull/22693/files).

Unfortunately this raises an error in 0.8 nvim versions due to the
function not existing.

```
Failed to run `config` for nvim-tree.lua
...are/nvim/lazy/nvim-tree.lua/lua/nvim-tree/appearance.lua:199: attempt to call field 'nvim_get_hl' (a nil value)
stacktrace:
  - ~/.config/nvim/lua/confidenceman02/plugins/nvim-tree.lua:14 _in_ **config**
  - ~/.config/nvim/lua/confidenceman02/lazy.lua:14
```

- Fall back to get_hl_defs when detecting 0.8
- Set the 'link' property to nil to emulate `link = false` in
  `builder.lua`

* fix(#2415): nvim 0.8 highlight overhaul support, limited to only show highest highlight precedence

---------

Co-authored-by: Jaime Terreu <jaime@terreu.com>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-01-30 10:37:32 +11:00
Alexander Courtis
e9ac136a3a fix(#2415): NvimTreeIndentMarker highlight group: FileIcon->FolderIcon (#2656)
fix(#2415): fix NvimTreeIndentMarker highlight group: FileIcon->FolderIcon
2024-01-29 13:28:20 +11:00
Alexander Courtis
d9cb432d2c fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul (#2639)
* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul

* fix(#2415): disambiguate highlight groups, see :help nvim-tree-highlight-overhaul
2024-01-29 12:43:02 +11:00
Alexander Courtis
fbee8a69a4 fix(#2643): correctly apply linked highlight groups in tree window (#2653)
* fix(#2643): correctly apply linked highlight groups in tree window

* fix(#2643): recreate and apply combined highlight groups on colorscheme change
2024-01-29 12:42:19 +11:00
Alexander Courtis
7bdb220d0f fix(#2637): show buffer modified icons and highlights (#2638) 2024-01-21 17:24:43 +11:00
Danila Usachev
48b1d8638f fix(#2632): occasional error stack when locating nvim-tree window (#2633)
fix: passing nil as window handle in view.get_winnr

Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-01-21 15:54:27 +11:00
Tomasz N
75ff64e666 fix: bad column offset when using full_name (#2629)
Co-authored-by: __ <__@__>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-01-21 15:37:46 +11:00
Kevin Ko
74525ac047 fix: allow highlight overrides for DEFAULT_DEFS: NvimTreeFolderIcon, NvimTreeWindowPicker (#2636) 2024-01-21 10:32:28 +11:00
Alexander Courtis
e9c5abe073 feat(#2415): colour and highlight overhaul, see :help nvim-tree-highlight-overhaul (#2455)
* feat(#2415): granular highlight_diagnostics, normalise groups (#2454)

* chore: normalise colours and enable cterm (#2471)

* feat(#2415): granular highlight_git, normalise git groups (#2487)

* docs: update CONTRIBUTING.md (#2485)

* feat(#2415): granular highlight_git, normalise git groups

* feat(#2415): normalise and add modified groups

* feat(#2415): create Decorator class for modified and bookmarks

* feat(#2415): create DecoratorDiagnostics

* feat(#2415): create DecoratorGit

* feat(#2415): create DecoratorGit

* add DecoratorCopied DecoratorCut

* add DecoratorOpened

* remove unloaded_bufnr checks as the view debouncer takes care of it

* Add `renderer.highlight_git` to accepted strings

* fix(#2415): builder refactor (#2538)

* simplify builder signs

* decorators take care of themselves and are priority ordered

* simplify builder hl groups

* refactor builder for icon arrays

* builder use decorators generically

* fix(#2415): harden sign creation (#2539)

* fix(#2415): harden unicode signs

* Decorator tidy

* normalise git sign creation and tidy

* tidy builder

* NvimTreeBookmarkIcon

* tidy HL doc

* tidy HL doc

* tidy HL doc

* tidy builder doc

* standardise on '---@param'

* DiagnosticWarning -> DiagnosticWarn

* annotate decorators

* limit to two highlight groups for line rendering

* style

* apply #2519

* feat(#2415): combined hl groups (#2601)

* feat(#2415): create combined highlight groups

* feat(#2415): create combined highlight groups

* feat(#2415): create combined highlight groups

* ci: allow workflow_dispatch (#2620)

* one and only one hl namespace, required winhl removal

* small tidies

* colors.lua -> appearance.lua

* full-name uses one and only namespace

* don't highlight fast, just apply to namespace, safer win_set_hl

* gut builder (#2622)

collapse Builder

* fix group_empty function check

* feat(#2415): highlight-overhaul release date

---------

Co-authored-by: Akmadan23 <azadahmadi@mailo.com>
2024-01-20 16:12:13 +11:00
Alexander Courtis
f24afa2cef fix(#2624): open file from docked floating window (#2627) 2024-01-14 11:08:15 +11:00
dependabot[bot]
b8c3a23e76 chore(deps): bump actions/checkout from 3 to 4 (#2623)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 10:09:04 +01:00
Alexander Courtis
9f6d3fac82 ci: fix: run on push release-please--branches--master--components--nvim-tree (#2621) 2024-01-08 11:24:19 +11:00
Alexander Courtis
78a5836092 ci: allow workflow_dispatch (#2620) 2024-01-07 10:20:23 +11:00
Alexander Courtis
86810e5c0b ci: run on push release-please--branches--master--components--nvim-tree (#2619) 2024-01-07 09:57:13 +11:00
Antonin Godard
5d13cc8205 feat(#1389): api: recursive node navigation for git and diagnostics (#2525)
* feat(#1389): add next recursive for git and diag moves

The recurse opt can be used to directly go to the next item showing
git/diagnostic status recursively.

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* refactor: status logic in single function

Rename get_status to status_is_valid.

Use status_is_valid function in multiple place to avoid duplicating
code.

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* feat(#1389): add prev recursive for git and diag moves

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* fix(#1389): next recursive: take root node into account

The root node cannot have a status. Previously if moving from the root
node, status_is_valid was trying to fetch the status from it and errored.

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* fix(#1389): doc: remove show_on_open_dirs limitation

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* feat(#1389): move find_node_line to utils

Signed-off-by: Antonin Godard <antoningodard@pm.me>

* feat(#1389): doc: note recursive moves are to files only, tidy

---------

Signed-off-by: Antonin Godard <antoningodard@pm.me>
Co-authored-by: Alexander Courtis <alex@courtis.org>
2024-01-07 09:08:58 +11:00
Alexander Courtis
6a99f5af78 ci: lua language server and Makefile (#2546)
* ci: add lls-check

* ci: add lls-check to ci.yml

* ci: download lua-language-server binary

* ci: download lua-language-server binary

* ci: dummy failure to test

* Revert "ci: dummy failure to test"

This reverts commit 2bc43bad430209e32a5049a16c56710c4f6e2f7b.

* ci: ignore lls-out

* ci: better name

* ci: shellcheck nits

* ci: add luals libs and tidy

* ci: tidy

* ci: add neovim 0.9.4

* ci: add ci neovim 0.9.4 to lib path

* ci: dummy failure to test

* Revert "ci: dummy failure to test"

This reverts commit 45987335d81ec65fecc6636b339671a9a9fcdd97.

* Revert "ci: add ci neovim 0.9.4 to lib path"

This reverts commit 4f397d6ea8bbdf6e808f9dc9db5ecbae291d8cd4.

* Revert "ci: add neovim 0.9.4"

This reverts commit 46fd1b368d27a1892b55381691723db3b30a7527.

* ci: action downloads and installs luals

* ci: remove workspaces from luals

* ci: consistent script naming

* ci: add quality to contributing

* ci: consistent script naming

* ci: add lsp to diagnostics

* ci: temporary find to enumerate home

* ci: add VIMRUNTIME for lls

* ci: temporary find to enumerate home

* ci: temporary find to enumerate home

* ci: remove temporary find to enumerate home

* ci: correct VIMRUNTIME

* ci: add ${3rd}/luv/library

* ci: note VIMRUNTIME override

* ci: add Makefile

* ci: add Makefile

* ci: add Makefile

* ci: add Makefile

* ci: document checks and fixes

* ci: add help check

* ci: add help check

* ci: dummy help failure

* Revert "ci: dummy help failure"

This reverts commit c50cceaa4a.

* ci: document checks and fixes

* ci: document checks and fixes

* ci: matrix nvim version

* ci: matrix nvim version

* Revert "ci: matrix nvim version"

This reverts commit fcef6a11e9.

* Revert "ci: matrix nvim version"

This reverts commit a8cb50d39d.

* ci: matrix nvim version from env

* ci: matrix nvim version from env

* ci: matrix nvim version from env

* ci: matrix nvim version

* ci: matrix nvim version

* ci: matrix per job

* ci: matrix per job

* ci: many lua versions

* ci: move doc to style

* ci: tidy ci and contributing
2024-01-06 13:18:52 +11:00
55 changed files with 2687 additions and 1118 deletions

View File

@@ -2,11 +2,13 @@ name: CI
on:
pull_request:
branches:
- '*'
push:
branches:
- master
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
permissions:
contents: read
@@ -14,31 +16,69 @@ 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: "5.1"
luaVersion: ${{ matrix.lua_version }}
- uses: leafo/gh-actions-luarocks@v4
- name: luacheck
run: |
luarocks install luacheck 1.1.1
luacheck lua
- run: luarocks install luacheck 1.1.1
- run: make lint
style:
runs-on: ubuntu-latest
strategy:
matrix:
stylua_version: [ 0.19.1 ]
steps:
- uses: actions/checkout@v4
- name: stylua
uses: JohnnyMorganz/stylua-action@v3
uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: "0.19"
version: ${{ matrix.stylua_version }}
args: --check lua
- name: doc-comments
run: ./scripts/doc-comments.sh
- run: make style-doc
check:
runs-on: ubuntu-latest
strategy:
matrix:
nvim_version: [ stable, nightly ]
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
- run: echo "luals/bin" >> "$GITHUB_PATH"
- name: make check
env:
VIMRUNTIME: /home/runner/nvim-${{ matrix.nvim_version }}/share/nvim/runtime
run: make check
- run: make help-check

View File

@@ -2,6 +2,10 @@ on:
push:
branches:
- master
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
name: release-please
permissions:
contents: write

View File

@@ -6,6 +6,10 @@ on:
- reopened
- edited
- synchronize
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
jobs:
semantic-pr-subject:
runs-on: ubuntu-latest

2
.gitignore vendored Normal file
View File

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

View File

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

View File

@@ -1,7 +1,14 @@
{
"$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 +1,3 @@
{
".": "0.99.0"
".": "1.1.1"
}

View File

@@ -1,5 +1,66 @@
# Changelog
## [1.1.1](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.1.0...nvim-tree-v1.1.1) (2024-03-15)
### Bug Fixes
* **#2395:** marks.bulk.move defaults to directory at cursor ([#2688](https://github.com/nvim-tree/nvim-tree.lua/issues/2688)) ([cfea5bd](https://github.com/nvim-tree/nvim-tree.lua/commit/cfea5bd0806aab41bef6014c6cf5a510910ddbdb))
* **#2705:** change NvimTreeWindowPicker cterm background from Cyan to more visible DarkBlue ([#2708](https://github.com/nvim-tree/nvim-tree.lua/issues/2708)) ([1fd9c98](https://github.com/nvim-tree/nvim-tree.lua/commit/1fd9c98960463d2d5d400916c0633b2df016941d))
* bookmark filter should include parent directory ([#2704](https://github.com/nvim-tree/nvim-tree.lua/issues/2704)) ([76b9810](https://github.com/nvim-tree/nvim-tree.lua/commit/76b98109f62caa12b2f1dff472060b2233ea2e90))
## [1.1.0](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v1.0.0...nvim-tree-v1.1.0) (2024-03-14)
### Features
* **#2630:** file renames can now create directories ([#2657](https://github.com/nvim-tree/nvim-tree.lua/issues/2657)) ([efafd73](https://github.com/nvim-tree/nvim-tree.lua/commit/efafd73efa9bc8c26282aed563ba0f01c7465b06))
* add api.fs.copy.basename, default mapping ge ([#2698](https://github.com/nvim-tree/nvim-tree.lua/issues/2698)) ([8f2a50f](https://github.com/nvim-tree/nvim-tree.lua/commit/8f2a50f1cd0c64003042364cf317c8788eaa6c8c))
### Bug Fixes
* **#2695:** git toplevel guard against missing paths ([#2696](https://github.com/nvim-tree/nvim-tree.lua/issues/2696)) ([3c4267e](https://github.com/nvim-tree/nvim-tree.lua/commit/3c4267eb5045fa86b67fe40c0c63d31efc801e77))
* searchcount exception on invalid search regex ([#2693](https://github.com/nvim-tree/nvim-tree.lua/issues/2693)) ([041dbd1](https://github.com/nvim-tree/nvim-tree.lua/commit/041dbd18f440207ad161503a384e7c82d575db66))
## [1.0.0](https://github.com/nvim-tree/nvim-tree.lua/compare/nvim-tree-v0.100.0...nvim-tree-v1.0.0) (2024-02-18)
### Features
* **#2654:** filters.custom may be a function ([#2655](https://github.com/nvim-tree/nvim-tree.lua/issues/2655)) ([4a87b8b](https://github.com/nvim-tree/nvim-tree.lua/commit/4a87b8b46b4a30107971871df3cb7f4c30fdd5d0))
### Miscellaneous Chores
* release 1.0.0 ([#2678](https://github.com/nvim-tree/nvim-tree.lua/issues/2678)) ([d16246a](https://github.com/nvim-tree/nvim-tree.lua/commit/d16246a7575538f77e9246520449b99333c469f7))
## [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-&gt;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-&gt;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)

View File

@@ -4,31 +4,82 @@ Thank you for contributing.
See [Development](https://github.com/nvim-tree/nvim-tree.lua/wiki/Development) for environment setup, tips and tools.
## Styling and formatting
# Tools
Code is formatted using luacheck, and linted using stylua.
You can install these with:
Following are used during CI and strongly recommended during local development.
```bash
luarocks install luacheck
cargo install stylua
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
```
You can setup the git hooks by running `scripts/setup-hooks.sh`.
## style
## Adding new actions
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
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`.
## Documentation
Once you did, you should run `make help-update`
# Documentation
## Opts
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
## API
When adding or changing API please update :help nvim-tree-api
# Pull Request
Please reference any issues in the description e.g. "resolves #1234".

47
Makefile Normal file
View File

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

@@ -38,6 +38,8 @@ Please install via your preferred package manager. See [Installation](https://gi
`nvim-tree/nvim-tree.lua`
Major or minor versions may be specified via tags: `v<MAJOR>` e.g. `v1` or `v<MAJOR>.<MINOR>` e.g. `v1.23`
`nvim-tree/nvim-web-devicons` optional, for file icons
Disabling [netrw](https://neovim.io/doc/user/pi_netrw.html) is strongly advised, see [:help nvim-tree-netrw](doc/nvim-tree-lua.txt)
@@ -53,7 +55,7 @@ Setup the plugin in your `init.lua`
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- set termguicolors to enable highlight groups
-- optionally enable 24-bit colour
vim.opt.termguicolors = true
-- empty setup using defaults
@@ -110,6 +112,23 @@ require("nvim-tree").setup {
}
```
### 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. e.g.
```lua
vim.cmd([[
:hi NvimTreeExecFile guifg=#ffa0a0
:hi NvimTreeSpecialFile guifg=#ff80ff gui=underline
:hi NvimTreeSymlink guifg=Yellow gui=italic
:hi link NvimTreeImageFile Title
]])
```
See [:help nvim-tree-highlight](doc/nvim-tree-lua.txt) for details.
## Commands
See [:help nvim-tree-commands](doc/nvim-tree-lua.txt)

View File

@@ -10,6 +10,7 @@ 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|
@@ -43,13 +44,22 @@ 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|
13. Legacy |nvim-tree-legacy|
13.1 Legacy: Opts |nvim-tree-legacy-opts|
13.2 Legacy: Highlight |nvim-tree-legacy-highlight|
14. Index |nvim-tree-index|
14.1 Index: Opts |nvim-tree-index-opts|
14.2 Index: API |nvim-tree-index-api|
==============================================================================
1. INTRODUCTION *nvim-tree-introduction*
@@ -113,7 +123,7 @@ Setup the plugin in your `init.lua` >
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- set termguicolors to enable highlight groups
-- optionally enable 24-bit colour
vim.opt.termguicolors = true
-- empty setup using defaults
@@ -175,10 +185,12 @@ Show the mappings: `g?`
`f` Live Filter: Start |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()|
`ge` Copy Basename |nvim-tree-api.fs.copy.basename()|
`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()|
@@ -227,6 +239,23 @@ 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. e.g. >
vim.cmd([[
:hi NvimTreeExecFile guifg=#ffa0a0
:hi NvimTreeSpecialFile guifg=#ff80ff gui=underline
:hi NvimTreeSymlink guifg=Yellow gui=italic
:hi link NvimTreeImageFile Title
]])
<
See |nvim-tree-highlight| for details.
==============================================================================
3. COMMANDS *nvim-tree-commands*
@@ -321,6 +350,14 @@ via |nvim-tree.on_attach| e.g. >
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*
@@ -387,8 +424,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 = false,
highlight_diagnostics = false,
highlight_git = "none",
highlight_diagnostics = "none",
highlight_opened_files = "none",
highlight_modified = "none",
highlight_bookmarks = "none",
@@ -642,7 +679,7 @@ Prefer startup root directory when updating root directory of the tree.
Only relevant when `update_focused_file.update_root` is `true`
Type: `boolean`, Default: `false`
*nvim-tree.sync_root_with_cwd* (previously `update_cwd`)
*nvim-tree.sync_root_with_cwd*
Changes the tree root directory on `DirChanged` and refreshes the tree.
Type: `boolean`, Default: `false`
@@ -664,7 +701,7 @@ Type: `boolean`, Default: `false`
File and folder sorting options.
*nvim-tree.sort.sorter* (previously `sort_by`)
*nvim-tree.sort.sorter*
Changes how files within the same directory are sorted.
Can be one of `"name"`, `"case_sensitive"`, `"modification_time"`, `"extension"`,
`"suffix"`, `"filetype"` or a function.
@@ -743,7 +780,7 @@ Show |signcolumn|. Value can be `"yes"`, `"auto"`, `"no"`.
Width of the window: can be a `%` string, a number representing columns, a
function or a table.
A table indicates that the view should be dynamically sized based on the
longest line (previously `view.adaptive_size`).
longest line.
Type: `string | number | table | function()` returning a number
Default: `30`
@@ -789,8 +826,9 @@ Use nvim-tree in a floating window.
==============================================================================
5.3 OPTS: RENDERER *nvim-tree-opts-renderer*
Highlight precedence:
clipboard > diagnostics > bookmarked > modified > opened > git
Highlight precedence, additive:
git < opened < modified < bookmarked < diagnostics < copied < cut
Neovim <= 0.8 will only show the highest.
*nvim-tree.renderer.add_trailing*
Appends a trailing slash to folder names.
@@ -832,18 +870,20 @@ Whether to show the destination of the symlink.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.highlight_git*
Enable highlight for git attributes using `NvimTreeGit*` highlight groups.
Enable highlight for git attributes using `NvimTreeGit*HL` highlight groups.
Requires |nvim-tree.git.enable|
Type: `boolean`, Default: `false`
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`
*nvim-tree.renderer.highlight_diagnostics*
Enable highlight for diagnostics using `LspDiagnosticsError*Text` highlight groups.
Enable highlight for diagnostics using `NvimTreeDiagnostic*HL` highlight groups.
Requires |nvim-tree.diagnostics.enable|
Type: `boolean`, Default: `false`
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`
*nvim-tree.renderer.highlight_opened_files*
Highlight icons and/or names for |bufloaded()| files using the
`NvimTreeOpenedFile` highlight group.
`NvimTreeOpenedHL` 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"`
@@ -892,8 +932,8 @@ Configuration options for tree indent markers.
*nvim-tree.renderer.icons*
Configuration options for icons.
Icon sign column precedence:
diagnostics > modified > git > bookmarked
Icon order and sign column precedence:
git < modified < bookmarked < diagnostics
*nvim-tree.renderer.icons.web_devicons*
Configure optional plugin `"nvim-tree/nvim-web-devicons"`
@@ -907,7 +947,7 @@ Icon sign column precedence:
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.web_devicons.file.color*
Use icon colors for files.
Use icon colors for files. Overrides highlight groups.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.web_devicons.folder*
@@ -919,7 +959,7 @@ Icon sign column precedence:
Type: `boolean`, Default: `false`
*nvim-tree.renderer.icons.web_devicons.folder.color*
Use icon colors for folders.
Use icon colors for folders. Overrides highlight groups.
Type: `boolean`, Default: `true`
*nvim-tree.renderer.icons.git_placement*
@@ -1060,7 +1100,6 @@ Enable this feature.
Type: `boolean`, Default: `false`
*nvim-tree.update_focused_file.update_root*
(previously `update_focused_file.update_cwd`)
Update the root directory of the tree if the file is not under current
root directory. It prefers vim's cwd and `root_dirs`.
Otherwise it falls back to the folder containing the file.
@@ -1203,7 +1242,7 @@ Only relevant when |modified.show_on_dirs| is `true`.
File / folder filters that may be toggled.
*nvim-tree.filters.git_ignored* (previously `git.ignore`)
*nvim-tree.filters.git_ignored*
Ignore files based on `.gitignore`. Requires |git.enable| `= true`
Toggle via |nvim-tree-api.tree.toggle_gitignore_filter()|, default `I`
Type: `boolean`, Default: `true`
@@ -1236,7 +1275,7 @@ Enabling this is not useful as there is no means yet to persist bookmarks.
Custom list of vim regex for file/directory names that will not be shown.
Backslashes must be escaped e.g. "^\\.git". See |string-match|.
Toggle via |nvim-tree-api.tree.toggle_custom_filter()|, default `U`
Type: {string}, Default: `{}`
Type: {string} | `function(absolute_path)`, Default: `{}`
*nvim-tree.filters.exclude*
List of directories or files to exclude from filtering: always show them.
@@ -1350,7 +1389,7 @@ Configuration options for opening a file from nvim-tree.
Prevent new opened file from opening in the same window as the tree.
Type: `boolean`, Default: `true`
*nvim-tree.actions.open_file.resize_window* (previously `view.auto_resize`)
*nvim-tree.actions.open_file.resize_window*
Resizes the tree when opening a file.
Type: `boolean`, Default: `true`
@@ -1418,7 +1457,7 @@ Windows default `"trash"` requires `trash-cli` or similar
*nvim-tree.tab.sync*
Configuration for syncing nvim-tree across tabs.
*nvim-tree.tab.sync.open* (previously `nvim-tree.open_on_tab`)
*nvim-tree.tab.sync.open*
Opens the tree automatically when switching tabpage or opening a new
tabpage if the tree was previously open.
Type: `boolean`, Default: `false`
@@ -1427,7 +1466,7 @@ Configuration for syncing nvim-tree across tabs.
Closes the tree across all tabpages when the tree is closed.
Type: `boolean`, Default: `false`
*nvim-tree.tab.sync.ignore* (previously `nvim-tree.ignore_buf_on_tab_change`)
*nvim-tree.tab.sync.ignore*
List of filetypes or buffer names on new tab that will prevent
|nvim-tree.tab.sync.open| and |nvim-tree.tab.sync.close|
Type: {string}, Default: `{}`
@@ -1467,7 +1506,7 @@ Confirmation prompts.
Prompt before removing.
Type: `boolean`, Default: `true`
*nvim-tree.ui.confirm.trash* (previously `trash.require_confirm`)
*nvim-tree.ui.confirm.trash*
Prompt before trashing.
Type: `boolean`, Default: `true`
@@ -1843,6 +1882,12 @@ 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.
@@ -1875,6 +1920,12 @@ 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.
@@ -1882,6 +1933,12 @@ node.navigate.git.next_skip_gitignored()
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.
@@ -1890,10 +1947,22 @@ node.navigate.git.prev_skip_gitignored()
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.
@@ -2041,7 +2110,7 @@ config.mappings.get_keymap_default()
(table) as per |nvim_buf_get_keymap()|
==============================================================================
6.8 API COMMANDS *nvim-tree-api.commands*
6.9 API COMMANDS *nvim-tree-api.commands*
commands.get() *nvim-tree-api.commands.get()*
Retrieve all commands, see |nvim-tree-commands|
@@ -2052,6 +2121,15 @@ 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*
@@ -2163,10 +2241,12 @@ You are encouraged to copy these to your own |nvim-tree.on_attach| function.
vim.keymap.set('n', 'f', api.live_filter.start, opts('Live Filter: Start'))
vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
vim.keymap.set('n', 'ge', api.fs.copy.basename, opts('Copy Basename'))
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'))
@@ -2213,42 +2293,32 @@ groups.
Example |:highlight| >
:hi NvimTreeSymlink guifg=blue gui=bold,underline
<
You should have 'termguicolors' enabled, otherwise, colors will not be
applied.
It is recommended to enable 'termguicolors' for the more pleasant 24-bit
colours.
To view the active highlight groups run `:so $VIMRUNTIME/syntax/hitest.vim`
To view the nvim-tree highlight groups run |:NvimTreeHiTest|
To view all active highlight groups run `:so $VIMRUNTIME/syntax/hitest.vim`
as per |:highlight|
Default linked group follows name.
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
<
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:
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
<
Standard: >
NvimTreeNormal Normal
NvimTreeNormalFloat NormalFloat
@@ -2267,67 +2337,137 @@ 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
<
Bookmark Icon: >
NvimTreeBookmark
<
Bookmark Highlight: >
Bookmarks: >
NvimTreeBookmarkIcon NvimTreeFolderIcon
NvimTreeBookmarkHL SpellLocal
<
Picker: >
NvimTreeWindowPicker
Modified: >
NvimTreeModifiedIcon Type
NvimTreeModifiedFileHL NvimTreeModifiedIcon
NvimTreeModifiedFolderHL NvimTreeModifiedIcon
<
Live Filter: >
NvimTreeLiveFilterPrefix
NvimTreeLiveFilterValue
Opened: >
NvimTreeOpenedHL Special
<
Git Icon: >
NvimTreeGitDirty
NvimTreeGitStaged
NvimTreeGitMerge
NvimTreeGitRenamed
NvimTreeGitNew
NvimTreeGitDeleted
NvimTreeGitIgnored Comment
NvimTreeGitDeletedIcon Statement
NvimTreeGitDirtyIcon Statement
NvimTreeGitIgnoredIcon Comment
NvimTreeGitMergeIcon Constant
NvimTreeGitNewIcon PreProc
NvimTreeGitRenamedIcon PreProc
NvimTreeGitStagedIcon Constant
<
Git File Text: >
NvimTreeFileDirty NvimTreeGitDirty
NvimTreeFileStaged NvimTreeGitStaged
NvimTreeFileMerge NvimTreeGitMerge
NvimTreeFileRenamed NvimTreeGitRenamed
NvimTreeFileNew NvimTreeGitNew
NvimTreeFileDeleted NvimTreeGitDeleted
NvimTreeFileIgnored NvimTreeGitIgnored
Git File File Highlight: >
NvimTreeGitFileDeletedHL NvimTreeGitDeletedIcon
NvimTreeGitFileDirtyHL NvimTreeGitDirtyIcon
NvimTreeGitFileIgnoredHL NvimTreeGitIgnoredIcon
NvimTreeGitFileMergeHL NvimTreeGitMergeIcon
NvimTreeGitFileNewHL NvimTreeGitNewIcon
NvimTreeGitFileRenamedHL NvimTreeGitRenamedIcon
NvimTreeGitFileStagedHL NvimTreeGitStagedIcon
<
Git Folder Text: >
NvimTreeFolderDirty NvimTreeFileDirty
NvimTreeFolderStaged NvimTreeFileStaged
NvimTreeFolderMerge NvimTreeFileMerge
NvimTreeFolderRenamed NvimTreeFileRenamed
NvimTreeFolderNew NvimTreeFileNew
NvimTreeFolderDeleted NvimTreeFileDeleted
NvimTreeFolderIgnored NvimTreeFileIgnored
Git Folder Folder Highlight: >
NvimTreeGitFolderDeletedHL NvimTreeGitFileDeletedHL
NvimTreeGitFolderDirtyHL NvimTreeGitFileDirtyHL
NvimTreeGitFolderIgnoredHL NvimTreeGitFileIgnoredHL
NvimTreeGitFolderMergeHL NvimTreeGitFileMergeHL
NvimTreeGitFolderNewHL NvimTreeGitFileNewHL
NvimTreeGitFolderRenamedHL NvimTreeGitFileRenamedHL
NvimTreeGitFolderStagedHL NvimTreeGitFileStagedHL
<
Diagnostics Icon: >
NvimTreeLspDiagnosticsError DiagnosticError
NvimTreeLspDiagnosticsWarning DiagnosticWarn
NvimTreeLspDiagnosticsInformation DiagnosticInfo
NvimTreeLspDiagnosticsHint DiagnosticHint
NvimTreeDiagnosticErrorIcon DiagnosticError
NvimTreeDiagnosticWarnIcon DiagnosticWarn
NvimTreeDiagnosticInfoIcon DiagnosticInfo
NvimTreeDiagnosticHintIcon DiagnosticHint
<
Diagnostics File Text: >
NvimTreeLspDiagnosticsErrorText NvimTreeLspDiagnosticsError
NvimTreeLspDiagnosticsWarningText NvimTreeLspDiagnosticsWarning
NvimTreeLspDiagnosticsInfoText NvimTreeLspDiagnosticsInformation
NvimTreeLspDiagnosticsHintText NvimTreeLspDiagnosticsHint
Diagnostics File Highlight: >
NvimTreeDiagnosticErrorFileHL DiagnosticUnderlineError
NvimTreeDiagnosticWarnFileHL DiagnosticUnderlineWarn
NvimTreeDiagnosticInfoFileHL DiagnosticUnderlineInfo
NvimTreeDiagnosticHintFileHL DiagnosticUnderlineHint
<
Diagnostics Folder Text: >
NvimTreeLspDiagnosticsErrorFolderText NvimTreeLspDiagnosticsErrorText
NvimTreeLspDiagnosticsWarningFolderText NvimTreeLspDiagnosticsWarningText
NvimTreeLspDiagnosticsInfoFolderText NvimTreeLspDiagnosticsInfoText
NvimTreeLspDiagnosticsHintFolderText NvimTreeLspDiagnosticsHintText
Diagnostics Folder Highlight: >
NvimTreeDiagnosticErrorFolderHL NvimTreeDiagnosticErrorFileHL
NvimTreeDiagnosticWarnFolderHL NvimTreeDiagnosticWarnFileHL
NvimTreeDiagnosticInfoFolderHL NvimTreeDiagnosticInfoFileHL
NvimTreeDiagnosticHintFolderHL NvimTreeDiagnosticHintFileHL
<
==============================================================================
8.2 HIGHLIGHT: OVERHAUL *nvim-tree-highlight-overhaul*
See |nvim-tree-legacy-highlight| for old highlight group compatibility.
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
Approximate pre-overhaul values for the `SpellCap` groups may be set via: >
vim.cmd([[
:hi NvimTreeExecFile gui=bold guifg=#ffa0a0
:hi NvimTreeSymlink gui=bold guifg=#ffff60
:hi NvimTreeSpecialFile gui=bold,underline guifg=#ff80ff
:hi NvimTreeImageFile gui=bold guifg=#ff80ff
]])
<
==============================================================================
9. EVENTS *nvim-tree-events*
@@ -2501,4 +2641,339 @@ keep using |netrw| without its browser features please ensure:
|nvim-tree.disable_netrw| `= false`
|nvim-tree.hijack_netrw| ` = true`
==============================================================================
13. LEGACY *nvim-tree-legacy*
Breaking refactors have been made however the legacy versions will be silently
migrated and used.
There are no plans to remove this migration.
==============================================================================
13.1 LEGACY: OPTS *nvim-tree-legacy-opts*
Legacy options are translated to the current, making type and value changes as
needed.
`update_cwd` |nvim-tree.sync_root_with_cwd|
`update_focused_file.update_cwd` |nvim-tree.update_focused_file.update_root|
`open_on_tab` |nvim-tree.tab.sync.open|
`ignore_buf_on_tab_change` |nvim-tree.tab.sync.ignore|
`renderer.root_folder_modifier` |nvim-tree.renderer.root_folder_label|
`update_focused_file.debounce_delay` |nvim-tree.view.debounce_delay|
`trash.require_confirm` |nvim-tree.ui.confirm.trash|
`view.adaptive_size` |nvim-tree.view.width|
`sort_by` |nvim-tree.sort.sorter|
`git.ignore` |nvim-tree.filters.git_ignored|
`renderer.icons.webdev_colors` |nvim-tree.renderer.icons.web_devicons.file.color|
==============================================================================
13.2 LEGACY: HIGHLIGHT *nvim-tree-legacy-highlight*
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
<
==============================================================================
14 INDEX *nvim-tree-index*
==============================================================================
14.1 INDEX: OPTS *nvim-tree-index-opts*
|nvim-tree.actions.change_dir|
|nvim-tree.actions.change_dir.enable|
|nvim-tree.actions.change_dir.global|
|nvim-tree.actions.change_dir.restrict_above_cwd|
|nvim-tree.actions.expand_all|
|nvim-tree.actions.expand_all.exclude|
|nvim-tree.actions.expand_all.max_folder_discovery|
|nvim-tree.actions.file_popup|
|nvim-tree.actions.file_popup.open_win_config|
|nvim-tree.actions.open_file|
|nvim-tree.actions.open_file.eject|
|nvim-tree.actions.open_file.quit_on_open|
|nvim-tree.actions.open_file.resize_window|
|nvim-tree.actions.open_file.window_picker|
|nvim-tree.actions.open_file.window_picker.chars|
|nvim-tree.actions.open_file.window_picker.enable|
|nvim-tree.actions.open_file.window_picker.exclude|
|nvim-tree.actions.open_file.window_picker.picker|
|nvim-tree.actions.remove_file.close_window|
|nvim-tree.actions.use_system_clipboard|
|nvim-tree.auto_reload_on_write|
|nvim-tree.diagnostics.debounce_delay|
|nvim-tree.diagnostics.enable|
|nvim-tree.diagnostics.icons|
|nvim-tree.diagnostics.severity|
|nvim-tree.diagnostics.severity.max|
|nvim-tree.diagnostics.severity.min|
|nvim-tree.diagnostics.show_on_dirs|
|nvim-tree.diagnostics.show_on_open_dirs|
|nvim-tree.disable_netrw|
|nvim-tree.experimental|
|nvim-tree.filesystem_watchers.debounce_delay|
|nvim-tree.filesystem_watchers.enable|
|nvim-tree.filesystem_watchers.ignore_dirs|
|nvim-tree.filters.custom|
|nvim-tree.filters.dotfiles|
|nvim-tree.filters.exclude|
|nvim-tree.filters.git_clean|
|nvim-tree.filters.git_ignored|
|nvim-tree.filters.no_bookmark|
|nvim-tree.filters.no_buffer|
|nvim-tree.git.cygwin_support|
|nvim-tree.git.disable_for_dirs|
|nvim-tree.git.enable|
|nvim-tree.git.show_on_dirs|
|nvim-tree.git.show_on_open_dirs|
|nvim-tree.git.timeout|
|nvim-tree.help.sort_by|
|nvim-tree.hijack_cursor|
|nvim-tree.hijack_directories.auto_open|
|nvim-tree.hijack_directories.enable|
|nvim-tree.hijack_netrw|
|nvim-tree.hijack_unnamed_buffer_when_opening|
|nvim-tree.live_filter.always_show_folders|
|nvim-tree.live_filter.prefix|
|nvim-tree.log.enable|
|nvim-tree.log.truncate|
|nvim-tree.log.types|
|nvim-tree.log.types.all|
|nvim-tree.log.types.config|
|nvim-tree.log.types.copy_paste|
|nvim-tree.log.types.dev|
|nvim-tree.log.types.diagnostics|
|nvim-tree.log.types.git|
|nvim-tree.log.types.profile|
|nvim-tree.log.types.watcher|
|nvim-tree.modified.enable|
|nvim-tree.modified.show_on_dirs|
|nvim-tree.modified.show_on_open_dirs|
|nvim-tree.notify.threshold|
|nvim-tree.on_attach|
|nvim-tree.prefer_startup_root|
|nvim-tree.reload_on_bufenter|
|nvim-tree.renderer.add_trailing|
|nvim-tree.renderer.full_name|
|nvim-tree.renderer.group_empty|
|nvim-tree.renderer.highlight_bookmarks|
|nvim-tree.renderer.highlight_clipboard|
|nvim-tree.renderer.highlight_diagnostics|
|nvim-tree.renderer.highlight_git|
|nvim-tree.renderer.highlight_modified|
|nvim-tree.renderer.highlight_opened_files|
|nvim-tree.renderer.icons|
|nvim-tree.renderer.icons.bookmarks_placement|
|nvim-tree.renderer.icons.diagnostics_placement|
|nvim-tree.renderer.icons.git_placement|
|nvim-tree.renderer.icons.glyphs|
|nvim-tree.renderer.icons.glyphs.default|
|nvim-tree.renderer.icons.glyphs.folder|
|nvim-tree.renderer.icons.glyphs.git|
|nvim-tree.renderer.icons.glyphs.modified|
|nvim-tree.renderer.icons.glyphs.symlink|
|nvim-tree.renderer.icons.modified_placement|
|nvim-tree.renderer.icons.padding|
|nvim-tree.renderer.icons.show|
|nvim-tree.renderer.icons.show.bookmarks|
|nvim-tree.renderer.icons.show.diagnostics|
|nvim-tree.renderer.icons.show.file|
|nvim-tree.renderer.icons.show.folder|
|nvim-tree.renderer.icons.show.folder_arrow|
|nvim-tree.renderer.icons.show.git|
|nvim-tree.renderer.icons.show.modified|
|nvim-tree.renderer.icons.symlink_arrow|
|nvim-tree.renderer.icons.web_devicons|
|nvim-tree.renderer.icons.web_devicons.file|
|nvim-tree.renderer.icons.web_devicons.file.color|
|nvim-tree.renderer.icons.web_devicons.file.enable|
|nvim-tree.renderer.icons.web_devicons.folder|
|nvim-tree.renderer.icons.web_devicons.folder.color|
|nvim-tree.renderer.icons.web_devicons.folder.enable|
|nvim-tree.renderer.indent_markers|
|nvim-tree.renderer.indent_markers.enable|
|nvim-tree.renderer.indent_markers.icons|
|nvim-tree.renderer.indent_markers.inline_arrows|
|nvim-tree.renderer.indent_width|
|nvim-tree.renderer.root_folder_label|
|nvim-tree.renderer.special_files|
|nvim-tree.renderer.symlink_destination|
|nvim-tree.respect_buf_cwd|
|nvim-tree.root_dirs|
|nvim-tree.select_prompts|
|nvim-tree.sort.files_first|
|nvim-tree.sort.folders_first|
|nvim-tree.sort.sorter|
|nvim-tree.sync_root_with_cwd|
|nvim-tree.system_open.args|
|nvim-tree.system_open.cmd|
|nvim-tree.tab.sync|
|nvim-tree.tab.sync.close|
|nvim-tree.tab.sync.ignore|
|nvim-tree.tab.sync.open|
|nvim-tree.trash.cmd|
|nvim-tree.ui.confirm|
|nvim-tree.ui.confirm.default_yes|
|nvim-tree.ui.confirm.remove|
|nvim-tree.ui.confirm.trash|
|nvim-tree.update_focused_file.enable|
|nvim-tree.update_focused_file.ignore_list|
|nvim-tree.update_focused_file.update_root|
|nvim-tree.view.centralize_selection|
|nvim-tree.view.cursorline|
|nvim-tree.view.debounce_delay|
|nvim-tree.view.float|
|nvim-tree.view.float.enable|
|nvim-tree.view.float.open_win_config|
|nvim-tree.view.float.quit_on_focus_loss|
|nvim-tree.view.number|
|nvim-tree.view.preserve_window_proportions|
|nvim-tree.view.relativenumber|
|nvim-tree.view.side|
|nvim-tree.view.signcolumn|
|nvim-tree.view.width|
|nvim-tree.view.width.max|
|nvim-tree.view.width.min|
|nvim-tree.view.width.padding|
==============================================================================
14.2 INDEX: API *nvim-tree-index-api*
|nvim-tree-api.commands.get()|
|nvim-tree-api.config.mappings.default_on_attach()|
|nvim-tree-api.config.mappings.get_keymap()|
|nvim-tree-api.config.mappings.get_keymap_default()|
|nvim-tree-api.diagnostics.hi_test()|
|nvim-tree-api.events.subscribe()|
|nvim-tree-api.fs.clear_clipboard()|
|nvim-tree-api.fs.copy.absolute_path()|
|nvim-tree-api.fs.copy.filename()|
|nvim-tree-api.fs.copy.node()|
|nvim-tree-api.fs.copy.relative_path()|
|nvim-tree-api.fs.create()|
|nvim-tree-api.fs.cut()|
|nvim-tree-api.fs.paste()|
|nvim-tree-api.fs.print_clipboard()|
|nvim-tree-api.fs.remove()|
|nvim-tree-api.fs.rename()|
|nvim-tree-api.fs.rename_basename()|
|nvim-tree-api.fs.rename_full()|
|nvim-tree-api.fs.rename_node()|
|nvim-tree-api.fs.rename_sub()|
|nvim-tree-api.fs.trash()|
|nvim-tree-api.git.reload()|
|nvim-tree-api.live_filter.clear()|
|nvim-tree-api.live_filter.start()|
|nvim-tree-api.marks.bulk.delete()|
|nvim-tree-api.marks.bulk.move()|
|nvim-tree-api.marks.bulk.trash()|
|nvim-tree-api.marks.clear()|
|nvim-tree-api.marks.get()|
|nvim-tree-api.marks.list()|
|nvim-tree-api.marks.navigate.next()|
|nvim-tree-api.marks.navigate.prev()|
|nvim-tree-api.marks.navigate.select()|
|nvim-tree-api.marks.toggle()|
|nvim-tree-api.node.navigate.diagnostics.next()|
|nvim-tree-api.node.navigate.diagnostics.next_recursive()|
|nvim-tree-api.node.navigate.diagnostics.prev()|
|nvim-tree-api.node.navigate.diagnostics.prev_recursive()|
|nvim-tree-api.node.navigate.git.next()|
|nvim-tree-api.node.navigate.git.next_recursive()|
|nvim-tree-api.node.navigate.git.next_skip_gitignored()|
|nvim-tree-api.node.navigate.git.prev()|
|nvim-tree-api.node.navigate.git.prev_recursive()|
|nvim-tree-api.node.navigate.git.prev_skip_gitignored()|
|nvim-tree-api.node.navigate.opened.next()|
|nvim-tree-api.node.navigate.opened.prev()|
|nvim-tree-api.node.navigate.parent()|
|nvim-tree-api.node.navigate.parent_close()|
|nvim-tree-api.node.navigate.sibling.first()|
|nvim-tree-api.node.navigate.sibling.last()|
|nvim-tree-api.node.navigate.sibling.next()|
|nvim-tree-api.node.navigate.sibling.prev()|
|nvim-tree-api.node.open.drop()|
|nvim-tree-api.node.open.edit()|
|nvim-tree-api.node.open.horizontal()|
|nvim-tree-api.node.open.no_window_picker()|
|nvim-tree-api.node.open.preview()|
|nvim-tree-api.node.open.preview_no_picker()|
|nvim-tree-api.node.open.replace_tree_buffer()|
|nvim-tree-api.node.open.tab()|
|nvim-tree-api.node.open.tab_drop()|
|nvim-tree-api.node.open.toggle_group_empty()|
|nvim-tree-api.node.open.vertical()|
|nvim-tree-api.node.run.cmd()|
|nvim-tree-api.node.run.system()|
|nvim-tree-api.node.show_info_popup()|
|nvim-tree-api.tree.change_root()|
|nvim-tree-api.tree.change_root_to_node()|
|nvim-tree-api.tree.change_root_to_parent()|
|nvim-tree-api.tree.close()|
|nvim-tree-api.tree.close_in_all_tabs()|
|nvim-tree-api.tree.close_in_this_tab()|
|nvim-tree-api.tree.collapse_all()|
|nvim-tree-api.tree.expand_all()|
|nvim-tree-api.tree.find_file()|
|nvim-tree-api.tree.focus()|
|nvim-tree-api.tree.get_nodes()|
|nvim-tree-api.tree.get_node_under_cursor()|
|nvim-tree-api.tree.is_tree_buf()|
|nvim-tree-api.tree.is_visible()|
|nvim-tree-api.tree.open()|
|nvim-tree-api.tree.reload()|
|nvim-tree-api.tree.search_node()|
|nvim-tree-api.tree.toggle()|
|nvim-tree-api.tree.toggle_custom_filter()|
|nvim-tree-api.tree.toggle_git_clean_filter()|
|nvim-tree-api.tree.toggle_gitignore_filter()|
|nvim-tree-api.tree.toggle_help()|
|nvim-tree-api.tree.toggle_hidden_filter()|
|nvim-tree-api.tree.toggle_no_bookmark_filter()|
|nvim-tree-api.tree.toggle_no_buffer_filter()|
|nvim-tree-api.tree.winid()|
==============================================================================
vim:tw=78:ts=4:sw=4:et:ft=help:norl:

View File

@@ -1,6 +1,6 @@
local lib = require "nvim-tree.lib"
local log = require "nvim-tree.log"
local colors = require "nvim-tree.colors"
local appearance = require "nvim-tree.appearance"
local renderer = require "nvim-tree.renderer"
local view = require "nvim-tree.view"
local commands = require "nvim-tree.commands"
@@ -10,7 +10,7 @@ local legacy = require "nvim-tree.legacy"
local core = require "nvim-tree.core"
local git = require "nvim-tree.git"
local filters = require "nvim-tree.explorer.filters"
local modified = require "nvim-tree.modified"
local buffers = require "nvim-tree.buffers"
local events = require "nvim-tree.events"
local notify = require "nvim-tree.notify"
@@ -104,15 +104,9 @@ function M.open_on_directory()
actions.root.change_dir.force_dirchange(bufname, true)
end
function M.reset_highlight()
colors.setup()
view.reset_winhl()
renderer.render_hl(view.get_bufnr())
end
function M.place_cursor_on_node()
local search = vim.fn.searchcount()
if search and search.exact_match == 1 then
local ok, search = pcall(vim.fn.searchcount)
if ok and search and search.exact_match == 1 then
return
end
@@ -168,8 +162,14 @@ local function setup_autocommands(opts)
vim.api.nvim_create_autocmd(name, vim.tbl_extend("force", default_opts, custom_opts))
end
-- reset highlights when colorscheme is changed
create_nvim_tree_autocmd("ColorScheme", { callback = M.reset_highlight })
-- reset and draw (highlights) when colorscheme is changed
create_nvim_tree_autocmd("ColorScheme", {
callback = function()
appearance.setup()
view.reset_winhl()
renderer.draw()
end,
})
-- prevent new opened file from opening in the same window as nvim-tree
create_nvim_tree_autocmd("BufWipeout", {
@@ -210,7 +210,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(nil, data.buf)
actions.reloaders.reload_explorer()
end)
end
end,
@@ -314,7 +314,7 @@ local function setup_autocommands(opts)
create_nvim_tree_autocmd({ "BufModifiedSet", "BufWritePost" }, {
callback = function()
utils.debounce("Buf:modified", opts.view.debounce_delay, function()
modified.reload()
buffers.reload_modified()
actions.reloaders.reload_explorer()
end)
end,
@@ -386,8 +386,8 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
indent_width = 2,
special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
symlink_destination = true,
highlight_git = false,
highlight_diagnostics = false,
highlight_git = "none",
highlight_diagnostics = "none",
highlight_opened_files = "none",
highlight_modified = "none",
highlight_bookmarks = "none",
@@ -623,6 +623,9 @@ local ACCEPTED_TYPES = {
group_empty = { "boolean", "function" },
root_folder_label = { "function", "string", "boolean" },
},
filters = {
custom = { "function" },
},
actions = {
open_file = {
window_picker = {
@@ -641,9 +644,11 @@ 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" },
@@ -786,7 +791,7 @@ function M.setup(conf)
require("nvim-tree.actions").setup(opts)
require("nvim-tree.keymap").setup(opts)
require("nvim-tree.colors").setup()
require("nvim-tree.appearance").setup()
require("nvim-tree.diagnostics").setup(opts)
require("nvim-tree.explorer").setup(opts)
require("nvim-tree.git").setup(opts)
@@ -796,7 +801,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.modified").setup(opts)
require("nvim-tree.buffers").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

@@ -7,8 +7,6 @@ local notify = require "nvim-tree.notify"
local renderer = require "nvim-tree.renderer"
local reloaders = require "nvim-tree.actions.reloaders"
local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local find_file = require("nvim-tree.actions.finders.find-file").fn
local M = {
@@ -297,6 +295,12 @@ function M.copy_filename(node)
copy_to_clipboard(node.name)
end
---@param node Node
function M.copy_basename(node)
local basename = vim.fn.fnamemodify(node.name, ":r")
copy_to_clipboard(basename)
end
---@param node Node
function M.copy_path(node)
local absolute_path = node.absolute_path
@@ -317,34 +321,23 @@ function M.copy_absolute_path(node)
copy_to_clipboard(content)
end
--- Clipboard text highlight group and position when highlight_clipboard.
---Node is cut. Will not be copied.
---@param node 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
---@return boolean
function M.is_cut(node)
return vim.tbl_contains(clipboard.cut, node)
end
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
---Node is copied. Will not be cut.
---@param node Node
---@return boolean
function M.is_copied(node)
return vim.tbl_contains(clipboard.copy, node)
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

@@ -9,6 +9,16 @@ local M = {
config = {},
}
---@param iter function iterable
---@return integer
local function get_num_nodes(iter)
local i = 0
for _ in iter do
i = i + 1
end
return i
end
local ALLOWED_MODIFIERS = {
[":p"] = true,
[":p:h"] = true,
@@ -31,15 +41,46 @@ function M.rename(node, to)
return
end
-- create a folder for each path element if the folder does not exist
local idx = 0
local path_to_create = ""
local num_nodes = get_num_nodes(utils.path_split(utils.path_remove_trailing(to)))
local is_error = false
for path in utils.path_split(to) do
idx = idx + 1
local p = utils.path_remove_trailing(path)
if #path_to_create == 0 and vim.fn.has "win32" == 1 then
path_to_create = utils.path_join { p, path_to_create }
else
path_to_create = utils.path_join { path_to_create, p }
end
if idx == num_nodes then
events._dispatch_will_rename_node(node.absolute_path, to)
local success, err = vim.loop.fs_rename(node.absolute_path, to)
if not success then
notify.warn(err_fmt(notify_from, notify_to, err))
return
end
elseif not utils.file_exists(path_to_create) then
local success = vim.loop.fs_mkdir(path_to_create, 493)
if not success then
notify.error("Could not create folder " .. notify.render_path(path_to_create))
is_error = true
break
end
is_error = false
end
end
if not is_error then
notify.info(string.format("%s -> %s", notify_from, notify_to))
utils.rename_loaded_buffers(node.absolute_path, to)
events._dispatch_node_renamed(node.absolute_path, to)
end
end
---@param default_modifier string|nil

View File

@@ -6,39 +6,47 @@ local explorer_node = require "nvim-tree.explorer.node"
local diagnostics = require "nvim-tree.diagnostics"
local M = {}
local MAX_DEPTH = 100
---@class NavigationItemOpts
---@field where string
---@field what string
---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
---@param opts NavigationItemOpts
---@return fun()
function M.fn(opts)
return function()
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)
local node_cur = lib.get_node_at_cursor()
local first_node_line = core.get_nodes_starting_line()
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, first_node_line)
local iter_start, iter_end, iter_step, cur, first, nex
if opts.where == "next" then
if where == "next" then
iter_start, iter_end, iter_step = first_node_line, #nodes_by_line, 1
elseif opts.where == "prev" then
elseif where == "prev" then
iter_start, iter_end, iter_step = #nodes_by_line, first_node_line, -1
end
for line = iter_start, iter_end, iter_step do
local node = nodes_by_line[line]
local valid = false
if opts.what == "git" then
local git_status = explorer_node.get_git_status(node)
valid = git_status ~= nil and (not opts.skip_gitignored or git_status[1] ~= "!!")
elseif opts.what == "diag" then
local diag_status = diagnostics.get_diag_status(node)
valid = diag_status ~= nil and diag_status.value ~= nil
elseif opts.what == "opened" then
valid = vim.fn.bufloaded(node.absolute_path) ~= 0
end
local valid = status_is_valid(node, what, skip_gitignored)
if not first and valid then
first = line
@@ -57,6 +65,173 @@ function M.fn(opts)
elseif vim.o.wrapscan and first then
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

View File

@@ -10,13 +10,12 @@ local M = {}
---@param node Explorer|nil
---@param projects table
---@param unloaded_bufnr number|nil
local function refresh_nodes(node, projects, unloaded_bufnr)
local function refresh_nodes(node, projects)
Iterator.builder({ node })
:applier(function(n)
if n.nodes then
local toplevel = git.get_toplevel(n.cwd or n.link_to or n.absolute_path)
explorer_module.reload(n, projects[toplevel] or {}, unloaded_bufnr)
explorer_module.reload(n, projects[toplevel] or {})
end
end)
:recursor(function(n)
@@ -43,18 +42,16 @@ function M.reload_node_status(parent_node, projects)
end
local event_running = false
---@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)
function M.reload_explorer()
if event_running or not core.get_explorer() or vim.v.exiting ~= vim.NIL then
return
end
event_running = true
local projects = git.reload()
refresh_nodes(core.get_explorer(), projects, unloaded_bufnr)
refresh_nodes(core.get_explorer(), projects)
if view.is_visible() then
renderer.draw(unloaded_bufnr)
renderer.draw()
end
event_running = false
end

View File

@@ -2,6 +2,7 @@ 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"
@@ -39,6 +40,7 @@ local Api = {
mappings = {},
},
commands = {},
diagnostics = {},
}
--- Do nothing when setup not called.
@@ -161,6 +163,7 @@ Api.fs.print_clipboard = wrap(actions.fs.copy_paste.print_clipboard)
Api.fs.copy.node = wrap_node(actions.fs.copy_paste.copy)
Api.fs.copy.absolute_path = wrap_node(actions.fs.copy_paste.copy_absolute_path)
Api.fs.copy.filename = wrap_node(actions.fs.copy_paste.copy_filename)
Api.fs.copy.basename = wrap_node(actions.fs.copy_paste.copy_basename)
Api.fs.copy.relative_path = wrap_node(actions.fs.copy_paste.copy_path)
---@param mode string
@@ -175,13 +178,13 @@ end
---@param mode string
---@return fun(node: table)
local function open_or_expand_or_dir_up(mode)
local function open_or_expand_or_dir_up(mode, toggle_group)
return function(node)
if node.name == ".." then
actions.root.change_dir.fn ".."
elseif node.nodes then
lib.expand_or_collapse(node)
else
lib.expand_or_collapse(node, toggle_group)
elseif not toggle_group then
edit(mode, node)
end
end
@@ -195,6 +198,7 @@ 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")
@@ -210,10 +214,14 @@ 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" })
@@ -240,6 +248,8 @@ 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.diagnostics.hi_test = wrap(appearance_diagnostics.hi_test)
Api.commands.get = wrap(function()
return require("nvim-tree.commands").get()
end)

View File

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

@@ -0,0 +1,202 @@
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=DarkBlue" },
-- 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

View File

@@ -1,40 +1,50 @@
local M = {}
---@type table<string, boolean> record of which file is modified
M._record = {}
M._modified = {}
---refresh M.record
function M.reload()
M._record = {}
---refresh M._modified
function M.reload_modified()
M._modified = {}
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._record[path] ~= true
M._modified[path] ~= true
-- no need to keep going if already recorded
-- This also prevents an infinite loop
do
M._record[path] = true
M._modified[path] = true
path = vim.fn.fnamemodify(path, ":h")
end
end
end
end
---@param node Node
---@param node table
---@return boolean
function M.is_modified(node)
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)
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
end
---@param opts table
function M.setup(opts)
M.config = opts.modified
M.config = {
modified = opts.modified,
}
end
return M

View File

@@ -1,130 +0,0 @@
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,6 +134,13 @@ 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

@@ -4,9 +4,6 @@ local log = require "nvim-tree.log"
local M = {}
---TODO add "$VIMRUNTIME" to "workspace.library" and use the @enum instead of this integer
---@alias lsp.DiagnosticSeverity integer
---COC severity level strings to LSP severity levels
---@enum COC_SEVERITY_LEVELS
local COC_SEVERITY_LEVELS = {

View File

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

View File

@@ -4,6 +4,7 @@ local marks = require "nvim-tree.marks"
local M = {
ignore_list = {},
exclude_list = {},
custom_function = nil,
}
---@param path string
@@ -47,16 +48,15 @@ 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, unloaded_bufnr)
local function buf(path, bufinfo)
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) and b.bufnr ~= unloaded_bufnr then
if b.name == path or b.name:find(path .. "/", 1, true) then
return false
end
end
@@ -73,7 +73,20 @@ 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]
if not M.config.filter_no_bookmark then
return false
end
-- add trailing slash to make it match only mark's parent directory
-- not it's siblings
local parent = utils.path_add_trailing(path)
for mark, _ in pairs(bookmarks) do
if path == mark or vim.fn.stridx(mark, parent) == 0 then
return false
end
end
return true
end
---@param path string
@@ -85,6 +98,11 @@ local function custom(path)
local basename = utils.path_basename(path)
-- filter user's custom function
if M.custom_function and M.custom_function(path) then
return true
end
-- filter custom regexes
local relpath = utils.path_relative(path, vim.loop.cwd())
for pat, _ in pairs(M.ignore_list) do
@@ -105,16 +123,13 @@ 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, unloaded_bufnr)
function M.prepare(git_status)
local status = {
git_status = git_status or {},
unloaded_bufnr = unloaded_bufnr,
bufinfo = {},
bookmarks = {},
}
@@ -140,11 +155,7 @@ function M.should_filter(path, status)
return false
end
return git(path, status.git_status)
or buf(path, status.bufinfo, status.unloaded_bufnr)
or dotfile(path)
or custom(path)
or bookmark(path, status.bookmarks)
return git(path, status.git_status) or buf(path, status.bufinfo) or dotfile(path) or custom(path) or bookmark(path, status.bookmarks)
end
function M.setup(opts)
@@ -161,11 +172,15 @@ function M.setup(opts)
M.exclude_list = opts.filters.exclude
local custom_filter = opts.filters.custom
if type(custom_filter) == "function" then
M.custom_function = custom_filter
else
if custom_filter and #custom_filter > 0 then
for _, filter_name in pairs(custom_filter) do
M.ignore_list[filter_name] = true
end
end
end
end
return M

View File

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

View File

@@ -136,6 +136,10 @@ end
---@param path string absolute
---@return string|nil
function M.get_toplevel(path)
if not path then
return nil
end
if not M.config.git.enable then
return nil
end

View File

@@ -2,11 +2,6 @@ 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,14 +119,20 @@ 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, not padded
local hl = { { "NvimTreeRootFolder", 0, 0, #head_lhs } }
-- header text, not padded
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

@@ -68,10 +68,12 @@ function M.default_on_attach(bufnr)
vim.keymap.set('n', 'f', api.live_filter.start, opts('Live Filter: Start'))
vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
vim.keymap.set('n', 'ge', api.fs.copy.basename, opts('Copy Basename'))
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'))

View File

@@ -3,6 +3,7 @@ local notify = require "nvim-tree.notify"
local M = {}
-- silently move, please add to help nvim-tree-legacy-opts
local function refactored(opts)
-- 2022/06/20
utils.move_missing_val(opts, "update_focused_file", "update_cwd", opts, "update_focused_file", "update_root", true)
@@ -41,6 +42,16 @@ 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)
@@ -51,12 +62,12 @@ end
local function removed(opts)
if opts.auto_close then
notify.warn "auto close feature has been removed, see note in the README (tips & reminder section)"
notify.warn "auto close feature has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Auto-Close"
opts.auto_close = nil
end
if opts.focus_empty_on_setup then
notify.warn "focus_empty_on_setup has been removed and will be replaced by a new startup configuration. Please remove this option. See https://bit.ly/3yJch2T"
notify.warn "focus_empty_on_setup has been removed: https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup"
opts.focus_empty_on_setup = nil
end

View File

@@ -3,6 +3,7 @@ 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
@@ -24,7 +25,7 @@ function M.get_node_at_cursor()
return
end
local cursor = vim.api.nvim_win_get_cursor(view.get_winnr())
local cursor = vim.api.nvim_win_get_cursor(winnr)
local line = cursor[1]
if line == 1 and view.is_root_folder_visible(core.get_cwd()) then
@@ -86,6 +87,34 @@ 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)
@@ -98,8 +127,21 @@ 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)
function M.expand_or_collapse(node, toggle_group)
toggle_group = toggle_group or false
if node.has_children then
node.has_children = false
end
@@ -108,9 +150,20 @@ function M.expand_or_collapse(node)
core.get_explorer():expand(node)
end
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
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
end
renderer.draw()
@@ -213,6 +266,7 @@ 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

@@ -3,6 +3,7 @@ local core = require "nvim-tree.core"
local utils = require "nvim-tree.utils"
local rename_file = require "nvim-tree.actions.fs.rename-file"
local notify = require "nvim-tree.notify"
local lib = require "nvim-tree.lib"
local M = {
config = {},
@@ -14,9 +15,18 @@ function M.bulk_move()
return
end
local node_at_cursor = lib.get_node_at_cursor()
local default_path = core.get_cwd()
if node_at_cursor and node_at_cursor.type == "directory" then
default_path = node_at_cursor.absolute_path
elseif node_at_cursor and node_at_cursor.parent then
default_path = node_at_cursor.parent.absolute_path
end
local input_opts = {
prompt = "Move to: ",
default = core.get_cwd(),
default = default_path,
completion = "dir",
}

View File

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

View File

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

View File

@@ -1,136 +1,92 @@
local utils = require "nvim-tree.utils"
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 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 HL_POSITION = require("nvim-tree.enum").HL_POSITION
local M = {
opts = {},
decorators = {},
picture_map = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
},
}
---@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
local DEFAULT_ROOT_FOLDER_LABEL = ":~:s?$?/..?"
function Builder.new(root_cwd)
return setmetatable({
---@return Builder
function Builder:new()
local o = {
root_cwd = core.get_cwd(),
index = 0,
depth = 0,
highlights = {},
hl_args = {},
combined_groups = {},
lines = {},
markers = {},
signs = {},
root_cwd = root_cwd,
}, Builder)
}
setmetatable(o, self)
self.__index = self
return o
end
function Builder:configure_root_label(root_folder_label)
self.root_folder_label = root_folder_label or DEFAULT_ROOT_FOLDER_LABEL
return self
---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 })
end
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)
---@private
function Builder:get_folder_name(node)
local name = node.name
local next = node.group_next
while next do
name = name .. "/" .. next.name
name = string.format("%s/%s", name, next.name)
next = next.group_next
end
if node.group_next and self.group_name_modifier then
local new_name = self.group_name_modifier(name)
if node.group_next and type(M.opts.renderer.group_empty) == "function" then
local new_name = M.opts.renderer.group_empty(name)
if type(new_name) == "string" then
name = new_name
else
@@ -138,16 +94,13 @@ function Builder:_get_folder_name(node)
end
end
return name .. self.trailing_slash
return string.format("%s%s", name, M.opts.renderer.add_trailing and "/" or "")
end
---@class HighlightedString
---@field str string
---@field hl string[]
---@private
---@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
@@ -156,21 +109,22 @@ 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 .. v.str
string = string.format("%s%s", 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
@@ -181,12 +135,14 @@ function Builder:_build_folder(node)
end
local foldername_hl = "NvimTreeFolderName"
if node.link_to and self.symlink_destination then
if node.link_to and M.opts.renderer.symlink_destination then
local arrow = icons.i.symlink_arrow
local link_to = utils.path_relative(node.link_to, core.get_cwd())
foldername = foldername .. arrow .. link_to
local link_to = utils.path_relative(node.link_to, self.root_cwd)
foldername = string.format("%s%s%s", foldername, arrow, link_to)
foldername_hl = "NvimTreeSymlinkFolderName"
elseif vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then
elseif
vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name)
then
foldername_hl = "NvimTreeSpecialFolderName"
elseif node.open then
foldername_hl = "NvimTreeOpenedFolderName"
@@ -197,174 +153,56 @@ 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 self.symlink_destination then
local link_to = utils.path_relative(node.link_to, core.get_cwd())
symlink_formatted = symlink_formatted .. arrow .. link_to
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)
end
return { str = icon, hl = { "NvimTreeSymlinkIcon" } }, { str = symlink_formatted, hl = { "NvimTreeSymlink" } }
end
---@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
---@private
---@param node table
---@return HighlightedString icon
---@return HighlightedString name
function Builder:_build_file(node)
local icon = self:_build_file_icon(node)
function Builder:build_file(node)
local hl
if vim.tbl_contains(self.special_files, node.absolute_path) or vim.tbl_contains(self.special_files, node.name) then
if vim.tbl_contains(M.opts.renderer.special_files, node.absolute_path) or vim.tbl_contains(M.opts.renderer.special_files, node.name) then
hl = "NvimTreeSpecialFile"
elseif node.executable then
hl = "NvimTreeExecFile"
elseif self.picture_map[node.extension] then
elseif M.picture_map[node.extension] then
hl = "NvimTreeImageFile"
end
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
local icon, hl_group = icons.get_file_icon(node.name, node.extension)
return { str = icon, hl = { hl_group } }, { str = node.name, hl = { hl } }
end
---@private
---@param indent_markers HighlightedString[]
---@param arrows HighlightedString[]|nil
---@param icon HighlightedString
---@param name HighlightedString
---@param git_icons HighlightedString[]|nil
---@param diagnostics_icon HighlightedString|nil
---@param modified_icon HighlightedString|nil
---@param bookmark_icon HighlightedString|nil
---@param node table
---@return HighlightedString[]
function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon, bookmark_icon)
function Builder:format_line(indent_markers, arrows, icon, name, node)
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 = self.icon_padding })
table.insert(t1, { str = M.opts.renderer.icons.padding })
end
table.insert(t1, v)
end
@@ -379,78 +217,134 @@ function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, dia
local line = { indent_markers, arrows }
add_to_end(line, { icon })
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 })
for i = #M.decorators, 1, -1 do
add_to_end(line, M.decorators[i]:icons_before(node))
end
add_to_end(line, { name })
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 })
for i = #M.decorators, 1, -1 do
add_to_end(line, M.decorators[i]:icons_after(node))
end
return line
end
function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
local copy_paste = require "nvim-tree.actions.fs.copy-paste"
---@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
---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
-- 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
-- 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)
-- 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))
local line = self:format_line(indent_markers, arrows, icon, name, node)
table.insert(self.lines, self:unwrap_highlighted_strings(line))
self.index = self.index + 1
@@ -458,13 +352,14 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
if node.open then
self.depth = self.depth + 1
self:build(node, unloaded_bufnr)
self:build_lines(node)
self.depth = self.depth - 1
end
end
function Builder:_get_nodes_number(nodes)
if not self.filter then
---@private
function Builder:get_nodes_number(nodes)
if not live_filter.filter then
return #nodes
end
@@ -477,53 +372,77 @@ function Builder:_get_nodes_number(nodes)
return i
end
function Builder:build(tree, unloaded_bufnr)
local num_children = self:_get_nodes_number(tree.nodes)
---@private
function Builder:build_lines(node)
if not node then
node = core.get_explorer()
end
local num_children = self:get_nodes_number(node.nodes)
local idx = 1
for _, node in ipairs(tree.nodes) do
if not node.hidden then
self:_build_line(node, idx, num_children, unloaded_bufnr)
for _, n in ipairs(node.nodes) do
if not n.hidden then
self:build_signs(n)
self:build_line(n, idx, num_children)
idx = idx + 1
end
end
return self
end
local function format_root_name(root_cwd, root_label)
---@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(root_cwd)
local label = root_label(self.root_cwd)
if type(label) == "string" then
return label
else
root_label = DEFAULT_ROOT_FOLDER_LABEL
return "???"
end
end
return utils.path_remove_trailing(vim.fn.fnamemodify(root_cwd, root_label))
return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label))
end
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))
---@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 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))
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:unwrap()
return self.lines, self.highlights, self.signs
function Builder.setup(opts)
M.opts = opts
-- 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),
}
end
return Builder

View File

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

@@ -2,18 +2,23 @@ local HL_POSITION = require("nvim-tree.enum").HL_POSITION
local diagnostics = require "nvim-tree.diagnostics"
local M = {
HS_FILE = {},
HS_FOLDER = {},
ICON = {},
hl_pos = HL_POSITION.none,
-- highlight strings for the icons
HS_ICON = {},
-- highlight groups for HL
HG_FILE = {},
HG_FOLDER = {},
-- position for HL
HL_POS = HL_POSITION.none,
}
---Diagnostics text highlight group when highlight_diagnostics.
---Diagnostics highlight group and position 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
@@ -26,7 +31,7 @@ function M.get_highlight(node)
end
if group then
return M.hl_pos, group
return M.HL_POS, group
else
return HL_POSITION.none, nil
end
@@ -49,40 +54,38 @@ function M.setup(opts)
}
if opts.diagnostics.enable and opts.renderer.highlight_diagnostics then
-- TODO add a HL_POSITION
-- M.hl_pos = HL_POSITION[opts.renderer.highlight_diagnostics]
M.hl_pos = HL_POSITION.name
M.HL_POS = HL_POSITION[opts.renderer.highlight_diagnostics]
end
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_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_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.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.ICON[vim.diagnostic.severity.ERROR] = {
M.HS_ICON[vim.diagnostic.severity.ERROR] = {
str = M.config.diagnostics.icons.error,
hl = { "NvimTreeLspDiagnosticsError" },
hl = { "NvimTreeDiagnosticErrorIcon" },
}
M.ICON[vim.diagnostic.severity.WARN] = {
M.HS_ICON[vim.diagnostic.severity.WARN] = {
str = M.config.diagnostics.icons.warning,
hl = { "NvimTreeLspDiagnosticsWarning" },
hl = { "NvimTreeDiagnosticWarningIcon" },
}
M.ICON[vim.diagnostic.severity.INFO] = {
M.HS_ICON[vim.diagnostic.severity.INFO] = {
str = M.config.diagnostics.icons.info,
hl = { "NvimTreeLspDiagnosticsInformation" },
hl = { "NvimTreeDiagnosticInfoIcon" },
}
M.ICON[vim.diagnostic.severity.HINT] = {
M.HS_ICON[vim.diagnostic.severity.HINT] = {
str = M.config.diagnostics.icons.hint,
hl = { "NvimTreeLspDiagnosticsHint" },
hl = { "NvimTreeDiagnosticHintIcon" },
}
for _, i in ipairs(M.ICON) do
for _, i in ipairs(M.HS_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 = "cursor",
relative = "win",
row = 0,
col = 1 - vim.fn.getcursorcharpos()[3],
bufpos = { vim.api.nvim_win_get_cursor(0)[1] - 1, 0 },
width = math.min(text_width, vim.o.columns - 2),
height = 1,
noautocmd = true,

View File

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

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

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

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

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

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

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

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

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

@@ -0,0 +1,35 @@
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,33 +2,30 @@ 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 = {
last_highlights = {},
}
local M = {}
local SIGN_GROUP = "NvimTreeRendererSigns"
local namespace_id = vim.api.nvim_create_namespace "NvimTreeHighlights"
local function _draw(bufnr, lines, hl, signs)
---@param bufnr number
---@param lines string[]
---@param hl_args AddHighlightArgs[]
---@param signs string[]
local function _draw(bufnr, lines, hl_args, 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)
M.render_hl(bufnr, hl_args)
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.fn.sign_unplace(SIGN_GROUP)
for _, sign in pairs(signs) do
vim.fn.sign_place(0, SIGN_GROUP, sign.sign, bufnr, { lnum = sign.lnum, priority = sign.priority })
for i, sign_name in pairs(signs) do
vim.fn.sign_place(0, SIGN_GROUP, sign_name, bufnr, { lnum = i + 1 })
end
end
@@ -37,7 +34,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 or M.last_highlights) do
for _, data in ipairs(hl) 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])
@@ -46,16 +43,7 @@ function M.render_hl(bufnr, hl)
end
end
local picture_map = {
jpg = true,
jpeg = true,
png = true,
gif = true,
webp = true,
jxl = true,
}
function M.draw(unloaded_bufnr)
function M.draw()
local bufnr = view.get_bufnr()
if not core.get_explorer() or not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
return
@@ -66,30 +54,11 @@ function M.draw(unloaded_bufnr)
local cursor = vim.api.nvim_win_get_cursor(view.get_winnr())
icon_component.reset_config()
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()
local builder = Builder:new():build()
_draw(bufnr, lines, hl, signs)
_draw(bufnr, builder.lines, builder.hl_args, builder.signs)
M.last_highlights = hl
if cursor and #lines >= cursor[1] then
if cursor and #builder.lines >= cursor[1] then
vim.api.nvim_win_set_cursor(view.get_winnr(), cursor)
end
@@ -102,15 +71,12 @@ 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,6 +116,28 @@ 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

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 ~= nil then
if tabinfo and tabinfo.winnr and vim.api.nvim_win_is_valid(tabinfo.winnr) then
return tabinfo.winnr
end
end

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/update-help.sh
# run from repository root: scripts/help-update.sh OR make help-update
#
@@ -21,6 +21,39 @@ sed -e "s/^ / /" /tmp/DEFAULT_OPTS.2.lua > /tmp/DEFAULT_OPTS.6.lua
sed -i -e "/${begin}/,/${end}/{ /${begin}/{p; r /tmp/DEFAULT_OPTS.6.lua
}; /${end}/p; d; }" doc/nvim-tree-lua.txt
#
# opts index
#
begin="nvim-tree-index-opts\*"
end="====================="
printf '\n' > /tmp/index-opts.txt
sed -E "
/^ *\*(nvim-tree\..*)\*$/! d ;
s/^.*\*(.*)\*/|\1|/g
" doc/nvim-tree-lua.txt | sort -d >> /tmp/index-opts.txt
printf '\n' >> /tmp/index-opts.txt
sed -i -e "/${begin}/,/${end}/{ /${begin}/{p; r /tmp/index-opts.txt
}; /${end}/p; d; }" doc/nvim-tree-lua.txt
#
# api index
#
begin="nvim-tree-index-api\*"
end="====================="
printf '\n' > /tmp/index-api.txt
sed -E "
/\*(nvim-tree-api.*\(\))\*/! d ;
s/^.*\*(.*)\*/|\1|/g
" doc/nvim-tree-lua.txt | sort -d >> /tmp/index-api.txt
printf '\n' >> /tmp/index-api.txt
sed -i -e "/${begin}/,/${end}/{ /${begin}/{p; r /tmp/index-api.txt
}; /${end}/p; d; }" doc/nvim-tree-lua.txt
#
# DEFAULT_ON_ATTACH
#
@@ -38,7 +71,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 line
" /tmp/DEFAULT_ON_ATTACH.lua | while read -r line
do
eval "printf '%-17.17s %-26.26s %s\n' ${line}" >> /tmp/DEFAULT_ON_ATTACH.help
done

44
scripts/luals-check.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/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