#2004 Build the whole macro line from the Tab menu - #2007
Merged
TimothyLuke merged 3 commits intoAug 23, 2026
Conversation
Tab in a macro block opened a flat list of spellbook spells and GSE
variables and pasted a name at the caret. It saved typing one word; the
author still wrote every command, bracket, conditional and reset= by
hand.
Tab now opens a line builder. The menu stays open while the line is
assembled, each pick lands in its canonical place -- command,
conditionals, reset=, spells -- whatever order they are picked in, and
entries that would produce an invalid line are greyed with a tooltip
saying why.
Undo Last / Boiler Plates / Macros / GSE Variables / Commands /
Conditionals / Reset / Spells / ; / , nil
Conditionals accumulate into one always-closed bracket group, rewritten
in place ([a] -> [a,b]), with same-family collapse (spec:1 + spec:2 ->
spec:1/2) and duplicate picks deduped; [] closes the run. Reset is
offered only on a /castsequence line, slash-collapses its values and
keeps a single number. ";" opens a fresh clause with its own conditionals
and reset=, and ", nil" is offered only at the end of a clause that has
its own reset= and ends with a spell. Macros and GSE Variables stay
mutually exclusive with macro text, in both directions.
Two things make it robust rather than clever:
* The text is the single source of truth. The clause state is
re-derived from the live text before every conditional and reset
pick, so picks that end a clause -- or the author typing between
picks -- cannot leave stale offsets behind. Every read decodes the
box first, so a repaint mid-build cannot shift offsets or blind a
gate, and edits splice via SetText at tracked offsets rather than
trusting the caret of an unfocused box.
* Nothing depends on the menu's lifecycle. Blizzard menus release and
re-acquire during submenu navigation, and MenuResponse.Refresh does
not re-run the root generator, so any pick that changes a gate closes
and reopens the menu instead. The menu is opened through the manager
with an explicit anchor on the macro box, so those reopens do not
walk it across the screen the way cursor anchoring did.
Editor.lua defers its focus-loss commit repaint while a session is live,
so it cannot recolour the box mid-build; it runs on the next real focus
loss once the menu is gone.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
luacheck reported 28 undefined globals in QoL.lua: the line builder reaches past MenuUtil (already allowed) to MenuResponse for its pick return values, and to Menu / MenuVariants / AnchorUtil for the anchored open, plus GameTooltip_AddNormalLine for the greyed entries' tooltips. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tabbing on a fresh block put the command on a second line: the pick asks rowBeforeCaret() whether the current row is empty, and on a new block that row is the "Need Stuff Here" placeholder -- text, so the command was prefixed with a newline. The splice then replaces the placeholder outright, leaving that newline stranded at the top of the block. The placeholder is not content, so report the row as empty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2004
Tab in a macro block opened a flat list of spellbook spells and GSE variables and pasted a name at the caret. It saved typing one word; the author still wrote every command, bracket, conditional and
reset=by hand — and that is where the mistakes are.Tab now opens a line builder. The menu stays open while the line is assembled, each pick lands in its canonical place — command > conditionals >
reset=> spells — whatever order they are picked in, and entries that would produce an invalid line are greyed with a tooltip saying why.[a]→[a,b]), with same-family collapse (spec:1+spec:2→spec:1/2) and duplicates deduped.[]closes the run ([stuff][], or/cast [])./castsequenceline; values slash-collapse and a single number is kept — a second numeric pick replaces it.;opens a fresh clause on the same command with its own conditionals and its ownreset=; offered only after a spell., nilonly at the end of a clause that has its ownreset=and already ends with a spell.reset=instead of duplicating them.Two things make it robust rather than clever:
The text is the single source of truth. Clause state is re-derived from the live text before every conditional and reset pick, so picks that end a clause — or the author typing between picks — cannot leave stale offsets behind. Every read decodes the box first, so a repaint mid-build cannot shift offsets or blind a gate, and edits splice via
SetTextat tracked offsets rather than trusting the caret of an unfocused box.Nothing depends on the menu's lifecycle. Blizzard menus release and re-acquire during submenu navigation, and
MenuResponse.Refreshdoes not re-run the root generator, so any pick that changes a gate closes and reopens the menu. The menu is opened through the manager with an explicit anchor on the macro box (MenuManagerMixin:OpenMenu, public via the proxy), so those reopens do not walk it across the screen the way cursor anchoring did — with a fallback to the cursor path if that API is absent.Editor.luacarries one change: the focus-loss commit repaint is deferred while a session is live, so it cannot recolour the box mid-build. It runs on the next real focus loss once the menu is gone.Testing
luac -pclean on all three files.;, second conditional into a;clause's group,reset=into the right clause, number replacement, slash collapse,[]across multi-group and already-closed lines).🤖 Generated with Claude Code