From 0fd1f6e3bc728a92e8691865f125deca6f51b126 Mon Sep 17 00:00:00 2001 From: kiyan Date: Sun, 17 Jul 2022 09:52:43 +0200 Subject: [PATCH] feat(api): add public API module --- README.md | 4 + doc/nvim-tree-lua.txt | 240 +++++++++++++++++++++++---------------- lua/nvim-tree/api.lua | 112 ++++++++++++++++++ lua/nvim-tree/events.lua | 73 +++++------- 4 files changed, 289 insertions(+), 140 deletions(-) create mode 100644 lua/nvim-tree/api.lua diff --git a/README.md b/README.md index 0e365426f65..a462cf20624 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,10 @@ Basic commands: `:NvimTreeCollapse` Collapses the nvim-tree recursively. +## Api + +nvim-tree exposes a public api; see [:help nvim-tree-api](doc/nvim-tree-lua.txt). This is a stable non breaking api. + ## Mappings nvim-tree comes with number of mappings; for default mappings please see [:help nvim-tree-default-mappings](doc/nvim-tree-lua.txt), for way of configuring mappings see [:help nvim-tree-mappings](doc/nvim-tree-lua.txt) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 3a01f8205e0..3a968cfca40 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -10,11 +10,11 @@ CONTENTS *nvim-tree* 3. Commands |nvim-tree-commands| 4. Setup/Configuration |nvim-tree-setup| 4.1 Vinegar Style |nvim-tree-vinegar| - 5. Mappings |nvim-tree-mappings| - 6. Highlight Groups |nvim-tree-highlight| - 7. Events |nvim-tree-events| - 7.1 Available Events |nvim-tree.events| - 8. Bookmarks |nvim-tree-bookmarks| + 5. Api |nvim-tree-api| + 6. Mappings |nvim-tree-mappings| + 7. Highlight Groups |nvim-tree-highlight| + 8. Events |nvim-tree-events| + 9. Bookmarks |nvim-tree-bookmarks| ============================================================================== 1. INTRODUCTION *nvim-tree-introduction* @@ -944,7 +944,99 @@ You'll also need to set |nvim-tree.hijack_netrw| to `true` during setup. A good functionnality to enable is |nvim-tree.hijack_directories|. ============================================================================== - 5. MAPPINGS *nvim-tree-mappings* + 5. API *nvim-tree-api* + +Nvim-tree's public API can be used to access features. +> + local nt_api = require("nvim-tree.api") + + nt_api.tree.toggle() +< +This module exposes stable functionalities, it is advised to use this in order +to avoid breaking configurations due to internal breaking changes. + +The api is separated in multiple modules, which can be accessed with +`require("nvim-tree.api").moduleName.functionality`. + +Functions that needs a tree node parameter are exposed with an abstraction +that injects the node from the cursor position in the tree when calling +the function. It will use the node you pass as an argument in priority if it +exists. + +- api.tree: *nvim-tree.api.tree* + - open `(path?: string)` + - close + - toggle `(find_file?: bool, no_focus?: bool, path?: string)` + - focus + - reload + - change_root `(path: string)` + - change_root_to_parent + - get_node_under_cursor + - find_file `(filename: string)` + - search_node + - collapse_all `(keep_buffers?: bool)` + - expand_all + - toggle_gitignore_filter + - toggle_custom_filter + - toggle_hidden_filter + - toggle_help + +- api.fs: *nvim-tree.api.fs* + - create + - remove + - trash + - rename + - rename_sub + - copy + - cut + - paste + - print_clipboard + - copy.absolute_path + - copy.filename + - copy.relative_path + +- api.node: *nvim-tree.api.node* + - open.edit + - open.vertical + - open.horizontal + - open.tab + - open.preview + - show_info_popup + - run.cmd + - run.system + - navigate.sibling.next + - navigate.sibling.prev + - navigate.sibling.first + - navigate.sibling.last + - navigate.parent + - navigate.parent_close + - navigate.git.next + - navigate.git.prev + - navigate.diagnostics.next + - navigate.diagnostics.prev + +- api.git: *nvim-tree.api.git* + - reload + +- api.events: *nvim-tree.api.events* + - subscribe `(eventType: Event, callback: function(...args))` + - Event (enum type, please see |nvim_tree_events_kind|) + +- api.live_filter: *nvim-tree.api.live_filter* + - start + - clear + +- api.marks: *nvim-tree.api.marks* + - get + - list + - toggle + - bulk.move + - navigate.next + - navigate.prev + - navigate.select + +============================================================================== + 6. MAPPINGS *nvim-tree-mappings* The `list` option in `view.mappings.list` is a table of @@ -1071,7 +1163,7 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings } -- END_DEFAULT_MAPPINGS < ============================================================================== - 6. HIGHLIGHT GROUPS *nvim-tree-highlight* + 7. HIGHLIGHT GROUPS *nvim-tree-highlight* All the following highlight groups can be configured by hand. Aside from `NvimTreeWindowPicker`, it is not advised to colorize the background of these @@ -1145,7 +1237,7 @@ NvimTreeBookmark ============================================================================== - 7. EVENTS *nvim-tree-events* + 8. EVENTS *nvim-tree-events* |nvim_tree_events| @@ -1153,121 +1245,77 @@ nvim-tree will dispatch events whenever an action is made. These events can be subscribed to through handler functions. This allows for even further customization of nvim-tree. -A handler for an event is just a function which receives one argument - -the payload of the event. The payload is different for each event type. Refer +A handler for an event is just a function which receives one argument, the +payload of the event. The payload is different for each event type. Refer to |nvim_tree_registering_handlers| for more information. -< |nvim_tree_registering_handlers| -Handlers are registered by calling the `on_*` functions available in the -`require('nvim-tree.events')` module. See |nvim-tree.events|. +Handlers are registered by calling the `events.subscribe` function available in the +`require("nvim-tree.api")` module. +For example, registering a handler for when a node is renamed is done like this: +> + local api = require('nvim-tree.api') -For example, registering a handler for when a node is renamed is done like this: > - - local events = require('nvim-tree.events') - - events.on_node_renamed(function(data) + api.events.subscribe(Event.NodeRenamed, function(data) print("Node renamed from " .. data.old_name .. " to " .. data.new_name) end) +< -============================================================================== - 7.1 Lua module: nvim-tree.events *nvim-tree.events* +|nvim_tree_events_kind| + +You can access the event enum with: +> + local Event = require('nvim-tree.api').events.Event +< +Here is the list of available variant of this enum: - *nvim-tree.events.on_nvim_tree_ready()* -on_nvim_tree_ready({handler}) - Registers a handler for when NvimTree has been initialized. +- Event.Ready + When NvimTree has been initialized + • Note: Handler takes no parameter. - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function()`. +- Event.TreeOpen + • Note: Handler takes no parameter. - *nvim-tree.events.on_node_renamed()* -on_node_renamed({handler}) - Registers a handler for when a node is renamed. - • Note: A node can either be a file or a directory. +- Event.TreeClose + • Note: Handler takes no parameter. - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(payload)`. - payload: ~ +- Event.Resize - When NvimTree is resized. + handler parameters: ~ + size: `number` size of the view in columns. + +- Event.NodeRenamed + • Note: A node can either be a file or a directory. + handler parameters: ~ {old_name} `{string}` Absolute path to the old node location. {new_name} `{string}` Absolute path to the new node location. - *nvim-tree.events.on_file_created()* -on_file_created({handler}) - Registers a handler for when a file is created. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(payload)`. - payload: ~ +- Event.FileCreated + handler parameters: ~ {fname} `{string}` Absolute path to the created file - *nvim-tree.events.on_file_removed()* -on_file_removed({handler}) - Registers a handler for when a file is removed. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(payload)`. - payload: ~ +- Event.FileRemoved + handler parameters: ~ {fname} `{string}` Absolute path to the removed file. - *nvim-tree.events.on_folder_created()* -on_folder_created({handler}) - Registers a handler for when a folder is created. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(payload)`. - payload: ~ +- Event.FolderCreated + handler parameters: ~ {folder_name} `{string}` Absolute path to the created folder. - *nvim-tree.events.on_folder_removed()* -on_folder_removed({handler}) - Registers a handler for when a folder is removed. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(payload)`. - payload: ~ +- Event.FolderRemoved + handler parameters: ~ {folder_name} `{string}` Absolute path to the removed folder. - *nvim-tree.events.on_tree_open()* -on_tree_open({handler}) - Registers a handler for when NvimTree is opened. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function()`. - - *nvim-tree.events.on_tree_close()* -on_tree_close({handler}) - Registers a handler for when NvimTree is closed. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function()`. - - *nvim-tree.events.on_tree_resize()* -on_tree_resize({handler}) - Registers a handler for when NvimTree is resized. - - Parameters: ~ - {handler} `{function}` Handler function, with the - signature `function(size)`. - ============================================================================== - 8. BOOKMARKS *nvim-tree-bookmarks* + 9. BOOKMARKS *nvim-tree-bookmarks* You can toggle marks on files/folders with -`require("nvim-tree.marks").toggle_mark(node)` which is bound to `m` by +`require("nvim-tree.api").marks.toggle(node)` which is bound to `m` by default. To get the list of marked paths, you can call -`require("nvim-tree.marks").get_marks()`. This will return `{node}`. +`require("nvim-tree.api").marks.list()`. This will return `{node}`. *nvim-tree.bookmarks.navigation* @@ -1277,8 +1325,8 @@ want to focus the tree view each time we wish to switch to another mark. This requires binding bookmark navigation yourself. -- in your lua configuration -vim.keymap.set("n", "mn", require("nvim-tree.marks.navigation").next) -vim.keymap.set("n", "mp", require("nvim-tree.marks.navigation").prev) -vim.keymap.set("n", "ms", require("nvim-tree.marks.navigation").select) +vim.keymap.set("n", "mn", require("nvim-tree.api").marks.navigate.next) +vim.keymap.set("n", "mp", require("nvim-tree.api").marks.navigate.prev) +vim.keymap.set("n", "ms", require("nvim-tree.api").marks.navigate.select) vim:tw=78:ts=4:sw=4:et:ft=help:norl: diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua new file mode 100644 index 00000000000..e84f05430dd --- /dev/null +++ b/lua/nvim-tree/api.lua @@ -0,0 +1,112 @@ +local Api = { + tree = {}, + node = { navigate = { sibling = {}, git = {}, diagnostics = {} }, run = {}, open = {} }, + events = {}, + marks = { bulk = {}, navigate = {} }, + fs = { copy = {} }, + git = {}, + live_filter = {}, +} + +local function inject_node(f) + return function(node) + node = node or require("nvim-tree.lib").get_node_at_cursor() + f(node) + end +end + +Api.tree.open = require("nvim-tree").open +Api.tree.toggle = require("nvim-tree").toggle +Api.tree.close = require("nvim-tree.view").close +Api.tree.focus = require("nvim-tree").focus +Api.tree.reload = require("nvim-tree.actions.reloaders.reloaders").reload_explorer +Api.tree.change_root = require("nvim-tree").change_dir +Api.tree.change_root_to_parent = inject_node(require("nvim-tree.actions.root.dir-up").fn) +Api.tree.get_node_under_cursor = require("nvim-tree.lib").get_node_at_cursor +Api.tree.find_file = require("nvim-tree.actions.finders.find-file").fn +Api.tree.search_node = require("nvim-tree.actions.finders.search-node").fn +Api.tree.collapse_all = require("nvim-tree.actions.tree-modifiers.collapse-all").fn +Api.tree.expand_all = inject_node(require("nvim-tree.actions.tree-modifiers.expand-all").fn) +Api.tree.toggle_gitignore_filter = require("nvim-tree.actions.tree-modifiers.toggles").git_ignored +Api.tree.toggle_custom_filter = require("nvim-tree.actions.tree-modifiers.toggles").custom +Api.tree.toggle_hidden_filter = require("nvim-tree.actions.tree-modifiers.toggles").dotfiles +Api.tree.toggle_help = require("nvim-tree.actions.tree-modifiers.toggles").help + +Api.fs.create = inject_node(require("nvim-tree.actions.fs.create-file").fn) +Api.fs.remove = inject_node(require("nvim-tree.actions.fs.remove-file").fn) +Api.fs.trash = inject_node(require("nvim-tree.actions.fs.trash").fn) +Api.fs.rename = inject_node(require("nvim-tree.actions.fs.rename-file").fn(false)) +Api.fs.rename_sub = inject_node(require("nvim-tree.actions.fs.rename-file").fn(true)) +Api.fs.copy = inject_node(require("nvim-tree.actions.fs.copy-paste").copy) +Api.fs.cut = inject_node(require("nvim-tree.actions.fs.copy-paste").cut) +Api.fs.paste = inject_node(require("nvim-tree.actions.fs.copy-paste").paste) +Api.fs.print_clipboard = require("nvim-tree.actions.fs.copy-paste").print_clipboard +Api.fs.copy.absolute_path = inject_node(require("nvim-tree.actions.fs.copy-paste").copy_absolute_path) +Api.fs.copy.filename = inject_node(require("nvim-tree.actions.fs.copy-paste").copy_filename) +Api.fs.copy.relative_path = inject_node(require("nvim-tree.actions.fs.copy-paste").copy_path) + +local function edit(mode, node) + local path = node.absolute_path + if node.link_to and not node.nodes then + path = node.link_to + end + require("nvim-tree.actions.node.open-file").fn(mode, path) +end + +local function open_or_expand_or_dir_up(mode) + return function(node) + if node.name == ".." then + require("nvim-tree.actions.root.change-dir").fn ".." + elseif node.nodes then + require("nvim-tree.lib").expand_or_collapse(node) + else + edit(mode, node) + end + end +end + +local function open_preview(node) + if node.nodes or node.name == ".." then + return + end + + edit("preview", node) +end + +Api.node.open.edit = inject_node(open_or_expand_or_dir_up "edit") +Api.node.open.vertical = inject_node(open_or_expand_or_dir_up "vsplit") +Api.node.open.horizontal = inject_node(open_or_expand_or_dir_up "split") +Api.node.open.tab = inject_node(open_or_expand_or_dir_up "tabnew") +Api.node.open.preview = inject_node(open_preview) + +Api.node.show_info_popup = inject_node(require("nvim-tree.actions.node.file-popup").toggle_file_info) +Api.node.run.cmd = inject_node(require("nvim-tree.actions.node.run-command").run_file_command) +Api.node.run.system = inject_node(require("nvim-tree.actions.node.system-open").fn) +Api.node.navigate.sibling.next = inject_node(require("nvim-tree.actions.moves.sibling").fn "next") +Api.node.navigate.sibling.prev = inject_node(require("nvim-tree.actions.moves.sibling").fn "prev") +Api.node.navigate.sibling.first = inject_node(require("nvim-tree.actions.moves.sibling").fn "first") +Api.node.navigate.sibling.last = inject_node(require("nvim-tree.actions.moves.sibling").fn "last") +Api.node.navigate.parent = inject_node(require("nvim-tree.actions.moves.parent").fn(false)) +Api.node.navigate.parent_close = inject_node(require("nvim-tree.actions.moves.parent").fn(true)) +Api.node.navigate.git.next = inject_node(require("nvim-tree.actions.moves.item").fn("next", "git")) +Api.node.navigate.git.prev = inject_node(require("nvim-tree.actions.moves.item").fn("prev", "git")) +Api.node.navigate.diagnostics.next = inject_node(require("nvim-tree.actions.moves.item").fn("next", "diag")) +Api.node.navigate.diagnostics.prev = inject_node(require("nvim-tree.actions.moves.item").fn("prev", "diag")) + +Api.git.reload = require("nvim-tree.actions.reloaders.reloaders").reload_git + +Api.events.subscribe = require("nvim-tree.events").subscribe +Api.events.Event = require("nvim-tree.events").Event + +Api.live_filter.start = require("nvim-tree.live-filter").start_filtering +Api.live_filter.clear = require("nvim-tree.live-filter").clear_filter + +Api.marks.get = inject_node(require("nvim-tree.marks").get_mark) +Api.marks.list = require("nvim-tree.marks").get_marks +Api.marks.toggle = inject_node(require("nvim-tree.marks").toggle_mark) +Api.marks.bulk.move = require("nvim-tree.marks.bulk-move").bulk_move +Api.marks.navigate.next = require("nvim-tree.marks.navigation").next +Api.marks.navigate.prev = require("nvim-tree.marks.navigation").prev +Api.marks.navigate.select = require("nvim-tree.marks.navigation").select + +return Api diff --git a/lua/nvim-tree/events.lua b/lua/nvim-tree/events.lua index b5acfcf1177..89010b731b5 100644 --- a/lua/nvim-tree/events.lua +++ b/lua/nvim-tree/events.lua @@ -4,7 +4,7 @@ local M = {} local global_handlers = {} -local Event = { +M.Event = { Ready = "Ready", NodeRenamed = "NodeRenamed", TreeOpen = "TreeOpen", @@ -20,7 +20,7 @@ local function get_handlers(event_name) return global_handlers[event_name] or {} end -local function register_handler(event_name, handler) +function M.subscribe(event_name, handler) local handlers = get_handlers(event_name) table.insert(handlers, handler) global_handlers[event_name] = handlers @@ -37,107 +37,92 @@ end --@private function M._dispatch_ready() - dispatch(Event.Ready) + dispatch(M.Event.Ready) end --@private function M._dispatch_node_renamed(old_name, new_name) - dispatch(Event.NodeRenamed, { old_name = old_name, new_name = new_name }) + dispatch(M.Event.NodeRenamed, { old_name = old_name, new_name = new_name }) end --@private function M._dispatch_file_removed(fname) - dispatch(Event.FileRemoved, { fname = fname }) + dispatch(M.Event.FileRemoved, { fname = fname }) end --@private function M._dispatch_file_created(fname) - dispatch(Event.FileCreated, { fname = fname }) + dispatch(M.Event.FileCreated, { fname = fname }) end --@private function M._dispatch_folder_created(folder_name) - dispatch(Event.FolderCreated, { folder_name = folder_name }) + dispatch(M.Event.FolderCreated, { folder_name = folder_name }) end --@private function M._dispatch_folder_removed(folder_name) - dispatch(Event.FolderRemoved, { folder_name = folder_name }) + dispatch(M.Event.FolderRemoved, { folder_name = folder_name }) end --@private function M._dispatch_on_tree_open() - dispatch(Event.TreeOpen, nil) + dispatch(M.Event.TreeOpen, nil) end --@private function M._dispatch_on_tree_close() - dispatch(Event.TreeClose, nil) + dispatch(M.Event.TreeClose, nil) end --@private function M._dispatch_on_tree_resize(size) - dispatch(Event.Resize, size) + dispatch(M.Event.Resize, size) end ---Registers a handler for the Ready event. ---@param handler (function) Handler with the signature `function()` +--- @deprecated function M.on_nvim_tree_ready(handler) - register_handler(Event.Ready, handler) + M.subscribe(M.Event.Ready, handler) end ---Registers a handler for the NodeRenamed event. ---@param handler (function) Handler with the signature function(payload), where payload is a table containing: --- - old_name (string) Absolute path to the old node location. --- - new_name (string) Absolute path to the new node location. +--- @deprecated function M.on_node_renamed(handler) - register_handler(Event.NodeRenamed, handler) + M.subscribe(M.Event.NodeRenamed, handler) end ---Registers a handler for the FileCreated event. ---@param handler (function) Handler with the signature function(payload), where payload is a table containing: --- - fname (string) Absolute path to the created file. +--- @deprecated function M.on_file_created(handler) - register_handler(Event.FileCreated, handler) + M.subscribe(M.Event.FileCreated, handler) end ---Registers a handler for the FileRemoved event. ---@param handler (function) Handler with the signature function(payload), where payload is a table containing: --- - fname (string) Absolute path to the removed file. +--- @deprecated function M.on_file_removed(handler) - register_handler(Event.FileRemoved, handler) + M.subscribe(M.Event.FileRemoved, handler) end ---Registers a handler for the FolderCreated event. ---@param handler (function) Handler with the signature function(payload), where payload is a table containing: --- - folder_name (string) Absolute path to the created folder. +--- @deprecated function M.on_folder_created(handler) - register_handler(Event.FolderCreated, handler) + M.subscribe(M.Event.FolderCreated, handler) end ---Registers a handler for the FolderRemoved event. ---@param handler (function) Handler with the signature function(payload), where payload is a table containing: --- - folder_name (string) Absolute path to the removed folder. +--- @deprecated function M.on_folder_removed(handler) - register_handler(Event.FolderRemoved, handler) + M.subscribe(M.Event.FolderRemoved, handler) end ---Registers a handler for the TreeOpen event. ---@param handler (function) Handler with the signature function(payload) +--- @deprecated function M.on_tree_open(handler) - register_handler(Event.TreeOpen, handler) + M.subscribe(M.Event.TreeOpen, handler) end ---Registers a handler for the TreeClose event. ---@param handler (function) Handler with the signature function(payload) +--- @deprecated function M.on_tree_close(handler) - register_handler(Event.TreeClose, handler) + M.subscribe(M.Event.TreeClose, handler) end ---Registers a handler for the Resize event. ---@param handler (function) Handler with the signature function(size) +--- @deprecated function M.on_tree_resize(handler) - register_handler(Event.Resize, handler) + M.subscribe(M.Event.Resize, handler) end return M