From ca004728498a71afd401cf6b8cdc949742b7ea0f Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Wed, 4 Feb 2026 23:06:15 -0800 Subject: allow filtering search results by type --- state.lua | 59 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 24 deletions(-) (limited to 'state.lua') diff --git a/state.lua b/state.lua index b5e07f5..f7f2234 100644 --- a/state.lua +++ b/state.lua @@ -37,6 +37,7 @@ function mt:push_menu(t) if menu.type == 'search' then menu.search_options = menu.options menu.search_text = menu.search_text or '' + menu.search_term = menu.search_term or '' menu.search_cursor = menu.search_cursor or #menu.search_text + 1 menu:update_search_matches() @@ -85,6 +86,8 @@ end function menu_mt:save_checkpoint() self.checkpoint = { search_text = self.search_text, + search_term = self.search_term, + search_filter = self.search_filter, cursor = self.cursor, view_top = self.view_top, } @@ -92,7 +95,8 @@ end function menu_mt:restore_checkpoint() local t = self.checkpoint - self:set_search_text(t.search_text) + self:set_search_text( + t.search_text, nil, t.search_term, t.search_filter) self.cursor = t.cursor self.view_top = t.view_top end @@ -201,47 +205,54 @@ function menu_mt:set_search_cursor(pos) return true end -function menu_mt:set_search_text(str, pos) +function menu_mt:set_search_text(str, pos, term, filter) self.search_text = str + self.search_term = term + self.search_filter = filter self:set_search_cursor(pos or self.search_cursor) self:update_search_matches() end function menu_mt:update_search_matches() - if #self.search_text == 0 then + if not self.search_filter and #self.search_term == 0 then self.options = self.search_options return end -- no utf8 :( - local case_sensitive = not not self.search_text:find('%u') + local case_sensitive = not not self.search_term:find('%u') local options = {} for _, v in ipairs(self.search_options) do - local matches + if not self.search_filter or self.search_filter(v) then + local matches - local name = v.name - if not case_sensitive then - name = name:lower() - end + local name = v.name + if not case_sensitive then + name = name:lower() + end - local i, j = 0, 0 - while true do - i, j = name:find(self.search_text, j + 1, true) - if not i then - break + local i, j = 0, 0 + while true do + i, j = name:find(self.search_term, j + 1, true) + -- j < i avoids infinite loop on empty term + if not i or j < i then + break + end + matches = matches or {} + matches[#matches+1] = {start = i, stop = j} end - matches = matches or {} - matches[#matches+1] = {start = i, stop = j} - end - if matches then - -- search options may contain dynamic data that is - -- updated on redraw. using a proxy table instead of - -- copying prevents potential updates on every change - -- of search text. - options[#options+1] = setmetatable( - {matches = matches}, {__index = v}) + if matches then + -- search options may contain dynamic data that + -- is updated on redraw. using a proxy table + -- instead of copying prevents potential + -- updates on every change of search text. + options[#options+1] = setmetatable( + {matches = matches}, {__index = v}) + elseif i then + options[#options+1] = v + end end end -- cgit v1.2.3-70-g09d2