Skip to content

Commit 45c249e

Browse files
committed
test moving api.impl.lua
1 parent ca8d82f commit 45c249e

File tree

2 files changed

+462
-366
lines changed

2 files changed

+462
-366
lines changed

lua/nvim-tree/api-impl.lua

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
local core = require("nvim-tree.core")
2+
local view = require("nvim-tree.view")
3+
local utils = require("nvim-tree.utils")
4+
local actions = require("nvim-tree.actions")
5+
local appearance_hi_test = require("nvim-tree.appearance.hi-test")
6+
local events = require("nvim-tree.events")
7+
local help = require("nvim-tree.help")
8+
local keymap = require("nvim-tree.keymap")
9+
local notify = require("nvim-tree.notify")
10+
11+
local DirectoryNode = require("nvim-tree.node.directory")
12+
local FileNode = require("nvim-tree.node.file")
13+
local FileLinkNode = require("nvim-tree.node.file-link")
14+
local RootNode = require("nvim-tree.node.root")
15+
local UserDecorator = require("nvim-tree.renderer.decorator.user")
16+
17+
local Api = {
18+
tree = {},
19+
node = {
20+
navigate = {
21+
sibling = {},
22+
git = {},
23+
diagnostics = {},
24+
opened = {},
25+
},
26+
run = {},
27+
open = {},
28+
buffer = {},
29+
},
30+
events = {},
31+
marks = {
32+
bulk = {},
33+
navigate = {},
34+
},
35+
fs = {
36+
copy = {},
37+
},
38+
git = {},
39+
live_filter = {},
40+
config = {
41+
mappings = {},
42+
},
43+
commands = {},
44+
diagnostics = {},
45+
decorator = {},
46+
}
47+
48+
---Print error when setup not called.
49+
---@param fn fun(...): any
50+
---@return fun(...): any
51+
local function wrap(fn)
52+
return function(...)
53+
if vim.g.NvimTreeSetup == 1 then
54+
return fn(...)
55+
else
56+
notify.error("nvim-tree setup not called")
57+
end
58+
end
59+
end
60+
61+
---Invoke a method on the singleton explorer.
62+
---Print error when setup not called.
63+
---@param explorer_method string explorer method name
64+
---@return fun(...): any
65+
local function wrap_explorer(explorer_method)
66+
return wrap(function(...)
67+
local explorer = core.get_explorer()
68+
if explorer then
69+
return explorer[explorer_method](explorer, ...)
70+
end
71+
end)
72+
end
73+
74+
---Inject the node as the first argument if present otherwise do nothing.
75+
---@param fn fun(node: Node, ...): any
76+
---@return fun(node: Node?, ...): any
77+
local function wrap_node(fn)
78+
return function(node, ...)
79+
node = node or wrap_explorer("get_node_at_cursor")()
80+
if node then
81+
return fn(node, ...)
82+
end
83+
end
84+
end
85+
86+
---Inject the node or nil as the first argument if absent.
87+
---@param fn fun(node: Node?, ...): any
88+
---@return fun(node: Node?, ...): any
89+
local function wrap_node_or_nil(fn)
90+
return function(node, ...)
91+
node = node or wrap_explorer("get_node_at_cursor")()
92+
return fn(node, ...)
93+
end
94+
end
95+
96+
---Invoke a member's method on the singleton explorer.
97+
---Print error when setup not called.
98+
---@param explorer_member string explorer member name
99+
---@param member_method string method name to invoke on member
100+
---@param ... any passed to method
101+
---@return fun(...): any
102+
local function wrap_explorer_member_args(explorer_member, member_method, ...)
103+
local method_args = ...
104+
return wrap(function(...)
105+
local explorer = core.get_explorer()
106+
if explorer then
107+
return explorer[explorer_member][member_method](explorer[explorer_member], method_args, ...)
108+
end
109+
end)
110+
end
111+
112+
---Invoke a member's method on the singleton explorer.
113+
---Print error when setup not called.
114+
---@param explorer_member string explorer member name
115+
---@param member_method string method name to invoke on member
116+
---@return fun(...): any
117+
local function wrap_explorer_member(explorer_member, member_method)
118+
return wrap(function(...)
119+
local explorer = core.get_explorer()
120+
if explorer then
121+
return explorer[explorer_member][member_method](explorer[explorer_member], ...)
122+
end
123+
end)
124+
end
125+
126+
---@class ApiTreeOpenOpts
127+
---@field path string|nil path
128+
---@field current_window boolean|nil default false
129+
---@field winid number|nil
130+
---@field find_file boolean|nil default false
131+
---@field update_root boolean|nil default false
132+
133+
Api.tree.open = wrap(actions.tree.open.fn)
134+
Api.tree.focus = Api.tree.open
135+
136+
---@class ApiTreeToggleOpts
137+
---@field path string|nil
138+
---@field current_window boolean|nil default false
139+
---@field winid number|nil
140+
---@field find_file boolean|nil default false
141+
---@field update_root boolean|nil default false
142+
---@field focus boolean|nil default true
143+
144+
Api.tree.toggle = wrap(actions.tree.toggle.fn)
145+
Api.tree.close = wrap(view.close)
146+
Api.tree.close_in_this_tab = wrap(view.close_this_tab_only)
147+
Api.tree.close_in_all_tabs = wrap(view.close_all_tabs)
148+
Api.tree.reload = wrap_explorer("reload_explorer")
149+
150+
---@class ApiTreeResizeOpts
151+
---@field width string|function|number|table|nil
152+
---@field absolute number|nil
153+
---@field relative number|nil
154+
155+
Api.tree.resize = wrap(actions.tree.resize.fn)
156+
157+
Api.tree.change_root = wrap(function(...)
158+
require("nvim-tree").change_dir(...)
159+
end)
160+
161+
Api.tree.change_root_to_node = wrap_node(function(node)
162+
if node.name == ".." or node:is(RootNode) then
163+
actions.root.change_dir.fn("..")
164+
return
165+
end
166+
167+
if node:is(FileNode) and node.parent ~= nil then
168+
actions.root.change_dir.fn(node.parent:last_group_node().absolute_path)
169+
return
170+
end
171+
172+
if node:is(DirectoryNode) then
173+
actions.root.change_dir.fn(node:last_group_node().absolute_path)
174+
return
175+
end
176+
end)
177+
178+
Api.tree.change_root_to_parent = wrap_node(wrap_explorer("dir_up"))
179+
Api.tree.get_node_under_cursor = wrap_explorer("get_node_at_cursor")
180+
Api.tree.get_nodes = wrap_explorer("get_nodes")
181+
182+
---@class ApiTreeFindFileOpts
183+
---@field buf string|number|nil
184+
---@field open boolean|nil default false
185+
---@field current_window boolean|nil default false
186+
---@field winid number|nil
187+
---@field update_root boolean|nil default false
188+
---@field focus boolean|nil default false
189+
190+
Api.tree.find_file = wrap(actions.tree.find_file.fn)
191+
Api.tree.search_node = wrap(actions.finders.search_node.fn)
192+
193+
---@class ApiCollapseOpts
194+
---@field keep_buffers boolean|nil default false
195+
196+
Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse.all)
197+
198+
---@class ApiTreeExpandOpts
199+
---@field expand_until (fun(expansion_count: integer, node: Node): boolean)|nil
200+
201+
Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand.all)
202+
Api.tree.toggle_enable_filters = wrap_explorer_member("filters", "toggle")
203+
Api.tree.toggle_gitignore_filter = wrap_explorer_member_args("filters", "toggle", "git_ignored")
204+
Api.tree.toggle_git_clean_filter = wrap_explorer_member_args("filters", "toggle", "git_clean")
205+
Api.tree.toggle_no_buffer_filter = wrap_explorer_member_args("filters", "toggle", "no_buffer")
206+
Api.tree.toggle_custom_filter = wrap_explorer_member_args("filters", "toggle", "custom")
207+
Api.tree.toggle_hidden_filter = wrap_explorer_member_args("filters", "toggle", "dotfiles")
208+
Api.tree.toggle_no_bookmark_filter = wrap_explorer_member_args("filters", "toggle", "no_bookmark")
209+
Api.tree.toggle_help = wrap(help.toggle)
210+
Api.tree.is_tree_buf = wrap(utils.is_nvim_tree_buf)
211+
212+
---@class ApiTreeIsVisibleOpts
213+
---@field tabpage number|nil
214+
---@field any_tabpage boolean|nil default false
215+
216+
Api.tree.is_visible = wrap(view.is_visible)
217+
218+
---@class ApiTreeWinIdOpts
219+
---@field tabpage number|nil default nil
220+
221+
Api.tree.winid = wrap(view.winid)
222+
223+
Api.fs.create = wrap_node_or_nil(actions.fs.create_file.fn)
224+
Api.fs.remove = wrap_node(actions.fs.remove_file.fn)
225+
Api.fs.trash = wrap_node(actions.fs.trash.fn)
226+
Api.fs.rename_node = wrap_node(actions.fs.rename_file.fn(":t"))
227+
Api.fs.rename = wrap_node(actions.fs.rename_file.fn(":t"))
228+
Api.fs.rename_sub = wrap_node(actions.fs.rename_file.fn(":p:h"))
229+
Api.fs.rename_basename = wrap_node(actions.fs.rename_file.fn(":t:r"))
230+
Api.fs.rename_full = wrap_node(actions.fs.rename_file.fn(":p"))
231+
Api.fs.cut = wrap_node(wrap_explorer_member("clipboard", "cut"))
232+
Api.fs.paste = wrap_node(wrap_explorer_member("clipboard", "paste"))
233+
Api.fs.clear_clipboard = wrap_explorer_member("clipboard", "clear_clipboard")
234+
Api.fs.print_clipboard = wrap_explorer_member("clipboard", "print_clipboard")
235+
Api.fs.copy.node = wrap_node(wrap_explorer_member("clipboard", "copy"))
236+
Api.fs.copy.absolute_path = wrap_node(wrap_explorer_member("clipboard", "copy_absolute_path"))
237+
Api.fs.copy.filename = wrap_node(wrap_explorer_member("clipboard", "copy_filename"))
238+
Api.fs.copy.basename = wrap_node(wrap_explorer_member("clipboard", "copy_basename"))
239+
Api.fs.copy.relative_path = wrap_node(wrap_explorer_member("clipboard", "copy_path"))
240+
---
241+
---@class NodeEditOpts
242+
---@field quit_on_open boolean|nil default false
243+
---@field focus boolean|nil default true
244+
245+
---@param mode string
246+
---@param node Node
247+
---@param edit_opts NodeEditOpts?
248+
local function edit(mode, node, edit_opts)
249+
local file_link = node:as(FileLinkNode)
250+
local path = file_link and file_link.link_to or node.absolute_path
251+
local cur_tabpage = vim.api.nvim_get_current_tabpage()
252+
253+
actions.node.open_file.fn(mode, path)
254+
255+
edit_opts = edit_opts or {}
256+
257+
local mode_unsupported_quit_on_open = mode == "drop" or mode == "tab_drop" or mode == "edit_in_place"
258+
if not mode_unsupported_quit_on_open and edit_opts.quit_on_open then
259+
view.close(cur_tabpage)
260+
end
261+
262+
local mode_unsupported_focus = mode == "drop" or mode == "tab_drop" or mode == "edit_in_place"
263+
local focus = edit_opts.focus == nil or edit_opts.focus == true
264+
if not mode_unsupported_focus and not focus then
265+
-- if mode == "tabnew" a new tab will be opened and we need to focus back to the previous tab
266+
if mode == "tabnew" then
267+
vim.cmd(":tabprev")
268+
end
269+
view.focus()
270+
end
271+
end
272+
273+
---@param mode string
274+
---@param toggle_group boolean?
275+
---@return fun(node: Node, edit_opts: NodeEditOpts?)
276+
local function open_or_expand_or_dir_up(mode, toggle_group)
277+
---@param node Node
278+
---@param edit_opts NodeEditOpts?
279+
return function(node, edit_opts)
280+
local root = node:as(RootNode)
281+
local dir = node:as(DirectoryNode)
282+
283+
if root or node.name == ".." then
284+
actions.root.change_dir.fn("..")
285+
elseif dir then
286+
dir:expand_or_collapse(toggle_group)
287+
elseif not toggle_group then
288+
edit(mode, node, edit_opts)
289+
end
290+
end
291+
end
292+
293+
Api.node.open.edit = wrap_node(open_or_expand_or_dir_up("edit"))
294+
Api.node.open.drop = wrap_node(open_or_expand_or_dir_up("drop"))
295+
Api.node.open.tab_drop = wrap_node(open_or_expand_or_dir_up("tab_drop"))
296+
Api.node.open.replace_tree_buffer = wrap_node(open_or_expand_or_dir_up("edit_in_place"))
297+
Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up("edit_no_picker"))
298+
Api.node.open.vertical = wrap_node(open_or_expand_or_dir_up("vsplit"))
299+
Api.node.open.vertical_no_picker = wrap_node(open_or_expand_or_dir_up("vsplit_no_picker"))
300+
Api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up("split"))
301+
Api.node.open.horizontal_no_picker = wrap_node(open_or_expand_or_dir_up("split_no_picker"))
302+
Api.node.open.tab = wrap_node(open_or_expand_or_dir_up("tabnew"))
303+
Api.node.open.toggle_group_empty = wrap_node(open_or_expand_or_dir_up("toggle_group_empty", true))
304+
Api.node.open.preview = wrap_node(open_or_expand_or_dir_up("preview"))
305+
Api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up("preview_no_picker"))
306+
307+
Api.node.show_info_popup = wrap_node(actions.node.file_popup.toggle_file_info)
308+
Api.node.run.cmd = wrap_node(actions.node.run_command.run_file_command)
309+
Api.node.run.system = wrap_node(actions.node.system_open.fn)
310+
311+
Api.node.navigate.sibling.next = wrap_node(actions.moves.sibling.fn("next"))
312+
Api.node.navigate.sibling.prev = wrap_node(actions.moves.sibling.fn("prev"))
313+
Api.node.navigate.sibling.first = wrap_node(actions.moves.sibling.fn("first"))
314+
Api.node.navigate.sibling.last = wrap_node(actions.moves.sibling.fn("last"))
315+
Api.node.navigate.parent = wrap_node(actions.moves.parent.fn(false))
316+
Api.node.navigate.parent_close = wrap_node(actions.moves.parent.fn(true))
317+
Api.node.navigate.git.next = wrap_node(actions.moves.item.fn({ where = "next", what = "git" }))
318+
Api.node.navigate.git.next_skip_gitignored = wrap_node(actions.moves.item.fn({ where = "next", what = "git", skip_gitignored = true }))
319+
Api.node.navigate.git.next_recursive = wrap_node(actions.moves.item.fn({ where = "next", what = "git", recurse = true }))
320+
Api.node.navigate.git.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "git" }))
321+
Api.node.navigate.git.prev_skip_gitignored = wrap_node(actions.moves.item.fn({ where = "prev", what = "git", skip_gitignored = true }))
322+
Api.node.navigate.git.prev_recursive = wrap_node(actions.moves.item.fn({ where = "prev", what = "git", recurse = true }))
323+
Api.node.navigate.diagnostics.next = wrap_node(actions.moves.item.fn({ where = "next", what = "diag" }))
324+
Api.node.navigate.diagnostics.next_recursive = wrap_node(actions.moves.item.fn({ where = "next", what = "diag", recurse = true }))
325+
Api.node.navigate.diagnostics.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "diag" }))
326+
Api.node.navigate.diagnostics.prev_recursive = wrap_node(actions.moves.item.fn({ where = "prev", what = "diag", recurse = true }))
327+
Api.node.navigate.opened.next = wrap_node(actions.moves.item.fn({ where = "next", what = "opened" }))
328+
Api.node.navigate.opened.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "opened" }))
329+
330+
Api.node.expand = wrap_node(actions.tree.modifiers.expand.node)
331+
Api.node.collapse = wrap_node(actions.tree.modifiers.collapse.node)
332+
333+
---@class ApiNodeDeleteWipeBufferOpts
334+
---@field force boolean|nil default false
335+
336+
Api.node.buffer.delete = wrap_node(function(node, opts)
337+
actions.node.buffer.delete(node, opts)
338+
end)
339+
Api.node.buffer.wipe = wrap_node(function(node, opts)
340+
actions.node.buffer.wipe(node, opts)
341+
end)
342+
343+
Api.git.reload = wrap_explorer("reload_git")
344+
345+
Api.events.subscribe = events.subscribe
346+
Api.events.Event = events.Event
347+
348+
Api.live_filter.start = wrap_explorer_member("live_filter", "start_filtering")
349+
Api.live_filter.clear = wrap_explorer_member("live_filter", "clear_filter")
350+
351+
Api.marks.get = wrap_node(wrap_explorer_member("marks", "get"))
352+
Api.marks.list = wrap_explorer_member("marks", "list")
353+
Api.marks.toggle = wrap_node(wrap_explorer_member("marks", "toggle"))
354+
Api.marks.clear = wrap_explorer_member("marks", "clear")
355+
Api.marks.bulk.delete = wrap_explorer_member("marks", "bulk_delete")
356+
Api.marks.bulk.trash = wrap_explorer_member("marks", "bulk_trash")
357+
Api.marks.bulk.move = wrap_explorer_member("marks", "bulk_move")
358+
Api.marks.navigate.next = wrap_explorer_member("marks", "navigate_next")
359+
Api.marks.navigate.prev = wrap_explorer_member("marks", "navigate_prev")
360+
Api.marks.navigate.select = wrap_explorer_member("marks", "navigate_select")
361+
362+
Api.config.mappings.get_keymap = wrap(keymap.get_keymap)
363+
Api.config.mappings.get_keymap_default = wrap(keymap.get_keymap_default)
364+
Api.config.mappings.default_on_attach = keymap.default_on_attach
365+
366+
Api.diagnostics.hi_test = wrap(appearance_hi_test)
367+
368+
Api.commands.get = wrap(function()
369+
return require("nvim-tree.commands").get()
370+
end)
371+
372+
---Create a decorator class by calling :extend()
373+
---See :help nvim-tree-decorators
374+
---@type nvim_tree.api.decorator.UserDecorator
375+
Api.decorator.UserDecorator = UserDecorator --[[@as nvim_tree.api.decorator.UserDecorator]]
376+
377+
return Api

0 commit comments

Comments
 (0)