@@ -26,7 +26,7 @@ M.close = function(state)
26
26
window_existed = true
27
27
if state .current_position == " split" then
28
28
-- we are going to hide the buffer instead of closing the window
29
- state .position .save ()
29
+ M .position .save (state )
30
30
local new_buf = vim .fn .bufnr (" #" )
31
31
if new_buf < 1 then
32
32
new_buf = vim .api .nvim_create_buf (true , false )
@@ -171,26 +171,31 @@ end
171
171
--- otherwise.
172
172
M .focus_node = function (state , id , do_not_focus_window , relative_movement , bottom_scroll_padding )
173
173
if not id and not relative_movement then
174
+ log .debug (" focus_node called with no id and no relative movement" )
174
175
return nil
175
176
end
176
177
relative_movement = relative_movement or 0
177
178
bottom_scroll_padding = bottom_scroll_padding or 0
178
179
179
180
local tree = state .tree
180
181
if not tree then
182
+ log .debug (" focus_node called with no tree" )
181
183
return false
182
184
end
183
185
local node = tree :get_node (id )
184
186
if not node then
187
+ log .debug (" focus_node cannot find node with id " , id )
185
188
return false
186
189
end
187
190
id = node :get_id () -- in case nil was passed in for id, meaning current node
188
191
189
192
local bufnr = utils .get_value (state , " bufnr" , 0 , true )
190
193
if bufnr == 0 then
194
+ log .debug (" focus_node: state has no bufnr " , state .bufnr , " / " , state .winid )
191
195
return false
192
196
end
193
197
if not vim .api .nvim_buf_is_valid (bufnr ) then
198
+ log .debug (" focus_node: bufnr is not valid" )
194
199
return false
195
200
end
196
201
local lines = vim .api .nvim_buf_line_count (state .bufnr )
@@ -241,11 +246,13 @@ M.focus_node = function(state, id, do_not_focus_window, relative_movement, botto
241
246
end
242
247
return success
243
248
else
249
+ log .debug (" focus_node: window does not exist" )
244
250
return false
245
251
end
246
252
end
247
253
else
248
254
-- must be out of nodes
255
+ log .debug (" focus_node: node not found" )
249
256
return false
250
257
end
251
258
end
@@ -312,6 +319,43 @@ M.collapse_all_nodes = function(tree)
312
319
root :expand ()
313
320
end
314
321
322
+ --- Functions to save and restore the focused node.
323
+ M .position = {
324
+ save = function (state )
325
+ if state .tree and M .window_exists (state ) then
326
+ local node = state .tree :get_node ()
327
+ if node then
328
+ state .position .node_id = node :get_id ()
329
+ end
330
+ end
331
+ -- Only need to restore the cursor state once per save, comes
332
+ -- into play when some actions fire multiple times per "iteration"
333
+ -- within the scope of where we need to perform the restore operation
334
+ state .position .is .restorable = true
335
+ end ,
336
+ set = function (state , node_id )
337
+ if not type (node_id ) == " string" and node_id > " " then
338
+ return
339
+ end
340
+ state .position .node_id = node_id
341
+ state .position .is .restorable = true
342
+ end ,
343
+ restore = function (state )
344
+ if not state .position .node_id then
345
+ log .debug (" No node_id to restore to" )
346
+ return
347
+ end
348
+ if state .position .is .restorable then
349
+ log .debug (" Restoring position to node_id: " .. state .position .node_id )
350
+ M .focus_node (state , state .position .node_id , true )
351
+ else
352
+ log .debug (" Position is not restorable" )
353
+ end
354
+ state .position .is .restorable = false
355
+ end ,
356
+ is = { restorable = true },
357
+ }
358
+
315
359
--- Visits all nodes in the tree and returns a list of all nodes that match the
316
360
--- given predicate.
317
361
--- @param tree table The NuiTree to search.
@@ -414,6 +458,7 @@ create_window = function(state)
414
458
end , { once = true })
415
459
state .winid = win .winid
416
460
state .bufnr = win .bufnr
461
+ log .debug (" Created floating window with winid: " , win .winid , " and bufnr: " , win .bufnr )
417
462
vim .api .nvim_buf_set_name (state .bufnr , bufname )
418
463
419
464
-- why is this necessary?
@@ -449,7 +494,7 @@ create_window = function(state)
449
494
450
495
if win == nil then
451
496
autocmd .buf .define (state .bufnr , " WinLeave" , function ()
452
- state .position .save ()
497
+ M .position .save (state )
453
498
end )
454
499
else
455
500
-- Used to track the position of the cursor within the tree as it gains and loses focus
@@ -459,7 +504,7 @@ create_window = function(state)
459
504
-- to mention that it would be too late to register `WinEnter` here for the first
460
505
-- iteration of that event on the tree window)
461
506
win :on ({ " WinLeave" }, function ()
462
- state .position .save ()
507
+ M .position .save (state )
463
508
end )
464
509
465
510
win :on ({ " BufDelete" }, function ()
@@ -589,7 +634,7 @@ draw = function(nodes, state, parent_id)
589
634
590
635
-- Restore the cursor position/focused node in the tree based on the state
591
636
-- when it was last closed
592
- state .position .restore ()
637
+ M .position .restore (state )
593
638
end
594
639
595
640
--- Shows the given items as a tree.
0 commit comments