restty 0.1.22 → 0.1.23

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.
@@ -8576,6 +8576,10 @@ class OutputFilter {
8576
8576
  clipboardWrite;
8577
8577
  clipboardRead;
8578
8578
  getDefaultColors;
8579
+ semanticPromptSeen = false;
8580
+ promptClickEvents = false;
8581
+ promptInputActive = false;
8582
+ commandRunning = false;
8579
8583
  constructor(options) {
8580
8584
  this.getCursorPosition = options.getCursorPosition;
8581
8585
  this.sendReply = options.sendReply;
@@ -8607,6 +8611,80 @@ class OutputFilter {
8607
8611
  isSynchronizedOutput() {
8608
8612
  return this.synchronizedOutput;
8609
8613
  }
8614
+ isPromptClickEventsEnabled() {
8615
+ return this.semanticPromptSeen && this.promptClickEvents && this.promptInputActive && !this.commandRunning && !this.altScreen;
8616
+ }
8617
+ encodePromptClickEvent(cell) {
8618
+ if (!this.isPromptClickEventsEnabled())
8619
+ return "";
8620
+ const row = Math.max(1, Math.floor(cell.row) + 1);
8621
+ const col = Math.max(1, Math.floor(cell.col) + 1);
8622
+ return `\x1B[<0;${col};${row}M`;
8623
+ }
8624
+ readOsc133BoolOption(options, key) {
8625
+ if (!options)
8626
+ return null;
8627
+ const prefix = `${key}=`;
8628
+ const fields = options.split(";");
8629
+ for (let i = 0;i < fields.length; i += 1) {
8630
+ const field = fields[i];
8631
+ if (!field.startsWith(prefix))
8632
+ continue;
8633
+ const value = field.slice(prefix.length);
8634
+ if (value === "1")
8635
+ return true;
8636
+ if (value === "0")
8637
+ return false;
8638
+ return null;
8639
+ }
8640
+ return null;
8641
+ }
8642
+ observeSemanticPromptOsc(action, options) {
8643
+ const clickEvents = this.readOsc133BoolOption(options, "click_events");
8644
+ if (clickEvents !== null)
8645
+ this.promptClickEvents = clickEvents;
8646
+ switch (action) {
8647
+ case "A":
8648
+ case "B":
8649
+ case "I":
8650
+ this.semanticPromptSeen = true;
8651
+ this.promptInputActive = true;
8652
+ this.commandRunning = false;
8653
+ break;
8654
+ case "C":
8655
+ this.semanticPromptSeen = true;
8656
+ this.promptInputActive = false;
8657
+ this.commandRunning = true;
8658
+ break;
8659
+ case "D":
8660
+ this.semanticPromptSeen = true;
8661
+ this.promptInputActive = false;
8662
+ this.commandRunning = false;
8663
+ break;
8664
+ case "P":
8665
+ this.semanticPromptSeen = true;
8666
+ break;
8667
+ default:
8668
+ break;
8669
+ }
8670
+ }
8671
+ observeOsc(seq) {
8672
+ const content = seq.slice(2);
8673
+ const sep = content.indexOf(";");
8674
+ if (sep < 0)
8675
+ return;
8676
+ const code = content.slice(0, sep);
8677
+ if (code !== "133")
8678
+ return;
8679
+ const rest = content.slice(sep + 1);
8680
+ if (!rest)
8681
+ return;
8682
+ const action = rest[0] ?? "";
8683
+ if (!action)
8684
+ return;
8685
+ const options = rest.length > 2 && rest[1] === ";" ? rest.slice(2) : "";
8686
+ this.observeSemanticPromptOsc(action, options);
8687
+ }
8610
8688
  replyOscColor(code, rgb) {
8611
8689
  const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
8612
8690
  const r = toHex4(rgb[0]);
@@ -8749,6 +8827,7 @@ class OutputFilter {
8749
8827
  break;
8750
8828
  }
8751
8829
  const seq2 = data.slice(i, j2);
8830
+ this.observeOsc(seq2);
8752
8831
  if (!this.handleOsc(seq2)) {
8753
8832
  result += data.slice(i, j2 + terminatorLen);
8754
8833
  }
@@ -8858,6 +8937,8 @@ function createInputHandler(options = {}) {
8858
8937
  isFocusReporting: () => filter.isFocusReporting(),
8859
8938
  isAltScreen: () => filter.isAltScreen(),
8860
8939
  isSynchronizedOutput: () => filter.isSynchronizedOutput(),
8940
+ isPromptClickEventsEnabled: () => filter.isPromptClickEventsEnabled(),
8941
+ encodePromptClickEvent: (cell) => filter.encodePromptClickEvent(cell),
8861
8942
  sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
8862
8943
  };
8863
8944
  }
@@ -50571,6 +50652,11 @@ function createResttyApp(options) {
50571
50652
  panLastY: 0,
50572
50653
  pendingTimer: 0
50573
50654
  };
50655
+ const desktopSelectionState = {
50656
+ pendingPointerId: null,
50657
+ pendingCell: null,
50658
+ startedWithActiveSelection: false
50659
+ };
50574
50660
  const linkState = {
50575
50661
  hoverId: 0,
50576
50662
  hoverUri: ""
@@ -50590,11 +50676,7 @@ function createResttyApp(options) {
50590
50676
  function updateCanvasCursor() {
50591
50677
  if (!canvas)
50592
50678
  return;
50593
- if (selectionState.dragging || selectionState.active) {
50594
- canvas.style.cursor = "text";
50595
- return;
50596
- }
50597
- canvas.style.cursor = linkState.hoverId ? "pointer" : "default";
50679
+ canvas.style.cursor = "text";
50598
50680
  }
50599
50681
  function isTouchPointer(event) {
50600
50682
  return event.pointerType === "touch";
@@ -50608,6 +50690,11 @@ function createResttyApp(options) {
50608
50690
  touchSelectionState.pendingCell = null;
50609
50691
  touchSelectionState.pendingStartedAt = 0;
50610
50692
  }
50693
+ function clearPendingDesktopSelection() {
50694
+ desktopSelectionState.pendingPointerId = null;
50695
+ desktopSelectionState.pendingCell = null;
50696
+ desktopSelectionState.startedWithActiveSelection = false;
50697
+ }
50611
50698
  function tryActivatePendingTouchSelection(pointerId) {
50612
50699
  if (touchSelectionMode !== "long-press")
50613
50700
  return false;
@@ -50623,6 +50710,7 @@ function createResttyApp(options) {
50623
50710
  return true;
50624
50711
  }
50625
50712
  function beginSelectionDrag(cell, pointerId) {
50713
+ clearPendingDesktopSelection();
50626
50714
  selectionState.active = true;
50627
50715
  selectionState.dragging = true;
50628
50716
  selectionState.anchor = cell;
@@ -51424,6 +51512,7 @@ function createResttyApp(options) {
51424
51512
  });
51425
51513
  inputHandler.setMouseMode("auto");
51426
51514
  function clearSelection() {
51515
+ clearPendingDesktopSelection();
51427
51516
  selectionState.active = false;
51428
51517
  selectionState.dragging = false;
51429
51518
  selectionState.anchor = null;
@@ -51683,6 +51772,7 @@ function createResttyApp(options) {
51683
51772
  }
51684
51773
  }
51685
51774
  if (shouldRoutePointerToAppMouse(event.shiftKey) && !shouldPreferLocalPrimarySelection(event) && inputHandler.sendMouseEvent("down", event)) {
51775
+ clearPendingDesktopSelection();
51686
51776
  event.preventDefault();
51687
51777
  canvas.setPointerCapture?.(event.pointerId);
51688
51778
  return;
@@ -51718,7 +51808,9 @@ function createResttyApp(options) {
51718
51808
  event.preventDefault();
51719
51809
  const cell = normalizeSelectionCell(positionToCell(event));
51720
51810
  updateLinkHover(cell);
51721
- beginSelectionDrag(cell, event.pointerId);
51811
+ desktopSelectionState.pendingPointerId = event.pointerId;
51812
+ desktopSelectionState.pendingCell = cell;
51813
+ desktopSelectionState.startedWithActiveSelection = selectionState.active;
51722
51814
  };
51723
51815
  const onPointerMove = (event) => {
51724
51816
  if (scrollbarDragState.pointerId === event.pointerId) {
@@ -51770,6 +51862,19 @@ function createResttyApp(options) {
51770
51862
  return;
51771
51863
  }
51772
51864
  const cell = normalizeSelectionCell(positionToCell(event));
51865
+ if (desktopSelectionState.pendingPointerId === event.pointerId && desktopSelectionState.pendingCell) {
51866
+ const anchor = desktopSelectionState.pendingCell;
51867
+ if (anchor.row !== cell.row || anchor.col !== cell.col) {
51868
+ beginSelectionDrag(anchor, event.pointerId);
51869
+ selectionState.focus = cell;
51870
+ updateLinkHover(null);
51871
+ updateCanvasCursor();
51872
+ needsRender = true;
51873
+ return;
51874
+ }
51875
+ updateLinkHover(cell);
51876
+ return;
51877
+ }
51773
51878
  if (selectionState.dragging) {
51774
51879
  event.preventDefault();
51775
51880
  selectionState.focus = cell;
@@ -51817,6 +51922,12 @@ function createResttyApp(options) {
51817
51922
  return;
51818
51923
  }
51819
51924
  const cell = normalizeSelectionCell(positionToCell(event));
51925
+ const clearSelectionFromClick = desktopSelectionState.pendingPointerId === event.pointerId && desktopSelectionState.startedWithActiveSelection && !selectionState.dragging;
51926
+ if (desktopSelectionState.pendingPointerId === event.pointerId) {
51927
+ clearPendingDesktopSelection();
51928
+ }
51929
+ if (clearSelectionFromClick)
51930
+ clearSelection();
51820
51931
  if (selectionState.dragging) {
51821
51932
  event.preventDefault();
51822
51933
  selectionState.dragging = false;
@@ -51834,6 +51945,14 @@ function createResttyApp(options) {
51834
51945
  }
51835
51946
  updateLinkHover(cell);
51836
51947
  }
51948
+ if (!selectionState.active && event.button === 0 && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey && inputHandler.isPromptClickEventsEnabled()) {
51949
+ const seq = inputHandler.encodePromptClickEvent(cell);
51950
+ if (seq) {
51951
+ event.preventDefault();
51952
+ sendKeyInput(seq);
51953
+ return;
51954
+ }
51955
+ }
51837
51956
  if (!selectionState.active && event.button === 0 && linkState.hoverUri) {
51838
51957
  openLink(linkState.hoverUri);
51839
51958
  }
@@ -51842,6 +51961,9 @@ function createResttyApp(options) {
51842
51961
  if (scrollbarDragState.pointerId === event.pointerId) {
51843
51962
  scrollbarDragState.pointerId = null;
51844
51963
  }
51964
+ if (desktopSelectionState.pendingPointerId === event.pointerId) {
51965
+ clearPendingDesktopSelection();
51966
+ }
51845
51967
  if (isTouchPointer(event)) {
51846
51968
  if (touchSelectionState.pendingPointerId === event.pointerId) {
51847
51969
  clearPendingTouchSelection();
@@ -1,4 +1,4 @@
1
- import type { CursorPosition, WindowOp } from "./types";
1
+ import type { CellPosition, CursorPosition, WindowOp } from "./types";
2
2
  import type { MouseController } from "./mouse";
3
3
  /**
4
4
  * Construction options for OutputFilter.
@@ -50,6 +50,10 @@ export declare class OutputFilter {
50
50
  private clipboardWrite?;
51
51
  private clipboardRead?;
52
52
  private getDefaultColors?;
53
+ private semanticPromptSeen;
54
+ private promptClickEvents;
55
+ private promptInputActive;
56
+ private commandRunning;
53
57
  constructor(options: OutputFilterOptions);
54
58
  setCursorProvider(fn: () => CursorPosition): void;
55
59
  setReplySink(fn: (data: string) => void): void;
@@ -58,6 +62,11 @@ export declare class OutputFilter {
58
62
  isBracketedPaste(): boolean;
59
63
  isFocusReporting(): boolean;
60
64
  isSynchronizedOutput(): boolean;
65
+ isPromptClickEventsEnabled(): boolean;
66
+ encodePromptClickEvent(cell: CellPosition): string;
67
+ private readOsc133BoolOption;
68
+ private observeSemanticPromptOsc;
69
+ private observeOsc;
61
70
  private replyOscColor;
62
71
  private handleOsc;
63
72
  private handleModeSeq;
@@ -160,6 +160,8 @@ export type InputHandler = {
160
160
  isFocusReporting: () => boolean;
161
161
  isAltScreen: () => boolean;
162
162
  isSynchronizedOutput: () => boolean;
163
+ isPromptClickEventsEnabled: () => boolean;
164
+ encodePromptClickEvent: (cell: CellPosition) => string;
163
165
  /**
164
166
  * Encode pointer input as terminal mouse events (SGR).
165
167
  */
package/dist/internal.js CHANGED
@@ -89,7 +89,7 @@ import {
89
89
  updateComposition,
90
90
  updateGridState,
91
91
  updateImePosition
92
- } from "./chunk-d3xkkgrb.js";
92
+ } from "./chunk-mkkhfg0z.js";
93
93
  // src/selection/selection.ts
94
94
  function createSelectionState() {
95
95
  return {
package/dist/restty.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  isBuiltinThemeName,
9
9
  listBuiltinThemeNames,
10
10
  parseGhosttyTheme
11
- } from "./chunk-d3xkkgrb.js";
11
+ } from "./chunk-mkkhfg0z.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-d3xkkgrb.js";
3
+ } from "./chunk-mkkhfg0z.js";
4
4
 
5
5
  // src/xterm.ts
6
6
  class Terminal {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restty",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "Browser terminal rendering library powered by WASM, WebGPU/WebGL2, and TypeScript text shaping.",
5
5
  "keywords": [
6
6
  "terminal",