Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,22 @@ read_globals = {
"C_Reputation", "C_SuperTrack", "C_TaxiMap", "C_Texture", "C_Timer",
"C_ToyBox", "C_VignetteInfo",

-- UI utility functions
"UIFrameFadeIn", "UIFrameFadeOut", "UIFrameFadeRemoveFrame",
"AchievementFrameCategories_SelectElementData",
"UnitPopup_ShowMenu", "BattlePetToolTip_ShowLink",
"GetUnitSpeed", "GetItemCooldown", "EJ_GetInstanceInfo",

-- Data types
"UiMapPoint",

-- Cross-addon references
"EasyFindDevDB",

-- Constants, Enums, Mixins
"Enum", "Settings", "BackdropTemplateMixin",
"SOUNDKIT", "UIDROPDOWNMENU_OPEN_MENU", "UISpecialFrames",
"FACTION_BAR_COLORS",
"LE_PET_JOURNAL_FILTER_COLLECTED", "LE_PET_JOURNAL_FILTER_NOT_COLLECTED",

-- Font objects
Expand Down
58 changes: 23 additions & 35 deletions Database.lua
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
local ADDON_NAME, ns = ...
local _, ns = ...

local Database = {}
ns.Database = Database

local Utils = ns.Utils
local pairs, ipairs, type = Utils.pairs, Utils.ipairs, Utils.type
local tinsert, tsort, tconcat = Utils.tinsert, Utils.tsort, Utils.tconcat
local ipairs = Utils.ipairs
local tsort, tconcat = Utils.tsort, Utils.tconcat
local sfind, slower, ssub = Utils.sfind, Utils.slower, Utils.ssub
local mmin, mmax, mabs = Utils.mmin, Utils.mmax, Utils.mabs
local unpack = Utils.unpack

local C_CurrencyInfo = C_CurrencyInfo
local wipe = wipe

-- Word split cache: avoids per-call gmatch + table creation in scoring hot path.
-- Key = lowercase string, value = array of words split on [%w']+.
Expand Down Expand Up @@ -373,9 +370,9 @@ function Database:PopulateDynamicReputations()

-- Collapse back any headers we expanded during scanning
for pass = 1, 50 do
local numFactions = C_Reputation.GetNumFactions()
local numFactionsPost = C_Reputation.GetNumFactions()
local didCollapse = false
for i = numFactions, 1, -1 do
for i = numFactionsPost, 1, -1 do
local factionData = C_Reputation.GetFactionDataByIndex(i)
if factionData and factionData.isHeader and headersWeExpanded[factionData.name] then
-- Check if header is expanded using both property names
Expand Down Expand Up @@ -436,8 +433,8 @@ function Database:PopulateDynamicMounts()
if not mountIDs then return end

for _, mountID in ipairs(mountIDs) do
local name, spellID, icon, isActive, isUsable, sourceType, isFavorite,
isFactionSpecific, faction, shouldHideOnChar, isCollected = C_MountJournal.GetMountInfoByID(mountID)
local name, spellID, icon, _, _, _, _,
_, _, shouldHideOnChar, isCollected = C_MountJournal.GetMountInfoByID(mountID)
if name and isCollected and not shouldHideOnChar then
uiSearchData[#uiSearchData + 1] = setmetatable({
name = name,
Expand Down Expand Up @@ -520,7 +517,7 @@ function Database:PopulateDynamicPets()

local seen = {}
for i = 1, numPets do
local petID, speciesID, owned, customName, level, favorite, isRevoked,
local petID, speciesID, owned, _, _, _, _,
speciesName, icon = C_PetJournal.GetPetInfoByIndex(i)
if speciesName and speciesName ~= "" and owned and not seen[speciesID] then
seen[speciesID] = true
Expand Down Expand Up @@ -1443,7 +1440,7 @@ function Database:BuildUIDatabase()
name = "Reset All Instances",
keywords = {"reset instances", "reset all instances", "instance reset", "dungeon reset"},
available = function()
local inInstance, instanceType = IsInInstance()
local inInstance = IsInInstance()
if inInstance then return false end
if IsInGroup() and not UnitIsGroupLeader("player") then return false end
return true
Expand Down Expand Up @@ -2051,25 +2048,20 @@ function Database:SearchUI(query, skipCategories)
local searchCount = #searchSet
for i = 1, searchCount do
local data = searchSet[i]
-- Skip entries whose category is filtered out (Mount/Toy items only)
if skipCategories and skipCategories[data.category] then
-- Filtered out by user preference, skip entirely
-- Skip entries that have an availability check that returns false
elseif data.available and not data.available() then
-- Not available in current context, skip
else
local nameLower = data.nameLower
local score = Database:ScoreName(nameLower, query, queryLen, queryWords)

-- Keyword matching (additive)
score = score + Database:ScoreKeywords(data.keywordsLower, query, queryLen, queryWords)

if score >= 30 then
results[#results + 1] = { data = data, score = score }
candidateIdx = candidateIdx + 1
prevCandidates[candidateIdx] = data
if not (skipCategories and skipCategories[data.category])
and not (data.available and not data.available()) then
local nameLower = data.nameLower
local score = Database:ScoreName(nameLower, query, queryLen, queryWords)

-- Keyword matching (additive)
score = score + Database:ScoreKeywords(data.keywordsLower, query, queryLen, queryWords)

if score >= 30 then
results[#results + 1] = { data = data, score = score }
candidateIdx = candidateIdx + 1
prevCandidates[candidateIdx] = data
end
end
end -- else (availability check)
end
-- Trim stale entries from previous search
for i = candidateIdx + 1, #prevCandidates do
Expand Down Expand Up @@ -2271,10 +2263,7 @@ function Database:BuildHierarchicalResults(results)
local child = node.children[childName]
local hasChildren = #child.childOrder > 0

-- Skip empty path nodes (no data and no content in descendants)
if not hasActualContent(child) then
-- Skip this entire branch
else
if hasActualContent(child) then
-- Check if this leaf node is actually a container in the database
-- (has children that didn't match the search query).
local isContainer = false
Expand Down Expand Up @@ -2314,7 +2303,6 @@ function Database:GetContainerChildren(containerData)
local prefix = {}
for _, p in ipairs(containerData.path) do prefix[#prefix + 1] = p end
prefix[#prefix + 1] = containerData.name
local prefixKey = tconcat(prefix, "\1")
local prefixLen = #prefix

local children = {}
Expand Down
15 changes: 4 additions & 11 deletions Highlight.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
local ADDON_NAME, ns = ...
local _, ns = ...

local Highlight = {}
ns.Highlight = Highlight

local Utils = ns.Utils
local GetButtonText = Utils.GetButtonText
local IsButtonSelected = Utils.IsButtonSelected
local SearchFrameTree = Utils.SearchFrameTree
local SearchFrameTreeFuzzy = Utils.SearchFrameTreeFuzzy
local GetAllFrameText = Utils.GetAllFrameText
local ScrollBoxScrollTo = Utils.ScrollBoxScrollTo
local ScrollBoxFindButton = Utils.ScrollBoxFindButton
local ClickButton = Utils.ClickButton
local select, ipairs, pairs = Utils.select, Utils.ipairs, Utils.pairs
local sfind, slower, sformat = Utils.sfind, Utils.slower, Utils.sformat
local mmin, mmax, mabs, mpi = Utils.mmin, Utils.mmax, Utils.mabs, Utils.mpi
local select, ipairs = Utils.select, Utils.ipairs
local sfind, slower = Utils.sfind, Utils.slower
local mmax, mpi = Utils.mmax, Utils.mpi
local pcall = Utils.pcall

local GOLD_COLOR = ns.GOLD_COLOR
Expand All @@ -25,9 +21,6 @@ local CreateFrame = CreateFrame
local C_Timer = C_Timer
local GetTime = GetTime
local UIParent = UIParent
local hooksecurefunc = hooksecurefunc
local wipe = wipe
local strsplit = strsplit

local HOVER_MIN_DISPLAY = 0.3 -- seconds the highlight must be visible before hover clears it

Expand Down
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Copyright (c) 2026. All rights reserved.

This software and associated files may not be copied, modified, merged,
published, distributed, sublicensed, or sold without prior written
permission from the copyright holder.

Use of this software is permitted only as distributed through official
channels (CurseForge, GitHub Releases).
44 changes: 13 additions & 31 deletions MapSearch.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local ADDON_NAME, ns = ...
local _, ns = ...

local MapSearch = {}
ns.MapSearch = MapSearch
Expand All @@ -7,8 +7,8 @@ local Utils = ns.Utils
local DebugPrint = Utils.DebugPrint
local pairs, ipairs, type, select = Utils.pairs, Utils.ipairs, Utils.type, Utils.select
local tinsert, tsort, tconcat, tremove = Utils.tinsert, Utils.tsort, Utils.tconcat, Utils.tremove
local sfind, slower, sformat = Utils.sfind, Utils.slower, Utils.sformat
local mmin, mmax, mabs, mpi, mfloor, msin = Utils.mmin, Utils.mmax, Utils.mabs, Utils.mpi, Utils.mfloor, math.sin
local sfind, slower = Utils.sfind, Utils.slower
local mmin, mmax, mpi = Utils.mmin, Utils.mmax, Utils.mpi
local pcall, tostring = Utils.pcall, Utils.tostring

local GOLD_COLOR = ns.GOLD_COLOR
Expand All @@ -27,15 +27,11 @@ local IsShiftKeyDown = IsShiftKeyDown
local IsMouseButtonDown = IsMouseButtonDown
local hooksecurefunc = hooksecurefunc
local wipe = wipe
local strsplit = strsplit

-- Cache C_* API functions at file scope to get unhooked copies
local GetMapInfo = C_Map.GetMapInfo
local GetMapGroupID = C_Map.GetMapGroupID
local GetMapGroupMembersInfo = C_Map.GetMapGroupMembersInfo
local GetMapChildrenInfo = C_Map.GetMapChildrenInfo
local GetBestMapForUnit = C_Map.GetBestMapForUnit
local GetPlayerMapPosition = C_Map.GetPlayerMapPosition
local GetMapInfoAtPosition = C_Map.GetMapInfoAtPosition
local SetUserWaypoint = C_Map.SetUserWaypoint
local GetAreaPOIForMap = C_AreaPoiInfo and C_AreaPoiInfo.GetAreaPOIForMap
Expand All @@ -44,7 +40,6 @@ local GetDelvesForMap = C_AreaPoiInfo and C_AreaPoiInfo.GetDelvesForMap
local GetVignettePosition = C_VignetteInfo and C_VignetteInfo.GetVignettePosition
local GetTaxiNodesForMap = C_TaxiMap and C_TaxiMap.GetTaxiNodesForMap
local GetDungeonEntrancesForMap = C_EncounterJournal and C_EncounterJournal.GetDungeonEntrancesForMap
local GetDungeonEntranceMapInfo = C_EncounterJournal and C_EncounterJournal.GetDungeonEntranceMapInfo
local HasUserWaypoint = C_Map.HasUserWaypoint
local ClearUserWaypoint = C_Map.ClearUserWaypoint
local GetUserWaypoint = C_Map.GetUserWaypoint
Expand Down Expand Up @@ -262,7 +257,7 @@ function ns.UpdateIndicator(parentFrame)
tex:SetTexCoord(0, 1, 0, 1)
end
-- Use directional override if set, otherwise use style default
local indicatorRotation = 0
local indicatorRotation
if parentFrame.indicatorDirection then
indicatorRotation = ns.GetDirectionalRotation(parentFrame.indicatorDirection)
elseif style.rotation then
Expand Down Expand Up @@ -329,7 +324,6 @@ local TEXT_WRAP_FRACTION = 0.85
local SCROLL_CENTER_FRACTION = 0.95
local highlightFrame
local indicatorFrame
local currentHighlightedPin
local waypointPin
local zoneHighlightFrame -- For highlighting zones on continent maps
local isGlobalSearch = false -- Tracks which search bar triggered the current search
Expand All @@ -354,7 +348,7 @@ local waypointController -- Invisible controller that drives OnUpdate

-- MINIMAP WAYPOINT TRACKER - perimeter glow (far) + ring/arrow (near)

local matan2, mcos, msin, msqrt = math.atan2, math.cos, math.sin, math.sqrt
local matan2, mcos, msin = math.atan2, math.cos, math.sin
local GetPlayerFacing = GetPlayerFacing
local UnitPosition = UnitPosition
local NEAR_RING_RADIUS = 28 -- pixels from minimap center to ring edge
Expand Down Expand Up @@ -1726,7 +1720,6 @@ function MapSearch:CreateSearchFrame()
globalSearchFrame:SetPoint("TOPRIGHT", WorldMapFrame.ScrollContainer, "BOTTOMRIGHT", 0, gYOff)
end

local WHITE8x8 = "Interface\\BUTTONS\\WHITE8x8"
ns.CreateSearchBorder(globalSearchFrame)
if (EasyFind.db.resultsTheme or "Classic") == "Retail" then
globalSearchFrame:SetBackdrop(nil)
Expand Down Expand Up @@ -2116,6 +2109,9 @@ function MapSearch:CreateSearchFrame()
navFrame:SetPropagateKeyboardInput(false)

local function HandleNavKeyDown(key)
if key == "LSHIFT" or key == "RSHIFT" or key == "LCTRL" or key == "RCTRL"
or key == "LALT" or key == "RALT" then return end

local eb = activeSearchFrame and activeSearchFrame.editBox
local dropdown = GetActiveDropdown()

Expand All @@ -2139,9 +2135,6 @@ function MapSearch:CreateSearchFrame()
end
elseif key == "ESCAPE" then
dropdown:Hide()
elseif key == "LSHIFT" or key == "RSHIFT" or key == "LCTRL" or key == "RCTRL"
or key == "LALT" or key == "RALT" then
-- stay in dropdown nav
end
return
end
Expand Down Expand Up @@ -2267,9 +2260,6 @@ function MapSearch:CreateSearchFrame()
if MapSearch.StopKeyRepeat then MapSearch.StopKeyRepeat() end
MapSearch:UpdateSelectionHighlight(true)
end
elseif key == "LSHIFT" or key == "RSHIFT" or key == "LCTRL" or key == "RCTRL"
or key == "LALT" or key == "RALT" then
-- Modifier keys alone: stay in nav mode
else
ClearToolbarFocus()
selectedResultIndex = 0
Expand Down Expand Up @@ -3027,14 +3017,12 @@ function MapSearch:GroupZonesByParent(zones)
return zone.parentName or ""
end

-- First pass: count how many zones share each full parent path
local pathCounts = {}
-- First pass: build path display and parent mapIDs
local pathDisplay = {}
local pathParentMapID = {}

for _, zone in ipairs(zones) do
local pathKey = getPathKey(zone)
pathCounts[pathKey] = (pathCounts[pathKey] or 0) + 1
if not pathDisplay[pathKey] then
pathDisplay[pathKey] = getPathDisplay(zone)
-- Get the last mapID in the path for navigation
Expand All @@ -3053,9 +3041,7 @@ function MapSearch:GroupZonesByParent(zones)
for _, zone in ipairs(zones) do
local pathKey = getPathKey(zone)

if processedPaths[pathKey] then
-- Already processed this path group, skip
else
if not processedPaths[pathKey] then
processedPaths[pathKey] = true

-- Collect all zones with this same parent path
Expand Down Expand Up @@ -3832,8 +3818,8 @@ function MapSearch:HighlightZoneOnMap(targetMapID, zoneName)
if cL then
local cX, cY = (cL + cR) / 2, (cT + cB) / 2
if cX > 0 and cX < 1 and cY > 0 and cY < 1 then
local resolved = GetMapInfoAtPosition(currentMapID, cX, cY)
if resolved and resolved.mapID == targetMapID then
local resolvedInfo = GetMapInfoAtPosition(currentMapID, cX, cY)
if resolvedInfo and resolvedInfo.mapID == targetMapID then
DebugPrint("[EasyFind] CASE 1b: Target visible on current map (containing zone)")
self.pendingZoneHighlight = targetMapID
C_Timer.After(0.05, function()
Expand Down Expand Up @@ -5174,7 +5160,6 @@ function MapSearch:GetPinInfo(pin)
-- Area POIs (boats, zeppelins, portals, etc) - but NOT quests
if pin.areaPoiInfo then
name = pin.areaPoiInfo.name or pin.areaPoiInfo.description
pinType = "areapoi"

local poiName = slower(name or "")
local poiDesc = slower(pin.areaPoiInfo.description or "")
Expand Down Expand Up @@ -5614,7 +5599,7 @@ function MapSearch:SearchPOIs(pois, query)
local seen = reuseSearchSeen
local duplicates = reuseSearchDuplicates

local matchedCategory, catScore, isExactCategoryMatch = self:GetCategoryMatch(query)
local matchedCategory = self:GetCategoryMatch(query)
local relatedCategories = matchedCategory and self:GetRelatedCategories(matchedCategory) or {}

-- First pass: name matches
Expand Down Expand Up @@ -6149,7 +6134,6 @@ function MapSearch:SelectResult(data)
-- Clear preview state so OnLeave doesn't undo the real selection
self._previewing = nil
self._savedPinState = nil
local sourceFrame = activeSearchFrame or searchFrame
self._suppressTextChanged = true
searchFrame.editBox:SetText("")
searchFrame.editBox:ClearFocus()
Expand Down Expand Up @@ -6521,7 +6505,6 @@ function MapSearch:HighlightPin(pin)
return
end

currentHighlightedPin = pin

-- Convert UI-unit sizes to canvas units
local userScale = EasyFind.db.iconScale or 0.8
Expand Down Expand Up @@ -6600,7 +6583,6 @@ function MapSearch:ClearHighlight()
end
end

currentHighlightedPin = nil
end

-- Resolve preview-able coordinates for a search result on the current map.
Expand Down
4 changes: 1 addition & 3 deletions Options.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local ADDON_NAME, ns = ...
local _, ns = ...

local Options = {}
ns.Options = Options
Expand All @@ -10,7 +10,6 @@ local tonumber, tostring = Utils.tonumber, Utils.tostring
local tinsert = Utils.tinsert
local IsMouseButtonDown = IsMouseButtonDown

local GOLD_COLOR = ns.GOLD_COLOR
local DEFAULT_OPACITY = ns.DEFAULT_OPACITY
local TOOLTIP_BORDER = ns.TOOLTIP_BORDER
local DARK_PANEL_BG = ns.DARK_PANEL_BG
Expand Down Expand Up @@ -1067,7 +1066,6 @@ function Options:Initialize()
.. "(Map Search) to open map zones in one click instead of highlighting them first."
)
-- Keybind buttons
local KEYBIND_TOP = -8 -- offset below shortcutText (added dynamically)
local KEYBIND_ROW_H = 28
local KEYBIND_BTN_W = 140

Expand Down
Loading
Loading