Skip to content

Commit b364458

Browse files
committed
Refacto: rewrite everything
- The tree is created with libuv functions, which makes it blazingly fast. - The tree may now be faster than any other vim trees, it can handle directories with thousands of files without any latency at all (tested on 40K files, works flawlessly). - More solid logic for opening and closing the tree. - tree state is remembered (closing / opening a folder keeps opened subdirectories open) - detection of multiple git projects in the tree - more icon support - smart rendering - smart updates - ms windows support
1 parent e1fbabf commit b364458

File tree

16 files changed

+1087
-1027
lines changed

16 files changed

+1087
-1027
lines changed

README.md

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# A File Explorer For Neovim Written In Lua
22

3-
## Notice
4-
5-
- This plugin does not work on windows.
6-
73
## Install
84

95
Install with [vim-plug](https://github.com/junegunn/vim-plug):
@@ -16,11 +12,10 @@ Plug 'kyazdani42/nvim-tree.lua'
1612
```vim
1713
let g:lua_tree_side = 'right' | 'left' "left by default
1814
let g:lua_tree_size = 40 "30 by default
19-
let g:lua_tree_ignore = [ '.git', 'node_modules', '.cache' ] "empty by default, not working on mac atm
15+
let g:lua_tree_ignore = [ '.git', 'node_modules', '.cache' ] "empty by default
2016
let g:lua_tree_auto_open = 1 "0 by default, opens the tree when typing `vim $DIR` or `vim`
2117
let g:lua_tree_auto_close = 1 "0 by default, closes the tree when it's the last window
22-
let g:lua_tree_follow = 1 "0 by default, this option will bind BufEnter to the LuaTreeFindFile command
23-
" :help LuaTreeFindFile for more info
18+
let g:lua_tree_follow = 1 "0 by default, this option allows the cursor to be updated when entering a buffer
2419
let g:lua_tree_show_icons = {
2520
\ 'git': 1,
2621
\ 'folders': 0,
@@ -44,14 +39,17 @@ let g:lua_tree_bindings = {
4439
\ 'rename': 'r'
4540
\ }
4641
42+
let g:lua_tree_icons = {
43+
\
44+
\ }
45+
4746
nnoremap <C-n> :LuaTreeToggle<CR>
4847
nnoremap <leader>r :LuaTreeRefresh<CR>
4948
nnoremap <leader>n :LuaTreeFindFile<CR>
5049
5150
set termguicolors " this variable must be enabled for colors to be applied properly
5251
5352
" a list of groups can be found at `:help lua_tree_highlight`
54-
highlight LuaTreeFolderName guibg=cyan gui=bold,underline
5553
highlight LuaTreeFolderIcon guibg=blue
5654
```
5755

@@ -60,7 +58,8 @@ highlight LuaTreeFolderIcon guibg=blue
6058
- move around like in any vim buffer
6159
- `<CR>` on `..` will cd in the above directory
6260
- `.` will cd in the directory under the cursor
63-
- type `a` to add a file
61+
- type `a` to add a file. Adding a directory requires leaving a leading `/` at the end of the path.
62+
> you can add multiple directories by doing foo/bar/baz/f and it will add foo bar and baz directories and f as a file
6463
- type `r` to rename a file
6564
- type `d` to delete a file (will prompt for confirmation)
6665
- if the file is a directory, `<CR>` will open the directory
@@ -72,21 +71,20 @@ highlight LuaTreeFolderIcon guibg=blue
7271
- Double left click acts like `<CR>`
7372
- Double right click acts like `.`
7473

74+
## Note
75+
76+
This plugin is very fast. It has been tested on 40K items which opens instantly. \
77+
The performance of that plugin is due to the use of the `libuv` `scandir` and `scandir_next` functions instead of spawning an `ls` process which can get slow on large files when combining with `stat` to get file informations.
78+
7579
## Features
76-
- [x] Open file in current buffer or in split with FzF like bindings (`<CR>`, `<C-v>`, `<C-x>`, `<C-t>`)
77-
- [x] File icons with vim-devicons
78-
- [x] Syntax highlighting ([exa](https://github.com/ogham/exa) like)
79-
- [x] Change directory with `.`
80-
- [x] Add / Rename / delete files
81-
- [x] Git integration
82-
- [x] Mouse support
80+
- Open file in current buffer or in split with FzF like bindings (`<CR>`, `<C-v>`, `<C-x>`, `<C-t>`)
81+
- File icons with vim-devicons
82+
- Syntax highlighting ([exa](https://github.com/ogham/exa) like)
83+
- Change directory with `.`
84+
- Add / Rename / delete files
85+
- Git integration
86+
- Mouse support
8387

8488
## Screenshot
8589

8690
![alt text](.github/screenshot.png?raw=true "file explorer")
87-
88-
## TODO
89-
90-
- Tree creation could be async
91-
- bufferize tree
92-
- better default colors (use vim highlight groups)

lua/lib/colors.lua

Lines changed: 211 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,50 @@
11
local api = vim.api
2-
local get_colors = require 'lib/config'.get_colors
3-
4-
local colors = get_colors()
52

63
local M = {}
74

8-
local function create_hl()
5+
local function get_color_from_hl(hl_name, fallback)
6+
local id = vim.api.nvim_get_hl_id_by_name(hl_name)
7+
if not id then return fallback end
8+
9+
local hl = vim.api.nvim_get_hl_by_id(id, true)
10+
if not hl or not hl.foreground then return fallback end
11+
12+
return hl.foreground
13+
end
14+
15+
local function get_colors()
16+
return {
17+
red = vim.g.terminal_color_1 or get_color_from_hl('Keyword', 'Red'),
18+
green = vim.g.terminal_color_2 or get_color_from_hl('Character', 'Green'),
19+
yellow = vim.g.terminal_color_3 or get_color_from_hl('PreProc', 'Yellow'),
20+
blue = vim.g.terminal_color_4 or get_color_from_hl('Include', 'Blue'),
21+
purple = vim.g.terminal_color_5 or get_color_from_hl('Define', 'Purple'),
22+
cyan = vim.g.terminal_color_6 or get_color_from_hl('Conditional', 'Cyan'),
23+
dark_red = vim.g.terminal_color_9 or get_color_from_hl('Keyword', 'DarkRed'),
24+
orange = vim.g.terminal_color_11 or get_color_from_hl('Number', 'Orange'),
25+
}
26+
end
27+
28+
local function get_hl_groups()
29+
local colors = get_colors()
30+
931
return {
1032
Symlink = { gui = 'bold', fg = colors.cyan },
11-
FolderName = { gui = 'bold', fg = colors.blue },
1233
FolderIcon = { fg = '#90a4ae' },
1334

1435
ExecFile = { gui = 'bold', fg = colors.green },
1536
SpecialFile = { gui = 'bold,underline', fg = colors.yellow },
1637
ImageFile = { gui = 'bold', fg = colors.purple },
1738
MarkdownFile = { fg = colors.purple },
39+
MarkdownIcon = { fg = colors.purple },
1840
LicenseIcon = { fg = colors.yellow },
1941
YamlIcon = { fg = colors.yellow },
2042
TomlIcon = { fg = colors.yellow },
2143
GitignoreIcon = { fg = colors.yellow },
2244
JsonIcon = { fg = colors.yellow },
2345

2446
LuaIcon = { fg = '#42a5f5' },
47+
GoIcon = { fg = '#7Fd5EA' },
2548
PythonIcon = { fg = colors.green },
2649
ShellIcon = { fg = colors.green },
2750
JavascriptIcon = { fg = colors.yellow },
@@ -40,25 +63,196 @@ local function create_hl()
4063
}
4164
end
4265

43-
local HIGHLIGHTS = create_hl()
66+
M.hl_groups = {
67+
['LICENSE'] = 'LicenseIcon';
68+
['license'] = 'LicenseIcon';
69+
['vim'] = 'VimIcon';
70+
['.vimrc'] = 'VimIcon';
71+
['c'] = 'CIcon';
72+
['cpp'] = 'CIcon';
73+
['python'] = 'PythonIcon';
74+
['lua'] = 'LuaIcon';
75+
['rs'] = 'RustIcon';
76+
['sh'] = 'ShellIcon';
77+
['csh'] = 'ShellIcon';
78+
['zsh'] = 'ShellIcon';
79+
['bash'] = 'ShellIcon';
80+
['md'] = 'MarkdownIcon';
81+
['json'] = 'JsonIcon';
82+
['toml'] = 'TomlIcon';
83+
['go'] = 'GoIcon';
84+
['yaml'] = 'YamlIcon';
85+
['yml'] = 'YamlIcon';
86+
['conf'] = 'GitignoreIcon';
87+
['javascript'] = 'JavascriptIcon';
88+
['typescript'] = 'TypescriptIcon';
89+
['jsx'] = 'ReactIcon';
90+
['tsx'] = 'ReactIcon';
91+
['htm'] = 'HtmlIcon';
92+
['html'] = 'HtmlIcon';
93+
['slim'] = 'HtmlIcon';
94+
['haml'] = 'HtmlIcon';
95+
['ejs'] = 'HtmlIcon';
4496

45-
local LINKS = {
46-
Normal = 'Normal',
47-
EndOfBuffer = 'EndOfBuffer',
48-
CursorLine = 'CursorLine',
49-
VertSplit = 'VertSplit',
50-
CursorColumn = 'CursorColumn'
97+
['Gemfile$'] = 'RubyIcon';
98+
['Vagrantfile$'] = 'VagrantIcon';
99+
-- ['styl'] = '';
100+
-- ['sass'] = '';
101+
-- ['scss'] = '';
102+
--
103+
-- ['css'] = '';
104+
-- ['less'] = '';
105+
-- ['md'] = '';
106+
-- ['mdx'] = '';
107+
-- ['markdown'] = '';
108+
-- ['rmd'] = '';
109+
-- ['json'] = '';
110+
-- ['webmanifest'] = '';
111+
-- ['js'] = '';
112+
-- ['mjs'] = '';
113+
-- ['jsx'] = '';
114+
-- ['rb'] = '';
115+
-- ['gemspec'] = '';
116+
-- ['rake'] = '';
117+
-- ['php'] = '';
118+
-- ['py'] = '';
119+
-- ['pyc'] = '';
120+
-- ['pyo'] = '';
121+
-- ['pyd'] = '';
122+
-- ['coffee'] = '';
123+
-- ['mustache'] = '';
124+
-- ['hbs'] = '';
125+
-- ['conf'] = '';
126+
-- ['ini'] = '';
127+
-- ['yml'] = '';
128+
-- ['yaml'] = '';
129+
-- ['toml'] = '';
130+
-- ['bat'] = '';
131+
-- ['jpg'] = '';
132+
-- ['jpeg'] = '';
133+
-- ['bmp'] = '';
134+
-- ['png'] = '';
135+
-- ['webp'] = '';
136+
-- ['gif'] = '';
137+
-- ['ico'] = '';
138+
-- ['twig'] = '';
139+
-- ['cpp'] = '';
140+
-- ['c++'] = '';
141+
-- ['cxx'] = '';
142+
-- ['cc'] = '';
143+
-- ['cp'] = '';
144+
-- ['c'] = '';
145+
-- ['cs'] = '';
146+
-- ['h'] = '';
147+
-- ['hh'] = '';
148+
-- ['hpp'] = '';
149+
-- ['hxx'] = '';
150+
-- ['hs'] = '';
151+
-- ['lhs'] = '';
152+
-- ['lua'] = '';
153+
-- ['java'] = '';
154+
-- ['sh'] = '';
155+
-- ['fish'] = '';
156+
-- ['bash'] = '';
157+
-- ['zsh'] = '';
158+
-- ['ksh'] = '';
159+
-- ['csh'] = '';
160+
-- ['awk'] = '';
161+
-- ['ps1'] = '';
162+
-- ['ml'] = 'λ';
163+
-- ['mli'] = 'λ';
164+
-- ['diff'] = '';
165+
-- ['db'] = '';
166+
-- ['sql'] = '';
167+
-- ['dump'] = '';
168+
-- ['clj'] = '';
169+
-- ['cljc'] = '';
170+
-- ['cljs'] = '';
171+
-- ['edn'] = '';
172+
-- ['scala'] = '';
173+
-- ['go'] = '';
174+
-- ['dart'] = '';
175+
-- ['xul'] = '';
176+
-- ['sln'] = '';
177+
-- ['suo'] = '';
178+
-- ['pl'] = '';
179+
-- ['pm'] = '';
180+
-- ['t'] = '';
181+
-- ['rss'] = '';
182+
-- ['f#'] = '';
183+
-- ['fsscript'] = '';
184+
-- ['fsx'] = '';
185+
-- ['fs'] = '';
186+
-- ['fsi'] = '';
187+
-- ['rs'] = '';
188+
-- ['rlib'] = '';
189+
-- ['d'] = '';
190+
-- ['erl'] = '';
191+
-- ['hrl'] = '';
192+
-- ['ex'] = '';
193+
-- ['exs'] = '';
194+
-- ['eex'] = '';
195+
-- ['leex'] = '';
196+
-- ['vim'] = '';
197+
-- ['ai'] = '';
198+
-- ['psd'] = '';
199+
-- ['psb'] = '';
200+
-- ['ts'] = '';
201+
-- ['jl'] = '';
202+
-- ['pp'] = '';
203+
-- ['vue'] = '﵂';
204+
-- ['elm'] = '';
205+
-- ['swift'] = '';
206+
-- ['xcplayground'] = '';
207+
-- ['tex'] = 'ﭨ';
208+
-- ['r'] = 'ﳒ';
209+
-- ['rproj'] = '鉶';
210+
-- ['mix.lock'] = '';
211+
-- ['dropbox'] = '';
212+
-- ['.ds_store'] = '';
213+
-- ['.gitconfig'] = '';
214+
-- ['.gitignore'] = '';
215+
-- ['.gitlab-ci.yml'] = '';
216+
-- ['.bashrc'] = '';
217+
-- ['.zshrc'] = '';
218+
-- ['.vimrc'] = '';
219+
-- ['.gvimrc'] = '';
220+
-- ['_vimrc'] = '';
221+
-- ['_gvimrc'] = '';
222+
-- ['.bashprofile'] = '';
223+
-- ['favicon.ico'] = '';
224+
-- ['license'] = '';
225+
-- ['LICENSE'] = '';
226+
-- ['node_modules'] = '';
227+
-- ['procfile'] = '';
228+
-- ['dockerfile'] = '';
229+
-- ['docker-compose.yml'] = '';
230+
-- ['rakefile'] = '';
231+
-- ['config.ru'] = '';
232+
-- ['makefile'] = '';
233+
-- ['cmakelists.txt'] = '';
51234
}
52235

53-
function M.init_colors()
54-
colors = get_colors()
55-
HIGHLIGHTS = create_hl()
56-
for k, d in pairs(HIGHLIGHTS) do
236+
local function get_links()
237+
return {
238+
FolderName = 'Directory',
239+
Normal = 'Normal',
240+
EndOfBuffer = 'EndOfBuffer',
241+
CursorLine = 'CursorLine',
242+
VertSplit = 'VertSplit',
243+
CursorColumn = 'CursorColumn'
244+
}
245+
end
246+
247+
function M.setup()
248+
local higlight_groups = get_hl_groups()
249+
for k, d in pairs(higlight_groups) do
57250
local gui = d.gui or 'NONE'
58251
api.nvim_command('hi def LuaTree'..k..' gui='..gui..' guifg='..d.fg)
59252
end
60253

61-
for k, d in pairs(LINKS) do
254+
local links = get_links()
255+
for k, d in pairs(links) do
62256
api.nvim_command('hi def link LuaTree'..k..' '..d)
63257
end
64258
end

0 commit comments

Comments
 (0)