fix(keymap): prevent Niri and Hyprland CPU-budget failures (1.3.4) (#135)

* fix(keymap): reduce Niri parser CPU usage

* test(keymap): cover Niri parser scan budget

* fix(keymap): keep Hyprland refreshes within CPU budget

* chore(keymap): bump release to 1.3.4
This commit is contained in:
blacku
2026-07-28 21:11:34 -04:00
committed by GitHub
parent c04fe989e4
commit 9c60991b0d
9 changed files with 449 additions and 102 deletions
+30 -15
View File
@@ -744,26 +744,41 @@ local function parseConfig(root, rootSource)
local currentBind = nil
local slashdashDepth = nil
local lineNumber = 0
local hiddenLines = sourceLines(source)
local hiddenCategory = nil
local hiddenCursor = 1
while hiddenCursor <= #hiddenLines do
local block, blockEnd, candidate = hiddenBlockAt(hiddenLines, hiddenCursor)
if candidate then
if block == nil then
warn("hidden_block_invalid:" .. path .. ":" .. tostring(hiddenCursor))
-- Hidden sentinels are uncommon. Avoid a second character-by-character
-- pass over every ordinary config: on large stock Niri configs that pass
-- alone can consume a substantial part of Luau's callback CPU budget.
if source:find("// Keymap hidden ", 1, true) ~= nil then
local hiddenLines = sourceLines(source)
local hiddenCategory = nil
local hiddenCursor = 1
while hiddenCursor <= #hiddenLines do
local block, blockEnd, candidate = hiddenBlockAt(hiddenLines, hiddenCursor)
if candidate then
if block == nil then
warn("hidden_block_invalid:" .. path .. ":" .. tostring(hiddenCursor))
else
hidden[#hidden + 1] = hiddenTarget(block, path, hiddenCursor, blockEnd, hiddenCategory)
end
hiddenCursor = blockEnd + 1
else
hidden[#hidden + 1] = hiddenTarget(block, path, hiddenCursor, blockEnd, hiddenCategory)
local _, comment = stripComments(hiddenLines[hiddenCursor], false)
local label = type(comment) == "string" and comment:match('^%s*#?%s*"([^\"]+)"%s*$') or nil
if label ~= nil and label ~= "" then hiddenCategory = label end
hiddenCursor = hiddenCursor + 1
end
hiddenCursor = blockEnd + 1
else
local _, comment = stripComments(hiddenLines[hiddenCursor], false)
local label = type(comment) == "string" and comment:match('^%s*#?%s*"([^\"]+)"%s*$') or nil
if label ~= nil and label ~= "" then hiddenCategory = label end
hiddenCursor = hiddenCursor + 1
end
end
-- Most split Niri setups also include theme, output, input, and window
-- rule files. Once hidden sentinels have been handled, a file without
-- either keyword cannot contribute binds or extend the include graph.
-- This cheap rejection keeps unrelated config files out of the parser's
-- character-level brace/comment scan.
if source:find("binds", 1, true) == nil and source:find("include", 1, true) == nil then
visiting[path] = nil
return
end
local function finishBind()
local action = contentBeforeOuterClose(table.concat(currentBind.parts, "\n"))
parseBind(