Skip to content

Commit 6087d20

Browse files
authored
feat(command): state config overrides via command.execute() (#1926)
1 parent f766696 commit 6087d20

File tree

5 files changed

+70
-40
lines changed

5 files changed

+70
-40
lines changed

lua/neo-tree/command/init.lua

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,28 @@ M._last = {
1717
position = nil,
1818
}
1919

20-
---Executes a Neo-tree action from outside of a Neo-tree window,
21-
---such as show, hide, navigate, etc.
22-
---@param args table The action to execute. The table can have the following keys:
23-
--- action = string The action to execute, can be one of:
24-
--- "close",
25-
--- "focus", <-- default value
26-
--- "show",
27-
--- source = string The source to use for this action. This will default
28-
--- to the default_source specified in the user's config.
29-
--- Can be one of:
30-
--- "filesystem",
31-
--- "buffers",
32-
--- "git_status",
33-
-- "migrations"
34-
--- position = string The position this action will affect. This will default
35-
--- to the the last used position or the position specified
36-
--- in the user's config for the given source. Can be one of:
37-
--- "left",
38-
--- "right",
39-
--- "float",
40-
--- "current"
41-
--- toggle = boolean Whether to toggle the visibility of the Neo-tree window.
42-
--- reveal = boolean Whether to reveal the current file in the Neo-tree window.
43-
--- reveal_file = string The specific file to reveal.
44-
--- dir = string The root directory to set.
45-
--- git_base = string The git base used for diff
46-
M.execute = function(args)
20+
---@class neotree.command.execute.Args
21+
---The action to execute
22+
---@field action string|"focus"|"show"|"close"?
23+
---The source to use for this action. This will default to the default_source specified in the user's config.
24+
---@field source string|"filesystem"|"buffers"|"git_status"|"migrations"|"last"?
25+
---The position this action will affect. This will default to the the last used position or the position specified in
26+
---the user's config for the given source.
27+
---@field position string|"left"|"right"|"float"|"current"?
28+
---@field toggle boolean? Whether to toggle the visibility of the Neo-tree window.
29+
---@field selector boolean? Whether to toggle the visibility of the Neo-tree window.
30+
---@field reveal boolean? Whether to reveal the current file in the Neo-tree window.
31+
---@field reveal_file string? The specific file to reveal.
32+
---@field reveal_force_cwd boolean? Whether to always change directories when a reveal file is outside the cwd.
33+
---@field dir string? The root directory to set.
34+
---@field git_base string? The git base used for diff
35+
36+
---@class (partial) neotree.command.execute.StateConfigOverride : neotree.Config.Filesystem, neotree.Config.Buffers, neotree.Config.GitStatus, neotree.Config.DocumentSymbols
37+
38+
---Executes a Neo-tree command, like focus/show/close.
39+
---@param args neotree.command.execute.Args
40+
---@param state_config_override neotree.command.execute.StateConfigOverride?
41+
M.execute = function(args, state_config_override)
4742
local nt = require("neo-tree")
4843
nt.ensure_config()
4944

@@ -100,8 +95,14 @@ M.execute = function(args)
10095
if requested_position == "current" then
10196
local winid = vim.api.nvim_get_current_win()
10297
state = manager.get_state(args.source, nil, winid)
98+
if state_config_override then
99+
state = manager._change_state(args.source, nil, winid, state_config_override)
100+
end
103101
else
104102
state = manager.get_state(args.source, nil, nil)
103+
if state_config_override then
104+
state = manager._change_state(args.source, nil, nil, state_config_override)
105+
end
105106
end
106107

107108
-- Next handle toggle, the rest is irrelevant if there is a window to toggle
@@ -113,12 +114,8 @@ M.execute = function(args)
113114
end
114115

115116
-- Handle position override
116-
local default_position = nt.config[args.source].window.position
117-
local current_position = state.current_position or default_position
118-
local position_changed = false
119117
if args.position then
120118
state.current_position = args.position
121-
position_changed = args.position ~= current_position
122119
end
123120

124121
-- Handle setting directory if requested

lua/neo-tree/command/parser.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ end
184184

185185
---@param args string|string[]
186186
---@param strict_checking boolean
187-
---@return neotree.command.Parser.Parsed parsed_args
187+
---@return neotree.command.execute.Args parsed_args
188188
M.parse = function(args, strict_checking)
189189
require("neo-tree").ensure_config()
190190
local result = {}

lua/neo-tree/sources/manager.lua

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,29 @@ M.get_state = function(source_name, tabid, winid)
214214
return tab_state
215215
end
216216

217+
---Modifies an existing state. Does not currently create a new one if one does not exist.
218+
---@param source_name string
219+
---@param tabid integer?
220+
---@param winid integer?
221+
---@param override table
222+
---@return neotree.State new_state
223+
M._change_state = function(source_name, tabid, winid, override)
224+
assert(source_name, "get_state: source_name cannot be nil")
225+
tabid = tabid or vim.api.nvim_get_current_tabpage()
226+
local sd = get_source_data(source_name)
227+
if type(winid) == "number" then
228+
local cur_state = assert(sd.state_by_win[winid], "no state for winid " .. winid)
229+
local new_state = vim.tbl_deep_extend("force", cur_state, override)
230+
sd.state_by_win[winid] = new_state
231+
return new_state
232+
end
233+
234+
local cur_state = assert(sd.state_by_tab[tabid], "no state for tabid " .. tabid)
235+
local new_state = vim.tbl_deep_extend("force", cur_state, override)
236+
sd.state_by_tab[tabid] = new_state
237+
return new_state
238+
end
239+
217240
---Returns the state for the current buffer, assuming it is a neo-tree buffer.
218241
---@param winid number? The window id to use, if nil, the current window is used.
219242
---@return neotree.State? state The state for the current buffer, if it's a neo-tree buffer.

tests/neo-tree/manager/state_spec.lua

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

tests/neo-tree/sources/manager_spec.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,24 @@ describe("Manager", function()
9191
}
9292
end
9393

94+
it("can retrieve/create states at startup", function()
95+
local fs_state = manager.get_state("filesystem")
96+
local buffers_state = manager.get_state("buffers")
97+
assert.are_equal(type(fs_state), "table")
98+
assert.are_equal(type(buffers_state), "table")
99+
end)
100+
it("can change states", function()
101+
local old_state = manager.get_state("filesystem")
102+
local new_bind_to_cwd = old_state.bind_to_cwd
103+
104+
local overridden_state = manager._change_state("filesystem", nil, nil, {
105+
bind_to_cwd = new_bind_to_cwd,
106+
})
107+
local new_stored_state = manager.get_state("filesystem")
108+
assert.are_equal(overridden_state, new_stored_state)
109+
assert(new_stored_state.bind_to_cwd == new_bind_to_cwd)
110+
end)
111+
94112
it("should respect changed tab cwd", function()
95113
local ctx = setup_2_tabs()
96114

0 commit comments

Comments
 (0)