Skip to content

Commit e43f1e3

Browse files
committed
feat(files): add command to close current node, closes #19
1 parent 9047a35 commit e43f1e3

File tree

7 files changed

+116
-67
lines changed

7 files changed

+116
-67
lines changed

README.md

+40-13
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,46 @@ structures in a sidebar **or** floating window.
77

88
Example for packer:
99
```lua
10-
use {
11-
"nvim-neo-tree/neo-tree.nvim",
12-
branch = "v1.x",
13-
requires = {
14-
"nvim-lua/plenary.nvim",
15-
"kyazdani42/nvim-web-devicons", -- not strictly required, but recommended
16-
"MunifTanjim/nui.nvim"
17-
},
18-
config = function ()
19-
require("neo-tree").setup()
20-
vim.cmd([[nnoremap \ :NeoTreeReveal<cr>]])
21-
end
22-
}
10+
use {
11+
"nvim-neo-tree/neo-tree.nvim",
12+
branch = "v1.x",
13+
requires = {
14+
"nvim-lua/plenary.nvim",
15+
"kyazdani42/nvim-web-devicons", -- not strictly required, but recommended
16+
"MunifTanjim/nui.nvim"
17+
},
18+
config = function ()
19+
require("neo-tree").setup({
20+
popup_border_style = "rounded",
21+
filesystem = {
22+
window = {
23+
mappings = {
24+
["<2-LeftMouse>"] = "open",
25+
["<cr>"] = "open",
26+
["S"] = "open_split",
27+
["s"] = "open_vsplit",
28+
["C"] = "close_node",
29+
["<bs>"] = "navigate_up",
30+
["."] = "set_root",
31+
["H"] = "toggle_hidden",
32+
["I"] = "toggle_gitignore",
33+
["R"] = "refresh",
34+
["/"] = "filter_as_you_type",
35+
["f"] = "filter_on_submit",
36+
["<c-x>"] = "clear_filter",
37+
["a"] = "add",
38+
["d"] = "delete",
39+
["r"] = "rename",
40+
["c"] = "copy_to_clipboard",
41+
["x"] = "cut_to_clipboard",
42+
["p"] = "paste_from_clipboard",
43+
}
44+
}
45+
}
46+
})
47+
vim.cmd([[nnoremap \ :NeoTreeReveal<cr>]])
48+
end
49+
}
2350
```
2451

2552
Here are the various ways to open the tree:

lua/neo-tree/sources/buffers/commands.lua

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ M.add = function(state)
1111
cc.add(state, buffers.refresh)
1212
end
1313

14+
M.close_node = cc.close_node
15+
1416
---Marks node as copied, so that it can be pasted somewhere else.
1517
M.copy_to_clipboard = function(state)
1618
cc.copy_to_clipboard(state, buffers.redraw)

lua/neo-tree/sources/common/commands.lua

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
local vim = vim
44
local fs_actions = require('neo-tree.sources.filesystem.lib.fs_actions')
55
local utils = require('neo-tree.utils')
6+
local renderer = require('neo-tree.ui.renderer')
67

78
local M = {}
89

@@ -22,6 +23,17 @@ M.add = function(state, callback)
2223
end)
2324
end
2425

26+
M.close_node = function(state, callback)
27+
local tree = state.tree
28+
local node = tree:get_node()
29+
node = tree:get_node(node:get_parent_id())
30+
if node then
31+
node:collapse()
32+
tree:render()
33+
renderer.focus_node(state, node:get_id())
34+
end
35+
end
36+
2537
---Marks node as copied, so that it can be pasted somewhere else.
2638
M.copy_to_clipboard = function(state, callback)
2739
local node = state.tree:get_node()

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

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ M.clear_filter = function(state)
1717
fs.reset_search(true)
1818
end
1919

20+
M.close_node = cc.close_node
21+
2022
---Marks node as copied, so that it can be pasted somewhere else.
2123
M.copy_to_clipboard = function(state)
2224
cc.copy_to_clipboard(state, fs.redraw)

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

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ local filesystem = {
2626
["<cr>"] = "open",
2727
["S"] = "open_split",
2828
["s"] = "open_vsplit",
29+
["C"] = "close_node",
2930
["<bs>"] = "navigate_up",
3031
["."] = "set_root",
3132
["H"] = "toggle_hidden",

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

+2-54
Original file line numberDiff line numberDiff line change
@@ -46,58 +46,6 @@ local get_path_to_reveal = function()
4646
return path
4747
end
4848

49-
local reveal_file = function(state, path)
50-
if not path then
51-
return nil
52-
end
53-
local tree = state.tree
54-
if not tree then
55-
return false
56-
end
57-
local node = tree:get_node(path)
58-
if not node then
59-
return false
60-
end
61-
--expand_to_root(tree, node)
62-
--tree:render()
63-
64-
local bufnr = utils.get_value(state, "bufnr", 0, true)
65-
if bufnr == 0 then
66-
return false
67-
end
68-
if not vim.api.nvim_buf_is_valid(bufnr) then
69-
return false
70-
end
71-
local lines = vim.api.nvim_buf_line_count(state.bufnr)
72-
local linenr = 0
73-
while linenr < lines do
74-
linenr = linenr + 1
75-
node = tree:get_node(linenr)
76-
if node then
77-
if node:get_id() == path then
78-
local col = 0
79-
if node.indent then
80-
col = string.len(node.indent)
81-
end
82-
if renderer.window_exists(state) then
83-
vim.api.nvim_set_current_win(state.winid)
84-
else
85-
renderer.draw(state.tree:get_nodes(), state, nil)
86-
end
87-
local success, err = pcall(vim.api.nvim_win_set_cursor, state.winid, { linenr, col })
88-
if not success then
89-
print("Failed to set cursor: " .. err)
90-
end
91-
return success
92-
end
93-
else
94-
--must be out of nodes
95-
return false
96-
end
97-
end
98-
return false
99-
end
100-
10149
M.close = function()
10250
local state = get_state()
10351
renderer.close(state)
@@ -157,7 +105,7 @@ M.navigate = function(path, path_to_reveal, callback)
157105

158106
if path_to_reveal then
159107
fs_scan.get_items_async(state, nil, path_to_reveal, function()
160-
local found = reveal_file(state, path_to_reveal)
108+
local found = renderer.focus_node(state, path_to_reveal)
161109
if not found and was_float then
162110
-- I'm not realy sure why it is not focused when it is created...
163111
--vim.api.nvim_set_current_win(state.winid)
@@ -198,7 +146,7 @@ M.reveal_current_file = function()
198146
return
199147
end
200148
if path then
201-
if not reveal_file(state, path) then
149+
if not renderer.focus_node(state, path) then
202150
M.focus(path)
203151
end
204152
end

lua/neo-tree/ui/renderer.lua

+57
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,63 @@ local prepare_node = function(item, state)
117117
return line
118118
end
119119

120+
---Sets the cursor at the specified node.
121+
---@param state table The current state of the source.
122+
---@param id string The id of the node to set the cursor at.
123+
---@return boolean boolean True if the node was found and focused, false
124+
---otherwise.
125+
M.focus_node = function(state, id)
126+
if not id then
127+
return nil
128+
end
129+
local tree = state.tree
130+
if not tree then
131+
return false
132+
end
133+
local node = tree:get_node(id)
134+
if not node then
135+
return false
136+
end
137+
--expand_to_root(tree, node)
138+
--tree:render()
139+
140+
local bufnr = utils.get_value(state, "bufnr", 0, true)
141+
if bufnr == 0 then
142+
return false
143+
end
144+
if not vim.api.nvim_buf_is_valid(bufnr) then
145+
return false
146+
end
147+
local lines = vim.api.nvim_buf_line_count(state.bufnr)
148+
local linenr = 0
149+
while linenr < lines do
150+
linenr = linenr + 1
151+
node = tree:get_node(linenr)
152+
if node then
153+
if node:get_id() == id then
154+
local col = 0
155+
if node.indent then
156+
col = string.len(node.indent)
157+
end
158+
if M.window_exists(state) then
159+
vim.api.nvim_set_current_win(state.winid)
160+
else
161+
M.draw(state.tree:get_nodes(), state, nil)
162+
end
163+
local success, err = pcall(vim.api.nvim_win_set_cursor, state.winid, { linenr, col })
164+
if not success then
165+
print("Failed to set cursor: " .. err)
166+
end
167+
return success
168+
end
169+
else
170+
--must be out of nodes
171+
return false
172+
end
173+
end
174+
return false
175+
end
176+
120177
M.get_expanded_nodes = function(tree)
121178
local node_ids = {}
122179

0 commit comments

Comments
 (0)