Skip to content
This repository was archived by the owner on Apr 17, 2025. It is now read-only.

Commit 0955adf

Browse files
author
Hinell
committed
feat(State): keep track of recently used item
* For global itemlist, most recently selected items is kept at `State.most_recent_item` * For itemgroup-relative selection, use `State.most_recent_igroups[id]`
1 parent 76f96aa commit 0955adf

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ require('legendary').setup({
385385
-- }
386386
-- })
387387
sort = {
388-
-- sort most recently used item to the top
388+
-- put most recently selected first, this works
389+
-- for both within global and item group lists
389390
most_recent_first = true,
390391
-- sort user-defined items before built-in items
391392
user_items_first = true,

lua/legendary/data/itemlist.lua

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,21 @@ function ItemList:filter(filters, context)
106106
end, 'Took %s ms to filter items in context.')
107107
end
108108

109+
---@class ItemListSortInplaceOpts
110+
---@field itemgroup string
111+
109112
---Sort the list *IN PLACE* according to config.
110113
---THIS MODIFIES THE LIST IN PLACE.
111-
function ItemList:sort_inplace()
114+
--- @param opts ItemListSortInplaceOpts
115+
function ItemList:sort_inplace(opts)
112116
-- inline require to avoid circular dependency
113117
local State = require('legendary.data.state')
114-
local opts = Config.sort
118+
vim.validate({
119+
itemgroup = { opts.itemgroup, 'string', true },
120+
})
121+
122+
-- Merge Config into local opts
123+
opts = vim.tbl_extend('keep', opts, Config.sort)
115124

116125
-- if no items have been added, and the most recent item has not changed,
117126
-- we're already sorted
@@ -179,8 +188,10 @@ function ItemList:sort_inplace()
179188
end
180189

181190
if opts.most_recent_first then
182-
if item1 == State.most_recent_item then
183-
return true
191+
if opts.itemgroup then
192+
return item1 == State.itemgroup_history[opts.itemgroup]
193+
else
194+
return item1 == State.most_recent_item
184195
end
185196
end
186197

lua/legendary/data/state.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ local ItemList = require('legendary.data.itemlist')
44
---@field items ItemList
55
---@field most_recent_item LegendaryItem|nil
66
---@field most_recent_filters LegendaryItemFilter[]|nil
7+
---@field itemgroup_history ItemList[]
78
local M = {}
89

910
M.items = ItemList:create()
1011
M.most_recent_item = nil
1112
M.most_recent_filters = nil
13+
M.itemgroup_history = {}
1214

1315
return M

lua/legendary/ui/init.lua

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,26 @@ local M = {}
2323
---@overload fun(opts:LegendaryFindOpts,context:LegendaryEditorContext)
2424
local function select_inner(opts, context, itemlist)
2525
opts = opts or {}
26+
27+
vim.validate({
28+
itemgroup = { opts.itemgroup, 'string', true },
29+
select_prompt = { opts.select_prompt, 'function', true },
30+
})
31+
2632
if itemlist then
27-
Log.trace('Relaunching select UI for an item group')
28-
else
2933
Log.trace('Launching select UI')
30-
end
31-
32-
-- if no itemlist passed
33-
if itemlist == nil then
34-
-- if an item group is specified, use that
34+
else
35+
Log.trace('Relaunching select UI for an item group')
36+
-- if no itemlist passed, try to use itemgroup
37+
-- if an item group id is specified, use that
3538
local itemgroup = State.items:get_item_group(opts.itemgroup)
3639
if itemgroup then
3740
itemlist = itemgroup.items
41+
else
42+
Log.error('Expected itemlist, got %s.\n %s', type(itemlist), vim.inspect(itemlist))
3843
end
3944
end
4045

41-
-- finally, use full item list if no other lists are specified
42-
itemlist = itemlist or State.items
43-
opts = opts or {}
44-
4546
local prompt = opts.select_prompt or Config.select_prompt
4647
if type(prompt) == 'function' then
4748
prompt = prompt()
@@ -51,7 +52,7 @@ local function select_inner(opts, context, itemlist)
5152
-- implementation of `sort_inplace` checks if
5253
-- sorting is actually needed and does nothing
5354
-- if it does not need to be sorted.
54-
itemlist:sort_inplace()
55+
itemlist:sort_inplace(opts)
5556

5657
local filters = opts.filters or {}
5758
if type(filters) ~= 'table' then
@@ -81,12 +82,23 @@ local function select_inner(opts, context, itemlist)
8182
return
8283
end
8384

85+
if opts.itemgroup then
86+
State.itemgroup_history[opts.itemgroup] = selected
87+
else
88+
State.most_recent_item = selected
89+
end
90+
8491
if Toolbox.is_itemgroup(selected) then
85-
return select_inner(opts, context, selected.items)
92+
local item_group_id = selected:id()
93+
94+
local opts_next = vim.tbl_extend('force', opts, {
95+
itemgroup = item_group_id,
96+
})
97+
98+
return select_inner(opts_next, context)
8699
end
87100

88101
Log.trace('Preparing to execute selected item')
89-
State.most_recent_item = selected
90102
Executor.exec_item(selected, context)
91103
end)
92104
end
@@ -96,7 +108,7 @@ end
96108
function M.select(opts)
97109
vim.cmd('doautocmd User LegendaryUiPre')
98110
local context = Executor.build_context()
99-
select_inner(opts, context)
111+
select_inner(opts, context, State.items)
100112
end
101113

102114
return M

0 commit comments

Comments
 (0)