nvim-neo-tree / neo-tree.nvim

Neovim plugin to manage the file system and other tree like structures.
MIT License
3.65k stars 216 forks source link

Custom Source `close_window` event breaking reopenability #645

Closed miversen33 closed 1 year ago

miversen33 commented 1 year ago

I'm not quite sure what I am doing wrong but Netman's Neotree Source cannot be reopened after its closed.

Code can be found here

The close event works perfectly (either by pressing q and triggering Neotree's close_window command) or by running :q However, when reopening the source (for Netman, that is :Neotree remote), you are presented with the following error

E5108: Error executing lua ...im/site/pack/packer/start/nui.nvim/lua/nui/tree/init.lua:254: Expected Lua number
stack traceback:
        [C]: in function 'nvim_win_get_cursor'
        ...im/site/pack/packer/start/nui.nvim/lua/nui/tree/init.lua:254: in function 'get_node'
        ...packer/start/netman.nvim/lua/netman/ui/neo-tree/init.lua:315: in function 'navigate'
        ...ker/start/neo-tree.nvim/lua/neo-tree/sources/manager.lua:451: in function 'navigate'
        ...packer/start/neo-tree.nvim/lua/neo-tree/command/init.lua:174: in function 'do_show_or_focus'
        ...packer/start/neo-tree.nvim/lua/neo-tree/command/init.lua:132: in function 'execute'
        ...packer/start/neo-tree.nvim/lua/neo-tree/command/init.lua:140: in function '_command'
        [string ":lua"]:1: in main chunk

The line in question in netman is

M.navigate = function(state, opts)
    local tree, node, nodes, parent_id
    opts = opts or {}
    -- Check to see if there is even a tree built
    tree = state.tree
    if not tree then
        -- Somehow there was no providers rendered.
        nodes = M.internal.generate_node_children(state)
        parent_id = nil
    else
        if opts.target_id then
            node = tree:get_node(opts.target_id)
        else
            -- \/ This is the line that breaks
            node = tree:get_node()
        end
        if not node or not node.extra then
            log.warn("Node doesn't exist or is missing the extra attribute", {node=node, opts=opts})
            return
        end
        if node:is_expanded() then
            node:collapse()
            renderer.redraw(state)
            return
        end
        nodes = M.internal.generate_node_children(state, node)
        parent_id = node:get_id()
    end
    renderer.show_nodes(nodes, state, parent_id)
end

I'm not really sure what I am doing wrong, I assume I just missed something. Got any guidance for me?

cseickel commented 1 year ago

The problem is that tree:get_node() works by getting the cursor position of the window that NuiTree was rendered into. At this moment, that window no longer exists. You need to gaurd against that with code like this:

  local window_exists = renderer.window_exists(state)
  if window_exists then
    local node = state.tree and state.tree:get_node()
    if node then
        -- now you can work with the focused node if it exists...
miversen33 commented 1 year ago

That did it :) You're the best, thanks!