Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions lua/neo-tree/sources/manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,26 @@ end
---@field win_width integer
---@field last_user_width integer

---@alias neotree.State.Position "top"|"bottom"|"left"|"right"|"current"|"float"
---@alias neotree.State.CurrentPosition "top"|"bottom"|"left"|"right"|"current"|"float"

---@alias neotree.Internal.SortFieldProvider fun(node: NuiTree.Node):any

---@class neotree.State.Position
---@field topline integer?
---@field lnum integer?
---@field node_id string?

---@class neotree.State : neotree.Config.Source
---@field name string
---@field tabid integer
---@field id integer
---@field bufnr integer?
---@field dirty boolean
---@field position table
---@field position neotree.State.Position
---@field git_base string
---@field sort table
---@field clipboard table
---@field current_position neotree.State.Position?
---@field current_position neotree.State.CurrentPosition?
---@field disposed boolean?
---@field winid integer?
---@field path string?
Expand All @@ -70,6 +75,7 @@ end
---private-ish
---@field orig_tree NuiTree?
---@field _ready boolean?
---@field _in_pre_render boolean?
---@field loading boolean?
---window
---@field window neotree.State.Window?
Expand Down Expand Up @@ -610,6 +616,8 @@ M.redraw = function(source_name)
end

---Refreshes the tree by scanning the filesystem again.
---@param source_name string
---@param callback function?
M.refresh = function(source_name, callback)
if type(callback) ~= "function" then
callback = nil
Expand Down
54 changes: 30 additions & 24 deletions lua/neo-tree/ui/renderer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ M.close = function(state, focus_prior_window)
window_existed = true
if state.current_position == "current" then
-- we are going to hide the buffer instead of closing the window
M.position.save(state)
local new_buf = vim.fn.bufnr("#")
if new_buf < 1 then
new_buf = vim.api.nvim_create_buf(true, false)
Expand All @@ -148,7 +147,7 @@ M.close = function(state, focus_prior_window)
-- focus the prior used window if we are closing the currently focused window
local current_winid = vim.api.nvim_get_current_win()
if current_winid == state.winid then
local pwin = require("neo-tree").get_prior_window()
local pwin = nt.get_prior_window()
if type(pwin) == "number" and pwin > 0 then
pcall(vim.api.nvim_set_current_win, pwin)
end
Expand Down Expand Up @@ -488,8 +487,7 @@ end
---Sets the cursor at the specified node.
---@param state neotree.State The current state of the source.
---@param id string? The id of the node to set the cursor at.
---@return boolean boolean True if the node was found and focused, false
---otherwise.
---@return boolean boolean True if the node was found and focused, false otherwise.
M.focus_node = function(state, id, do_not_focus_window, relative_movement, bottom_scroll_padding)
if not id and not relative_movement then
log.debug("focus_node called with no id and no relative movement")
Expand Down Expand Up @@ -546,29 +544,28 @@ M.focus_node = function(state, id, do_not_focus_window, relative_movement, botto
-- forget about cursor position as it is overwritten
M.position.clear(state)
-- now ensure that the window is scrolled correctly
local execute_win_command = function(cmd)
if vim.api.nvim_get_current_win() == state.winid then
vim.cmd(cmd)
else
vim.cmd("call win_execute(" .. state.winid .. [[, "]] .. cmd .. [[")]])
end
end

-- make sure we are not scrolled down if it can all fit on the screen
local lines = vim.api.nvim_buf_line_count(state.bufnr)
local win_height = vim.api.nvim_win_get_height(state.winid)
local virtual_bottom_line = vim.fn.line("w0", state.winid)
+ win_height
- bottom_scroll_padding
if virtual_bottom_line <= linenr then
execute_win_command("normal! " .. (linenr + bottom_scroll_padding) .. "zb")
vim.api.nvim_win_call(state.winid, function()
vim.cmd("normal! " .. (linenr + bottom_scroll_padding) .. "zb")
end)
pcall(vim.api.nvim_win_set_cursor, state.winid, { linenr, col })
elseif virtual_bottom_line > lines then
execute_win_command("normal! " .. (lines + bottom_scroll_padding) .. "zb")
vim.api.nvim_win_call(state.winid, function()
vim.cmd("normal! " .. (lines + bottom_scroll_padding) .. "zb")
end)
pcall(vim.api.nvim_win_set_cursor, state.winid, { linenr, col })
elseif linenr < (win_height / 2) then
execute_win_command("normal! zz")
vim.api.nvim_win_call(state.winid, function()
vim.cmd("normal! zz")
end)
end
M.position.save(state)
else
log.debug("Failed to set cursor: " .. err)
end
Expand Down Expand Up @@ -660,6 +657,8 @@ end

---Functions to save and restore the focused node.
M.position = {}

---Saves a window position to be restored later
---@param state neotree.State
M.position.save = function(state)
if state.position.topline and state.position.lnum then
Expand All @@ -674,7 +673,10 @@ M.position.save = function(state)
log.debug("Saved window position with topline: " .. state.position.topline)
end
end

---Queues a node to focus
---@param state neotree.State
---@param node_id string?
M.position.set = function(state, node_id)
if type(node_id) ~= "string" or node_id == "" then
return
Expand All @@ -687,6 +689,7 @@ M.position.set = function(state, node_id)
end
state.position.node_id = node_id
end

---@param state neotree.State
M.position.clear = function(state)
log.debug("Forget about cursor position.")
Expand All @@ -697,6 +700,7 @@ M.position.clear = function(state)
-- focus on it anymore
state.position.node_id = nil
end

---@param state neotree.State
M.position.restore = function(state)
if state.position.topline and state.position.lnum then
Expand All @@ -707,13 +711,14 @@ M.position.restore = function(state)
end)
end
if state.position.node_id then
print(state.position.node_id)
log.debug("Focusing on node_id: " .. state.position.node_id)
M.focus_node(state, state.position.node_id, true)
end
M.position.clear(state)
end

---Redraw the tree without relaoding from the source.
---Redraw the tree without reloading from the source.
---@param state neotree.State State of the tree.
M.redraw = function(state)
if state.tree and M.tree_is_visible(state) then
Expand All @@ -730,7 +735,7 @@ M.redraw = function(state)
end
end
---Visit all nodes ina tree recursively and reduce to a single value.
---@param tree table NuiTree
---@param tree NuiTree
---@param memo any Value that is passed to the accumulator function
---@param func function Accumulator function that is called for each node
---@return any any The final memo value.
Expand Down Expand Up @@ -1097,6 +1102,10 @@ M.acquire_window = function(state)
vim.api.nvim_buf_set_name(state.bufnr, bufname)
vim.api.nvim_set_current_win(state.winid)
-- Used to track the position of the cursor within the tree as it gains and loses focus
win:on({ "CursorMoved" }, function()
M.position.clear(state)
M.position.save(state)
end)
win:on({ "BufDelete" }, function()
M.position.save(state)
end)
Expand Down Expand Up @@ -1185,15 +1194,12 @@ M.tree_is_visible = function(state)
end

---Renders the given tree and expands window width if needed
--@param state neotree.State The state containing tree to render. Almost same as state.tree:render()
---@param state neotree.State The state containing tree to render. Almost same as state.tree:render()
render_tree = function(state)
local add_blank_line_at_top = require("neo-tree").config.add_blank_line_at_top
local add_blank_line_at_top = nt.config.add_blank_line_at_top
local should_auto_expand = state.window.auto_expand_width and state.current_position ~= "float"
local should_pre_render = should_auto_expand or state.current_position == "current"

log.debug("render_tree: Saving position")
M.position.save(state)

if should_pre_render and M.tree_is_visible(state) then
log.trace("pre-rendering tree")
state._in_pre_render = true
Expand Down Expand Up @@ -1329,7 +1335,7 @@ M.show_nodes = function(sourceItems, state, parentId, callback)
state.longest_node = 0
end

local config = require("neo-tree").config
local config = nt.config
if config.hide_root_node then
if not parentId then
sourceItems[1].skip_node = true
Expand All @@ -1344,7 +1350,7 @@ M.show_nodes = function(sourceItems, state, parentId, callback)

if state.group_empty_dirs then
if parent then
local scan_mode = require("neo-tree").config.filesystem.scan_mode
local scan_mode = nt.config.filesystem.scan_mode
if scan_mode == "deep" then
for i, item in ipairs(sourceItems) do
sourceItems[i] = group_empty_dirs(item)
Expand Down
Loading