From d7b3509e1c0c0d67d2630d70562a56aca8f13f33 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 20 Mar 2022 13:54:13 +1100 Subject: [PATCH 1/4] #837 search subdirs --- lua/nvim-tree/actions/search-node.lua | 120 +++++++++++--------------- 1 file changed, 50 insertions(+), 70 deletions(-) diff --git a/lua/nvim-tree/actions/search-node.lua b/lua/nvim-tree/actions/search-node.lua index ee7129feb5e..b82e2d4273c 100644 --- a/lua/nvim-tree/actions/search-node.lua +++ b/lua/nvim-tree/actions/search-node.lua @@ -1,95 +1,75 @@ +local api = vim.api +local uv = vim.loop local utils = require "nvim-tree.utils" -local view = require "nvim-tree.view" -local renderer = require "nvim-tree.renderer" local core = require "nvim-tree.core" +local find_file = require("nvim-tree.actions.find-file").fn local M = {} -function M.fn() - if not core.get_explorer() then +local function search(dir, input_path) + local path, name, stat, handle, _ + + if not dir then return end - local input_path = vim.fn.input("Search node: ", "", "file") - utils.clear_prompt() - - local absolute_input_path = utils.path_join { - core.get_cwd(), - input_path, - } - - local function count_visible_nodes(nodes) - local visible_nodes = 0 - for _, node in ipairs(nodes) do - visible_nodes = visible_nodes + 1 - - if node.open and node.nodes then - visible_nodes = visible_nodes + count_visible_nodes(node.nodes) - end - end - - return visible_nodes + handle, _ = uv.fs_scandir(dir) + if not handle then + return end - local tree_altered = false - local found_something = false - - local function search_node(nodes) - local index = 0 + name, _ = uv.fs_scandir_next(handle) + while name do + path = dir .. "/" .. name - for _, node in ipairs(nodes) do - index = index + 1 - - if absolute_input_path == node.absolute_path then - found_something = true - - if node.nodes and not node.open then - node.open = true - core.get_explorer():expand(node) - tree_altered = true - end - - return index - end - - if node.nodes then - -- e.g. user searches for "/foo/bar.txt", than directory "/foo/bar" should not match with filename - local matches = utils.str_find(absolute_input_path, node.absolute_path .. "/") - - if matches then - found_something = true - - -- if node is not open -> open it - if not node.open then - node.open = true - core.get_explorer():expand(node) - tree_altered = true - end + stat, _ = uv.fs_stat(path) + if not stat then + break + end - return index + search_node(node.nodes) - end - end + if string.find(path, "/" .. input_path .. "$") then + return path + end - if node.open then - index = index + count_visible_nodes(node.nodes) + if stat.type == "directory" then + path = search(path, input_path) + if path then + return path end end - return index + name, _ = uv.fs_scandir_next(handle) end +end - local index = search_node(core.get_explorer().nodes) +function M.fn() + if not core.get_explorer() then + return + end + + -- temporarily set &path + local bufnr = api.nvim_get_current_buf() + local path_existed, path_opt = pcall(api.nvim_buf_get_option, bufnr, "path") + api.nvim_buf_set_option(bufnr, "path", core.get_cwd() .. "/**") - if tree_altered then - renderer.draw() + -- completes files/dirs under cwd + local input_path = vim.fn.input("Search: ", "", "file_in_path") + utils.clear_prompt() + + -- reset &path + if path_existed then + api.nvim_buf_set_option(bufnr, "path", path_opt) + else + api.nvim_buf_set_option(bufnr, "path", nil) end - if found_something and view.is_visible() then - if view.is_root_folder_visible() then - index = index + 1 - end + -- strip trailing slash + input_path = string.gsub(input_path, "/$", "") - view.set_cursor { index, 0 } + -- search under cwd + local found = search(core.get_cwd(), input_path) + if found then + find_file(found) end end From 3c68babaf99183d6c0eb7906b99f273efdfb5179 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 20 Mar 2022 15:21:02 +1100 Subject: [PATCH 2/4] #837 find-file resolves symlinks --- lua/nvim-tree/actions/find-file.lua | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lua/nvim-tree/actions/find-file.lua b/lua/nvim-tree/actions/find-file.lua index f88c8e2acba..3ed341efb16 100644 --- a/lua/nvim-tree/actions/find-file.lua +++ b/lua/nvim-tree/actions/find-file.lua @@ -1,3 +1,4 @@ +local uv = vim.loop local view = require "nvim-tree.view" local utils = require "nvim-tree.utils" local renderer = require "nvim-tree.renderer" @@ -13,17 +14,35 @@ function M.fn(fname) end running[fname] = true + -- always match against the real path + local fname_real = uv.fs_realpath(fname) + if not fname_real then + return + end + local i = view.is_root_folder_visible() and 1 or 0 local tree_altered = false local function iterate_nodes(nodes) for _, node in ipairs(nodes) do i = i + 1 - if node.absolute_path == fname then - return i + + local stat, _ = uv.fs_stat(node.absolute_path) + if not stat then + break + end + local real_path, _ = uv.fs_realpath(node.absolute_path) + if not real_path then + break end - local path_matches = node.nodes and vim.startswith(fname, node.absolute_path .. utils.path_separator) + -- match against node absolute and real, for the case of symlinks, which will differ + if node.absolute_path == fname_real or real_path == fname_real then + return i + end + local abs_match = vim.startswith(fname_real, node.absolute_path .. utils.path_separator) + local real_match = vim.startswith(fname_real, real_path .. utils.path_separator) + local path_matches = node.nodes and abs_match or real_match if path_matches then if not node.open then node.open = true From de625a1026c342e2c9ea400b33df394b486073c0 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 26 Mar 2022 12:01:34 +1100 Subject: [PATCH 3/4] #837 find-file match node.link_to and some more safety checks --- lua/nvim-tree/actions/find-file.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lua/nvim-tree/actions/find-file.lua b/lua/nvim-tree/actions/find-file.lua index 3ed341efb16..4aa81d0a622 100644 --- a/lua/nvim-tree/actions/find-file.lua +++ b/lua/nvim-tree/actions/find-file.lua @@ -8,6 +8,8 @@ local M = {} local running = {} +---Find a path in the tree, expand it and focus it +---@param fname string canonical path function M.fn(fname) if running[fname] or not core.get_explorer() then return @@ -27,22 +29,17 @@ function M.fn(fname) for _, node in ipairs(nodes) do i = i + 1 - local stat, _ = uv.fs_stat(node.absolute_path) - if not stat then - break - end - local real_path, _ = uv.fs_realpath(node.absolute_path) - if not real_path then + if not node.absolute_path or not uv.fs_stat(node.absolute_path) then break end - -- match against node absolute and real, for the case of symlinks, which will differ - if node.absolute_path == fname_real or real_path == fname_real then + -- match against node absolute and link, as symlinks themselves will differ + if node.absolute_path == fname_real or node.link_to == fname_real then return i end local abs_match = vim.startswith(fname_real, node.absolute_path .. utils.path_separator) - local real_match = vim.startswith(fname_real, real_path .. utils.path_separator) - local path_matches = node.nodes and abs_match or real_match + local link_match = node.link_to and vim.startswith(fname_real, node.link_to .. utils.path_separator) + local path_matches = node.nodes and (abs_match or link_match) if path_matches then if not node.open then node.open = true From 2c52f140fba421f259fcfa189a12314a35e75b91 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sat, 26 Mar 2022 12:06:53 +1100 Subject: [PATCH 4/4] #837 doc /nit --- lua/nvim-tree/actions/find-file.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/actions/find-file.lua b/lua/nvim-tree/actions/find-file.lua index 4aa81d0a622..fca8c921c1d 100644 --- a/lua/nvim-tree/actions/find-file.lua +++ b/lua/nvim-tree/actions/find-file.lua @@ -9,7 +9,7 @@ local M = {} local running = {} ---Find a path in the tree, expand it and focus it ----@param fname string canonical path +---@param fname string full path function M.fn(fname) if running[fname] or not core.get_explorer() then return