Skip to content

Commit d833955

Browse files
committed
feat: add support for external sources, from discussion #403
1 parent 365df55 commit d833955

File tree

7 files changed

+121
-236
lines changed

7 files changed

+121
-236
lines changed

lua/neo-tree/command/parser.lua

Lines changed: 66 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,77 @@ local M = {
77
REF = "<REF>",
88
}
99

10-
-- For lists, the first value is the default value.
11-
local arguments = {
12-
action = {
13-
type = M.LIST,
14-
values = {
15-
"close",
16-
"focus",
17-
"show",
10+
M.setup = function (all_source_names)
11+
print("all_source_names", vim.inspect(all_source_names))
12+
local source_names = utils.table_copy(all_source_names)
13+
table.insert(source_names, "migrations")
14+
15+
-- For lists, the first value is the default value.
16+
local arguments = {
17+
action = {
18+
type = M.LIST,
19+
values = {
20+
"close",
21+
"focus",
22+
"show",
23+
},
1824
},
19-
},
20-
position = {
21-
type = M.LIST,
22-
values = {
23-
"left",
24-
"right",
25-
--"top", --technically valid, but why show it if no one will use it?
26-
--"bottom", --technically valid, but why show it if no one will use it?
27-
"float",
28-
"current",
25+
position = {
26+
type = M.LIST,
27+
values = {
28+
"left",
29+
"right",
30+
--"top", --technically valid, but why show it if no one will use it?
31+
--"bottom", --technically valid, but why show it if no one will use it?
32+
"float",
33+
"current",
34+
},
2935
},
30-
},
31-
source = {
32-
type = M.LIST,
33-
values = {
34-
"filesystem",
35-
"buffers",
36-
"git_status",
37-
"migrations",
36+
source = {
37+
type = M.LIST,
38+
values = source_names,
3839
},
39-
},
40-
dir = { type = M.PATH, stat_type = "directory" },
41-
reveal_file = { type = M.PATH, stat_type = "file" },
42-
git_base = { type = M.REF },
43-
toggle = { type = M.FLAG },
44-
reveal = { type = M.FLAG },
45-
reveal_force_cwd = { type = M.FLAG },
46-
}
40+
dir = { type = M.PATH, stat_type = "directory" },
41+
reveal_file = { type = M.PATH, stat_type = "file" },
42+
git_base = { type = M.REF },
43+
toggle = { type = M.FLAG },
44+
reveal = { type = M.FLAG },
45+
reveal_force_cwd = { type = M.FLAG },
46+
}
4747

48-
local arg_type_lookup = {}
49-
local list_args = {}
50-
local path_args = {}
51-
local ref_args = {}
52-
local flag_args = {}
53-
local reverse_lookup = {}
54-
for name, def in pairs(arguments) do
55-
arg_type_lookup[name] = def.type
56-
if def.type == M.LIST then
57-
table.insert(list_args, name)
58-
for _, vv in ipairs(def.values) do
59-
reverse_lookup[tostring(vv)] = name
48+
local arg_type_lookup = {}
49+
local list_args = {}
50+
local path_args = {}
51+
local ref_args = {}
52+
local flag_args = {}
53+
local reverse_lookup = {}
54+
for name, def in pairs(arguments) do
55+
arg_type_lookup[name] = def.type
56+
if def.type == M.LIST then
57+
table.insert(list_args, name)
58+
for _, vv in ipairs(def.values) do
59+
reverse_lookup[tostring(vv)] = name
60+
end
61+
elseif def.type == M.PATH then
62+
table.insert(path_args, name)
63+
elseif def.type == M.FLAG then
64+
table.insert(flag_args, name)
65+
reverse_lookup[name] = M.FLAG
66+
elseif def.type == M.REF then
67+
table.insert(ref_args, name)
68+
else
69+
error("Unknown type: " .. def.type)
6070
end
61-
elseif def.type == M.PATH then
62-
table.insert(path_args, name)
63-
elseif def.type == M.FLAG then
64-
table.insert(flag_args, name)
65-
reverse_lookup[name] = M.FLAG
66-
elseif def.type == M.REF then
67-
table.insert(ref_args, name)
68-
else
69-
error("Unknown type: " .. def.type)
7071
end
71-
end
7272

73-
M.arguments = arguments
74-
M.list_args = list_args
75-
M.path_args = path_args
76-
M.ref_args = ref_args
77-
M.flag_args = flag_args
78-
M.arg_type_lookup = arg_type_lookup
79-
M.reverse_lookup = reverse_lookup
73+
M.arguments = arguments
74+
M.list_args = list_args
75+
M.path_args = path_args
76+
M.ref_args = ref_args
77+
M.flag_args = flag_args
78+
M.arg_type_lookup = arg_type_lookup
79+
M.reverse_lookup = reverse_lookup
80+
end
8081

8182
M.resolve_path = function(path, validate_type)
8283
local expanded = vim.fn.expand(path)
@@ -101,7 +102,7 @@ local parse_arg = function(result, arg)
101102
if eq then
102103
local key = arg:sub(1, eq - 1)
103104
local value = arg:sub(eq + 1)
104-
local def = arguments[key]
105+
local def = M.arguments[key]
105106
if not def.type then
106107
error("Invalid argument: " .. arg)
107108
end
@@ -126,7 +127,7 @@ local parse_arg = function(result, arg)
126127
end
127128
else
128129
local value = arg
129-
local key = reverse_lookup[value]
130+
local key = M.reverse_lookup[value]
130131
if key == nil then
131132
-- maybe it's a git ref
132133
if M.verify_git_ref(value) then

lua/neo-tree/defaults.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
local config = {
2+
-- If a user has a sources list it will replace this one.
3+
-- Only sources listed here will be loaded.
4+
-- You can also add an external source by adding it's name to this list.
5+
-- The name used here must be the same name you would use in a require() call.
6+
sources = {
7+
"filesystem",
8+
"buffers",
9+
"git_status",
10+
},
211
close_if_last_window = false, -- Close Neo-tree if it is the last window left in the tab
312
-- popup_border_style is for input and confirmation dialogs.
413
-- Configurtaion of floating window is done in the individual source sections.

lua/neo-tree/setup/init.lua

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@ local highlights = require("neo-tree.ui.highlights")
88
local manager = require("neo-tree.sources.manager")
99
local netrw = require("neo-tree.setup.netrw")
1010

11-
-- If you add a new source, you need to add it to the sources table.
12-
-- Each source should have a defaults module that contains the default values
13-
-- for the source config, and a setup function that takes that config.
14-
local sources = {
15-
"filesystem",
16-
"buffers",
17-
"git_status",
18-
"example"
19-
}
20-
2111
local M = {}
2212

2313
local normalize_mappings = function(config)
@@ -408,13 +398,45 @@ M.merge_config = function(user_config, is_auto_config)
408398
normalize_mappings(default_config)
409399
normalize_mappings(user_config)
410400
merge_renderers(default_config, nil, user_config)
411-
for _, source_name in ipairs(sources) do
401+
402+
-- used to either limit the sources that or loaded, or add extra external sources
403+
local all_sources = {}
404+
local all_source_names = {}
405+
for _, source in ipairs(user_config.sources or default_config.sources) do
406+
local parts = utils.split(source, ".")
407+
local name = parts[#parts]
408+
if #parts > 1 then
409+
-- fully qualified module name
410+
all_sources[name] = source
411+
else
412+
-- might be a module name in the internal namespace
413+
local is_internal_ns, _ = pcall(require, "neo-tree.sources." .. source)
414+
if is_internal_ns then
415+
all_sources[name] = "neo-tree.sources." .. name
416+
else
417+
-- could also be a root level module name
418+
local exists, module = pcall(require, source)
419+
if exists then
420+
all_sources[name] = module.name or source
421+
else
422+
log.error("Source module not found", source)
423+
name = nil
424+
end
425+
end
426+
end
427+
if name then
428+
table.insert(all_source_names, name)
429+
end
430+
end
431+
log.debug("Sources to load: ", vim.inspect(all_sources))
432+
require("neo-tree.command.parser").setup(all_source_names)
433+
434+
for source_name, mod_root in pairs(all_sources) do
412435
default_config[source_name] = default_config[source_name] or {
413436
renderers = {},
414437
components = {},
415438
}
416439
local source_default_config = default_config[source_name]
417-
local mod_root = "neo-tree.sources." .. source_name
418440
source_default_config.components = require(mod_root .. ".components")
419441
source_default_config.commands = require(mod_root .. ".commands")
420442
source_default_config.name = source_name
@@ -462,11 +484,12 @@ M.merge_config = function(user_config, is_auto_config)
462484

463485
file_nesting.setup(M.config.nesting_rules)
464486

465-
for _, source_name in ipairs(sources) do
487+
for source_name, mod_root in pairs(all_sources) do
466488
for name, rndr in pairs(M.config[source_name].renderers) do
467489
M.config[source_name].renderers[name] = merge_global_components_config(rndr, M.config)
468490
end
469-
manager.setup(source_name, M.config[source_name], M.config)
491+
local module = require(mod_root)
492+
manager.setup(source_name, M.config[source_name], M.config, module)
470493
manager.redraw(source_name)
471494
end
472495

lua/neo-tree/sources/example/commands.lua

Lines changed: 0 additions & 21 deletions
This file was deleted.

lua/neo-tree/sources/example/components.lua

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)