Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lua/neo-tree/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ local config = {
["e"] = "toggle_auto_expand_width",
["q"] = "close_window",
["?"] = "show_help",
-- You can sort by command name with:
-- ["?"] = { "show_help", config = { sorter = function(a, b) return a.mapping.text < b.mapping.text end } },
-- The type of a and b are neotree.Help.Mapping
["<"] = "prev_source",
[">"] = "next_source",
},
Expand Down
3 changes: 2 additions & 1 deletion lua/neo-tree/sources/common/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,8 @@ end
M.show_help = function(state)
local title = state.config and state.config.title or nil
local prefix_key = state.config and state.config.prefix_key or nil
help.show(state, title, prefix_key)
local sorter = state.config and state.config.sorter or nil
help.show(state, title, prefix_key, sorter)
end

return M
67 changes: 46 additions & 21 deletions lua/neo-tree/sources/common/help.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local M = {}

---@param text string
---@param highlight string?
---@return NuiLine
local add_text = function(text, highlight)
local line = NuiLine()
line:append(text, highlight)
Expand All @@ -16,19 +17,19 @@ end
---@param state neotree.State
---@param prefix_key string?
local get_sub_keys = function(state, prefix_key)
local keys = utils.get_keys(state.resolved_mappings, true)
if prefix_key then
local len = prefix_key:len()
local sub_keys = {}
for _, key in ipairs(keys) do
if #key > len and key:sub(1, len) == prefix_key then
table.insert(sub_keys, key)
end
end
return sub_keys
else
local keys = utils.get_keys(state.resolved_mappings)
if not prefix_key then
return keys
end

local len = prefix_key:len()
local sub_keys = {}
for _, key in ipairs(keys) do
if #key > len and key:sub(1, len) == prefix_key then
table.insert(sub_keys, key)
end
end
return sub_keys
end

---@param key string
Expand All @@ -41,15 +42,28 @@ local function key_minus_prefix(key, prefix)
end
end

---@class neotree.Help.Mapping
---@field key string
---@field mapping neotree.State.ResolvedMapping

---@alias neotree.Help.Sorter fun(a: neotree.Help.Mapping, b: neotree.Help.Mapping):boolean

---@type neotree.Help.Sorter
local default_help_sort = function(a, b)
return a.key < b.key
end

---Shows a help screen for the mapped commands when will execute those commands
---when the corresponding key is pressed.
---@param state neotree.State state of the source.
---@param title string? if this is a sub-menu for a multi-key mapping, the title for the window.
---@param prefix_key string? if this is a sub-menu, the start of tehe multi-key mapping
M.show = function(state, title, prefix_key)
---@param sorter neotree.Help.Sorter?
M.show = function(state, title, prefix_key, sorter)
local tree_width = vim.api.nvim_win_get_width(state.winid)
local keys = get_sub_keys(state, prefix_key)

---@type NuiLine[]
local lines = { add_text("") }
lines[1] = add_text(" Press the corresponding key to execute the command.", "Comment")
lines[2] = add_text(" Press <Esc> to cancel.", "Comment")
Expand All @@ -60,19 +74,30 @@ M.show = function(state, title, prefix_key)
header:append("COMMAND", highlights.ROOT_NAME)
lines[4] = header
local max_width = #lines[1]:content()
---@type neotree.Help.Mapping[]
local maps = {}
for _, key in ipairs(keys) do
---@type neotree.State.ResolvedMapping
local value = state.resolved_mappings[key]
or { text = "<error mapping for key " .. key .. ">", handler = function() end }
local nline = NuiLine()
nline:append(string.format(" %14s", key_minus_prefix(key, prefix_key)), highlights.FILTER_TERM)
nline:append(" -> ", highlights.DIM_TEXT)
nline:append(value.text, highlights.NORMAL)
local line = nline:content()
maps[#maps + 1] = {
key = key,
mapping = state.resolved_mappings[key]
or { text = "<error mapping for key " .. key .. ">", handler = function() end },
}
end

table.sort(maps, sorter or default_help_sort)
for _, val in ipairs(maps) do
local nuiline = NuiLine()
nuiline:append(
string.format(" %14s", key_minus_prefix(val.key, prefix_key)),
highlights.FILTER_TERM
)
nuiline:append(" -> ", highlights.DIM_TEXT)
nuiline:append(val.mapping.text, highlights.NORMAL)
local line = nuiline:content()
if #line > max_width then
max_width = #line
end
table.insert(lines, nline)
lines[#lines + 1] = nuiline
end

local width = math.min(60, max_width + 1)
Expand Down
2 changes: 1 addition & 1 deletion lua/neo-tree/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ end

---Return the keys of a given table.
---@param tbl string[] The table to get the keys of.
---@param sorted boolean Whether to sort the keys.
---@param sorted boolean? Whether to sort the keys.
---@return string[] keys The keys of the table.
M.get_keys = function(tbl, sorted)
local keys = {}
Expand Down
Loading