From 51d262b488a91c9016aaefc7fd563cd945005b41 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 22 Dec 2024 14:23:47 +0800 Subject: [PATCH 1/6] Support Persist Bookmarks --- lua/nvim-tree/marks/init.lua | 77 +++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index c940f999983..0c00bcd3e35 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -10,6 +10,7 @@ local utils = require("nvim-tree.utils") local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") +local json = vim.json ---@class (exact) Marks: Class ---@field private explorer Explorer @@ -22,14 +23,6 @@ local Marks = Class:extend() ---@class (exact) MarksArgs ---@field explorer Explorer ----@protected ----@param args MarksArgs -function Marks:new(args) - self.explorer = args.explorer - - self.marks = {} -end - ---Clear all marks and reload if watchers disabled ---@private function Marks:clear_reload() @@ -46,22 +39,6 @@ function Marks:clear() self.explorer.renderer:draw() end ----@public ----@param node Node -function Marks:toggle(node) - if node.absolute_path == nil then - return - end - - if self:get(node) then - self.marks[node.absolute_path] = nil - else - self.marks[node.absolute_path] = node - end - - self.explorer.renderer:draw() -end - ---Return node if marked ---@public ---@param node Node @@ -243,6 +220,58 @@ function Marks:navigate_next() self:navigate(false) end +-- local json = vim.json + +local function save_bookmarks(marks) + local path = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" + local file = io.open(path, "w") + if file then + local data = {} + for path, _ in pairs(marks) do + table.insert(data, path) + end + file:write(vim.fn.json_encode(data)) + file:close() + end +end + +local function load_bookmarks() + local path = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" + local file = io.open(path, "r") + if file then + local content = file:read("*all") + file:close() + if content and content ~= "" then + local data = vim.fn.json_decode(content) + local marks = {} + for _, path in ipairs(data) do + marks[path] = true -- or reconstruct node if needed + end + return marks + end + end + return {} +end + +function Marks:new(args) + self.explorer = args.explorer + self.marks = load_bookmarks() or {} +end + +function Marks:toggle(node) + if node.absolute_path == nil then + return + end + + if self:get(node) then + self.marks[node.absolute_path] = nil + else + self.marks[node.absolute_path] = node + end + + save_bookmarks(self.marks) + self.explorer.renderer:draw() +end ---Prompts for selection of a marked node, sorted by absolute paths. ---A folder will be focused, a file will be opened. ---@public From 6ec9fc13ffcd22a4d456929b4b14c0fb4954e0f9 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 22 Dec 2024 14:44:44 +0800 Subject: [PATCH 2/6] Fix node new open error --- lua/nvim-tree/explorer/filters.lua | 4 +++- lua/nvim-tree/marks/init.lua | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/explorer/filters.lua b/lua/nvim-tree/explorer/filters.lua index 62230687e40..e9b3f2c7d0e 100644 --- a/lua/nvim-tree/explorer/filters.lua +++ b/lua/nvim-tree/explorer/filters.lua @@ -209,7 +209,9 @@ function Filters:prepare(project) local explorer = require("nvim-tree.core").get_explorer() if explorer then for _, node in pairs(explorer.marks:list()) do - status.bookmarks[node.absolute_path] = node.type + if type(node) == "table" then + status.bookmarks[node.absolute_path] = node.type + end end end diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 0c00bcd3e35..5f05d272fdc 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -223,8 +223,8 @@ end -- local json = vim.json local function save_bookmarks(marks) - local path = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" - local file = io.open(path, "w") + local storepath = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" + local file = io.open(storepath, "w") if file then local data = {} for path, _ in pairs(marks) do @@ -236,8 +236,8 @@ local function save_bookmarks(marks) end local function load_bookmarks() - local path = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" - local file = io.open(path, "r") + local storepath = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" + local file = io.open(storepath, "r") if file then local content = file:read("*all") file:close() From 318f0ba1cf84933037a5c87b3dd61aaf27c73d8a Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 22 Dec 2024 15:12:54 +0800 Subject: [PATCH 3/6] Fix filter marks index issue --- lua/nvim-tree/explorer/filters.lua | 6 ++---- lua/nvim-tree/marks/init.lua | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/explorer/filters.lua b/lua/nvim-tree/explorer/filters.lua index e9b3f2c7d0e..5518f31b43e 100644 --- a/lua/nvim-tree/explorer/filters.lua +++ b/lua/nvim-tree/explorer/filters.lua @@ -208,10 +208,8 @@ function Filters:prepare(project) local explorer = require("nvim-tree.core").get_explorer() if explorer then - for _, node in pairs(explorer.marks:list()) do - if type(node) == "table" then - status.bookmarks[node.absolute_path] = node.type - end + for key, node in pairs(explorer.marks.marks) do + status.bookmarks[key] = node end end diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 5f05d272fdc..930b4c85797 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -10,7 +10,6 @@ local utils = require("nvim-tree.utils") local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") -local json = vim.json ---@class (exact) Marks: Class ---@field private explorer Explorer @@ -220,7 +219,6 @@ function Marks:navigate_next() self:navigate(false) end --- local json = vim.json local function save_bookmarks(marks) local storepath = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" From 464930d333230a4d62b6be0445103744fe796a95 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 16 Feb 2025 17:37:32 +0800 Subject: [PATCH 4/6] Made saving/loading conditional on enable_persistence, --- lua/nvim-tree.lua | 6 +- lua/nvim-tree/marks/init.lua | 113 +++++++++++++++++++---------------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 7bf6891c131..a67aa0b91a8 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -511,7 +511,11 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS watcher = false, }, }, -} -- END_DEFAULT_OPTS + marks = { + enable_persistence = false, + save_path = nil, -- nil will default to stdpath("data") .. "/nvim-tree-bookmarks.json" + }, +}-- END_DEFAULT_OPTS local function merge_options(conf) return vim.tbl_deep_extend("force", DEFAULT_OPTS, conf or {}) diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 930b4c85797..3604d1e6f03 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -11,6 +11,49 @@ local utils = require("nvim-tree.utils") local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") +local function get_save_path(opts) + return opts.marks.save_path or (vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json") +end + +local function save_bookmarks(marks, opts) + if not opts.marks.enable_persistence then + return + end + + local storepath = get_save_path(opts) + local file = io.open(storepath, "w") + if file then + local data = {} + for path, _ in pairs(marks) do + table.insert(data, path) + end + print(storepath) + file:write(vim.json.encode(data)) + file:close() + end +end + +local function load_bookmarks(opts) + if not opts.marks.enable_persistence then + return {} + end + local storepath = get_save_path(opts) + local file = io.open(storepath, "r") + if file then + local content = file:read("*all") + file:close() + if content and content ~= "" then + local data = vim.json.decode(content) + local marks = {} + for _, path in ipairs(data) do + marks[path] = true -- or reconstruct node if needed + end + return marks + end + end + return {} +end + ---@class (exact) Marks: Class ---@field private explorer Explorer ---@field private marks table by absolute path @@ -22,6 +65,11 @@ local Marks = Class:extend() ---@class (exact) MarksArgs ---@field explorer Explorer +function Marks:new(args) + self.explorer = args.explorer + self.marks = load_bookmarks(self.explorer.opts) or {} +end + ---Clear all marks and reload if watchers disabled ---@private function Marks:clear_reload() @@ -38,6 +86,20 @@ function Marks:clear() self.explorer.renderer:draw() end +function Marks:toggle(node) + if node.absolute_path == nil then + return + end + + if self:get(node) then + self.marks[node.absolute_path] = nil + else + self.marks[node.absolute_path] = node + end + save_bookmarks(self.marks, self.explorer.opts) + self.explorer.renderer:draw() +end + ---Return node if marked ---@public ---@param node Node @@ -219,57 +281,6 @@ function Marks:navigate_next() self:navigate(false) end - -local function save_bookmarks(marks) - local storepath = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" - local file = io.open(storepath, "w") - if file then - local data = {} - for path, _ in pairs(marks) do - table.insert(data, path) - end - file:write(vim.fn.json_encode(data)) - file:close() - end -end - -local function load_bookmarks() - local storepath = vim.fn.stdpath("data") .. "/nvim-tree-bookmarks.json" - local file = io.open(storepath, "r") - if file then - local content = file:read("*all") - file:close() - if content and content ~= "" then - local data = vim.fn.json_decode(content) - local marks = {} - for _, path in ipairs(data) do - marks[path] = true -- or reconstruct node if needed - end - return marks - end - end - return {} -end - -function Marks:new(args) - self.explorer = args.explorer - self.marks = load_bookmarks() or {} -end - -function Marks:toggle(node) - if node.absolute_path == nil then - return - end - - if self:get(node) then - self.marks[node.absolute_path] = nil - else - self.marks[node.absolute_path] = node - end - - save_bookmarks(self.marks) - self.explorer.renderer:draw() -end ---Prompts for selection of a marked node, sorted by absolute paths. ---A folder will be focused, a file will be opened. ---@public From fbfa65b5bea21eb82bc2887b8f76e6c876a1f0d0 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 16 Feb 2025 17:42:40 +0800 Subject: [PATCH 5/6] add method comments --- lua/nvim-tree/marks/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 3604d1e6f03..9f86d706be9 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -65,6 +65,8 @@ local Marks = Class:extend() ---@class (exact) MarksArgs ---@field explorer Explorer +---@protected +---@param args MarksArgs function Marks:new(args) self.explorer = args.explorer self.marks = load_bookmarks(self.explorer.opts) or {} @@ -86,6 +88,8 @@ function Marks:clear() self.explorer.renderer:draw() end +---@public +---@param node Node function Marks:toggle(node) if node.absolute_path == nil then return From 69f5a6342476e22021c4184069d62c22654ee9e1 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 16 Feb 2025 17:57:02 +0800 Subject: [PATCH 6/6] Use a pcall to prevent an error being raised --- lua/nvim-tree/marks/init.lua | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index 9f86d706be9..3225d4d15fd 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -27,16 +27,12 @@ local function save_bookmarks(marks, opts) for path, _ in pairs(marks) do table.insert(data, path) end - print(storepath) file:write(vim.json.encode(data)) file:close() end end local function load_bookmarks(opts) - if not opts.marks.enable_persistence then - return {} - end local storepath = get_save_path(opts) local file = io.open(storepath, "r") if file then @@ -69,7 +65,15 @@ local Marks = Class:extend() ---@param args MarksArgs function Marks:new(args) self.explorer = args.explorer - self.marks = load_bookmarks(self.explorer.opts) or {} + self.marks = {} + if self.explorer.opts.marks.enable_persistence then + local ok, loaded_marks = pcall(load_bookmarks, self.explorer.opts) + if ok then + self.marks = loaded_marks + else + notify.warn("Failed to load bookmarks: " .. loaded_marks) + end + end end ---Clear all marks and reload if watchers disabled @@ -100,7 +104,13 @@ function Marks:toggle(node) else self.marks[node.absolute_path] = node end - save_bookmarks(self.marks, self.explorer.opts) + + if self.explorer.opts.marks.enable_persistence then + local ok, err = pcall(save_bookmarks, self.marks, self.explorer.opts) + if not ok then + notify.warn("Failed to save bookmarks: " .. err) + end + end self.explorer.renderer:draw() end