diff --git a/lua/legendary/data/itemlist.lua b/lua/legendary/data/itemlist.lua index 70509cc3..0a29789b 100644 --- a/lua/legendary/data/itemlist.lua +++ b/lua/legendary/data/itemlist.lua @@ -108,10 +108,15 @@ end ---Sort the list *IN PLACE* according to config. ---THIS MODIFIES THE LIST IN PLACE. -function ItemList:sort_inplace() +function ItemList:sort_inplace(opts) -- inline require to avoid circular dependency local State = require('legendary.data.state') - local opts = Config.sort + vim.validate({ + itemgroup = { opts.itemgroup, 'string', true }, + }) + + -- Merge Config into local opts + opts = vim.tbl_extend('keep', opts, Config.sort) -- if no items have been added, and the most recent item has not changed, -- we're already sorted @@ -179,8 +184,13 @@ function ItemList:sort_inplace() end if opts.most_recent_first then - if item1 == State.most_recent_item then - return true + if opts.itemgroup then + local recentIGroup = item1 == State.most_recent_igroups[opts.itemgroup] + if recentIGroup then + return recentIGroup + end + else + return item1 == State.most_recent_item end end diff --git a/lua/legendary/data/state.lua b/lua/legendary/data/state.lua index 238f6b9c..c6084996 100644 --- a/lua/legendary/data/state.lua +++ b/lua/legendary/data/state.lua @@ -9,5 +9,7 @@ local M = {} M.items = ItemList:create() M.most_recent_item = nil M.most_recent_filters = nil +-- most recent per item group (added after v2.13.5) +M.most_recent_igroups = {} return M diff --git a/lua/legendary/ui/init.lua b/lua/legendary/ui/init.lua index 0b534196..b783a245 100644 --- a/lua/legendary/ui/init.lua +++ b/lua/legendary/ui/init.lua @@ -23,25 +23,26 @@ local M = {} ---@overload fun(opts:LegendaryFindOpts,context:LegendaryEditorContext) local function select_inner(opts, context, itemlist) opts = opts or {} + + vim.validate({ + itemgroup = { opts.itemgroup, 'string', true }, + select_prompt = { opts.select_prompt, 'function', true }, + }) + if itemlist then - Log.trace('Relaunching select UI for an item group') - else Log.trace('Launching select UI') - end - - -- if no itemlist passed - if itemlist == nil then - -- if an item group is specified, use that + else + Log.trace('Relaunching select UI for an item group') + -- if no itemlist passed, try to use itemgroup + -- if an item group id is specified, use that local itemgroup = State.items:get_item_group(opts.itemgroup) if itemgroup then itemlist = itemgroup.items + else + Log.error('Expected itemlist, got %s.\n %s', type(itemlist), vim.inspect(itemlist)) end end - -- finally, use full item list if no other lists are specified - itemlist = itemlist or State.items - opts = opts or {} - local prompt = opts.select_prompt or Config.select_prompt if type(prompt) == 'function' then prompt = prompt() @@ -51,7 +52,7 @@ local function select_inner(opts, context, itemlist) -- implementation of `sort_inplace` checks if -- sorting is actually needed and does nothing -- if it does not need to be sorted. - itemlist:sort_inplace() + itemlist:sort_inplace(opts) local filters = opts.filters or {} if type(filters) ~= 'table' then @@ -81,12 +82,21 @@ local function select_inner(opts, context, itemlist) return end + if opts.itemgroup then + State.most_recent_igroups[opts.itemgroup] = selected + else + State.most_recent_item = selected + end + if Toolbox.is_itemgroup(selected) then - return select_inner(opts, context, selected.items) + local items_group_id = selected:id() + local opts_next = vim.tbl_extend('force', opts, { + itemgroup = items_group_id, + }) + return select_inner(opts_next, context) end Log.trace('Preparing to execute selected item') - State.most_recent_item = selected Executor.exec_item(selected, context) end) end @@ -96,7 +106,7 @@ end function M.select(opts) vim.cmd('doautocmd User LegendaryUiPre') local context = Executor.build_context() - select_inner(opts, context) + select_inner(opts, context, State.items) end return M