Commit Graph
354 Commits
Author SHA1 Message Date
Daniel ImmsandCursor 564113e053 Add unit tests for parser reset, buffer scroll, ConPTY, and search (#5988)
* Add InputHandler unit tests for ISO-2022 charset mapping

InputHandler unit tests always used MockCharsetService, so regressions in
print()'s ASCII remapping, G0/G1 designation (ESC ( ) * +), and SO/SI
level switching were never caught at unit level.

Add an ISO-2022 character sets suite wired to real CharsetService and
BufferService that verifies DEC line drawing on G0 (ESC ( 0), G1 after
ESC ) 0 + SO, and charset/glevel restoration via ESC 7 / ESC 8 before
printing.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add BufferService.scroll unit tests for isUserScrolling

BufferService.scroll() adjusts ybase and ydisp differently depending on
whether the circular buffer is full and whether isUserScrolling is set,
but no unit test asserted those branches. InputHandler and other callers
use MockBufferService.scroll, which throws, so real scroll viewport logic
was only exercised indirectly.

Add BufferService.test.ts covering full-buffer scroll with the user
scrolled up (ydisp decrements), partial-buffer scroll while scrolled up
(ydisp unchanged), and full-buffer scroll at the viewport bottom
(ydisp tracks ybase).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add InputHandler unit tests for DECOM cursor positioning

CUP with DEC origin mode (DECOM) offsets rows by the scroll region top
and clamps within DECSTBM margins, but unit tests only toggled the mode
for save/restore. Playwright covered the combination; headless unit tests
did not.

Add a cursor positioning test matching the Playwright DECOM case: with
margins and origin on, CUP places the cursor relative to scrollTop, clamps
to the margin, and uses absolute rows when origin is off.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add WindowsMode unit tests for wrap heuristic edges

ConPTY does not set isWrapped on soft-wrapped lines; updateWindowsModeWrappedState
infers wrapping from the last cell of the previous row. Browser Terminal tests
exercise this only through full writes, with no direct coverage of the helper
or negative cases (trailing space or null).

Add WindowsMode.test.ts asserting isWrapped is set for a full non-space line,
cleared for trailing whitespace, and cleared when the previous line ends empty.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add OscParser.reset unit test for mid-payload abort

OscParser.reset() must call end(false) on active handlers when aborted
during PAYLOAD, but no test invoked reset() directly. EscapeSequenceParser
tests mock OSC, so production reset/cleanup was unverified at unit level.

Add a reset describe block asserting handlers receive END false after a
partial payload, then a subsequent OSC sequence completes normally.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add DcsParser.reset unit test for mid-payload abort

DcsParser.reset() must call unhook(false) on hooked handlers when aborted
mid-DCS, matching OscParser's end(false) cleanup. No DcsParser test called
reset() directly, leaving the abort path unverified at unit level.

Add a reset describe block asserting UNHOOK false after partial put, then a
subsequent DCS sequence completes with UNHOOK true.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add InputHandler print tests for grapheme joining

print() uses UnicodeService.shouldJoin to merge combining marks, but
InputHandler tests never exercised that path. The U+200B infinite-loop
regression test used mocks and had no assertions, so it would pass even
if print() misbehaved.

Add tests for e + combining acute in one parse and across two parses.
Strengthen the U+200B regression test to use BufferService and assert the
buffer does not grow spurious rows.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add CharsetService unit tests for glevel and designation

CharsetService only updates the active charset when setgCharset targets the
current glevel; most InputHandler tests use MockCharsetService instead. A
regression in setgLevel or inactive-slot designation would not be caught
without direct service tests.

Add CharsetService.test.ts covering inactive designation, setgLevel
activation, active-slot updates, and reset clearing state.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add reflowCursorLine unit tests for ConPTY resize behavior

reflowCursorLine lets resize reflow wrapped lines that contain the cursor
(needed when ConPTY does not). No test referenced the option or
reflowLargerGetLinesToRemove's cursor skip branch.

Add BufferReflow tests for skip vs reflow when the cursor is inside a
wrapped block, and Buffer.resize tests showing merge on widen only when
reflowCursorLine is enabled.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add EscapeSequenceParser reset test for async pause recovery

reset() sets ParserStackType.RESET so the next parse continues in GROUND
at chunkPos + 1 without resuming a paused async handler. Existing async
tests only verified reset lifts FAIL after improper continuation, not
mid-chunk recovery with trailing printable data.

Add a test that pauses on async CSI, calls reset(), then continues parsing
and asserts XY is printed once and the stack returns to NONE.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add Buffer.resize unit test for ConPTY row growth

When rows increase on Windows ConPTY, Buffer.resize appends lines without
decrementing ybase or ydisp so the viewport stays stable while ConPTY
repaints. Buffer tests covered the non-Windows scroll-up path but never
passed windowsPty into options.

Add a ConPTY row-growth test asserting ybase, ydisp, and line count when
windowsPty is configured.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add Buffer reflow test for ConPTY buildNumber threshold

Buffer disables reflow on ConPTY when buildNumber is below 21376, but no
unit test asserted that gate. Column shrink without reflow leaves wrapped
content on a single line instead of splitting across rows.

Add a test comparing shrink behavior at build 21375 versus 21376, plus
retain unwrap-on-widen coverage for supported ConPTY builds.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add ApcParser.reset unit test for mid-payload abort

ApcParser.reset() calls end(false) on active handlers when aborted mid-APC,
matching OscParser and DcsParser, but no ApcParser test invoked reset()
directly.

Add a reset describe block asserting END false after partial put and a
clean subsequent APC sequence.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add InputHandler unit test for REP with grapheme clusters

repeatPrecedingCharacter uses parser.precedingJoinState and reprints the
full cluster from the buffer, but only Playwright covered e + combining
acute with CSI b. A regression could break REP for joined sequences without
failing unit tests.

Add a print-suite test asserting CSI 2 b triples e + acute in one parse.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add InputHandler unit tests for REP no-op cases

repeatPrecedingCharacter returns early when parser.precedingJoinState is
zero, including after another escape sequence clears join state. Only the
positive grapheme REP case was unit tested.

Add tests for bare CSI b and for REP following SGR so regressions cannot
spuriously duplicate buffer content.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add DecorationManager unit test for wrapped search matches

DecorationManager splits matches across wrapped rows with per-segment x
and width, but only SearchEngine had unit coverage; decoration geometry
was left to Playwright.

Add DecorationManager.test.ts using a real Terminal, a wrapped-buffer
match from SearchEngine, and assertions on registerDecoration options
for both row segments.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add BufferService.scroll unit test for DECSTBM margins

When scrollTop is non-zero, scroll() shifts lines inside the margin with
shiftElements instead of pushing scrollback. Existing BufferService tests
only covered scrollTop === 0.

Add a test with margins on rows 1–3 that verifies rows outside the region
stay fixed and lines inside the region scroll correctly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add BufferService.scrollLines unit tests

scrollLines adjusts ydisp and toggles isUserScrolling for viewport
scrolling, but only scroll() had unit coverage. Regressions in the
user-scroll flag or ydisp clamping would affect the whole viewport.

Add tests for scrolling up, clamping at ydisp 0, and clearing
isUserScrolling when reaching the buffer bottom.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add DecorationManager overview ruler dedup unit test

Multiple highlight matches on the same buffer line should only register
one overview ruler marker; later matches on that line omit ruler options.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Assert overview ruler on each line of wrapped search match

Wrapped highlight decorations span two buffer lines; each segment
should register overview ruler options unlike same-line dedup.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 12:41:54 +00:00
Daniel ImmsandCursor 26e771d075 docs(common): fix grammar in Unicode and platform comments
Use "a Unicode" instead of "an Unicode" on IUnicodeService.register,
and "user's platform" instead of "users platform" above the platform
detection exports.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 15:28:36 +00:00
Daniel ImmsandCursor 5ef8001413 docs(common): fix activeVersion onChange JSDoc wording
The onChange event comment said "activate version changed" while the
property is activeVersion. Clarify that the event fires when the active
Unicode version changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 15:28:36 +00:00
Daniel Imms ddf2b7d091 Merge pull request #5969 from Tyriar/import-no-cycle-5897-2
Add oxlint import/no-cycle and break existing src/common cycles
2026-05-31 15:13:58 -07:00
Daniel ImmsandCursor 5684f95c8e Colocate circular list types in CircularList.ts
The import/no-cycle refactor had moved IInsertEvent, IDeleteEvent, and
ICircularList into Types.ts, with CircularList.ts re-exporting the event
types from there. That split the list abstraction from its implementation
and pulled Types into the circular-list dependency graph.

Define IInsertEvent, IDeleteEvent, and ICircularList in CircularList.ts
alongside the CircularList class. CircularList.ts now depends only on
Lifecycle and Event, not Types.ts.

Remove those definitions from Types.ts (and the unused Emitter import).

Update callers to import list types from CircularList:
- buffer/Types.ts (IBuffer.lines)
- DecorationService.ts (buffer line insert/delete handlers)
- browser TestUtils.test.ts (mock buffer lines)

Types.ts no longer imports or re-exports circular-list types, preserving
the acyclic Types -> buffer/CircularList boundary.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 14:37:01 -07:00
Daniel ImmsandCursor cd3dcc52b2 Colocate buffer types in buffer/Types.ts
The import/no-cycle refactor had moved IBuffer, IBufferSet, and related
cell/line types into src/common/Types.ts, with buffer/Types.ts only
re-exporting them. That inverted the natural module boundary and made
buffer code depend on the top-level types hub.

Define buffer-owned types in buffer/Types.ts instead:
- CharData, IExtendedAttrs, IAttributeData, ICellData, IBufferLine
- IMarker, IBuffer, IBufferSet, BufferIndex

Restore UnderlineStyle to buffer/Constants.ts (used by IExtendedAttrs)
and remove those definitions from Types.ts.

buffer/Types.ts imports only what it needs from outside the buffer layer:
ICircularList and ICharset from Types, IDisposable from Lifecycle,
IEvent from Event, and UnderlineStyle from Constants. Types.ts does not
import buffer/Types.ts, so the previous Types <-> buffer cycle stays broken.

Update imports across common, browser, headless, addons, and tests to use
common/buffer/Types for buffer types rather than common/Types.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 14:35:08 -07:00
Daniel ImmsandCursor 56a7195487 Add oxlint import/no-cycle and break existing src/common cycles
Enable oxlint's import/no-cycle rule (import plugin) so circular module
dependencies are caught in CI, similar to eslint-plugin-import/no-cycle
and biome no-import-cycles discussed in the issue.

Relocate shared types and dependencies to remove cycles under src/common:

- Types.ts: host IInsertEvent, IDeleteEvent, IParams, UnderlineStyle,
  IBuffer, and IBufferSet; drop imports from CircularList, buffer/Types,
  parser/Types, and Services
- CoreTerminal.ts: define and export ICoreTerminal
- ServiceRegistry.ts: define IServiceIdentifier (break Services registry loop)
- UnicodeService: stop constructing UnicodeV6; CoreTerminal registers the
  default v6 provider after service creation
- buffer/Types.ts and parser/Types.ts: re-export moved types for callers

Fixes https://github.com/xtermjs/xterm.js/issues/5897

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 10:08:04 -07:00
Per Bothner 28eadddb79 Merge branch 'master' into decoration-test 2026-05-31 09:49:20 -07:00
Per Bothner 7c82c1a815 Update more DecorationService tests to use existing bufferService. 2026-05-31 09:48:19 -07:00
Daniel ImmsandCursor 17ad33dc3d Remove TypeScript path mappings in favor of relative imports
Fixes https://github.com/xtermjs/xterm.js/issues/5896

TypeScript path mappings for common/*, browser/*, and headless/*
were not rewritten in emitted JavaScript, which forced webpack resolve
aliases and NODE_PATH workarounds so runtime could resolve modules.
That added build complexity and broke tooling such as ESLint import/no-cycle.

Changes:
- Convert ~750 imports across src/, addons/, and test/ to relative paths
- Remove common/browser/headless paths and src catch-all mappings from tsconfigs
  (keep @xterm/addon-* demo and addon typings paths)
- Remove webpack resolve.alias for common, browser, headless, and vs
- Drop NODE_PATH from unit tests, benchmarks, and VS Code launch config
- Fix addon-image IIPImageStorage to import ./Types after removing catch-all *

Verified: npm run build, esbuild, package, package-headless
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 09:16:10 -07:00
Per Bothner f76c7aa8ea Avoid "fake markers" in DecorationService.test.ts.
Instead we use an actual Marker in an actual Buffer.
2026-05-30 14:07:03 -07:00
Daniel Imms 4bb9c06b5f Merge pull request #5953 from xtermjs/cursor/alt-click-for-mouse-events-5b17
Add altClickForMouseEvents option
2026-05-28 06:35:56 -07:00
Daniel Imms 2069176528 Fix lint 2026-05-27 19:58:21 -07:00
Cursor AgentandDaniel Imms f8cef535c7 Rename altClickForMouseEvents to mouseEventsRequireAlt
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-05-27 21:41:44 +00:00
Cursor AgentandDaniel Imms fbb2a9710f Add altClickForMouseEvents option for issue #5952
When enabled during mouse events mode, click/drag/move events require the alt
key while wheel events are unaffected. Selection stays enabled by default
and takes precedence over macOptionClickForcesSelection.

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-05-27 20:13:31 +00:00
Cursor AgentandDaniel Imms 41dfdba2cf Avoid spread when merging decoration line buckets
Replace existing.push(...bucket) with an indexed loop in
_mergeLineBucket to avoid intermediate array allocations during
buffer trim/insert/delete re-indexing.

Reuse _mergeLineBucket in _handleBufferLinesTrim for consistency.

Fixes #5941

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-05-27 18:18:13 +00:00
Cursor AgentandDaniel Imms 090b77f354 Replace custom clone utility with structuredClone
Remove common/Clone.ts and its tests. Use the native structuredClone API
for cloning default modes, options, and test fixtures.

Fixes #5911

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-05-27 15:41:00 +00:00
Daniel ImmsandCursor 4a0cb5ae6b Add MicrotaskTimer and use it for decoration line index sync
Introduce MicrotaskTimer as a TimeoutTimer-style helper that schedules a
single runner via queueMicrotask, with set and cancel but no cancelAndSet.

Use it in DecorationLineCache to batch insert/delete line-index updates after
marker line adjustments, replacing ad-hoc queueMicrotask scheduling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 09:52:53 -07:00
Daniel ImmsandCursor 9e72a4b6d3 Refactor decoration line index into DecorationLineCache
Extract the per-line lookup index from DecorationService into an exported
DecorationLineCache class in the same module, with DecorationService listed
first for readability.

Optimize buffer insert/delete maintenance to shift map keys in O(unique
indexed lines) instead of full re-indexing every affected decoration. Only
multi-line decorations that span the mutation point get a full re-index.

Add a direct DecorationLineCache unit test in DecorationService.test.ts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 09:47:11 -07:00
Daniel ImmsandCursor f484584b70 Speed up decoration cell lookup with a per-line index
Refs #5176.

forEachDecorationAtCell and getDecorationsAtCell previously scanned every
registered decoration on each call. With thousands of search highlights this
becomes O(total decorations) per cell and blocks rendering during viewport
refreshes.

Maintain a Map of buffer line -> decorations that cover that line. Multi-line
decorations are indexed on every line in their span, so mixed single-line and
multi-line workloads stay fast without falling back to a full scan.

Keep the index aligned with buffer mutations:
- Register and unregister decorations in the line buckets on add/dispose.
- On trim, shift line keys synchronously (before marker handlers run).
- On insert/delete, re-index affected decorations in a microtask after marker
  line updates are applied.

Inject IBufferService so line listeners follow the active buffer. Add unit
tests for trim, dispose-on-trim, insert, and dense single-line plus multi-line
lookup. Add DecorationService.benchmark.ts to measure sparse hits and
viewport-sized grid scans with 20k decorations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 09:30:25 -07:00
Daniel Imms 80debafa11 Convert a lot of top level consts to const enums 2026-05-02 06:44:25 -07:00
Daniel Imms 16b5da5c4c Fix assertion, bring back triggerMouseEvent tests 2026-03-11 11:03:17 +09:00
Daniel Imms 5f3a4646be Move non-state methods into MouseService
Fixes #5756
2026-03-11 10:49:55 +09:00
Daniel Imms d63445be94 Move custom mouse event handler into MouseStateService
Don't need to keep it in CoreBrowserTerminal
2026-03-11 10:36:35 +09:00
Daniel Imms 2331abe6bd Rename CoreMouseService to MouseStateService
Part of #5756
2026-03-11 10:31:57 +09:00
Daniel Imms eccbc60aa0 Migrate to tsgo
Fixes #5689
2026-02-13 06:59:24 -08:00
Daniel Imms d155bb6767 Move overviewRuler API under scrollbar
Fixes #5678
2026-02-05 09:14:58 -08:00
Daniel Imms 3a147e8e10 Merge pull request #5679 from Tyriar/scrollbar
Add scrollbar.showScrollbar
2026-02-05 07:28:45 -08:00
Daniel Imms c2db7d4c8a Add scrollbar.showScrollbar
Fixes #5676
2026-02-05 07:20:23 -08:00
Daniel Imms 2e776c0820 Use ILogService in TaskQueue 2026-02-05 06:40:50 -08:00
Daniel Imms 6ef653e589 Merge remote-tracking branch 'upstream/master' into de_vs 2026-02-03 07:05:50 -08:00
Daniel Imms 8a00898533 Implement blink rendering
Fixes #944
2026-02-03 03:46:21 -08:00
Daniel Imms 77695cb405 Make arrows configurable via API 2026-02-02 12:33:33 -08:00
Daniel Imms bab7db13db Remove cancelEvent/cancel function 2026-01-31 22:18:32 -08:00
Daniel Imms 9fca3d8ecf Merge branch 'master' into 5626 2026-01-31 09:12:15 -08:00
Daniel Imms b30d9c3533 Remove trace decorator and unused platform consts 2026-01-30 07:27:38 -08:00
Daniel Imms f80dbf3d03 Fix lint, split up namespace and interface 2026-01-30 06:21:15 -08:00
Daniel Imms e8d99d50a6 Remove vs dependency in common
Fixes #5631
2026-01-30 06:03:16 -08:00
Daniel Imms 6f87ae77a7 Support color scheme reporting
CSI ? 996 n
CSI ? 2031 h
CSI ? 2031 l

Fixes #5626
2026-01-27 10:19:26 -08:00
meganrogge a20ff565b0 add showCursorImmediately option 2026-01-13 10:36:35 -06:00
Daniel Imms ee47054678 Implement win32-input-mode
Fixes #2357
2026-01-10 05:27:03 -08:00
Daniel Imms 50b0f3d7ee Add vtExtensions.kittySgrBoldFaintControl 2026-01-10 04:31:36 -08:00
Daniel Imms c624a47780 Maintain different buffer flags, stack limit, tests 2026-01-09 11:59:50 -08:00
Daniel Imms 992da3cc4d Hook up vt extensions option 2026-01-09 07:07:10 -08:00
Daniel Imms 2265fa2ade Implement kitty keyboard protocol (CSI u)
Fixes #4198
2026-01-09 05:59:57 -08:00
Daniel Imms 857c4529cd Save cursor and restore more modes
Fixes #1526
2025-12-30 04:49:54 -08:00
Daniel Imms 9780b44115 Fix decorations with height > 1
Fixes #4855
2025-12-29 04:14:56 -08:00
Daniel Imms ca5a681363 Add quirks setting to control DECSET/DECRST 12
Fixes #5314
2025-12-28 07:34:55 -08:00
Daniel Imms 5d24866042 Move customGlyphs option into webgl addon
Fixes #5480
2025-12-24 08:35:06 -08:00
Daniel Imms 663b94011a Remove remnants of deprecated options
Following up on #5462
2025-12-23 08:24:35 -08:00