Skip to content

Commit fa5018b

Browse files
authored
feat: add support for external sources, from discussion #403 (#406)
1 parent 86ec47e commit fa5018b

File tree

14 files changed

+202
-283
lines changed

14 files changed

+202
-283
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
uses: JohnnyMorganz/[email protected]
2020
with:
2121
token: ${{ secrets.GITHUB_TOKEN }}
22+
version: v0.13.1
2223
args: --color always --check lua/
2324

2425
plenary-tests:

lua/neo-tree/command/parser.lua

Lines changed: 66 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,76 @@ 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+
local source_names = utils.table_copy(all_source_names)
12+
table.insert(source_names, "migrations")
13+
14+
-- For lists, the first value is the default value.
15+
local arguments = {
16+
action = {
17+
type = M.LIST,
18+
values = {
19+
"close",
20+
"focus",
21+
"show",
22+
},
1823
},
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",
24+
position = {
25+
type = M.LIST,
26+
values = {
27+
"left",
28+
"right",
29+
--"top", --technically valid, but why show it if no one will use it?
30+
--"bottom", --technically valid, but why show it if no one will use it?
31+
"float",
32+
"current",
33+
},
2934
},
30-
},
31-
source = {
32-
type = M.LIST,
33-
values = {
34-
"filesystem",
35-
"buffers",
36-
"git_status",
37-
"migrations",
35+
source = {
36+
type = M.LIST,
37+
values = source_names,
3838
},
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-
}
39+
dir = { type = M.PATH, stat_type = "directory" },
40+
reveal_file = { type = M.PATH, stat_type = "file" },
41+
git_base = { type = M.REF },
42+
toggle = { type = M.FLAG },
43+
reveal = { type = M.FLAG },
44+
reveal_force_cwd = { type = M.FLAG },
45+
}
4746

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

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
72+
M.arguments = arguments
73+
M.list_args = list_args
74+
M.path_args = path_args
75+
M.ref_args = ref_args
76+
M.flag_args = flag_args
77+
M.arg_type_lookup = arg_type_lookup
78+
M.reverse_lookup = reverse_lookup
79+
end
8080

8181
M.resolve_path = function(path, validate_type)
8282
local expanded = vim.fn.expand(path)
@@ -101,7 +101,7 @@ local parse_arg = function(result, arg)
101101
if eq then
102102
local key = arg:sub(1, eq - 1)
103103
local value = arg:sub(eq + 1)
104-
local def = arguments[key]
104+
local def = M.arguments[key]
105105
if not def.type then
106106
error("Invalid argument: " .. arg)
107107
end
@@ -126,7 +126,7 @@ local parse_arg = function(result, arg)
126126
end
127127
else
128128
local value = arg
129-
local key = reverse_lookup[value]
129+
local key = M.reverse_lookup[value]
130130
if key == nil then
131131
-- maybe it's a git ref
132132
if M.verify_git_ref(value) then
@@ -155,6 +155,7 @@ local parse_arg = function(result, arg)
155155
end
156156

157157
M.parse = function(args, strict_checking)
158+
require("neo-tree").ensure_config()
158159
local result = {}
159160

160161
if type(args) == "string" then

lua/neo-tree/defaults.lua

Lines changed: 12 additions & 3 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.
@@ -106,7 +115,7 @@ local config = {
106115
highlight = "NeoTreeFileIcon"
107116
},
108117
modified = {
109-
symbol = "[+]",
118+
symbol = "[+] ",
110119
highlight = "NeoTreeModified",
111120
},
112121
name = {
@@ -139,7 +148,7 @@ local config = {
139148
{
140149
"container",
141150
width = "100%",
142-
right_padding = 1,
151+
right_padding = 0,
143152
--max_width = 60,
144153
content = {
145154
{ "name", zindex = 10 },
@@ -159,7 +168,7 @@ local config = {
159168
{
160169
"container",
161170
width = "100%",
162-
right_padding = 1,
171+
right_padding = 0,
163172
--max_width = 60,
164173
content = {
165174
{

lua/neo-tree/git/status.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,14 @@ M.status_async = function(path, base, opts)
304304
end,
305305
})
306306

307-
local showUntracked =
308-
vim.fn.systemlist({ "git", "-C", git_root, "config", "--get", "status.showUntrackedFiles" })
307+
local showUntracked = vim.fn.systemlist({
308+
"git",
309+
"-C",
310+
git_root,
311+
"config",
312+
"--get",
313+
"status.showUntrackedFiles",
314+
})
309315
log.debug("git status.showUntrackedFiles =", showUntracked[1])
310316
if showUntracked[1] == "no" then
311317
unstaged_job:after(parse_lines)

lua/neo-tree/log.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ end
5757
log.new = function(config, standalone)
5858
config = vim.tbl_deep_extend("force", default_config, config)
5959

60-
local outfile =
61-
string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "data" }), config.plugin)
60+
local outfile = string.format(
61+
"%s/%s.log",
62+
vim.api.nvim_call_function("stdpath", { "data" }),
63+
config.plugin
64+
)
6265

6366
local obj
6467
if standalone then

lua/neo-tree/setup/deprecations.lua

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ M.migrate = function(config)
4141
end
4242
utils.set_value(config, new, exising)
4343
config[old] = nil
44-
migrations[#migrations + 1] =
45-
string.format("The `%s` option has been deprecated, please use `%s` instead.", old, new)
44+
migrations[#migrations + 1] = string.format(
45+
"The `%s` option has been deprecated, please use `%s` instead.",
46+
old,
47+
new
48+
)
4649
end
4750
end
4851

@@ -58,8 +61,12 @@ M.migrate = function(config)
5861
local value = utils.get_value(config, key)
5962
if value == old_value then
6063
utils.set_value(config, key, new_value)
61-
migrations[#migrations + 1] =
62-
string.format("The `%s=%s` option has been renamed to `%s`.", key, old_value, new_value)
64+
migrations[#migrations + 1] = string.format(
65+
"The `%s=%s` option has been renamed to `%s`.",
66+
key,
67+
old_value,
68+
new_value
69+
)
6370
end
6471
end
6572

lua/neo-tree/setup/init.lua

Lines changed: 40 additions & 16 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)
@@ -410,16 +400,49 @@ M.merge_config = function(user_config, is_auto_config)
410400
normalize_mappings(default_config)
411401
normalize_mappings(user_config)
412402
merge_renderers(default_config, nil, user_config)
413-
for _, source_name in ipairs(sources) do
403+
404+
-- used to either limit the sources that or loaded, or add extra external sources
405+
local all_sources = {}
406+
local all_source_names = {}
407+
for _, source in ipairs(user_config.sources or default_config.sources) do
408+
local parts = utils.split(source, ".")
409+
local name = parts[#parts]
410+
if #parts > 1 then
411+
-- fully qualified module name
412+
all_sources[name] = source
413+
else
414+
-- might be a module name in the internal namespace
415+
local is_internal_ns, _ = pcall(require, "neo-tree.sources." .. source)
416+
if is_internal_ns then
417+
all_sources[name] = "neo-tree.sources." .. name
418+
else
419+
-- could also be a root level module name
420+
local exists, module = pcall(require, source)
421+
if exists then
422+
all_sources[name] = module.name or source
423+
else
424+
log.error("Source module not found", source)
425+
name = nil
426+
end
427+
end
428+
end
429+
if name then
430+
table.insert(all_source_names, name)
431+
end
432+
end
433+
log.debug("Sources to load: ", vim.inspect(all_sources))
434+
require("neo-tree.command.parser").setup(all_source_names)
435+
436+
for source_name, mod_root in pairs(all_sources) do
437+
local module = require(mod_root)
414438
default_config[source_name] = default_config[source_name]
415439
or {
416440
renderers = {},
417441
components = {},
418442
}
419443
local source_default_config = default_config[source_name]
420-
local mod_root = "neo-tree.sources." .. source_name
421-
source_default_config.components = require(mod_root .. ".components")
422-
source_default_config.commands = require(mod_root .. ".commands")
444+
source_default_config.components = module.components or require(mod_root .. ".components")
445+
source_default_config.commands = module.commands or require(mod_root .. ".commands")
423446
source_default_config.name = source_name
424447

425448
if user_config.use_default_mappings == false then
@@ -465,11 +488,12 @@ M.merge_config = function(user_config, is_auto_config)
465488

466489
file_nesting.setup(M.config.nesting_rules)
467490

468-
for _, source_name in ipairs(sources) do
491+
for source_name, mod_root in pairs(all_sources) do
469492
for name, rndr in pairs(M.config[source_name].renderers) do
470493
M.config[source_name].renderers[name] = merge_global_components_config(rndr, M.config)
471494
end
472-
manager.setup(source_name, M.config[source_name], M.config)
495+
local module = require(mod_root)
496+
manager.setup(source_name, M.config[source_name], M.config, module)
473497
manager.redraw(source_name)
474498
end
475499

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,10 @@ end
270270

271271
M.modified = function(config, node, state)
272272
local modified_buffers = state.modified_buffers or {}
273+
273274
if modified_buffers[node.path] then
274275
return {
275-
text = (config.symbol or "[+] "),
276+
text = (make_two_char(config.symbol) or "[+] "),
276277
highlight = config.highlight or highlights.MODIFIED,
277278
}
278279
else

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

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

0 commit comments

Comments
 (0)