Handle punctuation in FilteredList filter matching (#2085)

* allow punctuation to be typed into a filter

and allow the filter to match keys with punctuation
develop
Myk 2022-04-11 18:22:31 -07:00 committed by GitHub
parent 4a383b1c84
commit e6299700bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 9 deletions

@ -70,6 +70,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- Added functions reverse-engineered from ambushing unit code: ``Units::isHidden``, ``Units::isFortControlled``, ``Units::getOuterContainerRef``, ``Items::getOuterContainerRef``
## Lua
- ``widgets.FilteredList`` now allows all punctuation to be typed into the filter and can match search keys that start with punctuation.
- ``widgets.ListBox``: minimum height of dialog is now calculated correctly when there are no items in the list (e.g. when a filter doesn't match anything)
- Lua wrappers for functions reverse-engineered from ambushing unit code: ``isHidden(unit)``, ``isFortControlled(unit)``, ``getOuterContainerRef(unit)``, ``getOuterContainerRef(item)``
- ``dwarfmode.enterSidebarMode()``: passing ``df.ui_sidebar_mode.DesignateMine`` now always results in you entering ``DesignateMine`` mode and not ``DesignateChopTrees``, even when you looking at the surface where the default designation mode is ``DesignateChopTrees``

@ -814,8 +814,13 @@ function FilteredList:setFilter(filter, pos)
local ok = true
local search_key = v.search_key or v.text
for _,key in ipairs(tokens) do
key = key:escape_pattern()
-- start matches at non-space or non-punctuation. this allows
-- punctuation itself to be matched if that is useful (e.g.
-- filenames or parameter names)
if key ~= '' and
not string.match(search_key, '%f[^%s%p\x00]'..key) then
not search_key:match('%f[^%p\x00]'..key) and
not search_key:match('%f[^%s\x00]'..key) then
ok = false
break
end
@ -839,15 +844,7 @@ function FilteredList:onFilterChange(text)
self:setFilter(text)
end
local bad_chars = {
['%'] = true, ['.'] = true, ['+'] = true, ['*'] = true,
['['] = true, [']'] = true, ['('] = true, [')'] = true,
}
function FilteredList:onFilterChar(char, text)
if bad_chars[char] then
return false
end
if char == ' ' then
return string.match(text, '%S$')
end