Skip to content
17 changes: 11 additions & 6 deletions src/Classes/ItemDBControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -137,38 +137,43 @@ function ItemDBClass:DoesItemMatchFilters(item)
return false
end
end
local searchStr = self.controls.search.buf:lower()
local searchStr = self.controls.search.buf:lower():gsub("[%-%.%+%[%]%$%^%%%?%*]", "%%%0")
if searchStr:match("%S") then
local found = false
local mode = self.controls.searchMode.selIndex
if mode == 1 or mode == 2 then
if item.name:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, item.name:lower(), searchStr)
if not err and match then
found = true
end
end
if mode == 1 or mode == 3 then
for _, line in pairs(item.enchantModLines) do
if line.line:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, line.line:lower(), searchStr)
if not err and match then
found = true
break
end
end
for _, line in pairs(item.implicitModLines) do
if line.line:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, line.line:lower(), searchStr)
if not err and match then
found = true
break
end
end
for _, line in pairs(item.explicitModLines) do
if line.line:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, line.line:lower(), searchStr)
if not err and match then
found = true
break
end
end
if not found then
searchStr = searchStr:gsub(" ","")
for i, mod in ipairs(item.baseModList) do
if mod.name:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, mod.name:lower(), searchStr)
if not err and match then
found = true
break
end
Expand Down
8 changes: 5 additions & 3 deletions src/Classes/NotableDBControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,20 @@ function NotableDBClass:DoesNotableMatchFilters(node)
return false
end

local searchStr = self.controls.search.buf:lower()
local searchStr = self.controls.search.buf:lower():gsub("[%-%.%+%[%]%$%^%%%?%*]", "%%%0")
if searchStr:match("%S") then
local found = false
local mode = self.controls.searchMode.selIndex
if mode == 1 or mode == 2 then
if node.dn:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, node.dn:lower(), searchStr)
if not err and match then
found = true
end
end
if mode == 1 or mode == 3 then
for _, line in ipairs(node.sd) do
if line:lower():find(searchStr, 1, true) then
local err, match = PCall(string.matchOrPattern, line:lower(), searchStr)
if not err and match then
found = true
break
end
Expand Down
4 changes: 2 additions & 2 deletions src/Classes/PassiveTreeView.lua
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents)
local searchWords = {}
for matchstring, v in search:gmatch('"([^"]*)"') do
searchWords[#searchWords+1] = matchstring
search = search:gsub('"'..matchstring..'"', "")
search = search:gsub('"'..matchstring:gsub("([%(%)])", "%%%1")..'"', "")
end
for matchstring, v in search:gmatch("(%S*)") do
if matchstring:match("%S") ~= nil then
Expand Down Expand Up @@ -805,7 +805,7 @@ function PassiveTreeViewClass:DoesNodeMatchSearchParams(node)

local function search(haystack, need)
for i=#need, 1, -1 do
if haystack:match(need[i]) then
if haystack:matchOrPattern(need[i]) then
table.remove(need, i)
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/Classes/TreeTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ local TreeTabClass = newClass("TreeTab", "ControlHost", function(self, build)
self.controls.export = new("ButtonControl", { "LEFT", self.controls.import, "RIGHT" }, 8, 0, 90, 20, "Export Tree", function()
self:OpenExportPopup()
end)
self.controls.treeSearch = new("EditControl", { "LEFT", self.controls.export, "RIGHT" }, 8, 0, main.portraitMode and 200 or 300, 20, "", "Search", "%c%(%)", 100, function(buf)
self.controls.treeSearch = new("EditControl", { "LEFT", self.controls.export, "RIGHT" }, 8, 0, main.portraitMode and 200 or 300, 20, "", "Search", "%c", 100, function(buf)
self.viewer.searchStr = buf
end)
self.controls.treeSearch.tooltipText = "Uses Lua pattern matching for complex searches"
Expand Down
43 changes: 43 additions & 0 deletions src/Modules/Common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -835,4 +835,47 @@ function urlDecode(str)
return s_char(tonumber(x, 16))
end
return str:gsub("%%(%x%x)", hexToChar)
end

function string:matchOrPattern(pattern)
local function generateOrPatterns(pattern)
local subGroups = {}
local index = 1
-- find and call generate patterns on all subGroups
for subGroup in pattern:gmatch("%b()") do
local open, close = pattern:find(subGroup, (subGroups[index] and subGroups[index].close or 1), true)
t_insert(subGroups, { open = open, close = close, patterns = generateOrPatterns(subGroup:sub(2,-2)) })
index = index + 1
end

-- generate complete patterns from the subGroup patterns
local generatedPatterns = { pattern:sub(1, (subGroups[1] and subGroups[1].open or 0) - 1) }
for i, subGroup in ipairs(subGroups) do
local regularNextString = pattern:sub(subGroup.close + 1, (subGroups[i+1] and subGroups[i+1].open or 0) - 1)
local tempPatterns = {}
for _, subPattern in ipairs(generatedPatterns) do
for subGroupPattern in pairs(subGroup.patterns) do
t_insert(tempPatterns, subPattern..subGroupPattern..regularNextString)
end
end
generatedPatterns = tempPatterns
end

-- apply | operators
local orPatterns = { }
for _, generatedPattern in ipairs(generatedPatterns) do
for orPattern in generatedPattern:gmatch("[^|]+") do
orPatterns[orPattern] = true -- store string as key to avoid duplicates.
end
end
return orPatterns
end

local orPatterns = generateOrPatterns(pattern)
for orPattern in pairs(orPatterns) do
if self:match(orPattern) then
return true
end
end
return false
end