diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 2f840a4053f..37d04d78276 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -1264,4 +1264,16 @@ default. To get the list of marked paths, you can call `require("nvim-tree.marks").get_marks()`. This will return `{node}`. +*nvim-tree.bookmarks.navigation* + +Navigation for marks is not bound by default in nvim-tree because we don't +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:tw=78:ts=4:sw=4:et:ft=help:norl: diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 6831407c2fb..e259bb8971c 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -220,17 +220,6 @@ local function open_in_new_window(filename, mode, win_ids) lib.set_target_win() end -local function is_already_open(filename, win_ids) - for _, id in ipairs(win_ids) do - if filename == api.nvim_buf_get_name(api.nvim_win_get_buf(id)) then - api.nvim_set_current_win(id) - return true - end - end - - return false -end - local function is_already_loaded(filename) for _, buf_id in ipairs(api.nvim_list_bufs()) do if api.nvim_buf_is_loaded(buf_id) and filename == api.nvim_buf_get_name(buf_id) then @@ -258,7 +247,7 @@ function M.fn(mode, filename) local win_ids = api.nvim_tabpage_list_wins(tabpage) local buf_loaded = is_already_loaded(filename) - local found = is_already_open(filename, win_ids) + local found = utils.is_in_displayed_buffer(filename) if found and mode == "preview" then return end diff --git a/lua/nvim-tree/marks/navigation.lua b/lua/nvim-tree/marks/navigation.lua new file mode 100644 index 00000000000..a9b6a66907f --- /dev/null +++ b/lua/nvim-tree/marks/navigation.lua @@ -0,0 +1,93 @@ +local Iterator = require "nvim-tree.iterators.node-iterator" +local core = require "nvim-tree.core" +local Marks = require "nvim-tree.marks" +local open_file = require "nvim-tree.actions.node.open-file" +local utils = require "nvim-tree.utils" +local lib = require "nvim-tree.lib" + +local function get_nearest(node, where) + local first, prev, next, last = nil, nil, nil, nil + local found = false + + Iterator.builder(core.get_explorer().nodes) + :recursor(function(n) + return n.open and n.nodes + end) + :applier(function(n) + if n.absolute_path == node.absolute_path then + found = true + return + end + + if not Marks.get_mark(n) then + return + end + + last = n + first = first or n + + if found and not next then + next = n + end + + if not found then + prev = n + end + end) + :iterate() + + if not found then + return + end + + if where == "next" then + return next or first + else + return prev or last + end +end + +local function get(where, node) + if node then + return get_nearest(node, where) + end +end + +local function open_or_focus(node) + if node and not node.nodes and not utils.is_in_displayed_buffer(node.absolute_path) then + open_file.fn("edit", node.absolute_path) + elseif node then + utils.focus_file(node.absolute_path) + end +end + +local function navigate_to(where) + return function() + local node = lib.get_node_at_cursor() + local next = get(where, node) + open_or_focus(next) + end +end + +local M = {} + +M.next = navigate_to "next" +M.prev = navigate_to "prev" + +function M.select() + local list = vim.tbl_map(function(n) + return n.absolute_path + end, Marks.get_marks()) + + vim.ui.select(list, { + prompt = "Select a file to open or a folder to focus", + }, function(choice) + if not choice or choice == "" then + return + end + local node = Marks.get_mark { absolute_path = choice } + open_or_focus(node) + end) +end + +return M diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 08813359440..d33ba2b694f 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -335,4 +335,14 @@ function M.focus_file(path) require("nvim-tree.view").set_cursor { i + 1, 1 } end +function M.is_in_displayed_buffer(path) + for _, w in pairs(vim.api.nvim_tabpage_list_wins(0)) do + local b = vim.api.nvim_win_get_buf(w) + if vim.api.nvim_buf_get_name(b) == path then + return true + end + end + return false +end + return M