|
| 1 | +local core = {} -- circular dependency |
| 2 | +local lib = {} -- circular dependency |
| 3 | +local notify = require "nvim-tree.notify" |
| 4 | +local remove_file = {} -- circular dependency |
| 5 | +local rename_file = {} -- circular dependency |
| 6 | +local trash = {} -- circular dependency |
1 | 7 | local renderer = {} -- circular dependency
|
| 8 | +local utils = require "nvim-tree.utils" |
2 | 9 |
|
3 | 10 | ---@class Marks
|
4 |
| ----@field private marks Node[] |
| 11 | +---@field config table hydrated user opts.filters |
| 12 | +---@field private explorer Explorer |
| 13 | +---@field private marks table<string, Node> by absolute path |
5 | 14 | local Marks = {}
|
6 | 15 |
|
7 | 16 | ---@return Marks
|
8 |
| -function Marks:new() |
9 |
| - local o = {} |
| 17 | +---@param opts table user options |
| 18 | +---@param explorer Explorer |
| 19 | +function Marks:new(opts, explorer) |
| 20 | + local o = { |
| 21 | + explorer = explorer, |
| 22 | + config = { |
| 23 | + ui = opts.ui, |
| 24 | + filesystem_watchers = opts.filesystem_watchers, |
| 25 | + }, |
| 26 | + marks = {}, |
| 27 | + } |
| 28 | + |
10 | 29 | setmetatable(o, self)
|
11 | 30 | self.__index = self
|
12 |
| - |
13 |
| - o.marks = {} |
14 |
| - |
15 | 31 | return o
|
16 | 32 | end
|
17 | 33 |
|
| 34 | +---Clear all marks and reload if watchers disabled |
18 | 35 | ---@private
|
19 |
| ----@param node Node |
20 |
| -function Marks:add_mark(node) |
21 |
| - self.marks[node.absolute_path] = node |
22 |
| - |
23 |
| - renderer.draw() |
| 36 | +function Marks:clear_reload() |
| 37 | + self:clear() |
| 38 | + if not self.config.filesystem_watchers.enable then |
| 39 | + require("nvim-tree.actions.reloaders").reload_explorer() |
| 40 | + end |
24 | 41 | end
|
25 | 42 |
|
26 |
| ----@private |
27 |
| ----@param node Node |
28 |
| -function Marks:remove_mark(node) |
29 |
| - self.marks[node.absolute_path] = nil |
30 |
| - |
| 43 | +---Clear all marks and redraw |
| 44 | +---@public |
| 45 | +function Marks:clear() |
| 46 | + self.marks = {} |
31 | 47 | renderer.draw()
|
32 | 48 | end
|
33 | 49 |
|
| 50 | +---@public |
34 | 51 | ---@param node Node
|
35 |
| -function Marks:toggle_mark(node) |
| 52 | +function Marks:toggle(node) |
36 | 53 | if node.absolute_path == nil then
|
37 | 54 | return
|
38 | 55 | end
|
39 | 56 |
|
40 |
| - if self:get_mark(node) then |
41 |
| - self:remove_mark(node) |
| 57 | + if self:get(node) then |
| 58 | + self.marks[node.absolute_path] = nil |
42 | 59 | else
|
43 |
| - self:add_mark(node) |
| 60 | + self.marks[node.absolute_path] = node |
44 | 61 | end
|
45 | 62 |
|
46 | 63 | renderer.draw()
|
47 | 64 | end
|
48 | 65 |
|
49 |
| -function Marks:clear_marks() |
50 |
| - self.marks = {} |
51 |
| - |
52 |
| - renderer.draw() |
53 |
| -end |
54 |
| - |
| 66 | +---Return node if marked |
| 67 | +---@public |
55 | 68 | ---@param node Node
|
56 | 69 | ---@return Node|nil
|
57 |
| -function Marks:get_mark(node) |
| 70 | +function Marks:get(node) |
58 | 71 | return node and self.marks[node.absolute_path]
|
59 | 72 | end
|
60 | 73 |
|
| 74 | +---List marked nodes |
| 75 | +---@public |
61 | 76 | ---@return Node[]
|
62 |
| -function Marks:get_marks() |
| 77 | +function Marks:list() |
63 | 78 | local list = {}
|
64 | 79 | for _, node in pairs(self.marks) do
|
65 | 80 | table.insert(list, node)
|
66 | 81 | end
|
67 | 82 | return list
|
68 | 83 | end
|
69 | 84 |
|
70 |
| -function Marks.setup(opts) |
71 |
| - renderer = require "nvim-tree.renderer" |
| 85 | +---Delete marked; each removal will be optionally notified |
| 86 | +---@public |
| 87 | +function Marks:delete() |
| 88 | + if not next(self.marks) then |
| 89 | + notify.warn "No bookmarks to delete." |
| 90 | + return |
| 91 | + end |
72 | 92 |
|
73 |
| - require("nvim-tree.marks.bulk-delete").setup(opts) |
74 |
| - require("nvim-tree.marks.bulk-trash").setup(opts) |
75 |
| - require("nvim-tree.marks.bulk-move").setup(opts) |
| 93 | + local function execute() |
| 94 | + for _, node in pairs(self.marks) do |
| 95 | + remove_file.remove(node) |
| 96 | + end |
| 97 | + self:clear_reload() |
| 98 | + end |
| 99 | + |
| 100 | + if self.config.ui.confirm.remove then |
| 101 | + local prompt_select = "Remove bookmarked ?" |
| 102 | + local prompt_input = prompt_select .. " y/N: " |
| 103 | + lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_delete", function(item_short) |
| 104 | + utils.clear_prompt() |
| 105 | + if item_short == "y" then |
| 106 | + execute() |
| 107 | + end |
| 108 | + end) |
| 109 | + else |
| 110 | + execute() |
| 111 | + end |
| 112 | +end |
| 113 | + |
| 114 | +---Trash marked; each removal will be optionally notified |
| 115 | +---@public |
| 116 | +function Marks:trash() |
| 117 | + if not next(self.marks) then |
| 118 | + notify.warn "No bookmarks to trash." |
| 119 | + return |
| 120 | + end |
| 121 | + |
| 122 | + local function execute() |
| 123 | + for _, node in pairs(self.marks) do |
| 124 | + trash.remove(node) |
| 125 | + end |
| 126 | + self:clear_reload() |
| 127 | + end |
| 128 | + |
| 129 | + if self.config.ui.confirm.trash then |
| 130 | + local prompt_select = "Trash bookmarked ?" |
| 131 | + local prompt_input = prompt_select .. " y/N: " |
| 132 | + lib.prompt(prompt_input, prompt_select, { "", "y" }, { "No", "Yes" }, "nvimtree_bulk_trash", function(item_short) |
| 133 | + utils.clear_prompt() |
| 134 | + if item_short == "y" then |
| 135 | + execute() |
| 136 | + end |
| 137 | + end) |
| 138 | + else |
| 139 | + execute() |
| 140 | + end |
| 141 | +end |
| 142 | + |
| 143 | +---Move marked |
| 144 | +---@public |
| 145 | +function Marks:move() |
| 146 | + if not next(self.marks) then |
| 147 | + notify.warn "No bookmarks to move." |
| 148 | + return |
| 149 | + end |
| 150 | + |
| 151 | + local node_at_cursor = lib.get_node_at_cursor() |
| 152 | + local default_path = core.get_cwd() |
| 153 | + |
| 154 | + if node_at_cursor and node_at_cursor.type == "directory" then |
| 155 | + default_path = node_at_cursor.absolute_path |
| 156 | + elseif node_at_cursor and node_at_cursor.parent then |
| 157 | + default_path = node_at_cursor.parent.absolute_path |
| 158 | + end |
| 159 | + |
| 160 | + local input_opts = { |
| 161 | + prompt = "Move to: ", |
| 162 | + default = default_path, |
| 163 | + completion = "dir", |
| 164 | + } |
| 165 | + |
| 166 | + vim.ui.input(input_opts, function(location) |
| 167 | + utils.clear_prompt() |
| 168 | + if not location or location == "" then |
| 169 | + return |
| 170 | + end |
| 171 | + if vim.fn.filewritable(location) ~= 2 then |
| 172 | + notify.warn(location .. " is not writable, cannot move.") |
| 173 | + return |
| 174 | + end |
| 175 | + |
| 176 | + for _, node in pairs(self.marks) do |
| 177 | + local head = vim.fn.fnamemodify(node.absolute_path, ":t") |
| 178 | + local to = utils.path_join { location, head } |
| 179 | + rename_file.rename(node, to) |
| 180 | + end |
| 181 | + |
| 182 | + self:clear_reload() |
| 183 | + end) |
| 184 | +end |
| 185 | + |
| 186 | +function Marks.setup() |
| 187 | + core = require "nvim-tree.core" |
| 188 | + lib = require "nvim-tree.lib" |
| 189 | + remove_file = require "nvim-tree.actions.fs.remove-file" |
| 190 | + rename_file = require "nvim-tree.actions.fs.rename-file" |
| 191 | + renderer = require "nvim-tree.renderer" |
| 192 | + trash = require "nvim-tree.actions.fs.trash" |
76 | 193 | end
|
77 | 194 |
|
78 | 195 | return Marks
|
0 commit comments