restty 0.1.32 → 0.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13522,6 +13522,118 @@ function observeOscPromptState(state2, seq) {
13522
13522
  }
13523
13523
 
13524
13524
  // src/input/output/index.ts
13525
+ function normalizeCursorPosition(value) {
13526
+ if (!value)
13527
+ return null;
13528
+ const row = Number(value.row);
13529
+ const col = Number(value.col);
13530
+ if (!Number.isFinite(row) || !Number.isFinite(col))
13531
+ return null;
13532
+ return {
13533
+ row: Math.max(1, Math.floor(row)),
13534
+ col: Math.max(1, Math.floor(col))
13535
+ };
13536
+ }
13537
+ function resolveCursorStepParam(raw) {
13538
+ if (!raw)
13539
+ return 1;
13540
+ const parsed = Number(raw);
13541
+ if (!Number.isFinite(parsed) || parsed <= 0)
13542
+ return 1;
13543
+ return Math.floor(parsed);
13544
+ }
13545
+ function resolveCursorSetParam(raw) {
13546
+ if (!raw)
13547
+ return 1;
13548
+ const parsed = Number(raw);
13549
+ if (!Number.isFinite(parsed))
13550
+ return 1;
13551
+ return Math.max(1, Math.floor(parsed));
13552
+ }
13553
+ function applyTextToCursorHint(cursor, text, cols) {
13554
+ for (const ch of text) {
13555
+ const code = ch.charCodeAt(0);
13556
+ if (code === 13) {
13557
+ cursor.col = 1;
13558
+ continue;
13559
+ }
13560
+ if (code === 10) {
13561
+ cursor.row += 1;
13562
+ continue;
13563
+ }
13564
+ if (code === 8) {
13565
+ cursor.col = Math.max(1, cursor.col - 1);
13566
+ continue;
13567
+ }
13568
+ if (code === 9) {
13569
+ const nextTabCol = Math.floor((cursor.col - 1) / 8) * 8 + 9;
13570
+ cursor.col = cols > 0 ? Math.min(cols, nextTabCol) : nextTabCol;
13571
+ continue;
13572
+ }
13573
+ if (code < 32 || code === 127)
13574
+ continue;
13575
+ cursor.col += 1;
13576
+ if (cols > 0 && cursor.col > cols) {
13577
+ cursor.col = 1;
13578
+ cursor.row += 1;
13579
+ }
13580
+ }
13581
+ }
13582
+ function applyCsiToCursorHint(cursor, seq, cols) {
13583
+ if (!seq.startsWith("\x1B[") || seq.length < 3)
13584
+ return;
13585
+ const final = seq[seq.length - 1];
13586
+ const body = seq.slice(2, -1);
13587
+ if (!/^[0-9;]*$/.test(body))
13588
+ return;
13589
+ const parts = body.length ? body.split(";") : [];
13590
+ switch (final) {
13591
+ case "A": {
13592
+ cursor.row = Math.max(1, cursor.row - resolveCursorStepParam(parts[0]));
13593
+ return;
13594
+ }
13595
+ case "B": {
13596
+ cursor.row += resolveCursorStepParam(parts[0]);
13597
+ return;
13598
+ }
13599
+ case "C": {
13600
+ const next = cursor.col + resolveCursorStepParam(parts[0]);
13601
+ cursor.col = cols > 0 ? Math.min(cols, next) : next;
13602
+ return;
13603
+ }
13604
+ case "D": {
13605
+ cursor.col = Math.max(1, cursor.col - resolveCursorStepParam(parts[0]));
13606
+ return;
13607
+ }
13608
+ case "E": {
13609
+ cursor.row += resolveCursorStepParam(parts[0]);
13610
+ cursor.col = 1;
13611
+ return;
13612
+ }
13613
+ case "F": {
13614
+ cursor.row = Math.max(1, cursor.row - resolveCursorStepParam(parts[0]));
13615
+ cursor.col = 1;
13616
+ return;
13617
+ }
13618
+ case "G": {
13619
+ const next = resolveCursorSetParam(parts[0]);
13620
+ cursor.col = cols > 0 ? Math.min(cols, next) : next;
13621
+ return;
13622
+ }
13623
+ case "H":
13624
+ case "f": {
13625
+ cursor.row = resolveCursorSetParam(parts[0]);
13626
+ const next = resolveCursorSetParam(parts[1]);
13627
+ cursor.col = cols > 0 ? Math.min(cols, next) : next;
13628
+ return;
13629
+ }
13630
+ case "d": {
13631
+ cursor.row = resolveCursorSetParam(parts[0]);
13632
+ return;
13633
+ }
13634
+ }
13635
+ }
13636
+
13525
13637
  class OutputFilter {
13526
13638
  remainder = "";
13527
13639
  getCursorPosition;
@@ -13538,6 +13650,7 @@ class OutputFilter {
13538
13650
  getDefaultColors;
13539
13651
  desktopNotificationHandler;
13540
13652
  promptState = createPromptState();
13653
+ cursorHint = null;
13541
13654
  constructor(options) {
13542
13655
  this.getCursorPosition = options.getCursorPosition;
13543
13656
  this.sendReply = options.sendReply;
@@ -13551,6 +13664,7 @@ class OutputFilter {
13551
13664
  }
13552
13665
  setCursorProvider(fn) {
13553
13666
  this.getCursorPosition = fn;
13667
+ this.cursorHint = null;
13554
13668
  }
13555
13669
  setReplySink(fn) {
13556
13670
  this.sendReply = fn;
@@ -13616,12 +13730,17 @@ class OutputFilter {
13616
13730
  return output;
13617
13731
  let data = this.remainder + output;
13618
13732
  this.remainder = "";
13733
+ const metricCols = this.getWindowMetrics?.()?.cols;
13734
+ const colsHint = Number.isFinite(metricCols) && Number(metricCols) > 1 ? Math.floor(Number(metricCols)) : 0;
13735
+ let trackedCursor = this.cursorHint ?? normalizeCursorPosition(this.getCursorPosition()) ?? { row: 1, col: 1 };
13736
+ const getReplyCursor = () => trackedCursor;
13619
13737
  let result = "";
13620
13738
  let i = 0;
13621
13739
  while (i < data.length) {
13622
13740
  const ch = data[i];
13623
13741
  if (ch !== "\x1B") {
13624
13742
  result += ch;
13743
+ applyTextToCursorHint(trackedCursor, ch, colsHint);
13625
13744
  i += 1;
13626
13745
  continue;
13627
13746
  }
@@ -13686,12 +13805,14 @@ class OutputFilter {
13686
13805
  }
13687
13806
  if (!handleCoreCsiSequence(seq, {
13688
13807
  sendReply: this.sendReply,
13689
- getCursorPosition: this.getCursorPosition
13808
+ getCursorPosition: getReplyCursor
13690
13809
  })) {
13691
13810
  result += seq;
13811
+ applyCsiToCursorHint(trackedCursor, seq, colsHint);
13692
13812
  }
13693
13813
  i = j + 1;
13694
13814
  }
13815
+ this.cursorHint = { ...trackedCursor };
13695
13816
  return result;
13696
13817
  }
13697
13818
  }
@@ -63669,7 +63790,7 @@ function createRuntimeReporting(options) {
63669
63790
  function resolveCursorPosition(cursor) {
63670
63791
  if (!cursor)
63671
63792
  return lastResolvedCursor;
63672
- if (cursor.visible === 0) {
63793
+ if (cursor.visible === 0 && lastResolvedCursor) {
63673
63794
  return lastResolvedCursor;
63674
63795
  }
63675
63796
  let col = Number(cursor.col);
@@ -63690,14 +63811,32 @@ function createRuntimeReporting(options) {
63690
63811
  };
63691
63812
  const wasmExports = options.getWasmExports();
63692
63813
  const wasmHandle = options.getWasmHandle();
63693
- if (!inBounds(col, row) && wasmExports?.restty_active_cursor_x && wasmExports?.restty_active_cursor_y && wasmHandle) {
63814
+ const getActiveCursor = () => {
63815
+ if (!wasmExports?.restty_active_cursor_x || !wasmExports?.restty_active_cursor_y || !wasmHandle) {
63816
+ return null;
63817
+ }
63694
63818
  const activeCol = wasmExports.restty_active_cursor_x(wasmHandle);
63695
63819
  const activeRow = wasmExports.restty_active_cursor_y(wasmHandle);
63696
- if (inBounds(activeCol, activeRow)) {
63697
- col = activeCol;
63698
- row = activeRow;
63820
+ if (!inBounds(activeCol, activeRow))
63821
+ return null;
63822
+ return { col: activeCol, row: activeRow };
63823
+ };
63824
+ if (cursor.visible === 0 && !lastResolvedCursor) {
63825
+ const active = getActiveCursor();
63826
+ if (active) {
63827
+ lastResolvedCursor = {
63828
+ col: active.col,
63829
+ row: active.row,
63830
+ wideTail: cursor.wideTail === 1
63831
+ };
63832
+ return lastResolvedCursor;
63699
63833
  }
63700
63834
  }
63835
+ const activeFallback = !inBounds(col, row) ? getActiveCursor() : null;
63836
+ if (activeFallback) {
63837
+ col = activeFallback.col;
63838
+ row = activeFallback.row;
63839
+ }
63701
63840
  if (cols > 0 && rows > 0) {
63702
63841
  col = Math.max(0, Math.min(cols - 1, Math.floor(col)));
63703
63842
  row = Math.max(0, Math.min(rows - 1, Math.floor(row)));
@@ -64451,6 +64590,22 @@ function createResttyApp(options) {
64451
64590
  onFlush: (output) => sendInput(output, "pty")
64452
64591
  });
64453
64592
  let lastCursorForCpr = { row: 1, col: 1 };
64593
+ function resolveCursorForCpr() {
64594
+ if (wasmHandle && wasmExports?.restty_active_cursor_x && wasmExports?.restty_active_cursor_y) {
64595
+ const activeCol = wasmExports.restty_active_cursor_x(wasmHandle);
64596
+ const activeRow = wasmExports.restty_active_cursor_y(wasmHandle);
64597
+ const cols = lastRenderState?.cols ?? 0;
64598
+ const rows = lastRenderState?.rows ?? 0;
64599
+ const inBounds = cols > 0 && rows > 0 && Number.isFinite(activeCol) && Number.isFinite(activeRow) && activeCol >= 0 && activeRow >= 0 && activeCol < cols && activeRow < rows;
64600
+ if (inBounds) {
64601
+ lastCursorForCpr = {
64602
+ row: Math.floor(activeRow) + 1,
64603
+ col: Math.floor(activeCol) + 1
64604
+ };
64605
+ }
64606
+ }
64607
+ return lastCursorForCpr;
64608
+ }
64454
64609
  let inputHandler = null;
64455
64610
  let activeTheme = null;
64456
64611
  const webgpuUniforms = new Float32Array(8);
@@ -64588,7 +64743,7 @@ function createResttyApp(options) {
64588
64743
  }
64589
64744
  });
64590
64745
  inputHandler = createInputHandler({
64591
- getCursorPosition: () => lastCursorForCpr,
64746
+ getCursorPosition: resolveCursorForCpr,
64592
64747
  sendReply: (data) => {
64593
64748
  ptyTransport.sendInput(data);
64594
64749
  },
@@ -64649,7 +64804,7 @@ function createResttyApp(options) {
64649
64804
  cellH: gridState.cellH
64650
64805
  };
64651
64806
  },
64652
- getCursorForCpr: () => lastCursorForCpr,
64807
+ getCursorForCpr: resolveCursorForCpr,
64653
64808
  sendInput,
64654
64809
  runBeforeInputHook,
64655
64810
  shouldClearSelection: () => selectionState.active || selectionState.dragging,
@@ -54,6 +54,7 @@ export declare class OutputFilter {
54
54
  private getDefaultColors?;
55
55
  private desktopNotificationHandler?;
56
56
  private promptState;
57
+ private cursorHint;
57
58
  constructor(options: OutputFilterOptions);
58
59
  setCursorProvider(fn: () => CursorPosition): void;
59
60
  setReplySink(fn: (data: string) => void): void;
package/dist/internal.js CHANGED
@@ -100,7 +100,7 @@ import {
100
100
  updateGridState,
101
101
  updateImePosition,
102
102
  updateSelection
103
- } from "./chunk-8bv82tek.js";
103
+ } from "./chunk-p8wzkwjt.js";
104
104
  export {
105
105
  updateSelection,
106
106
  updateImePosition,
package/dist/restty.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  isBuiltinThemeName,
9
9
  listBuiltinThemeNames,
10
10
  parseGhosttyTheme
11
- } from "./chunk-8bv82tek.js";
11
+ } from "./chunk-p8wzkwjt.js";
12
12
  export {
13
13
  parseGhosttyTheme,
14
14
  listBuiltinThemeNames,
package/dist/xterm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createRestty
3
- } from "./chunk-8bv82tek.js";
3
+ } from "./chunk-p8wzkwjt.js";
4
4
 
5
5
  // src/xterm/app-options.ts
6
6
  function createCompatAppOptions(userAppOptions, emitData) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restty",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Browser terminal rendering library powered by WASM, WebGPU/WebGL2, and TypeScript text shaping.",
5
5
  "keywords": [
6
6
  "terminal",