Skip to content

Commit 38293fe

Browse files
authored
feat(filesystem): show window immediately without waiting for async scan (#1015)
closes #744
1 parent 1424449 commit 38293fe

File tree

7 files changed

+61
-23
lines changed

7 files changed

+61
-23
lines changed

lua/neo-tree/sources/filesystem/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ end
3333

3434
local follow_internal = function(callback, force_show, async)
3535
log.trace("follow called")
36+
local state = get_state()
3637
if vim.bo.filetype == "neo-tree" or vim.bo.filetype == "neo-tree-popup" then
3738
return false
3839
end
@@ -42,7 +43,6 @@ local follow_internal = function(callback, force_show, async)
4243
end
4344
---@cast path_to_reveal string
4445

45-
local state = get_state()
4646
if state.current_position == "float" then
4747
return false
4848
end
@@ -177,6 +177,7 @@ end
177177
---@param path_to_reveal string Node to focus after the items are loaded.
178178
---@param callback function Callback to call after the items are loaded.
179179
M.navigate = function(state, path, path_to_reveal, callback, async)
180+
state._ready = false
180181
log.trace("navigate", path, path_to_reveal, async)
181182
utils.debounce("filesystem_navigate", function()
182183
M._navigate_internal(state, path, path_to_reveal, callback, async)

lua/neo-tree/sources/filesystem/lib/fs_scan.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ local handle_refresh_or_up = function (context, async)
481481
end
482482

483483
M.get_items = function(state, parent_id, path_to_reveal, callback, async, recursive)
484+
renderer.acquire_window(state)
484485
if state.async_directory_scan == "always" then
485486
async = true
486487
elseif state.async_directory_scan == "never" then

lua/neo-tree/ui/renderer.lua

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ local windows = require("neo-tree.ui.windows")
1515
local M = { resize_timer_interval = 50 }
1616
local ESC_KEY = vim.api.nvim_replace_termcodes("<ESC>", true, false, true)
1717
local default_popup_size = { width = 60, height = "80%" }
18-
local draw, create_window, create_tree, render_tree
18+
local draw, create_tree, render_tree
1919

2020
local floating_windows = {}
2121
local update_floating_windows = function()
@@ -913,7 +913,14 @@ local get_buffer = function(bufname, state)
913913
return bufnr
914914
end
915915

916-
create_window = function(state)
916+
M.acquire_window = function(state)
917+
if M.window_exists(state) then
918+
return state.winid
919+
end
920+
921+
-- used by tests to determine if the tree is ready for testing
922+
state._ready = false
923+
917924
local default_position = utils.resolve_config_option(state, "window.position", "left")
918925
local relative = utils.resolve_config_option(state, "window.relative", "editor")
919926
state.current_position = state.current_position or default_position
@@ -954,6 +961,7 @@ create_window = function(state)
954961
local win
955962
if state.current_position == "float" then
956963
M.close_all_floating_windows()
964+
M.close(state)
957965
win = create_floating_window(state, win_options, bufname)
958966
elseif state.current_position == "current" then
959967
-- state.id is always the window id or tabnr that this state was created for
@@ -1020,7 +1028,7 @@ create_window = function(state)
10201028
end
10211029

10221030
set_buffer_mappings(state)
1023-
return win
1031+
return state.winid
10241032
end
10251033

10261034
M.update_floating_window_layouts = function()
@@ -1142,8 +1150,13 @@ draw = function(nodes, state, parent_id)
11421150
end
11431151

11441152
-- Create the tree if it doesn't exist.
1145-
if not parent_id and not M.window_exists(state) then
1146-
create_window(state)
1153+
if parent_id then
1154+
if not M.window_exists(state) then
1155+
log.trace("Window is gone, aborting lazy load of folder")
1156+
return
1157+
end
1158+
else
1159+
M.acquire_window(state)
11471160
create_tree(state)
11481161
end
11491162

@@ -1174,6 +1187,7 @@ draw = function(nodes, state, parent_id)
11741187
-- Restore the cursor position/focused node in the tree based on the state
11751188
-- when it was last closed
11761189
M.position.restore(state)
1190+
state._ready = true
11771191
end
11781192

11791193
local function group_empty_dirs(node)

tests/neo-tree/command/command_spec.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ local run_focus_command = function(command, expected_tree_node)
77
local winid = vim.api.nvim_get_current_win()
88

99
vim.cmd(command)
10+
u.wait_for_neo_tree({ interval = 10, timeout = 200 })
11+
--u.wait_for_neo_tree()
1012
verify.window_handle_is_not(winid)
1113
verify.buf_name_endswith("neo-tree filesystem [1]")
1214
if expected_tree_node then
@@ -186,11 +188,10 @@ describe("Command", function()
186188
u.editfile(baz)
187189
run_focus_command("Neotree reveal", baz)
188190
local expected_tree_node = baz
191+
-- toggle CLOSE
192+
vim.cmd(cmd)
189193

190194
verify.after(500, function()
191-
-- toggle CLOSE
192-
vim.cmd(cmd)
193-
194195
-- toggle OPEN
195196
u.editfile(topfile)
196197
if follow_current_file then

tests/neo-tree/ui/icons_spec.lua

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ describe("ui/icons", function()
4949
req_switch.disable_package("nvim-web-devicons")
5050

5151
vim.cmd([[:Neotree focus]])
52-
u.wait_for(function()
53-
return vim.bo.filetype == "neo-tree"
54-
end)
52+
u.wait_for_neo_tree()
5553

5654
local winid = vim.api.nvim_get_current_win()
5755
local bufnr = vim.api.nvim_win_get_buf(winid)
@@ -88,9 +86,7 @@ describe("ui/icons", function()
8886

8987
it("works w/ nvim-web-devicons", function()
9088
vim.cmd([[:Neotree focus]])
91-
u.wait_for(function()
92-
return vim.bo.filetype == "neo-tree"
93-
end)
89+
u.wait_for_neo_tree()
9490

9591
local winid = vim.api.nvim_get_current_win()
9692
local bufnr = vim.api.nvim_win_get_buf(winid)
@@ -151,9 +147,7 @@ describe("ui/icons", function()
151147
req_switch.disable_package("nvim-web-devicons")
152148

153149
vim.cmd([[:Neotree focus]])
154-
u.wait_for(function()
155-
return vim.bo.filetype == "neo-tree"
156-
end)
150+
u.wait_for_neo_tree()
157151

158152
local winid = vim.api.nvim_get_current_win()
159153
local bufnr = vim.api.nvim_win_get_buf(winid)
@@ -190,9 +184,7 @@ describe("ui/icons", function()
190184

191185
it("works w/ nvim-web-devicons", function()
192186
vim.cmd([[:Neotree focus]])
193-
u.wait_for(function()
194-
return vim.bo.filetype == "neo-tree"
195-
end)
187+
u.wait_for_neo_tree()
196188

197189
local winid = vim.api.nvim_get_current_win()
198190
local bufnr = vim.api.nvim_win_get_buf(winid)

tests/utils/init.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,12 @@ function mod.wait_for(callback, options)
180180
vim.wait(options.timeout or 1000, callback, options.interval or 100)
181181
end
182182

183+
---@param options? { interval?: integer, timeout?: integer }
184+
function mod.wait_for_neo_tree(options)
185+
local verify = require("tests.utils.verify")
186+
mod.wait_for(function()
187+
return verify.get_state() ~= nil
188+
end, options)
189+
end
190+
183191
return mod

tests/utils/verify.lua

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,35 @@ end
5454

5555
verify.tree_focused = function(timeout)
5656
verify.eventually(timeout or 1000, function()
57+
if not verify.get_state() then
58+
return false
59+
end
5760
return vim.api.nvim_buf_get_option(0, "filetype") == "neo-tree"
5861
end, "Current buffer is not a 'neo-tree' filetype")
5962
end
6063

64+
verify.get_state = function(source_name, winid)
65+
if source_name == nil then
66+
local success
67+
success, source_name = pcall(vim.api.nvim_buf_get_var, 0, "neo_tree_source")
68+
if not success then
69+
return nil
70+
end
71+
end
72+
local state = require("neo-tree.sources.manager").get_state(source_name, nil, winid)
73+
if not state.tree then
74+
return nil
75+
end
76+
if not state._ready then
77+
return nil
78+
end
79+
return state
80+
end
81+
6182
verify.tree_node_is = function(source_name, expected_node_id, winid, timeout)
6283
verify.eventually(timeout or 500, function()
63-
local state = require("neo-tree.sources.manager").get_state(source_name, nil, winid)
64-
if not state.tree then
84+
local state = verify.get_state(source_name, winid)
85+
if not state then
6586
return false
6687
end
6788
local success, node = pcall(state.tree.get_node, state.tree)

0 commit comments

Comments
 (0)