Table of Contents
Match colors in scripted triggers
A scripted trigger can require colors or text attributes in addition to text. The pattern finds candidate occurrences in text sent by the MUD. The style chain then checks the first displayed character of each occurrence.
For a saved trigger made in the Automations window, see Require a color or attribute.
Match text in one color
Calling a style chain with a pattern makes one style-qualified trigger condition:
import { createTrigger, echo, style } from "smudgy:core"; createTrigger(style.red(/^Danger:/), (matches) => { echo(`Bright-red warning: ${matches[0]}`); });
This trigger fires when an occurrence of ^Danger: begins in the bright ANSI red palette slot. The same words in another color do not qualify.
ANSI shorthand names mean the bright slot, as they do for styled output. Normal ANSI red uses style.fg({ color: “red”, bold: false }). For example, style.fg({ color: “red”, bold: false })(/^Warning:/) qualifies a warning that begins in normal red.
A string passed in parentheses is regex source. style.red(“^Danger:”) has the same pattern meaning as style.red(/^Danger:/). A style chain used as a tagged template still makes StyledText for echo. Parentheses qualify a text pattern; a constrained chain passed directly to createTrigger() is a style-only condition. The Automations reference describes ordinary regexes and the pattern tag.
Combine foreground, background, and attributes
Every part set on one chain must qualify. Anything left unset accepts any incoming value:
import { createTrigger, echo, style } from "smudgy:core"; const urgent = style .fg({ color: "yellow", bold: false }) .bgBlue .underline; createTrigger(urgent(/^A rune flares/), () => { echo("The underlined yellow-on-blue rune appeared."); });
This condition requires normal ANSI yellow foreground, bright ANSI blue background, and a single underline. It does not restrict bold, italic, or the other attributes. Later color setters replace earlier setters on the same channel.
The positive attribute requirements are bold, faint, italic, single or double underline, slow or fast blink, crossed out, and reverse. A predicate cannot require an attribute to be absent.
Match any run with a style
A constrained chain can stand alone where a trigger pattern normally goes:
import { createTrigger, echo, style } from "smudgy:core"; createTrigger(style.bold.red, () => { echo("The MUD sent a bold, bright-red run."); });
On a nonempty line, this searches for any nonempty run that is both bold and bright ANSI red. The rest of the line may use any style. On an empty line, it checks the style active at the line break. A bare style chain has no requirement and is rejected.
Three similar-looking empty expressions have different meanings:
import { style } from "smudgy:core"; style.red(""); // color-only StyleMatch style.red(new RegExp("")); // ordinary zero-width StyleMatch style.red``; // empty StyledText for output
The parenthesized empty string on a constrained chain is the explicit style-only sentinel and scans exactly like bare style.red. For either color-only form, matches[0] is “”; in a plaintext trigger body, $0 also expands to the empty string. By contrast, new RegExp(“”) has the source (?:), so it keeps ordinary zero-width regex behavior and can qualify only at a position with a displayed character. The empty tagged template remains output, not a trigger condition. Without a surviving color or positive attribute, style(“”) stays the ordinary inactive empty pattern rather than becoming match-all.
Express alternatives and exceptions
Entries in patterns are alternatives. Each entry carries its own style requirement. Entries in antiPatterns prevent the trigger from firing:
import { createTrigger, echo, style } from "smudgy:core"; createTrigger({ patterns: [ style.yellow(/^Warning:/), style.red(/^Danger:/), ], antiPatterns: [style.faint(/harmless/)], }, (matches) => { echo(`Action needed: ${matches[0]}`); });
Either bright-yellow Warning: or bright-red Danger: can start this trigger. The exception blocks it only when an occurrence of harmless begins with the faint attribute. A plain /harmless/ exception would block the text in every style.
The createTriggers() batch form uses the same leaves inside each definition. Every definition still needs its own script body.
Find the style the MUD sent
Screen appearance alone cannot distinguish an ANSI palette slot from an RGB value. A temporary plain trigger can print the style runs carried by a matching line:
import { createTrigger, line } from "smudgy:core"; createTrigger(/Warning:/, () => { console.log(line.styles); }, { name: "inspect-warning-style" });
Each entry reports its text range, foreground, background, and attributes. Several entries mean the line changed style. Compare the entry covering the pattern's first character with the intended condition, then remove the temporary trigger.
Match a color range
style.fg.range() and style.bg.range() describe an inclusive range of incoming RGB-backed colors. They take two RGB endpoint objects:
import { createTrigger, echo, pattern, style } from "smudgy:core"; const warmForeground = style.fg.range( { r: 220, g: 20, b: 60 }, { r: 255, g: 165, b: 0 }, ); createTrigger( warmForeground(pattern.contains`Warning: {message}`), ({ message }) => echo(`Warm-color warning: ${message}`), );
The endpoints define a region in hue, saturation, and value (HSV), not a blend of the two RGB colors. Hue moves forward around the color wheel from the first endpoint to the second. If From is near 350° and To is near 10°, the interval crosses 0° and selects a narrow band of reds. Reversing those endpoints selects the long route through most other hues. Saturation and value use the inclusive lower and upper endpoint values. An incoming gray has no meaningful hue, so only its saturation and value have to qualify; a gray endpoint cannot select an independent hue.
A range qualifies truecolor and xterm palette slots 16 through 255. It does not turn the 16 ANSI palette slots into theme RGB values. Choose an exact ANSI condition for those slots. Equal endpoints still select one HSV coordinate; style.fg({ r, g, b }) performs exact RGB matching.
A range chain is trigger-only. It cannot produce styled output or serve as a line-highlight option. Start a separate exact style chain when output needs a definite color.
Understand where the style is checked
The style belongs to the first displayed character of a matching occurrence. Suppose Warning: is plain and only dragon is red. style.red(/Warning: dragon/) does not qualify because the W is plain. style.red(/dragon/) does qualify.
Smudgy tries occurrences from left to right. If the first text occurrence has the wrong style and a later occurrence qualifies, captures come from the later occurrence. A match may cross color changes after its first character without changing the result.
Matching uses the style received from the MUD before the trigger handler edits the line. Foreground and background mean the terminal's stored channels before reverse-video presentation. A condition that also requires reverse uses the reverse attribute.
A bare style condition or parenthesized empty string on an empty line checks the style active at the line break. Any other decorated zero-width match must begin at a displayed character: ^ can qualify at the first character of a nonempty line, while an end-of-line $ or a position on an empty line has no character whose style can qualify.
Understand ANSI and RGB identity
Exact ANSI matching compares terminal palette slots. Exact RGB matching compares RGB values. Two colors that look alike under the current theme do not become the same condition.
The bold-as-bright preference affects ANSI foreground matching. When bold selects the bright palette, normal ANSI red carrying terminal bold can qualify for style.red. style.bold.red additionally requires the bold attribute. Background matching does not use this preference.
The output roles default, echo, output, and warn do not identify colors sent by the MUD and cannot become trigger conditions. Explicit negative attributes such as bold: false, underline: “none”, and blink: “none” are also rejected when a chain becomes a condition.
Combine prompts and raw patterns
Passing { prompt: true } to createTrigger() applies the same text-and-style rules to the current prompt as it arrives. The trigger can therefore run once on a prompt and again when that text becomes part of a completed line, following the existing prompt behavior.
rawPatterns inspect the original escape-bearing input. They remain alternatives to displayed patterns and cannot carry a style condition. A style-qualified antiPatterns entry can still veto a raw-positive match by inspecting the corresponding displayed line. Raw regexes remain useful for exact control sequences; terminal colors and attributes belong in style conditions.
Fix common errors
createTrigger()still requires a command string or function body after the condition.styleby itself is not a color-only condition because it sets no requirement.style(/text/)is valid and behaves like the plain pattern.- Apply every color and attribute before calling the chain with a pattern. Passing an existing style match into another style chain is an error.
- Decorate individual
patternsandantiPatternsentries. Passing the whole pattern object tostyle()is an error. - Styled values in
rawPatternsare rejected. Move the condition to a displayed pattern or exception. - A range chain is not styled output. Begin a new exact chain for
echoor a line edit.
Script-created triggers are rebuilt whenever scripts reload. They are not saved through userAutomations. Use the Automations window for a trigger that should be stored as profile data. See Automations for the complete signatures and types.
