Skip to content

Commit 5f05301

Browse files
committed
Merge branch 'master' into #1166-validate-config
2 parents 039fdfa + 15d5e06 commit 5f05301

File tree

13 files changed

+417
-253
lines changed

13 files changed

+417
-253
lines changed

.hooks/pre-commit.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
luacheck . || exit 1
4+
stylua lua/**/*.lua --check || exit 1

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ require'nvim-tree'.setup { -- BEGIN_DEFAULT_OPTS
194194
change_dir = {
195195
enable = true,
196196
global = false,
197+
restrict_above_cwd = false,
197198
},
198199
open_file = {
199200
quit_on_open = false,

doc/nvim-tree-lua.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ function.
163163
change_dir = {
164164
enable = true,
165165
global = false,
166+
restrict_above_cwd = false,
166167
},
167168
open_file = {
168169
quit_on_open = false,
@@ -486,6 +487,11 @@ Here is a list of the options available in the setup call:
486487
type: `boolean`
487488
default: `false`
488489

490+
- |actions.change_dir.restrict_above_cwd|: restrict changing to a directory
491+
above the global current working directory.
492+
type: `boolean`
493+
default: `false`
494+
489495
- |actions.open_file.quit_on_open|: closes the explorer when opening a file.
490496
It will also disable preventing a buffer overriding the tree.
491497
type: `boolean`

lua/nvim-tree.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
388388
change_dir = {
389389
enable = true,
390390
global = false,
391+
restrict_above_cwd = false,
391392
},
392393
open_file = {
393394
quit_on_open = false,

lua/nvim-tree/actions/change-dir.lua

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ local diagnostics = require "nvim-tree.diagnostics"
77

88
local M = {
99
current_tab = a.nvim_get_current_tabpage(),
10-
options = {
11-
global = false,
12-
change_cwd = true,
13-
},
1410
}
1511

1612
function M.fn(name, with_open)
@@ -20,6 +16,7 @@ function M.fn(name, with_open)
2016

2117
local foldername = name == ".." and vim.fn.fnamemodify(utils.path_remove_trailing(core.get_cwd()), ":h") or name
2218
local no_cwd_change = vim.fn.expand(foldername) == core.get_cwd()
19+
or M.options.restrict_above_cwd and foldername < vim.fn.getcwd(-1, -1)
2320
local new_tab = a.nvim_get_current_tabpage()
2421
local is_window = (vim.v.event.scope == "window" or vim.v.event.changed_window) and new_tab == M.current_tab
2522
if no_cwd_change or is_window then
@@ -32,7 +29,7 @@ end
3229
function M.force_dirchange(foldername, with_open)
3330
local ps = log.profile_start("change dir %s", foldername)
3431

35-
if M.options.change_cwd and vim.tbl_isempty(vim.v.event) then
32+
if M.options.enable and vim.tbl_isempty(vim.v.event) then
3633
if M.options.global then
3734
vim.cmd("cd " .. vim.fn.fnameescape(foldername))
3835
else
@@ -51,8 +48,7 @@ function M.force_dirchange(foldername, with_open)
5148
end
5249

5350
function M.setup(options)
54-
M.options.change_cwd = options.actions.change_dir.enable
55-
M.options.global = options.actions.change_dir.global
51+
M.options = options.actions.change_dir
5652
end
5753

5854
return M

lua/nvim-tree/colors.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local api = vim.api
2-
local icons = require "nvim-tree.renderer.icons"
2+
local icons = require "nvim-tree.renderer.icon-config"
33

44
local M = {}
55

lua/nvim-tree/renderer/builder.lua

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
local utils = require "nvim-tree.utils"
2+
3+
local git = require "nvim-tree.renderer.components.git"
4+
local pad = require "nvim-tree.renderer.components.padding"
5+
local icons = require "nvim-tree.renderer.components.icons"
6+
7+
-- TODO(refactor): the builder abstraction is not perfect yet. We shouldn't leak data in components.
8+
-- Components should return only and icon / highlight group pair at most.
9+
-- The code was mostly moved from renderer/init.lua and rearranged, so it's still under construction.
10+
11+
local Builder = {}
12+
Builder.__index = Builder
13+
14+
function Builder.new(root_cwd)
15+
return setmetatable({
16+
index = 0,
17+
depth = nil,
18+
highlights = {},
19+
lines = {},
20+
markers = {},
21+
root_cwd = root_cwd,
22+
}, Builder)
23+
end
24+
25+
function Builder:configure_initial_depth(show_arrows)
26+
self.depth = show_arrows and 2 or 0
27+
return self
28+
end
29+
30+
function Builder:configure_root_modifier(root_folder_modifier)
31+
self.root_folder_modifier = root_folder_modifier or ":~"
32+
return self
33+
end
34+
35+
function Builder:configure_trailing_slash(with_trailing)
36+
self.trailing_slash = with_trailing and "/" or ""
37+
return self
38+
end
39+
40+
function Builder:configure_special_map(special_map)
41+
self.special_map = special_map
42+
return self
43+
end
44+
45+
function Builder:configure_picture_map(picture_map)
46+
self.picture_map = picture_map
47+
return self
48+
end
49+
50+
function Builder:configure_opened_file_highlighting(level)
51+
if level == 1 then
52+
self.open_file_highlight = "icon"
53+
elseif level == 2 then
54+
self.open_file_highlight = "name"
55+
elseif level == 3 then
56+
self.open_file_highlight = "all"
57+
end
58+
59+
return self
60+
end
61+
62+
function Builder:_insert_highlight(group, start, end_)
63+
table.insert(self.highlights, { group, self.index, start, end_ or -1 })
64+
end
65+
66+
function Builder:_insert_line(line)
67+
table.insert(self.lines, line)
68+
end
69+
70+
local function get_folder_name(node)
71+
local name = node.name
72+
local next = node.group_next
73+
while next do
74+
name = name .. "/" .. next.name
75+
next = next.group_next
76+
end
77+
return name
78+
end
79+
80+
function Builder:_build_folder(node, padding, git_hl)
81+
local offset = string.len(padding)
82+
83+
local name = get_folder_name(node)
84+
local has_children = #node.nodes ~= 0 or node.has_children
85+
local icon = icons.get_folder_icon(node.open, node.link_to ~= nil, has_children)
86+
local git_icon = git.get_icons(node, self.index, offset, #icon, self.highlights) or ""
87+
88+
local folder_hl = "NvimTreeFolderName"
89+
if self.special_map[node.absolute_path] then
90+
folder_hl = "NvimTreeSpecialFolderName"
91+
elseif node.open then
92+
folder_hl = "NvimTreeOpenedFolderName"
93+
elseif not has_children then
94+
folder_hl = "NvimTreeEmptyFolderName"
95+
end
96+
97+
icons.set_folder_hl(
98+
self.index,
99+
offset,
100+
#icon + #git_icon,
101+
#name,
102+
"NvimTreeFolderIcon",
103+
folder_hl,
104+
self.highlights,
105+
self.open_file_highlight
106+
)
107+
if git_hl then
108+
icons.set_folder_hl(
109+
self.index,
110+
offset,
111+
#icon + #git_icon,
112+
#name,
113+
git_hl,
114+
git_hl,
115+
self.highlights,
116+
self.open_file_highlight
117+
)
118+
end
119+
self:_insert_line(padding .. icon .. git_icon .. name .. self.trailing_slash)
120+
end
121+
122+
-- TODO: missing git icon for symlinks
123+
function Builder:_build_symlink(node, padding, git_highlight)
124+
local icon = icons.i.symlink
125+
local arrow = icons.i.symlink_arrow
126+
127+
local link_highlight = git_highlight or "NvimTreeSymlink"
128+
129+
local line = padding .. icon .. node.name .. arrow .. node.link_to
130+
self:_insert_highlight(link_highlight, string.len(padding), string.len(line))
131+
self:_insert_line(line)
132+
end
133+
134+
function Builder:_build_file_icons(node, offset)
135+
if self.special_map[node.absolute_path] or self.special_map[node.name] then
136+
local git_icons = git.get_icons(node, self.index, offset, 0, self.highlights)
137+
self:_insert_highlight("NvimTreeSpecialFile", offset + #git_icons)
138+
return icons.i.special, git_icons
139+
else
140+
local icon = icons.get_file_icon(node.name, node.extension, self.index, offset, self.highlights)
141+
return icon, git.get_icons(node, self.index, offset, #icon, self.highlights)
142+
end
143+
end
144+
145+
function Builder:_highlight_opened_files(node, offset, icon, git_icons)
146+
local from = offset
147+
local to = offset
148+
149+
if self.open_file_highlight == "icon" then
150+
to = from + #icon
151+
elseif self.open_file_highlight == "name" then
152+
from = offset + #icon + #git_icons
153+
to = from + #node.name
154+
elseif self.open_file_highlight == "all" then
155+
to = -1
156+
end
157+
158+
self:_insert_highlight("NvimTreeOpenedFile", from, to)
159+
end
160+
161+
function Builder:_build_file(node, padding, git_highlight)
162+
local offset = string.len(padding)
163+
164+
local icon, git_icons = self:_build_file_icons(node, offset)
165+
166+
self:_insert_line(padding .. icon .. git_icons .. node.name)
167+
local col_start = offset + #icon + #git_icons
168+
169+
if node.executable then
170+
self:_insert_highlight("NvimTreeExecFile", col_start)
171+
elseif self.picture_map[node.extension] then
172+
self:_insert_highlight("NvimTreeImageFile", col_start)
173+
end
174+
175+
local should_highlight_opened_files = self.open_file_highlight and vim.fn.bufloaded(node.absolute_path) > 0
176+
if should_highlight_opened_files then
177+
self:_highlight_opened_files(node, offset, icon, git_icons)
178+
end
179+
180+
if git_highlight then
181+
self:_insert_highlight(git_highlight, col_start)
182+
end
183+
end
184+
185+
function Builder:build(tree)
186+
for idx, node in ipairs(tree.nodes) do
187+
local padding = pad.get_padding(self.depth, idx, tree, node, self.markers)
188+
189+
if self.depth > 0 then
190+
self:_insert_highlight("NvimTreeIndentMarker", 0, string.len(padding))
191+
end
192+
193+
local git_highlight = git.get_highlight(node)
194+
195+
local is_folder = node.nodes ~= nil
196+
local is_symlink = node.link_to ~= nil
197+
198+
if is_folder then
199+
self:_build_folder(node, padding, git_highlight)
200+
elseif is_symlink then
201+
self:_build_symlink(node, padding, git_highlight)
202+
else
203+
self:_build_file(node, padding, git_highlight)
204+
end
205+
self.index = self.index + 1
206+
207+
if node.open then
208+
self.depth = self.depth + 2
209+
self:build(node)
210+
self.depth = self.depth - 2
211+
end
212+
end
213+
214+
return self
215+
end
216+
217+
local function format_root_name(root_cwd, modifier)
218+
local base_root = utils.path_remove_trailing(vim.fn.fnamemodify(root_cwd, modifier))
219+
return utils.path_join { base_root, ".." }
220+
end
221+
222+
function Builder:build_header(show_header)
223+
if show_header then
224+
local root_name = format_root_name(self.root_cwd, self.root_folder_modifier)
225+
self:_insert_line(root_name)
226+
self:_insert_highlight("NvimTreeRootFolder", 0, string.len(root_name))
227+
self.index = 1
228+
end
229+
230+
return self
231+
end
232+
233+
function Builder:unwrap()
234+
return self.lines, self.highlights
235+
end
236+
237+
return Builder

lua/nvim-tree/renderer/git.lua renamed to lua/nvim-tree/renderer/components/git.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local _icons = require "nvim-tree.renderer.icons"
1+
local _icons = require "nvim-tree.renderer.icon-config"
22
local utils = require "nvim-tree.utils"
33

44
local M = {}

0 commit comments

Comments
 (0)