The escaping covers \ (backreference) and $ (interpolation), but the prxchange substitution uses `
This target hardcodes an internal SAS demo host (nextviya.emea.sas.com) and a demo user path (/Users/viyademo18/dc). It's referenced by the nextviya npm script in sas/package.json. Other targets already hardcode sas.4gl.io, so this follows the existing pattern, but confirm this internal host is intended to ship in the public repo.
Calling getFilteredComputeContexts() directly in the @for expression means Angular re-invokes the method on every change-detection cycle (it can't know the return value is stable). For a small list this is harmless, but the idiomatic and cheaper approach is to bind to a cached array property (e.g. update this.filteredComputeContexts inside ensureSelectedComputeContext() / onShowAllContextsChange() and iterate over that). This avoids a fresh filter allocation on every CD tick.
Subtle: substitutions run sequentially over columnNames, and substituteBoundedToken's output is fed back into the next column's pass. If a real column were named like a produced cell ref (e.g. a column literally named B1), an earlier substitution's output could be re-matched and re-substituted by this later pass. substituteBoundedToken's surrounding-blank requirement makes this unlikely in practice, and parseFormulaRule has the same ordering — flagging only as an accepted shared edge case.
Shared limitation (identical to parseFormulaRule.ts:53): this quoted-span regex doesn't handle doubled-quote escaping ("" inside a quoted string). A pasted value like ="say ""PRICE"" " would mis-segment and could expose PRICE to substitution. Not a regression since parseFormulaRule has the same pattern, but worth a shared follow-up if pasted formulas may contain escaped embedded quotes.
This paste listener is attached once in initSetup (which runs once per table load, not per edit session — so the comment's intent is correct), but there's no matching removeEventListener in ngOnDestroy. This matches the existing mousedown listener at line 3269 (same no-cleanup pattern), and since hot.rootElement is part of the component DOM that Angular tears down, the listener is GC'd with the node — so it's consistent rather than a leak. Worth addressing together with the mousedown listener if you ever do a cleanup pass.
editor.row === null is the weaker guard here — getActiveEditor() can return a finished-state editor whose row isn't reliably null across Handsontable versions. The load-bearing check is event.target !== editor.TEXTAREA (the editor's TEXTAREA only matches the paste target while a cell is actively being edited). Functionally safe as written (both are ANDed), but consider leading with the event.target !== editor.TEXTAREA check for clarity, since that's the one that actually distinguishes grid-level paste from in-editor paste.
Test Coverage
**Services: 22/60 (37%)