From 6790cedc7aa43adbe65257fa680dda24a787b76b Mon Sep 17 00:00:00 2001 From: joaomendoncaa Date: Tue, 17 Sep 2024 12:54:12 +0100 Subject: [PATCH 1/2] feat(preview): add `title` as an option inside `toggle_preview`'s `config` table --- README.md | 11 ++++++- lua/neo-tree/defaults.lua | 6 +++- lua/neo-tree/sources/common/preview.lua | 7 ++-- lua/neo-tree/utils/init.lua | 43 +++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3ade0996..bbf60ed6 100644 --- a/README.md +++ b/README.md @@ -714,7 +714,14 @@ an existing split by configuring the command like this: require("neo-tree").setup({ window = { mappings = { - ["P"] = { "toggle_preview", config = { use_float = false, use_image_nvim = true } }, + ["P"] = { + "toggle_preview", + config = { + use_float = false, + use_image_nvim = true, + title = 'Neo-tree Preview', + }, + }, } } }) @@ -724,6 +731,8 @@ Anything that causes Neo-tree to lose focus will end preview mode. When `use_float = false`, the window that was taken over by preview mode will revert back to whatever was shown in that window before preview mode began. +You can choose a custom title for the floating window by setting the `title` option in its config. + If you want to work with the floating preview mode window in autocmds or other custom code, the window will have the `neo-tree-preview` filetype. diff --git a/lua/neo-tree/defaults.lua b/lua/neo-tree/defaults.lua index cbd30c77..f7ba73d4 100644 --- a/lua/neo-tree/defaults.lua +++ b/lua/neo-tree/defaults.lua @@ -378,7 +378,11 @@ local config = { [""] = "open", -- [""] = { "open", config = { expand_nested_files = true } }, -- expand nested file takes precedence [""] = "cancel", -- close preview or floating neo-tree window - ["P"] = { "toggle_preview", config = { use_float = true, use_image_nvim = false } }, + ["P"] = { "toggle_preview", config = { + use_float = true, + use_image_nvim = false, + title = "Neo-tree Preview", -- You can define a custom title for the preview floating window. + } }, [""] = { "scroll_preview", config = {direction = -10} }, [""] = { "scroll_preview", config = {direction = 10} }, ["l"] = "focus_preview", diff --git a/lua/neo-tree/sources/common/preview.lua b/lua/neo-tree/sources/common/preview.lua index 153cd888..831a9e01 100644 --- a/lua/neo-tree/sources/common/preview.lua +++ b/lua/neo-tree/sources/common/preview.lua @@ -12,6 +12,10 @@ local function create_floating_preview_window(state) local default_position = utils.resolve_config_option(state, "window.position", "left") state.current_position = state.current_position or default_position + local toggle_preview_mapping, _ = + utils.table_find_by_value(state.window.mappings, "toggle_preview") + + local title = toggle_preview_mapping and toggle_preview_mapping.config.title or "Neo-tree Preview" local winwidth = vim.api.nvim_win_get_width(state.winid) local winheight = vim.api.nvim_win_get_height(state.winid) local height = vim.o.lines - 4 @@ -58,7 +62,7 @@ local function create_floating_preview_window(state) end local popups = require("neo-tree.ui.popups") - local options = popups.popup_options("Neo-tree Preview", width, { + local options = popups.popup_options(title, width, { ns_id = highlights.ns_id, size = { height = height, width = width }, relative = "editor", @@ -446,7 +450,6 @@ Preview.scroll = function(state) vim.cmd([[normal! ]] .. count .. input) end) end - end return Preview diff --git a/lua/neo-tree/utils/init.lua b/lua/neo-tree/utils/init.lua index 5ff54a0e..40e2bad7 100644 --- a/lua/neo-tree/utils/init.lua +++ b/lua/neo-tree/utils/init.lua @@ -1009,6 +1009,49 @@ M.table_merge = function(base_table, override_table) return table_merge_internal(merged_table, override_table) end +---Find a table containing a specific value in a nested table structure. +---@param tbl table The table to search. +---@param target_value any The value to search for. +---@param max_depth number? Maximum depth to search (default: 10). +---@param max_items number? Maximum number of items to check (default: 1000). +---@return table? parent_table The table containing the value, or nil if not found. +---@return string[]? path The path to the found value, or nil if not found. +M.table_find_by_value = function(tbl, target_value, max_depth, max_items) + max_depth = max_depth or 10 + max_items = max_items or 1000 + local items_checked = 0 + + local function search(t, depth, current_path) + items_checked = items_checked + 1 + + if items_checked > max_items then + return nil, nil + end + if depth > max_depth then + return nil, nil + end + if type(t) == "table" then + for k, v in pairs(t) do + if v == target_value then + return t, current_path + end + if type(v) == "table" then + local new_path = vim.deepcopy(current_path) + table.insert(new_path, k) + local found, path = search(v, depth + 1, new_path) + if found then + return found, path + end + end + end + end + return nil, nil + end + + local result, path = search(tbl, 0, {}) + return result, path +end + ---Evaluate the truthiness of a value, according to js/python rules. ---@param value any ---@return boolean From 71bad7a7534315ed3ac241f50ee1d4247528932f Mon Sep 17 00:00:00 2001 From: joaomendoncaa Date: Wed, 18 Sep 2024 23:23:59 +0100 Subject: [PATCH 2/2] chore(preview): tidy up util's `table_find_by_value` and some optimizations --- lua/neo-tree/sources/common/preview.lua | 3 +- lua/neo-tree/utils/init.lua | 60 +++++++++++++------------ 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/lua/neo-tree/sources/common/preview.lua b/lua/neo-tree/sources/common/preview.lua index 831a9e01..eba37a0c 100644 --- a/lua/neo-tree/sources/common/preview.lua +++ b/lua/neo-tree/sources/common/preview.lua @@ -12,8 +12,7 @@ local function create_floating_preview_window(state) local default_position = utils.resolve_config_option(state, "window.position", "left") state.current_position = state.current_position or default_position - local toggle_preview_mapping, _ = - utils.table_find_by_value(state.window.mappings, "toggle_preview") + local toggle_preview_mapping = utils.table_find_by_value(state.window.mappings, "toggle_preview") local title = toggle_preview_mapping and toggle_preview_mapping.config.title or "Neo-tree Preview" local winwidth = vim.api.nvim_win_get_width(state.winid) diff --git a/lua/neo-tree/utils/init.lua b/lua/neo-tree/utils/init.lua index 40e2bad7..1a43d672 100644 --- a/lua/neo-tree/utils/init.lua +++ b/lua/neo-tree/utils/init.lua @@ -1009,47 +1009,51 @@ M.table_merge = function(base_table, override_table) return table_merge_internal(merged_table, override_table) end ----Find a table containing a specific value in a nested table structure. +---Find the parent table to a target value inside a nested table structure. +--- ---@param tbl table The table to search. ---@param target_value any The value to search for. ----@param max_depth number? Maximum depth to search (default: 10). ----@param max_items number? Maximum number of items to check (default: 1000). +---@param max_depth number? Maximum depth to search (default: 5). +---@param max_items number? Maximum number of items to check (default: 555). ---@return table? parent_table The table containing the value, or nil if not found. ----@return string[]? path The path to the found value, or nil if not found. M.table_find_by_value = function(tbl, target_value, max_depth, max_items) - max_depth = max_depth or 10 - max_items = max_items or 1000 + max_depth = max_depth or 5 + max_items = max_items or 555 + + local stack = { { tbl, 0 } } local items_checked = 0 - local function search(t, depth, current_path) - items_checked = items_checked + 1 + while #stack > 0 and items_checked <= max_items do + local current, depth = unpack(table.remove(stack)) - if items_checked > max_items then - return nil, nil - end if depth > max_depth then - return nil, nil + goto continue end - if type(t) == "table" then - for k, v in pairs(t) do - if v == target_value then - return t, current_path - end - if type(v) == "table" then - local new_path = vim.deepcopy(current_path) - table.insert(new_path, k) - local found, path = search(v, depth + 1, new_path) - if found then - return found, path - end - end + + if type(current) ~= "table" then + goto continue + end + + for _, v in pairs(current) do + items_checked = items_checked + 1 + + if v == target_value then + return current + end + + if type(v) == "table" then + table.insert(stack, { v, depth + 1 }) + end + + if items_checked > max_items then + break end end - return nil, nil + + ::continue:: end - local result, path = search(tbl, 0, {}) - return result, path + return nil end ---Evaluate the truthiness of a value, according to js/python rules.