From 5cb362e96989e05b6b43f38d61b17d7704518f43 Mon Sep 17 00:00:00 2001 From: siduck Date: Mon, 26 May 2025 16:43:04 +0530 Subject: [PATCH 1/4] feat: keybinds for nested menus #27 --- lua/menu/mappings.lua | 26 +++++++++++++++++++++++++- lua/menu/ui.lua | 25 ++----------------------- lua/menu/utils.lua | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/lua/menu/mappings.lua b/lua/menu/mappings.lua index 66cbe1c..4620041 100644 --- a/lua/menu/mappings.lua +++ b/lua/menu/mappings.lua @@ -2,11 +2,21 @@ local utils = require "menu.utils" local map = vim.keymap.set local state = require "menu.state" +local function item_index(tb, v) + tb = type(tb) == "string" and require("menus." .. tb) or tb + + for index, value in ipairs(tb) do + if value.name == v.name then + return index + end + end +end + local M = {} M.actions = function(items, buf) local tb = vim.tbl_filter(function(v) - return not v.rtxt_type and v.rtxt and v.cmd + return v.rtxt and v.cmd end, items) for _, v in ipairs(tb) do @@ -22,6 +32,20 @@ M.actions = function(items, buf) map("n", v.rtxt, action, { buffer = buf }) end + + local nested_menus = vim.tbl_filter(function(v) + return v.items + end, items) + + for _, v in ipairs(nested_menus) do + local action = function() + vim.api.nvim_win_set_cursor(0, { item_index(items, v), 0 }) + utils.toggle_nested_menu(v.items) + end + + local keybind = v.keybind or tostring(item_index(nested_menus, v)) + map("n", keybind, action, { buffer = buf }) + end end M.nav_win = function() diff --git a/lua/menu/ui.lua b/lua/menu/ui.lua index e9c6d20..1dddf8a 100644 --- a/lua/menu/ui.lua +++ b/lua/menu/ui.lua @@ -27,27 +27,6 @@ local format_title = function(buf, name, rtxt, hl, actions, title) return line end -local function toggle_nested_menu(items) - local right_bufs = utils.adjacent_bufs() - - if #right_bufs > 0 then - require("volt.utils").close { - bufs = right_bufs, - close_func = function(buf) - state.bufs[buf] = nil - - for i, val in ipairs(state.bufids) do - if val == buf then - table.remove(state.bufids, i) - end - end - end, - } - else - require("menu").open(items, { nested = true }) - end -end - return function(buf) local lines = {} local bufv = state.bufs[buf] @@ -60,14 +39,14 @@ return function(buf) local nested_menu = item.items if nested_menu then - item.rtxt = "" + item.rtxt = (item.keybind or "") .. " " end local actions = { hover = { id = hover_id, redraw = "items" }, click = function() if nested_menu then - toggle_nested_menu(nested_menu) + utils.toggle_nested_menu(nested_menu) return end diff --git a/lua/menu/utils.lua b/lua/menu/utils.lua index 991105b..3860b74 100644 --- a/lua/menu/utils.lua +++ b/lua/menu/utils.lua @@ -64,4 +64,25 @@ M.delete_old_menus = function() end end +M.toggle_nested_menu = function(items) + local right_bufs = M.adjacent_bufs() + + if #right_bufs > 0 then + require("volt.utils").close { + bufs = right_bufs, + close_func = function(buf) + state.bufs[buf] = nil + + for i, val in ipairs(state.bufids) do + if val == buf then + table.remove(state.bufids, i) + end + end + end, + } + else + require("menu").open(items, { nested = true }) + end +end + return M From 20914a5b91c13c55db0ae53dfeafcbe6e16a5c67 Mon Sep 17 00:00:00 2001 From: siduck Date: Mon, 26 May 2025 16:47:16 +0530 Subject: [PATCH 2/4] refactor: use vim.fn.index instead of custom function! --- lua/menu/mappings.lua | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/lua/menu/mappings.lua b/lua/menu/mappings.lua index 4620041..061bbed 100644 --- a/lua/menu/mappings.lua +++ b/lua/menu/mappings.lua @@ -2,16 +2,6 @@ local utils = require "menu.utils" local map = vim.keymap.set local state = require "menu.state" -local function item_index(tb, v) - tb = type(tb) == "string" and require("menus." .. tb) or tb - - for index, value in ipairs(tb) do - if value.name == v.name then - return index - end - end -end - local M = {} M.actions = function(items, buf) @@ -39,11 +29,11 @@ M.actions = function(items, buf) for _, v in ipairs(nested_menus) do local action = function() - vim.api.nvim_win_set_cursor(0, { item_index(items, v), 0 }) + vim.api.nvim_win_set_cursor(0, { vim.fn.index(items, v) + 1, 0 }) utils.toggle_nested_menu(v.items) end - local keybind = v.keybind or tostring(item_index(nested_menus, v)) + local keybind = v.keybind or tostring(vim.fn.index(nested_menus, v) + 1) map("n", keybind, action, { buffer = buf }) end end From 7c32ab601f7b4b7416546c96aa59f43f5d881ab8 Mon Sep 17 00:00:00 2001 From: siduck Date: Fri, 30 May 2025 12:39:58 +0530 Subject: [PATCH 3/4] fix: nested_menu not opening if another is opened --- lua/menu/init.lua | 3 ++- lua/menu/mappings.lua | 2 +- lua/menu/state.lua | 1 + lua/menu/ui.lua | 2 +- lua/menu/utils.lua | 8 +++++++- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lua/menu/init.lua b/lua/menu/init.lua index d141cdc..2a0a227 100644 --- a/lua/menu/init.lua +++ b/lua/menu/init.lua @@ -83,11 +83,12 @@ M.open = function(items, opts) local close_post = function() state.bufs = {} state.config = nil + state.nested_menu = "" if api.nvim_win_is_valid(state.old_data.win) then api.nvim_set_current_win(state.old_data.win) vim.schedule(function() - local cursor_line = math.max(1,state.old_data.cursor[1]) + local cursor_line = math.max(1, state.old_data.cursor[1]) local cursor_col = math.max(0, state.old_data.cursor[2]) api.nvim_win_set_cursor(state.old_data.win, { cursor_line, cursor_col }) diff --git a/lua/menu/mappings.lua b/lua/menu/mappings.lua index 061bbed..7fafe4a 100644 --- a/lua/menu/mappings.lua +++ b/lua/menu/mappings.lua @@ -30,7 +30,7 @@ M.actions = function(items, buf) for _, v in ipairs(nested_menus) do local action = function() vim.api.nvim_win_set_cursor(0, { vim.fn.index(items, v) + 1, 0 }) - utils.toggle_nested_menu(v.items) + utils.toggle_nested_menu(v.name, v.items) end local keybind = v.keybind or tostring(vim.fn.index(nested_menus, v) + 1) diff --git a/lua/menu/state.lua b/lua/menu/state.lua index 64438c2..da353f3 100644 --- a/lua/menu/state.lua +++ b/lua/menu/state.lua @@ -1,6 +1,7 @@ local M = { bufs = {}, bufids = {}, + nested_menu = '' } return M diff --git a/lua/menu/ui.lua b/lua/menu/ui.lua index 1dddf8a..7aa7df6 100644 --- a/lua/menu/ui.lua +++ b/lua/menu/ui.lua @@ -46,7 +46,7 @@ return function(buf) hover = { id = hover_id, redraw = "items" }, click = function() if nested_menu then - utils.toggle_nested_menu(nested_menu) + utils.toggle_nested_menu(item.name, nested_menu) return end diff --git a/lua/menu/utils.lua b/lua/menu/utils.lua index 3860b74..2bd9229 100644 --- a/lua/menu/utils.lua +++ b/lua/menu/utils.lua @@ -64,7 +64,7 @@ M.delete_old_menus = function() end end -M.toggle_nested_menu = function(items) +M.toggle_nested_menu = function(name, items) local right_bufs = M.adjacent_bufs() if #right_bufs > 0 then @@ -80,9 +80,15 @@ M.toggle_nested_menu = function(items) end end, } + + if name ~= state.nested_menu then + require("menu").open(items, { nested = true }) + end else require("menu").open(items, { nested = true }) end + + state.nested_menu = name == state.nested_menu and "" or name end return M From f0a7abb8eb1e1bfb128e8d07a658dee40ff6b999 Mon Sep 17 00:00:00 2001 From: siduck Date: Fri, 30 May 2025 21:13:46 +0530 Subject: [PATCH 4/4] rm support for numeric mappings for nested menus --- lua/menu/mappings.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lua/menu/mappings.lua b/lua/menu/mappings.lua index 7fafe4a..e538c7b 100644 --- a/lua/menu/mappings.lua +++ b/lua/menu/mappings.lua @@ -28,13 +28,12 @@ M.actions = function(items, buf) end, items) for _, v in ipairs(nested_menus) do - local action = function() - vim.api.nvim_win_set_cursor(0, { vim.fn.index(items, v) + 1, 0 }) - utils.toggle_nested_menu(v.name, v.items) + if v.keybind then + map("n", v.keybind, function() + vim.api.nvim_win_set_cursor(0, { vim.fn.index(items, v) + 1, 0 }) + utils.toggle_nested_menu(v.name, v.items) + end, { buffer = buf }) end - - local keybind = v.keybind or tostring(vim.fn.index(nested_menus, v) + 1) - map("n", keybind, action, { buffer = buf }) end end