@fairyhunter13/opentui-core 0.1.102 → 0.1.104

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.
@@ -5168,7 +5168,7 @@ function visualizeRenderableTree(renderable, maxDepth = 10) {
5168
5168
  }
5169
5169
 
5170
5170
  // src/lib/styled-text.ts
5171
- var BrandedStyledText = Symbol.for("@fairyhunter13/opentui-core/StyledText");
5171
+ var BrandedStyledText = Symbol.for("@opentui/core/StyledText");
5172
5172
  function isStyledText(obj) {
5173
5173
  return obj && obj[BrandedStyledText];
5174
5174
  }
@@ -6666,7 +6666,7 @@ class ASCIIFontSelectionHelper {
6666
6666
  }
6667
6667
 
6668
6668
  // src/lib/singleton.ts
6669
- var singletonCacheSymbol = Symbol.for("@fairyhunter13/opentui-core/singleton");
6669
+ var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
6670
6670
  function singleton(key, factory) {
6671
6671
  const bag = globalThis[singletonCacheSymbol] ??= {};
6672
6672
  if (!(key in bag)) {
@@ -6843,7 +6843,7 @@ var env = new Proxy({}, {
6843
6843
 
6844
6844
  // src/lib/stdin-parser.ts
6845
6845
  import { Buffer as Buffer3 } from "buffer";
6846
- var DEFAULT_TIMEOUT_MS = 10;
6846
+ var DEFAULT_TIMEOUT_MS = 20;
6847
6847
  var DEFAULT_MAX_PENDING_BYTES = 64 * 1024;
6848
6848
  var INITIAL_PENDING_CAPACITY = 256;
6849
6849
  var ESC = 27;
@@ -7014,6 +7014,28 @@ function parsePositiveDecimalPrefix(sequence, start, endExclusive) {
7014
7014
  }
7015
7015
  return sawDigit ? value : null;
7016
7016
  }
7017
+ function parseKittyFirstFieldCodepoint(sequence, start, endExclusive) {
7018
+ if (start >= endExclusive)
7019
+ return null;
7020
+ let firstColon = -1;
7021
+ for (let index = start;index < endExclusive; index += 1) {
7022
+ if (sequence[index] === 58) {
7023
+ firstColon = index;
7024
+ break;
7025
+ }
7026
+ }
7027
+ if (firstColon === -1)
7028
+ return null;
7029
+ const codepoint = parsePositiveDecimalPrefix(sequence, start, firstColon);
7030
+ if (codepoint === null)
7031
+ return null;
7032
+ for (let index = firstColon + 1;index < endExclusive; index += 1) {
7033
+ const byte = sequence[index];
7034
+ if (byte !== 58 && !isAsciiDigit(byte))
7035
+ return null;
7036
+ }
7037
+ return codepoint;
7038
+ }
7017
7039
  function canStillBeKittyU(state) {
7018
7040
  return state.semicolons >= 1;
7019
7041
  }
@@ -7215,10 +7237,13 @@ class StdinParser {
7215
7237
  }
7216
7238
  flushTimeout(nowMsValue = this.clock.now()) {
7217
7239
  this.ensureAlive();
7218
- if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7240
+ if (this.pendingSinceMs !== null && (nowMsValue < this.pendingSinceMs || nowMsValue - this.pendingSinceMs < this.timeoutMs)) {
7219
7241
  return;
7220
7242
  }
7221
- if (nowMsValue < this.pendingSinceMs || nowMsValue - this.pendingSinceMs < this.timeoutMs) {
7243
+ this.tryForceFlush();
7244
+ }
7245
+ tryForceFlush() {
7246
+ if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7222
7247
  return;
7223
7248
  }
7224
7249
  this.forceFlush = true;
@@ -7480,7 +7505,12 @@ class StdinParser {
7480
7505
  continue;
7481
7506
  }
7482
7507
  if (byte === 59) {
7483
- const firstParamValue = parsePositiveDecimalPrefix(bytes, this.unitStart + 2, this.cursor);
7508
+ const firstParamStart = this.unitStart + 2;
7509
+ const firstParamEnd = this.cursor;
7510
+ let firstParamValue = parsePositiveDecimalPrefix(bytes, firstParamStart, firstParamEnd);
7511
+ if (firstParamValue === null && this.protocolContext.kittyKeyboardEnabled) {
7512
+ firstParamValue = parseKittyFirstFieldCodepoint(bytes, firstParamStart, firstParamEnd);
7513
+ }
7484
7514
  if (firstParamValue !== null) {
7485
7515
  this.cursor += 1;
7486
7516
  this.state = {
@@ -8078,7 +8108,7 @@ class StdinParser {
8078
8108
  return;
8079
8109
  }
8080
8110
  try {
8081
- this.flushTimeout(this.clock.now());
8111
+ this.tryForceFlush();
8082
8112
  this.onTimeoutFlush?.();
8083
8113
  } catch (error) {
8084
8114
  console.error("stdin parser timeout flush failed", error);
@@ -8782,13 +8812,6 @@ class TreeSitterClient extends EventEmitter2 {
8782
8812
  const { logType, data } = event.data;
8783
8813
  const message = data.join(" ");
8784
8814
  this.emit("worker:log", logType, message);
8785
- if (logType === "log") {
8786
- console.log("TSWorker:", ...data);
8787
- } else if (logType === "error") {
8788
- console.error("TSWorker:", ...data);
8789
- } else if (logType === "warn") {
8790
- console.warn("TSWorker:", ...data);
8791
- }
8792
8815
  return;
8793
8816
  }
8794
8817
  }
@@ -9416,7 +9439,7 @@ class DownloadUtils {
9416
9439
 
9417
9440
  // src/lib/tree-sitter/assets/update.ts
9418
9441
  import { readdir } from "fs/promises";
9419
- var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
9442
+ var __dirname = "/home/hafiz/git/github.com/fairyhunter13/opencode/vendor/opentui/packages/core/src/lib/tree-sitter/assets";
9420
9443
  function getDefaultOptions() {
9421
9444
  return {
9422
9445
  configPath: path4.resolve(__dirname, "../parsers-config"),
@@ -10670,7 +10693,7 @@ import { EventEmitter as EventEmitter4 } from "events";
10670
10693
 
10671
10694
  // src/buffer.ts
10672
10695
  import { toArrayBuffer, ptr } from "bun:ffi";
10673
- function packDrawOptions(border2, shouldFill, titleAlignment) {
10696
+ function packDrawOptions(border2, shouldFill, titleAlignment, bottomTitleAlignment) {
10674
10697
  let packed = 0;
10675
10698
  if (border2 === true) {
10676
10699
  packed |= 15;
@@ -10693,7 +10716,9 @@ function packDrawOptions(border2, shouldFill, titleAlignment) {
10693
10716
  right: 2
10694
10717
  };
10695
10718
  const alignment = alignmentMap[titleAlignment];
10719
+ const bottomAlignment = alignmentMap[bottomTitleAlignment];
10696
10720
  packed |= alignment << 5;
10721
+ packed |= bottomAlignment << 7;
10697
10722
  return packed;
10698
10723
  }
10699
10724
 
@@ -10925,8 +10950,8 @@ class OptimizedBuffer {
10925
10950
  this.guard();
10926
10951
  const style = parseBorderStyle(options.borderStyle, "single");
10927
10952
  const borderChars = options.customBorderChars ?? BorderCharArrays[style];
10928
- const packedOptions = packDrawOptions(options.border, options.shouldFill ?? false, options.titleAlignment || "left");
10929
- this.lib.bufferDrawBox(this.bufferPtr, options.x, options.y, options.width, options.height, borderChars, packedOptions, options.borderColor, options.backgroundColor, options.title ?? null);
10953
+ const packedOptions = packDrawOptions(options.border, options.shouldFill ?? false, options.titleAlignment || "left", options.bottomTitleAlignment || "left");
10954
+ this.lib.bufferDrawBox(this.bufferPtr, options.x, options.y, options.width, options.height, borderChars, packedOptions, options.borderColor, options.backgroundColor, options.title ?? null, options.bottomTitle ?? null);
10930
10955
  }
10931
10956
  pushScissorRect(x, y, width, height) {
10932
10957
  this.guard();
@@ -11768,7 +11793,7 @@ var ReserveInfoStruct = defineStruct([
11768
11793
  });
11769
11794
 
11770
11795
  // src/zig.ts
11771
- var module = await import(`@fairyhunter13/opentui-core-${process.platform}-${process.arch}/index.ts`);
11796
+ var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
11772
11797
  var targetLibPath = module.default;
11773
11798
  if (isBunfsPath(targetLibPath)) {
11774
11799
  targetLibPath = targetLibPath.replace("../", "");
@@ -12054,7 +12079,7 @@ function getOpenTUILib(libPath) {
12054
12079
  returns: "void"
12055
12080
  },
12056
12081
  bufferDrawBox: {
12057
- args: ["ptr", "i32", "i32", "u32", "u32", "ptr", "u32", "ptr", "ptr", "ptr", "u32"],
12082
+ args: ["ptr", "i32", "i32", "u32", "u32", "ptr", "u32", "ptr", "ptr", "ptr", "u32", "ptr", "u32"],
12058
12083
  returns: "void"
12059
12084
  },
12060
12085
  bufferPushScissorRect: {
@@ -13222,11 +13247,14 @@ class FFIRenderLib {
13222
13247
  });
13223
13248
  this.opentui.symbols.bufferDrawGrid(buffer, borderChars, borderFg.buffer, borderBg.buffer, columnOffsets, columnCount, rowOffsets, rowCount, ptr4(optionsBuffer));
13224
13249
  }
13225
- bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, title) {
13250
+ bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, title, bottomTitle) {
13226
13251
  const titleBytes = title ? this.encoder.encode(title) : null;
13227
13252
  const titleLen = title ? titleBytes.length : 0;
13228
13253
  const titlePtr = title ? titleBytes : null;
13229
- this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor.buffer, backgroundColor.buffer, titlePtr, titleLen);
13254
+ const bottomTitleBytes = bottomTitle ? this.encoder.encode(bottomTitle) : null;
13255
+ const bottomTitleLen = bottomTitle ? bottomTitleBytes.length : 0;
13256
+ const bottomTitlePtr = bottomTitle ? bottomTitleBytes : null;
13257
+ this.opentui.symbols.bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor.buffer, backgroundColor.buffer, titlePtr, titleLen, bottomTitlePtr, bottomTitleLen);
13230
13258
  }
13231
13259
  bufferResize(buffer, width, height) {
13232
13260
  this.opentui.symbols.bufferResize(buffer, width, height);
@@ -14544,7 +14572,7 @@ function isSizeType(value) {
14544
14572
  }
14545
14573
 
14546
14574
  // src/Renderable.ts
14547
- var BrandedRenderable = Symbol.for("@fairyhunter13/opentui-core/Renderable");
14575
+ var BrandedRenderable = Symbol.for("@opentui/core/Renderable");
14548
14576
  var LayoutEvents;
14549
14577
  ((LayoutEvents2) => {
14550
14578
  LayoutEvents2["LAYOUT_CHANGED"] = "layout-changed";
@@ -14900,29 +14928,31 @@ class Renderable extends BaseRenderable {
14900
14928
  return this._widthValue;
14901
14929
  }
14902
14930
  set width(value) {
14903
- if (isDimensionType(value)) {
14904
- this._width = value;
14905
- this.yogaNode.setWidth(value);
14906
- if (typeof value === "number" && this._flexShrink === 1) {
14907
- this._flexShrink = 0;
14908
- this.yogaNode.setFlexShrink(0);
14909
- }
14910
- this.requestRender();
14931
+ if (!isDimensionType(value) || this._width === value) {
14932
+ return;
14911
14933
  }
14934
+ this._width = value;
14935
+ this.yogaNode.setWidth(value);
14936
+ if (typeof value === "number" && this._flexShrink === 1) {
14937
+ this._flexShrink = 0;
14938
+ this.yogaNode.setFlexShrink(0);
14939
+ }
14940
+ this.requestRender();
14912
14941
  }
14913
14942
  get height() {
14914
14943
  return this._heightValue;
14915
14944
  }
14916
14945
  set height(value) {
14917
- if (isDimensionType(value)) {
14918
- this._height = value;
14919
- this.yogaNode.setHeight(value);
14920
- if (typeof value === "number" && this._flexShrink === 1) {
14921
- this._flexShrink = 0;
14922
- this.yogaNode.setFlexShrink(0);
14923
- }
14924
- this.requestRender();
14946
+ if (!isDimensionType(value) || this._height === value) {
14947
+ return;
14948
+ }
14949
+ this._height = value;
14950
+ this.yogaNode.setHeight(value);
14951
+ if (typeof value === "number" && this._flexShrink === 1) {
14952
+ this._flexShrink = 0;
14953
+ this.yogaNode.setFlexShrink(0);
14925
14954
  }
14955
+ this.requestRender();
14926
14956
  }
14927
14957
  get zIndex() {
14928
14958
  return this._zIndex;
@@ -15778,7 +15808,7 @@ class RootRenderable extends Renderable {
15778
15808
 
15779
15809
  // src/renderables/composition/vnode.ts
15780
15810
  import util from "util";
15781
- var BrandedVNode = Symbol.for("@fairyhunter13/opentui-core/VNode");
15811
+ var BrandedVNode = Symbol.for("@opentui/core/VNode");
15782
15812
  function isRenderableConstructor(value) {
15783
15813
  return typeof value === "function" && value.prototype && Renderable.prototype.isPrototypeOf(value.prototype);
15784
15814
  }
@@ -15942,1084 +15972,2506 @@ function delegate(mapping, vnode) {
15942
15972
  return vnode;
15943
15973
  }
15944
15974
 
15945
- // src/console.ts
15946
- import { EventEmitter as EventEmitter7 } from "events";
15947
- import { Console } from "console";
15948
- import fs from "fs";
15949
- import path5 from "path";
15950
- import util2 from "util";
15951
-
15952
- // src/lib/output.capture.ts
15953
- import { Writable } from "stream";
15975
+ // src/edit-buffer.ts
15954
15976
  import { EventEmitter as EventEmitter6 } from "events";
15955
15977
 
15956
- class Capture extends EventEmitter6 {
15957
- output = [];
15958
- constructor() {
15978
+ class EditBuffer extends EventEmitter6 {
15979
+ static registry = new Map;
15980
+ static nativeEventsSubscribed = false;
15981
+ lib;
15982
+ bufferPtr;
15983
+ textBufferPtr;
15984
+ id;
15985
+ _destroyed = false;
15986
+ _textBytes = [];
15987
+ _singleTextBytes = null;
15988
+ _singleTextMemId = null;
15989
+ _syntaxStyle;
15990
+ constructor(lib, ptr5) {
15959
15991
  super();
15992
+ this.lib = lib;
15993
+ this.bufferPtr = ptr5;
15994
+ this.textBufferPtr = lib.editBufferGetTextBuffer(ptr5);
15995
+ this.id = lib.editBufferGetId(ptr5);
15996
+ EditBuffer.registry.set(this.id, this);
15997
+ EditBuffer.subscribeToNativeEvents(lib);
15960
15998
  }
15961
- get size() {
15962
- return this.output.length;
15999
+ static create(widthMethod) {
16000
+ const lib = resolveRenderLib();
16001
+ const ptr5 = lib.createEditBuffer(widthMethod);
16002
+ return new EditBuffer(lib, ptr5);
15963
16003
  }
15964
- write(stream, data) {
15965
- this.output.push({ stream, output: data });
15966
- this.emit("write", stream, data);
16004
+ static subscribeToNativeEvents(lib) {
16005
+ if (EditBuffer.nativeEventsSubscribed)
16006
+ return;
16007
+ EditBuffer.nativeEventsSubscribed = true;
16008
+ lib.onAnyNativeEvent((name, data) => {
16009
+ const buffer = new Uint16Array(data);
16010
+ if (name.startsWith("eb_") && buffer.length >= 1) {
16011
+ const id = buffer[0];
16012
+ const instance = EditBuffer.registry.get(id);
16013
+ if (instance) {
16014
+ const eventName = name.slice(3);
16015
+ const eventData = data.slice(2);
16016
+ instance.emit(eventName, eventData);
16017
+ }
16018
+ }
16019
+ });
15967
16020
  }
15968
- claimOutput() {
15969
- const output = this.output.map((o) => o.output).join("");
15970
- this.clear();
15971
- return output;
16021
+ guard() {
16022
+ if (this._destroyed)
16023
+ throw new Error("EditBuffer is destroyed");
15972
16024
  }
15973
- clear() {
15974
- this.output = [];
16025
+ get ptr() {
16026
+ this.guard();
16027
+ return this.bufferPtr;
15975
16028
  }
15976
- }
15977
-
15978
- class CapturedWritableStream extends Writable {
15979
- stream;
15980
- capture;
15981
- isTTY = true;
15982
- columns = process.stdout.columns || 80;
15983
- rows = process.stdout.rows || 24;
15984
- constructor(stream, capture) {
15985
- super();
15986
- this.stream = stream;
15987
- this.capture = capture;
16029
+ setText(text) {
16030
+ this.guard();
16031
+ const textBytes = this.lib.encoder.encode(text);
16032
+ if (this._singleTextMemId !== null) {
16033
+ this.lib.textBufferReplaceMemBuffer(this.textBufferPtr, this._singleTextMemId, textBytes, false);
16034
+ } else {
16035
+ this._singleTextMemId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false);
16036
+ }
16037
+ this._singleTextBytes = textBytes;
16038
+ this.lib.editBufferSetTextFromMem(this.bufferPtr, this._singleTextMemId);
15988
16039
  }
15989
- _write(chunk, encoding, callback) {
15990
- const data = chunk.toString();
15991
- this.capture.write(this.stream, data);
15992
- callback();
16040
+ setTextOwned(text) {
16041
+ this.guard();
16042
+ const textBytes = this.lib.encoder.encode(text);
16043
+ this.lib.editBufferSetText(this.bufferPtr, textBytes);
15993
16044
  }
15994
- getColorDepth() {
15995
- return process.stdout.getColorDepth?.() || 8;
16045
+ replaceText(text) {
16046
+ this.guard();
16047
+ const textBytes = this.lib.encoder.encode(text);
16048
+ this._textBytes.push(textBytes);
16049
+ const memId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false);
16050
+ this.lib.editBufferReplaceTextFromMem(this.bufferPtr, memId);
15996
16051
  }
15997
- }
15998
-
15999
- // src/lib/keymapping.ts
16000
- var defaultKeyAliases = {
16001
- enter: "return",
16002
- esc: "escape"
16003
- };
16004
- function mergeKeyAliases(defaults, custom) {
16005
- return { ...defaults, ...custom };
16006
- }
16007
- function mergeKeyBindings(defaults, custom) {
16008
- const map = new Map;
16009
- for (const binding of defaults) {
16010
- const key = getKeyBindingKey(binding);
16011
- map.set(key, binding);
16052
+ replaceTextOwned(text) {
16053
+ this.guard();
16054
+ const textBytes = this.lib.encoder.encode(text);
16055
+ this.lib.editBufferReplaceText(this.bufferPtr, textBytes);
16012
16056
  }
16013
- for (const binding of custom) {
16014
- const key = getKeyBindingKey(binding);
16015
- map.set(key, binding);
16057
+ getLineCount() {
16058
+ this.guard();
16059
+ return this.lib.textBufferGetLineCount(this.textBufferPtr);
16016
16060
  }
16017
- return Array.from(map.values());
16018
- }
16019
- function getKeyBindingKey(binding) {
16020
- return `${binding.name}:${binding.ctrl ? 1 : 0}:${binding.shift ? 1 : 0}:${binding.meta ? 1 : 0}:${binding.super ? 1 : 0}`;
16021
- }
16022
- function buildKeyBindingsMap(bindings, aliasMap) {
16023
- const map = new Map;
16024
- const aliases = aliasMap || {};
16025
- for (const binding of bindings) {
16026
- const key = getKeyBindingKey(binding);
16027
- map.set(key, binding.action);
16061
+ getText() {
16062
+ this.guard();
16063
+ const maxSize = 1024 * 1024;
16064
+ const textBytes = this.lib.editBufferGetText(this.bufferPtr, maxSize);
16065
+ if (!textBytes)
16066
+ return "";
16067
+ return this.lib.decoder.decode(textBytes);
16028
16068
  }
16029
- for (const binding of bindings) {
16030
- const normalizedName = aliases[binding.name] || binding.name;
16031
- if (normalizedName !== binding.name) {
16032
- const aliasedKey = getKeyBindingKey({ ...binding, name: normalizedName });
16033
- map.set(aliasedKey, binding.action);
16034
- }
16069
+ insertChar(char) {
16070
+ this.guard();
16071
+ this.lib.editBufferInsertChar(this.bufferPtr, char);
16035
16072
  }
16036
- return map;
16037
- }
16038
- function keyBindingToString(binding) {
16039
- const parts = [];
16040
- if (binding.ctrl)
16041
- parts.push("ctrl");
16042
- if (binding.shift)
16043
- parts.push("shift");
16044
- if (binding.meta)
16045
- parts.push("meta");
16046
- if (binding.super)
16047
- parts.push("super");
16048
- parts.push(binding.name);
16049
- return parts.join("+");
16050
- }
16051
-
16052
- // src/console.ts
16053
- function getCallerInfo() {
16054
- const err = new Error;
16055
- const stackLines = err.stack?.split(`
16056
- `).slice(5) || [];
16057
- if (!stackLines.length)
16058
- return null;
16059
- const callerLine = stackLines[0].trim();
16060
- const regex = /at\s+(?:([\w$.<>]+)\s+\()?((?:\/|[A-Za-z]:\\)[^:]+):(\d+):(\d+)\)?/;
16061
- const match = callerLine.match(regex);
16062
- if (!match)
16063
- return null;
16064
- const functionName = match[1] || "<anonymous>";
16065
- const fullPath = match[2];
16066
- const fileName = fullPath.split(/[\\/]/).pop() || "<unknown>";
16067
- const lineNumber = parseInt(match[3], 10) || 0;
16068
- const columnNumber = parseInt(match[4], 10) || 0;
16069
- return { functionName, fullPath, fileName, lineNumber, columnNumber };
16070
- }
16071
- var capture = singleton("ConsoleCapture", () => new Capture);
16072
- registerEnvVar({
16073
- name: "OTUI_USE_CONSOLE",
16074
- description: "Whether to use the console. Will not capture console output if set to false.",
16075
- type: "boolean",
16076
- default: true
16077
- });
16078
- registerEnvVar({
16079
- name: "SHOW_CONSOLE",
16080
- description: "Show the console at startup if set to true.",
16081
- type: "boolean",
16082
- default: false
16083
- });
16084
-
16085
- class TerminalConsoleCache extends EventEmitter7 {
16086
- _cachedLogs = [];
16087
- MAX_CACHE_SIZE = 1000;
16088
- _collectCallerInfo = false;
16089
- _cachingEnabled = true;
16090
- _originalConsole = null;
16091
- get cachedLogs() {
16092
- return this._cachedLogs;
16073
+ insertText(text) {
16074
+ this.guard();
16075
+ this.lib.editBufferInsertText(this.bufferPtr, text);
16093
16076
  }
16094
- constructor() {
16095
- super();
16077
+ deleteChar() {
16078
+ this.guard();
16079
+ this.lib.editBufferDeleteChar(this.bufferPtr);
16096
16080
  }
16097
- activate() {
16098
- if (!this._originalConsole) {
16099
- this._originalConsole = global.console;
16100
- }
16101
- this.setupConsoleCapture();
16102
- this.overrideConsoleMethods();
16081
+ deleteCharBackward() {
16082
+ this.guard();
16083
+ this.lib.editBufferDeleteCharBackward(this.bufferPtr);
16103
16084
  }
16104
- setupConsoleCapture() {
16105
- if (!env.OTUI_USE_CONSOLE)
16106
- return;
16107
- const mockStdout = new CapturedWritableStream("stdout", capture);
16108
- const mockStderr = new CapturedWritableStream("stderr", capture);
16109
- global.console = new Console({
16110
- stdout: mockStdout,
16111
- stderr: mockStderr,
16112
- colorMode: true,
16113
- inspectOptions: {
16114
- compact: false,
16115
- breakLength: 80,
16116
- depth: 2
16117
- }
16118
- });
16085
+ deleteRange(startLine, startCol, endLine, endCol) {
16086
+ this.guard();
16087
+ this.lib.editBufferDeleteRange(this.bufferPtr, startLine, startCol, endLine, endCol);
16119
16088
  }
16120
- overrideConsoleMethods() {
16121
- console.log = (...args) => {
16122
- this.appendToConsole("LOG" /* LOG */, ...args);
16123
- };
16124
- console.info = (...args) => {
16125
- this.appendToConsole("INFO" /* INFO */, ...args);
16126
- };
16127
- console.warn = (...args) => {
16128
- this.appendToConsole("WARN" /* WARN */, ...args);
16129
- };
16130
- console.error = (...args) => {
16131
- this.appendToConsole("ERROR" /* ERROR */, ...args);
16132
- };
16133
- console.debug = (...args) => {
16134
- this.appendToConsole("DEBUG" /* DEBUG */, ...args);
16135
- };
16089
+ newLine() {
16090
+ this.guard();
16091
+ this.lib.editBufferNewLine(this.bufferPtr);
16136
16092
  }
16137
- setCollectCallerInfo(enabled) {
16138
- this._collectCallerInfo = enabled;
16093
+ deleteLine() {
16094
+ this.guard();
16095
+ this.lib.editBufferDeleteLine(this.bufferPtr);
16139
16096
  }
16140
- clearConsole() {
16141
- this._cachedLogs = [];
16097
+ moveCursorLeft() {
16098
+ this.guard();
16099
+ this.lib.editBufferMoveCursorLeft(this.bufferPtr);
16142
16100
  }
16143
- setCachingEnabled(enabled) {
16144
- this._cachingEnabled = enabled;
16101
+ moveCursorRight() {
16102
+ this.guard();
16103
+ this.lib.editBufferMoveCursorRight(this.bufferPtr);
16145
16104
  }
16146
- deactivate() {
16147
- this.restoreOriginalConsole();
16105
+ moveCursorUp() {
16106
+ this.guard();
16107
+ this.lib.editBufferMoveCursorUp(this.bufferPtr);
16148
16108
  }
16149
- restoreOriginalConsole() {
16150
- if (this._originalConsole) {
16151
- global.console = this._originalConsole;
16152
- }
16153
- this.setupConsoleCapture();
16109
+ moveCursorDown() {
16110
+ this.guard();
16111
+ this.lib.editBufferMoveCursorDown(this.bufferPtr);
16154
16112
  }
16155
- addLogEntry(level, ...args) {
16156
- const callerInfo = this._collectCallerInfo ? getCallerInfo() : null;
16113
+ gotoLine(line) {
16114
+ this.guard();
16115
+ this.lib.editBufferGotoLine(this.bufferPtr, line);
16116
+ }
16117
+ setCursor(line, col) {
16118
+ this.guard();
16119
+ this.lib.editBufferSetCursor(this.bufferPtr, line, col);
16120
+ }
16121
+ setCursorToLineCol(line, col) {
16122
+ this.guard();
16123
+ this.lib.editBufferSetCursorToLineCol(this.bufferPtr, line, col);
16124
+ }
16125
+ setCursorByOffset(offset) {
16126
+ this.guard();
16127
+ this.lib.editBufferSetCursorByOffset(this.bufferPtr, offset);
16128
+ }
16129
+ getCursorPosition() {
16130
+ this.guard();
16131
+ return this.lib.editBufferGetCursorPosition(this.bufferPtr);
16132
+ }
16133
+ getNextWordBoundary() {
16134
+ this.guard();
16135
+ const boundary = this.lib.editBufferGetNextWordBoundary(this.bufferPtr);
16136
+ return {
16137
+ row: boundary.row,
16138
+ col: boundary.col,
16139
+ offset: boundary.offset
16140
+ };
16141
+ }
16142
+ getPrevWordBoundary() {
16143
+ this.guard();
16144
+ const boundary = this.lib.editBufferGetPrevWordBoundary(this.bufferPtr);
16145
+ return {
16146
+ row: boundary.row,
16147
+ col: boundary.col,
16148
+ offset: boundary.offset
16149
+ };
16150
+ }
16151
+ getEOL() {
16152
+ this.guard();
16153
+ const boundary = this.lib.editBufferGetEOL(this.bufferPtr);
16154
+ return {
16155
+ row: boundary.row,
16156
+ col: boundary.col,
16157
+ offset: boundary.offset
16158
+ };
16159
+ }
16160
+ offsetToPosition(offset) {
16161
+ this.guard();
16162
+ const result = this.lib.editBufferOffsetToPosition(this.bufferPtr, offset);
16163
+ if (!result)
16164
+ return null;
16165
+ return { row: result.row, col: result.col };
16166
+ }
16167
+ positionToOffset(row, col) {
16168
+ this.guard();
16169
+ return this.lib.editBufferPositionToOffset(this.bufferPtr, row, col);
16170
+ }
16171
+ getLineStartOffset(row) {
16172
+ this.guard();
16173
+ return this.lib.editBufferGetLineStartOffset(this.bufferPtr, row);
16174
+ }
16175
+ getTextRange(startOffset, endOffset) {
16176
+ this.guard();
16177
+ if (startOffset >= endOffset)
16178
+ return "";
16179
+ const maxSize = 1024 * 1024;
16180
+ const textBytes = this.lib.editBufferGetTextRange(this.bufferPtr, startOffset, endOffset, maxSize);
16181
+ if (!textBytes)
16182
+ return "";
16183
+ return this.lib.decoder.decode(textBytes);
16184
+ }
16185
+ getTextRangeByCoords(startRow, startCol, endRow, endCol) {
16186
+ this.guard();
16187
+ const maxSize = 1024 * 1024;
16188
+ const textBytes = this.lib.editBufferGetTextRangeByCoords(this.bufferPtr, startRow, startCol, endRow, endCol, maxSize);
16189
+ if (!textBytes)
16190
+ return "";
16191
+ return this.lib.decoder.decode(textBytes);
16192
+ }
16193
+ debugLogRope() {
16194
+ this.guard();
16195
+ this.lib.editBufferDebugLogRope(this.bufferPtr);
16196
+ }
16197
+ undo() {
16198
+ this.guard();
16199
+ const maxSize = 256;
16200
+ const metaBytes = this.lib.editBufferUndo(this.bufferPtr, maxSize);
16201
+ if (!metaBytes)
16202
+ return null;
16203
+ return this.lib.decoder.decode(metaBytes);
16204
+ }
16205
+ redo() {
16206
+ this.guard();
16207
+ const maxSize = 256;
16208
+ const metaBytes = this.lib.editBufferRedo(this.bufferPtr, maxSize);
16209
+ if (!metaBytes)
16210
+ return null;
16211
+ return this.lib.decoder.decode(metaBytes);
16212
+ }
16213
+ canUndo() {
16214
+ this.guard();
16215
+ return this.lib.editBufferCanUndo(this.bufferPtr);
16216
+ }
16217
+ canRedo() {
16218
+ this.guard();
16219
+ return this.lib.editBufferCanRedo(this.bufferPtr);
16220
+ }
16221
+ clearHistory() {
16222
+ this.guard();
16223
+ this.lib.editBufferClearHistory(this.bufferPtr);
16224
+ }
16225
+ setDefaultFg(fg2) {
16226
+ this.guard();
16227
+ this.lib.textBufferSetDefaultFg(this.textBufferPtr, fg2);
16228
+ }
16229
+ setDefaultBg(bg2) {
16230
+ this.guard();
16231
+ this.lib.textBufferSetDefaultBg(this.textBufferPtr, bg2);
16232
+ }
16233
+ setDefaultAttributes(attributes) {
16234
+ this.guard();
16235
+ this.lib.textBufferSetDefaultAttributes(this.textBufferPtr, attributes);
16236
+ }
16237
+ resetDefaults() {
16238
+ this.guard();
16239
+ this.lib.textBufferResetDefaults(this.textBufferPtr);
16240
+ }
16241
+ setSyntaxStyle(style) {
16242
+ this.guard();
16243
+ this._syntaxStyle = style ?? undefined;
16244
+ this.lib.textBufferSetSyntaxStyle(this.textBufferPtr, style?.ptr ?? null);
16245
+ }
16246
+ getSyntaxStyle() {
16247
+ this.guard();
16248
+ return this._syntaxStyle ?? null;
16249
+ }
16250
+ addHighlight(lineIdx, highlight) {
16251
+ this.guard();
16252
+ this.lib.textBufferAddHighlight(this.textBufferPtr, lineIdx, highlight);
16253
+ }
16254
+ addHighlightByCharRange(highlight) {
16255
+ this.guard();
16256
+ this.lib.textBufferAddHighlightByCharRange(this.textBufferPtr, highlight);
16257
+ }
16258
+ removeHighlightsByRef(hlRef) {
16259
+ this.guard();
16260
+ this.lib.textBufferRemoveHighlightsByRef(this.textBufferPtr, hlRef);
16261
+ }
16262
+ clearLineHighlights(lineIdx) {
16263
+ this.guard();
16264
+ this.lib.textBufferClearLineHighlights(this.textBufferPtr, lineIdx);
16265
+ }
16266
+ clearAllHighlights() {
16267
+ this.guard();
16268
+ this.lib.textBufferClearAllHighlights(this.textBufferPtr);
16269
+ }
16270
+ getLineHighlights(lineIdx) {
16271
+ this.guard();
16272
+ return this.lib.textBufferGetLineHighlights(this.textBufferPtr, lineIdx);
16273
+ }
16274
+ clear() {
16275
+ this.guard();
16276
+ this.lib.editBufferClear(this.bufferPtr);
16277
+ }
16278
+ destroy() {
16279
+ if (this._destroyed)
16280
+ return;
16281
+ this._destroyed = true;
16282
+ EditBuffer.registry.delete(this.id);
16283
+ this.lib.destroyEditBuffer(this.bufferPtr);
16284
+ }
16285
+ }
16286
+
16287
+ // src/editor-view.ts
16288
+ class EditorView {
16289
+ lib;
16290
+ viewPtr;
16291
+ editBuffer;
16292
+ _destroyed = false;
16293
+ _extmarksController;
16294
+ _textBufferViewPtr;
16295
+ constructor(lib, ptr5, editBuffer) {
16296
+ this.lib = lib;
16297
+ this.viewPtr = ptr5;
16298
+ this.editBuffer = editBuffer;
16299
+ }
16300
+ static create(editBuffer, viewportWidth, viewportHeight) {
16301
+ const lib = resolveRenderLib();
16302
+ const viewPtr = lib.createEditorView(editBuffer.ptr, viewportWidth, viewportHeight);
16303
+ return new EditorView(lib, viewPtr, editBuffer);
16304
+ }
16305
+ guard() {
16306
+ if (this._destroyed)
16307
+ throw new Error("EditorView is destroyed");
16308
+ }
16309
+ get ptr() {
16310
+ this.guard();
16311
+ return this.viewPtr;
16312
+ }
16313
+ setViewportSize(width, height) {
16314
+ this.guard();
16315
+ this.lib.editorViewSetViewportSize(this.viewPtr, width, height);
16316
+ }
16317
+ setViewport(x, y, width, height, moveCursor = true) {
16318
+ this.guard();
16319
+ this.lib.editorViewSetViewport(this.viewPtr, x, y, width, height, moveCursor);
16320
+ }
16321
+ getViewport() {
16322
+ this.guard();
16323
+ return this.lib.editorViewGetViewport(this.viewPtr);
16324
+ }
16325
+ setScrollMargin(margin) {
16326
+ this.guard();
16327
+ this.lib.editorViewSetScrollMargin(this.viewPtr, margin);
16328
+ }
16329
+ setWrapMode(mode) {
16330
+ this.guard();
16331
+ this.lib.editorViewSetWrapMode(this.viewPtr, mode);
16332
+ }
16333
+ getVirtualLineCount() {
16334
+ this.guard();
16335
+ return this.lib.editorViewGetVirtualLineCount(this.viewPtr);
16336
+ }
16337
+ getTotalVirtualLineCount() {
16338
+ this.guard();
16339
+ return this.lib.editorViewGetTotalVirtualLineCount(this.viewPtr);
16340
+ }
16341
+ setSelection(start, end, bgColor, fgColor) {
16342
+ this.guard();
16343
+ this.lib.editorViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
16344
+ }
16345
+ updateSelection(end, bgColor, fgColor) {
16346
+ this.guard();
16347
+ this.lib.editorViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null);
16348
+ }
16349
+ resetSelection() {
16350
+ this.guard();
16351
+ this.lib.editorViewResetSelection(this.viewPtr);
16352
+ }
16353
+ getSelection() {
16354
+ this.guard();
16355
+ return this.lib.editorViewGetSelection(this.viewPtr);
16356
+ }
16357
+ hasSelection() {
16358
+ this.guard();
16359
+ return this.getSelection() !== null;
16360
+ }
16361
+ setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) {
16362
+ this.guard();
16363
+ return this.lib.editorViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null, updateCursor ?? false, followCursor ?? false);
16364
+ }
16365
+ updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) {
16366
+ this.guard();
16367
+ return this.lib.editorViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null, updateCursor ?? false, followCursor ?? false);
16368
+ }
16369
+ resetLocalSelection() {
16370
+ this.guard();
16371
+ this.lib.editorViewResetLocalSelection(this.viewPtr);
16372
+ }
16373
+ getSelectedText() {
16374
+ this.guard();
16375
+ const maxLength = 1024 * 1024;
16376
+ const selectedBytes = this.lib.editorViewGetSelectedTextBytes(this.viewPtr, maxLength);
16377
+ if (!selectedBytes)
16378
+ return "";
16379
+ return this.lib.decoder.decode(selectedBytes);
16380
+ }
16381
+ getCursor() {
16382
+ this.guard();
16383
+ return this.lib.editorViewGetCursor(this.viewPtr);
16384
+ }
16385
+ getText() {
16386
+ this.guard();
16387
+ const maxLength = 1024 * 1024;
16388
+ const textBytes = this.lib.editorViewGetText(this.viewPtr, maxLength);
16389
+ if (!textBytes)
16390
+ return "";
16391
+ return this.lib.decoder.decode(textBytes);
16392
+ }
16393
+ getVisualCursor() {
16394
+ this.guard();
16395
+ return this.lib.editorViewGetVisualCursor(this.viewPtr);
16396
+ }
16397
+ moveUpVisual() {
16398
+ this.guard();
16399
+ this.lib.editorViewMoveUpVisual(this.viewPtr);
16400
+ }
16401
+ moveDownVisual() {
16402
+ this.guard();
16403
+ this.lib.editorViewMoveDownVisual(this.viewPtr);
16404
+ }
16405
+ deleteSelectedText() {
16406
+ this.guard();
16407
+ this.lib.editorViewDeleteSelectedText(this.viewPtr);
16408
+ }
16409
+ setCursorByOffset(offset) {
16410
+ this.guard();
16411
+ this.lib.editorViewSetCursorByOffset(this.viewPtr, offset);
16412
+ }
16413
+ getNextWordBoundary() {
16414
+ this.guard();
16415
+ return this.lib.editorViewGetNextWordBoundary(this.viewPtr);
16416
+ }
16417
+ getPrevWordBoundary() {
16418
+ this.guard();
16419
+ return this.lib.editorViewGetPrevWordBoundary(this.viewPtr);
16420
+ }
16421
+ getEOL() {
16422
+ this.guard();
16423
+ return this.lib.editorViewGetEOL(this.viewPtr);
16424
+ }
16425
+ getVisualSOL() {
16426
+ this.guard();
16427
+ return this.lib.editorViewGetVisualSOL(this.viewPtr);
16428
+ }
16429
+ getVisualEOL() {
16430
+ this.guard();
16431
+ return this.lib.editorViewGetVisualEOL(this.viewPtr);
16432
+ }
16433
+ getLineInfo() {
16434
+ this.guard();
16435
+ return this.lib.editorViewGetLineInfo(this.viewPtr);
16436
+ }
16437
+ getLogicalLineInfo() {
16438
+ this.guard();
16439
+ return this.lib.editorViewGetLogicalLineInfo(this.viewPtr);
16440
+ }
16441
+ get extmarks() {
16442
+ if (!this._extmarksController) {
16443
+ this._extmarksController = createExtmarksController(this.editBuffer, this);
16444
+ }
16445
+ return this._extmarksController;
16446
+ }
16447
+ setPlaceholderStyledText(chunks) {
16448
+ this.guard();
16449
+ this.lib.editorViewSetPlaceholderStyledText(this.viewPtr, chunks);
16450
+ }
16451
+ setTabIndicator(indicator) {
16452
+ this.guard();
16453
+ const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator;
16454
+ this.lib.editorViewSetTabIndicator(this.viewPtr, codePoint);
16455
+ }
16456
+ setTabIndicatorColor(color) {
16457
+ this.guard();
16458
+ this.lib.editorViewSetTabIndicatorColor(this.viewPtr, color);
16459
+ }
16460
+ measureForDimensions(width, height) {
16461
+ this.guard();
16462
+ if (!this._textBufferViewPtr) {
16463
+ this._textBufferViewPtr = this.lib.editorViewGetTextBufferView(this.viewPtr);
16464
+ }
16465
+ return this.lib.textBufferViewMeasureForDimensions(this._textBufferViewPtr, width, height);
16466
+ }
16467
+ destroy() {
16468
+ if (this._destroyed)
16469
+ return;
16470
+ if (this._extmarksController) {
16471
+ this._extmarksController.destroy();
16472
+ this._extmarksController = undefined;
16473
+ }
16474
+ this._destroyed = true;
16475
+ this.lib.destroyEditorView(this.viewPtr);
16476
+ }
16477
+ }
16478
+
16479
+ // src/console.ts
16480
+ import { EventEmitter as EventEmitter8 } from "events";
16481
+ import { Console } from "console";
16482
+ import fs from "fs";
16483
+ import path5 from "path";
16484
+ import util2 from "util";
16485
+
16486
+ // src/lib/output.capture.ts
16487
+ import { Writable } from "stream";
16488
+ import { EventEmitter as EventEmitter7 } from "events";
16489
+
16490
+ class Capture extends EventEmitter7 {
16491
+ output = [];
16492
+ constructor() {
16493
+ super();
16494
+ }
16495
+ get size() {
16496
+ return this.output.length;
16497
+ }
16498
+ write(stream, data) {
16499
+ this.output.push({ stream, output: data });
16500
+ this.emit("write", stream, data);
16501
+ }
16502
+ claimOutput() {
16503
+ const output = this.output.map((o) => o.output).join("");
16504
+ this.clear();
16505
+ return output;
16506
+ }
16507
+ clear() {
16508
+ this.output = [];
16509
+ }
16510
+ }
16511
+
16512
+ class CapturedWritableStream extends Writable {
16513
+ stream;
16514
+ capture;
16515
+ isTTY = true;
16516
+ columns = process.stdout.columns || 80;
16517
+ rows = process.stdout.rows || 24;
16518
+ constructor(stream, capture) {
16519
+ super();
16520
+ this.stream = stream;
16521
+ this.capture = capture;
16522
+ }
16523
+ _write(chunk, encoding, callback) {
16524
+ const data = chunk.toString();
16525
+ this.capture.write(this.stream, data);
16526
+ callback();
16527
+ }
16528
+ getColorDepth() {
16529
+ return process.stdout.getColorDepth?.() || 8;
16530
+ }
16531
+ }
16532
+
16533
+ // src/lib/keymapping.ts
16534
+ var defaultKeyAliases = {
16535
+ enter: "return",
16536
+ esc: "escape",
16537
+ kp0: "0",
16538
+ kp1: "1",
16539
+ kp2: "2",
16540
+ kp3: "3",
16541
+ kp4: "4",
16542
+ kp5: "5",
16543
+ kp6: "6",
16544
+ kp7: "7",
16545
+ kp8: "8",
16546
+ kp9: "9",
16547
+ kpdecimal: ".",
16548
+ kpdivide: "/",
16549
+ kpmultiply: "*",
16550
+ kpminus: "-",
16551
+ kpplus: "+",
16552
+ kpenter: "enter",
16553
+ kpequal: "=",
16554
+ kpseparator: ",",
16555
+ kpleft: "left",
16556
+ kpright: "right",
16557
+ kpup: "up",
16558
+ kpdown: "down",
16559
+ kppageup: "pageup",
16560
+ kppagedown: "pagedown",
16561
+ kphome: "home",
16562
+ kpend: "end",
16563
+ kpinsert: "insert",
16564
+ kpdelete: "delete"
16565
+ };
16566
+ function mergeKeyAliases(defaults, custom) {
16567
+ return { ...defaults, ...custom };
16568
+ }
16569
+ function mergeKeyBindings(defaults, custom) {
16570
+ const map = new Map;
16571
+ for (const binding of defaults) {
16572
+ const key = getKeyBindingKey(binding);
16573
+ map.set(key, binding);
16574
+ }
16575
+ for (const binding of custom) {
16576
+ const key = getKeyBindingKey(binding);
16577
+ map.set(key, binding);
16578
+ }
16579
+ return Array.from(map.values());
16580
+ }
16581
+ function getKeyBindingKey(binding) {
16582
+ return `${binding.name}:${binding.ctrl ? 1 : 0}:${binding.shift ? 1 : 0}:${binding.meta ? 1 : 0}:${binding.super ? 1 : 0}`;
16583
+ }
16584
+ function buildKeyBindingsMap(bindings, aliasMap) {
16585
+ const map = new Map;
16586
+ const aliases = aliasMap || {};
16587
+ for (const binding of bindings) {
16588
+ const key = getKeyBindingKey(binding);
16589
+ map.set(key, binding.action);
16590
+ }
16591
+ for (const binding of bindings) {
16592
+ const normalizedName = aliases[binding.name] || binding.name;
16593
+ if (normalizedName !== binding.name) {
16594
+ const aliasedKey = getKeyBindingKey({ ...binding, name: normalizedName });
16595
+ map.set(aliasedKey, binding.action);
16596
+ }
16597
+ }
16598
+ return map;
16599
+ }
16600
+ function keyBindingToString(binding) {
16601
+ const parts = [];
16602
+ if (binding.ctrl)
16603
+ parts.push("ctrl");
16604
+ if (binding.shift)
16605
+ parts.push("shift");
16606
+ if (binding.meta)
16607
+ parts.push("meta");
16608
+ if (binding.super)
16609
+ parts.push("super");
16610
+ parts.push(binding.name);
16611
+ return parts.join("+");
16612
+ }
16613
+
16614
+ // src/console.ts
16615
+ function getCallerInfo() {
16616
+ const err = new Error;
16617
+ const stackLines = err.stack?.split(`
16618
+ `).slice(5) || [];
16619
+ if (!stackLines.length)
16620
+ return null;
16621
+ const callerLine = stackLines[0].trim();
16622
+ const regex = /at\s+(?:([\w$.<>]+)\s+\()?((?:\/|[A-Za-z]:\\)[^:]+):(\d+):(\d+)\)?/;
16623
+ const match = callerLine.match(regex);
16624
+ if (!match)
16625
+ return null;
16626
+ const functionName = match[1] || "<anonymous>";
16627
+ const fullPath = match[2];
16628
+ const fileName = fullPath.split(/[\\/]/).pop() || "<unknown>";
16629
+ const lineNumber = parseInt(match[3], 10) || 0;
16630
+ const columnNumber = parseInt(match[4], 10) || 0;
16631
+ return { functionName, fullPath, fileName, lineNumber, columnNumber };
16632
+ }
16633
+ var capture = singleton("ConsoleCapture", () => new Capture);
16634
+ registerEnvVar({
16635
+ name: "OTUI_USE_CONSOLE",
16636
+ description: "Whether to use the console. Will not capture console output if set to false.",
16637
+ type: "boolean",
16638
+ default: true
16639
+ });
16640
+ registerEnvVar({
16641
+ name: "SHOW_CONSOLE",
16642
+ description: "Show the console at startup if set to true.",
16643
+ type: "boolean",
16644
+ default: false
16645
+ });
16646
+
16647
+ class TerminalConsoleCache extends EventEmitter8 {
16648
+ _cachedLogs = [];
16649
+ MAX_CACHE_SIZE = 1000;
16650
+ _collectCallerInfo = false;
16651
+ _cachingEnabled = true;
16652
+ _originalConsole = null;
16653
+ get cachedLogs() {
16654
+ return this._cachedLogs;
16655
+ }
16656
+ constructor() {
16657
+ super();
16658
+ }
16659
+ activate() {
16660
+ if (!this._originalConsole) {
16661
+ this._originalConsole = global.console;
16662
+ }
16663
+ this.setupConsoleCapture();
16664
+ this.overrideConsoleMethods();
16665
+ }
16666
+ setupConsoleCapture() {
16667
+ if (!env.OTUI_USE_CONSOLE)
16668
+ return;
16669
+ const mockStdout = new CapturedWritableStream("stdout", capture);
16670
+ const mockStderr = new CapturedWritableStream("stderr", capture);
16671
+ global.console = new Console({
16672
+ stdout: mockStdout,
16673
+ stderr: mockStderr,
16674
+ colorMode: true,
16675
+ inspectOptions: {
16676
+ compact: false,
16677
+ breakLength: 80,
16678
+ depth: 2
16679
+ }
16680
+ });
16681
+ }
16682
+ overrideConsoleMethods() {
16683
+ console.log = (...args) => {
16684
+ this.appendToConsole("LOG" /* LOG */, ...args);
16685
+ };
16686
+ console.info = (...args) => {
16687
+ this.appendToConsole("INFO" /* INFO */, ...args);
16688
+ };
16689
+ console.warn = (...args) => {
16690
+ this.appendToConsole("WARN" /* WARN */, ...args);
16691
+ };
16692
+ console.error = (...args) => {
16693
+ this.appendToConsole("ERROR" /* ERROR */, ...args);
16694
+ };
16695
+ console.debug = (...args) => {
16696
+ this.appendToConsole("DEBUG" /* DEBUG */, ...args);
16697
+ };
16698
+ }
16699
+ setCollectCallerInfo(enabled) {
16700
+ this._collectCallerInfo = enabled;
16701
+ }
16702
+ clearConsole() {
16703
+ this._cachedLogs = [];
16704
+ }
16705
+ setCachingEnabled(enabled) {
16706
+ this._cachingEnabled = enabled;
16707
+ }
16708
+ deactivate() {
16709
+ this.restoreOriginalConsole();
16710
+ }
16711
+ restoreOriginalConsole() {
16712
+ if (this._originalConsole) {
16713
+ global.console = this._originalConsole;
16714
+ }
16715
+ }
16716
+ addLogEntry(level, ...args) {
16717
+ const callerInfo = this._collectCallerInfo ? getCallerInfo() : null;
16157
16718
  const logEntry = [new Date, level, args, callerInfo];
16158
16719
  if (this._cachingEnabled) {
16159
16720
  if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) {
16160
16721
  this._cachedLogs.shift();
16161
16722
  }
16162
- this._cachedLogs.push(logEntry);
16723
+ this._cachedLogs.push(logEntry);
16724
+ }
16725
+ return logEntry;
16726
+ }
16727
+ appendToConsole(level, ...args) {
16728
+ if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) {
16729
+ this._cachedLogs.shift();
16730
+ }
16731
+ const entry = this.addLogEntry(level, ...args);
16732
+ this.emit("entry", entry);
16733
+ }
16734
+ destroy() {
16735
+ this.deactivate();
16736
+ }
16737
+ }
16738
+ var terminalConsoleCache = singleton("TerminalConsoleCache", () => {
16739
+ const terminalConsoleCache2 = new TerminalConsoleCache;
16740
+ process.on("exit", () => {
16741
+ terminalConsoleCache2.destroy();
16742
+ });
16743
+ return terminalConsoleCache2;
16744
+ });
16745
+ var ConsolePosition;
16746
+ ((ConsolePosition2) => {
16747
+ ConsolePosition2["TOP"] = "top";
16748
+ ConsolePosition2["BOTTOM"] = "bottom";
16749
+ ConsolePosition2["LEFT"] = "left";
16750
+ ConsolePosition2["RIGHT"] = "right";
16751
+ })(ConsolePosition ||= {});
16752
+ var defaultConsoleKeybindings = [
16753
+ { name: "up", action: "scroll-up" },
16754
+ { name: "down", action: "scroll-down" },
16755
+ { name: "up", shift: true, action: "scroll-to-top" },
16756
+ { name: "down", shift: true, action: "scroll-to-bottom" },
16757
+ { name: "p", ctrl: true, action: "position-previous" },
16758
+ { name: "o", ctrl: true, action: "position-next" },
16759
+ { name: "+", action: "size-increase" },
16760
+ { name: "=", shift: true, action: "size-increase" },
16761
+ { name: "-", action: "size-decrease" },
16762
+ { name: "s", ctrl: true, action: "save-logs" },
16763
+ { name: "c", ctrl: true, shift: true, action: "copy-selection" }
16764
+ ];
16765
+ var DEFAULT_CONSOLE_OPTIONS = {
16766
+ position: "bottom" /* BOTTOM */,
16767
+ sizePercent: 30,
16768
+ zIndex: Infinity,
16769
+ colorInfo: "#00FFFF",
16770
+ colorWarn: "#FFFF00",
16771
+ colorError: "#FF0000",
16772
+ colorDebug: "#808080",
16773
+ colorDefault: "#FFFFFF",
16774
+ backgroundColor: RGBA.fromValues(0.1, 0.1, 0.1, 0.7),
16775
+ startInDebugMode: false,
16776
+ title: "Console",
16777
+ titleBarColor: RGBA.fromValues(0.05, 0.05, 0.05, 0.7),
16778
+ titleBarTextColor: "#FFFFFF",
16779
+ cursorColor: "#00A0FF",
16780
+ maxStoredLogs: 2000,
16781
+ maxDisplayLines: 3000,
16782
+ onCopySelection: undefined,
16783
+ keyBindings: undefined,
16784
+ keyAliasMap: undefined,
16785
+ selectionColor: RGBA.fromValues(0.3, 0.5, 0.8, 0.5),
16786
+ copyButtonColor: "#00A0FF"
16787
+ };
16788
+ var INDENT_WIDTH = 2;
16789
+
16790
+ class TerminalConsole extends EventEmitter8 {
16791
+ isVisible = false;
16792
+ isFocused = false;
16793
+ renderer;
16794
+ keyHandler;
16795
+ options;
16796
+ _debugModeEnabled = false;
16797
+ frameBuffer = null;
16798
+ consoleX = 0;
16799
+ consoleY = 0;
16800
+ consoleWidth = 0;
16801
+ consoleHeight = 0;
16802
+ scrollTopIndex = 0;
16803
+ isScrolledToBottom = true;
16804
+ currentLineIndex = 0;
16805
+ _displayLines = [];
16806
+ _allLogEntries = [];
16807
+ _needsFrameBufferUpdate = false;
16808
+ _entryListener;
16809
+ _selectionStart = null;
16810
+ _selectionEnd = null;
16811
+ _isDragging = false;
16812
+ _copyButtonBounds = {
16813
+ x: 0,
16814
+ y: 0,
16815
+ width: 0,
16816
+ height: 0
16817
+ };
16818
+ _autoScrollInterval = null;
16819
+ clock;
16820
+ _keyBindingsMap;
16821
+ _keyAliasMap;
16822
+ _keyBindings;
16823
+ _mergedKeyBindings;
16824
+ _actionHandlers;
16825
+ markNeedsRerender() {
16826
+ this._needsFrameBufferUpdate = true;
16827
+ this.renderer.requestRender();
16828
+ }
16829
+ getCopyButtonLabel() {
16830
+ const copyBindings = this._mergedKeyBindings.filter((b) => b.action === "copy-selection");
16831
+ const copyBinding = copyBindings[copyBindings.length - 1];
16832
+ if (copyBinding) {
16833
+ const shortcut = keyBindingToString(copyBinding);
16834
+ return `[Copy (${shortcut})]`;
16835
+ }
16836
+ return "[Copy]";
16837
+ }
16838
+ _rgbaInfo;
16839
+ _rgbaWarn;
16840
+ _rgbaError;
16841
+ _rgbaDebug;
16842
+ _rgbaDefault;
16843
+ backgroundColor;
16844
+ _rgbaTitleBar;
16845
+ _rgbaTitleBarText;
16846
+ _title;
16847
+ _rgbaCursor;
16848
+ _rgbaSelection;
16849
+ _rgbaCopyButton;
16850
+ _positions = [
16851
+ "top" /* TOP */,
16852
+ "right" /* RIGHT */,
16853
+ "bottom" /* BOTTOM */,
16854
+ "left" /* LEFT */
16855
+ ];
16856
+ constructor(renderer, options = {}) {
16857
+ super();
16858
+ this.renderer = renderer;
16859
+ this.clock = options.clock ?? new SystemClock;
16860
+ this.options = { ...DEFAULT_CONSOLE_OPTIONS, ...options };
16861
+ this.keyHandler = this.handleKeyPress.bind(this);
16862
+ this._debugModeEnabled = this.options.startInDebugMode;
16863
+ terminalConsoleCache.setCollectCallerInfo(this._debugModeEnabled);
16864
+ this._rgbaInfo = parseColor(this.options.colorInfo);
16865
+ this._rgbaWarn = parseColor(this.options.colorWarn);
16866
+ this._rgbaError = parseColor(this.options.colorError);
16867
+ this._rgbaDebug = parseColor(this.options.colorDebug);
16868
+ this._rgbaDefault = parseColor(this.options.colorDefault);
16869
+ this.backgroundColor = parseColor(this.options.backgroundColor);
16870
+ this._rgbaTitleBar = parseColor(this.options.titleBarColor);
16871
+ this._rgbaTitleBarText = parseColor(this.options.titleBarTextColor || this.options.colorDefault);
16872
+ this._title = this.options.title;
16873
+ this._rgbaCursor = parseColor(this.options.cursorColor);
16874
+ this._rgbaSelection = parseColor(this.options.selectionColor);
16875
+ this._rgbaCopyButton = parseColor(this.options.copyButtonColor);
16876
+ this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {});
16877
+ this._keyBindings = options.keyBindings || [];
16878
+ this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings);
16879
+ this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap);
16880
+ this._actionHandlers = this.buildActionHandlers();
16881
+ this._updateConsoleDimensions();
16882
+ this._scrollToBottom(true);
16883
+ this._entryListener = (logEntry) => {
16884
+ this._handleNewLog(logEntry);
16885
+ };
16886
+ terminalConsoleCache.on("entry", this._entryListener);
16887
+ if (env.SHOW_CONSOLE) {
16888
+ this.show();
16889
+ }
16890
+ }
16891
+ buildActionHandlers() {
16892
+ return new Map([
16893
+ ["scroll-up", () => this.scrollUp()],
16894
+ ["scroll-down", () => this.scrollDown()],
16895
+ ["scroll-to-top", () => this.scrollToTop()],
16896
+ ["scroll-to-bottom", () => this.scrollToBottomAction()],
16897
+ ["position-previous", () => this.positionPrevious()],
16898
+ ["position-next", () => this.positionNext()],
16899
+ ["size-increase", () => this.sizeIncrease()],
16900
+ ["size-decrease", () => this.sizeDecrease()],
16901
+ ["save-logs", () => this.saveLogsAction()],
16902
+ ["copy-selection", () => this.triggerCopyAction()]
16903
+ ]);
16904
+ }
16905
+ activate() {
16906
+ terminalConsoleCache.activate();
16907
+ }
16908
+ deactivate() {
16909
+ terminalConsoleCache.deactivate();
16910
+ }
16911
+ _handleNewLog(logEntry) {
16912
+ if (!this.isVisible)
16913
+ return;
16914
+ this._allLogEntries.push(logEntry);
16915
+ if (this._allLogEntries.length > this.options.maxStoredLogs) {
16916
+ this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs);
16917
+ }
16918
+ const newDisplayLines = this._processLogEntry(logEntry);
16919
+ this._displayLines.push(...newDisplayLines);
16920
+ if (this._displayLines.length > this.options.maxDisplayLines) {
16921
+ this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines);
16922
+ const linesRemoved = this._displayLines.length - this.options.maxDisplayLines;
16923
+ this.scrollTopIndex = Math.max(0, this.scrollTopIndex - linesRemoved);
16924
+ }
16925
+ if (this.isScrolledToBottom) {
16926
+ this._scrollToBottom();
16927
+ }
16928
+ this.markNeedsRerender();
16929
+ }
16930
+ _updateConsoleDimensions(termWidth, termHeight) {
16931
+ const width = termWidth ?? this.renderer.width;
16932
+ const height = termHeight ?? this.renderer.height;
16933
+ const sizePercent = this.options.sizePercent / 100;
16934
+ switch (this.options.position) {
16935
+ case "top" /* TOP */:
16936
+ this.consoleX = 0;
16937
+ this.consoleY = 0;
16938
+ this.consoleWidth = width;
16939
+ this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
16940
+ break;
16941
+ case "bottom" /* BOTTOM */:
16942
+ this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
16943
+ this.consoleWidth = width;
16944
+ this.consoleX = 0;
16945
+ this.consoleY = height - this.consoleHeight;
16946
+ break;
16947
+ case "left" /* LEFT */:
16948
+ this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
16949
+ this.consoleHeight = height;
16950
+ this.consoleX = 0;
16951
+ this.consoleY = 0;
16952
+ break;
16953
+ case "right" /* RIGHT */:
16954
+ this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
16955
+ this.consoleHeight = height;
16956
+ this.consoleY = 0;
16957
+ this.consoleX = width - this.consoleWidth;
16958
+ break;
16959
+ }
16960
+ this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, this.consoleHeight - 1));
16961
+ }
16962
+ handleKeyPress(event) {
16963
+ if (event.name === "escape") {
16964
+ this.blur();
16965
+ return;
16966
+ }
16967
+ const bindingKey = getKeyBindingKey({
16968
+ name: event.name,
16969
+ ctrl: event.ctrl,
16970
+ shift: event.shift,
16971
+ meta: event.meta,
16972
+ super: event.super,
16973
+ action: "scroll-up"
16974
+ });
16975
+ const action = this._keyBindingsMap.get(bindingKey);
16976
+ if (action) {
16977
+ const handler = this._actionHandlers.get(action);
16978
+ if (handler) {
16979
+ handler();
16980
+ return;
16981
+ }
16982
+ }
16983
+ }
16984
+ scrollUp() {
16985
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16986
+ if (this.currentLineIndex > 0) {
16987
+ this.currentLineIndex--;
16988
+ this.markNeedsRerender();
16989
+ } else if (this.scrollTopIndex > 0) {
16990
+ this.scrollTopIndex--;
16991
+ this.isScrolledToBottom = false;
16992
+ this.markNeedsRerender();
16993
+ }
16994
+ return true;
16995
+ }
16996
+ scrollDown() {
16997
+ const displayLineCount = this._displayLines.length;
16998
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16999
+ const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
17000
+ const canCursorMoveDown = this.currentLineIndex < logAreaHeight - 1 && this.scrollTopIndex + this.currentLineIndex < displayLineCount - 1;
17001
+ if (canCursorMoveDown) {
17002
+ this.currentLineIndex++;
17003
+ this.markNeedsRerender();
17004
+ } else if (this.scrollTopIndex < maxScrollTop) {
17005
+ this.scrollTopIndex++;
17006
+ this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
17007
+ this.markNeedsRerender();
17008
+ }
17009
+ return true;
17010
+ }
17011
+ scrollToTop() {
17012
+ if (this.scrollTopIndex > 0 || this.currentLineIndex > 0) {
17013
+ this.scrollTopIndex = 0;
17014
+ this.currentLineIndex = 0;
17015
+ this.isScrolledToBottom = this._displayLines.length <= Math.max(1, this.consoleHeight - 1);
17016
+ this.markNeedsRerender();
17017
+ }
17018
+ return true;
17019
+ }
17020
+ scrollToBottomAction() {
17021
+ const logAreaHeightForScroll = Math.max(1, this.consoleHeight - 1);
17022
+ const maxScrollPossible = Math.max(0, this._displayLines.length - logAreaHeightForScroll);
17023
+ if (this.scrollTopIndex < maxScrollPossible || !this.isScrolledToBottom) {
17024
+ this._scrollToBottom(true);
17025
+ this.markNeedsRerender();
17026
+ }
17027
+ return true;
17028
+ }
17029
+ positionPrevious() {
17030
+ const currentPositionIndex = this._positions.indexOf(this.options.position);
17031
+ const prevIndex = (currentPositionIndex - 1 + this._positions.length) % this._positions.length;
17032
+ this.options.position = this._positions[prevIndex];
17033
+ this.resize(this.renderer.width, this.renderer.height);
17034
+ return true;
17035
+ }
17036
+ positionNext() {
17037
+ const currentPositionIndex = this._positions.indexOf(this.options.position);
17038
+ const nextIndex = (currentPositionIndex + 1) % this._positions.length;
17039
+ this.options.position = this._positions[nextIndex];
17040
+ this.resize(this.renderer.width, this.renderer.height);
17041
+ return true;
17042
+ }
17043
+ sizeIncrease() {
17044
+ this.options.sizePercent = Math.min(100, this.options.sizePercent + 5);
17045
+ this.resize(this.renderer.width, this.renderer.height);
17046
+ return true;
17047
+ }
17048
+ sizeDecrease() {
17049
+ this.options.sizePercent = Math.max(10, this.options.sizePercent - 5);
17050
+ this.resize(this.renderer.width, this.renderer.height);
17051
+ return true;
17052
+ }
17053
+ saveLogsAction() {
17054
+ this.saveLogsToFile();
17055
+ return true;
17056
+ }
17057
+ triggerCopyAction() {
17058
+ this.triggerCopy();
17059
+ return true;
17060
+ }
17061
+ attachStdin() {
17062
+ if (this.isFocused)
17063
+ return;
17064
+ this.renderer.keyInput.on("keypress", this.keyHandler);
17065
+ this.isFocused = true;
17066
+ }
17067
+ detachStdin() {
17068
+ if (!this.isFocused)
17069
+ return;
17070
+ this.renderer.keyInput.off("keypress", this.keyHandler);
17071
+ this.isFocused = false;
17072
+ }
17073
+ formatTimestamp(date) {
17074
+ return new Intl.DateTimeFormat("en-US", {
17075
+ hour: "2-digit",
17076
+ minute: "2-digit",
17077
+ second: "2-digit",
17078
+ hour12: false
17079
+ }).format(date);
17080
+ }
17081
+ formatArguments(args) {
17082
+ return args.map((arg) => {
17083
+ if (arg instanceof Error) {
17084
+ const errorProps = arg;
17085
+ return `Error: ${errorProps.message}
17086
+ ` + (errorProps.stack ? `${errorProps.stack}
17087
+ ` : "");
17088
+ }
17089
+ if (typeof arg === "object" && arg !== null) {
17090
+ try {
17091
+ return util2.inspect(arg, { depth: 2 });
17092
+ } catch (e) {
17093
+ return String(arg);
17094
+ }
17095
+ }
17096
+ try {
17097
+ return util2.inspect(arg, { depth: 2 });
17098
+ } catch (e) {
17099
+ return String(arg);
17100
+ }
17101
+ }).join(" ");
17102
+ }
17103
+ resize(width, height) {
17104
+ this._updateConsoleDimensions(width, height);
17105
+ if (this.frameBuffer) {
17106
+ this.frameBuffer.resize(this.consoleWidth, this.consoleHeight);
17107
+ const displayLineCount = this._displayLines.length;
17108
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
17109
+ const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
17110
+ this.scrollTopIndex = Math.min(this.scrollTopIndex, maxScrollTop);
17111
+ this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
17112
+ const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex);
17113
+ this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, visibleLineCount - 1));
17114
+ if (this.isVisible) {
17115
+ this.markNeedsRerender();
17116
+ }
17117
+ }
17118
+ }
17119
+ clear() {
17120
+ terminalConsoleCache.clearConsole();
17121
+ this._allLogEntries = [];
17122
+ this._displayLines = [];
17123
+ this.markNeedsRerender();
17124
+ }
17125
+ toggle() {
17126
+ if (this.isVisible) {
17127
+ if (this.isFocused) {
17128
+ this.hide();
17129
+ } else {
17130
+ this.focus();
17131
+ }
17132
+ } else {
17133
+ this.show();
17134
+ }
17135
+ if (!this.renderer.isRunning) {
17136
+ this.renderer.requestRender();
17137
+ }
17138
+ }
17139
+ focus() {
17140
+ this.attachStdin();
17141
+ this._scrollToBottom(true);
17142
+ this.markNeedsRerender();
17143
+ }
17144
+ blur() {
17145
+ this.detachStdin();
17146
+ this.markNeedsRerender();
17147
+ }
17148
+ show() {
17149
+ if (!this.isVisible) {
17150
+ this.isVisible = true;
17151
+ this._processCachedLogs();
17152
+ terminalConsoleCache.setCachingEnabled(false);
17153
+ if (!this.frameBuffer) {
17154
+ this.frameBuffer = OptimizedBuffer.create(this.consoleWidth, this.consoleHeight, this.renderer.widthMethod, {
17155
+ respectAlpha: this.backgroundColor.a < 1,
17156
+ id: "console framebuffer"
17157
+ });
17158
+ }
17159
+ const logCount = terminalConsoleCache.cachedLogs.length;
17160
+ const visibleLogLines = Math.min(this.consoleHeight, logCount);
17161
+ this.currentLineIndex = Math.max(0, visibleLogLines - 1);
17162
+ this.scrollTopIndex = 0;
17163
+ this._scrollToBottom(true);
17164
+ this.focus();
17165
+ this.markNeedsRerender();
16163
17166
  }
16164
- return logEntry;
16165
17167
  }
16166
- appendToConsole(level, ...args) {
16167
- if (this._cachedLogs.length >= this.MAX_CACHE_SIZE) {
16168
- this._cachedLogs.shift();
17168
+ hide() {
17169
+ if (this.isVisible) {
17170
+ this.isVisible = false;
17171
+ this.blur();
17172
+ terminalConsoleCache.setCachingEnabled(true);
16169
17173
  }
16170
- const entry = this.addLogEntry(level, ...args);
16171
- this.emit("entry", entry);
16172
17174
  }
16173
17175
  destroy() {
17176
+ this.stopAutoScroll();
17177
+ this.hide();
16174
17178
  this.deactivate();
17179
+ terminalConsoleCache.off("entry", this._entryListener);
16175
17180
  }
16176
- }
16177
- var terminalConsoleCache = singleton("TerminalConsoleCache", () => {
16178
- const terminalConsoleCache2 = new TerminalConsoleCache;
16179
- process.on("exit", () => {
16180
- terminalConsoleCache2.destroy();
16181
- });
16182
- return terminalConsoleCache2;
16183
- });
16184
- var ConsolePosition;
16185
- ((ConsolePosition2) => {
16186
- ConsolePosition2["TOP"] = "top";
16187
- ConsolePosition2["BOTTOM"] = "bottom";
16188
- ConsolePosition2["LEFT"] = "left";
16189
- ConsolePosition2["RIGHT"] = "right";
16190
- })(ConsolePosition ||= {});
16191
- var defaultConsoleKeybindings = [
16192
- { name: "up", action: "scroll-up" },
16193
- { name: "down", action: "scroll-down" },
16194
- { name: "up", shift: true, action: "scroll-to-top" },
16195
- { name: "down", shift: true, action: "scroll-to-bottom" },
16196
- { name: "p", ctrl: true, action: "position-previous" },
16197
- { name: "o", ctrl: true, action: "position-next" },
16198
- { name: "+", action: "size-increase" },
16199
- { name: "=", shift: true, action: "size-increase" },
16200
- { name: "-", action: "size-decrease" },
16201
- { name: "s", ctrl: true, action: "save-logs" },
16202
- { name: "c", ctrl: true, shift: true, action: "copy-selection" }
16203
- ];
16204
- var DEFAULT_CONSOLE_OPTIONS = {
16205
- position: "bottom" /* BOTTOM */,
16206
- sizePercent: 30,
16207
- zIndex: Infinity,
16208
- colorInfo: "#00FFFF",
16209
- colorWarn: "#FFFF00",
16210
- colorError: "#FF0000",
16211
- colorDebug: "#808080",
16212
- colorDefault: "#FFFFFF",
16213
- backgroundColor: RGBA.fromValues(0.1, 0.1, 0.1, 0.7),
16214
- startInDebugMode: false,
16215
- title: "Console",
16216
- titleBarColor: RGBA.fromValues(0.05, 0.05, 0.05, 0.7),
16217
- titleBarTextColor: "#FFFFFF",
16218
- cursorColor: "#00A0FF",
16219
- maxStoredLogs: 2000,
16220
- maxDisplayLines: 3000,
16221
- onCopySelection: undefined,
16222
- keyBindings: undefined,
16223
- keyAliasMap: undefined,
16224
- selectionColor: RGBA.fromValues(0.3, 0.5, 0.8, 0.5),
16225
- copyButtonColor: "#00A0FF"
16226
- };
16227
- var INDENT_WIDTH = 2;
16228
-
16229
- class TerminalConsole extends EventEmitter7 {
16230
- isVisible = false;
16231
- isFocused = false;
16232
- renderer;
16233
- keyHandler;
16234
- options;
16235
- _debugModeEnabled = false;
16236
- frameBuffer = null;
16237
- consoleX = 0;
16238
- consoleY = 0;
16239
- consoleWidth = 0;
16240
- consoleHeight = 0;
16241
- scrollTopIndex = 0;
16242
- isScrolledToBottom = true;
16243
- currentLineIndex = 0;
16244
- _displayLines = [];
16245
- _allLogEntries = [];
16246
- _needsFrameBufferUpdate = false;
16247
- _entryListener;
16248
- _selectionStart = null;
16249
- _selectionEnd = null;
16250
- _isDragging = false;
16251
- _copyButtonBounds = {
16252
- x: 0,
16253
- y: 0,
16254
- width: 0,
16255
- height: 0
16256
- };
16257
- _autoScrollInterval = null;
16258
- clock;
16259
- _keyBindingsMap;
16260
- _keyAliasMap;
16261
- _keyBindings;
16262
- _mergedKeyBindings;
16263
- _actionHandlers;
16264
- markNeedsRerender() {
16265
- this._needsFrameBufferUpdate = true;
16266
- this.renderer.requestRender();
17181
+ getCachedLogs() {
17182
+ return terminalConsoleCache.cachedLogs.map((logEntry) => logEntry[0].toISOString() + " " + logEntry.slice(1).join(" ")).join(`
17183
+ `);
16267
17184
  }
16268
- getCopyButtonLabel() {
16269
- const copyBindings = this._mergedKeyBindings.filter((b) => b.action === "copy-selection");
16270
- const copyBinding = copyBindings[copyBindings.length - 1];
16271
- if (copyBinding) {
16272
- const shortcut = keyBindingToString(copyBinding);
16273
- return `[Copy (${shortcut})]`;
17185
+ updateFrameBuffer() {
17186
+ if (!this.frameBuffer)
17187
+ return;
17188
+ this.frameBuffer.clear(this.backgroundColor);
17189
+ const displayLines = this._displayLines;
17190
+ const displayLineCount = displayLines.length;
17191
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
17192
+ this.frameBuffer.fillRect(0, 0, this.consoleWidth, 1, this._rgbaTitleBar);
17193
+ const dynamicTitle = `${this._title}${this.isFocused ? " (Focused)" : ""}`;
17194
+ const titleX = Math.max(0, Math.floor((this.consoleWidth - dynamicTitle.length) / 2));
17195
+ this.frameBuffer.drawText(dynamicTitle, titleX, 0, this._rgbaTitleBarText, this._rgbaTitleBar);
17196
+ const copyLabel = this.getCopyButtonLabel();
17197
+ const copyButtonX = this.consoleWidth - copyLabel.length - 1;
17198
+ if (copyButtonX >= 0) {
17199
+ const copyButtonEnabled = this.hasSelection();
17200
+ const disabledColor = RGBA.fromInts(100, 100, 100, 255);
17201
+ const copyColor = copyButtonEnabled ? this._rgbaCopyButton : disabledColor;
17202
+ this.frameBuffer.drawText(copyLabel, copyButtonX, 0, copyColor, this._rgbaTitleBar);
17203
+ this._copyButtonBounds = { x: copyButtonX, y: 0, width: copyLabel.length, height: 1 };
17204
+ } else {
17205
+ this._copyButtonBounds = { x: -1, y: -1, width: 0, height: 0 };
16274
17206
  }
16275
- return "[Copy]";
16276
- }
16277
- _rgbaInfo;
16278
- _rgbaWarn;
16279
- _rgbaError;
16280
- _rgbaDebug;
16281
- _rgbaDefault;
16282
- backgroundColor;
16283
- _rgbaTitleBar;
16284
- _rgbaTitleBarText;
16285
- _title;
16286
- _rgbaCursor;
16287
- _rgbaSelection;
16288
- _rgbaCopyButton;
16289
- _positions = [
16290
- "top" /* TOP */,
16291
- "right" /* RIGHT */,
16292
- "bottom" /* BOTTOM */,
16293
- "left" /* LEFT */
16294
- ];
16295
- constructor(renderer, options = {}) {
16296
- super();
16297
- this.renderer = renderer;
16298
- this.clock = options.clock ?? new SystemClock;
16299
- this.options = { ...DEFAULT_CONSOLE_OPTIONS, ...options };
16300
- this.keyHandler = this.handleKeyPress.bind(this);
16301
- this._debugModeEnabled = this.options.startInDebugMode;
16302
- terminalConsoleCache.setCollectCallerInfo(this._debugModeEnabled);
16303
- this._rgbaInfo = parseColor(this.options.colorInfo);
16304
- this._rgbaWarn = parseColor(this.options.colorWarn);
16305
- this._rgbaError = parseColor(this.options.colorError);
16306
- this._rgbaDebug = parseColor(this.options.colorDebug);
16307
- this._rgbaDefault = parseColor(this.options.colorDefault);
16308
- this.backgroundColor = parseColor(this.options.backgroundColor);
16309
- this._rgbaTitleBar = parseColor(this.options.titleBarColor);
16310
- this._rgbaTitleBarText = parseColor(this.options.titleBarTextColor || this.options.colorDefault);
16311
- this._title = this.options.title;
16312
- this._rgbaCursor = parseColor(this.options.cursorColor);
16313
- this._rgbaSelection = parseColor(this.options.selectionColor);
16314
- this._rgbaCopyButton = parseColor(this.options.copyButtonColor);
16315
- this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {});
16316
- this._keyBindings = options.keyBindings || [];
17207
+ const startIndex = this.scrollTopIndex;
17208
+ const endIndex = Math.min(startIndex + logAreaHeight, displayLineCount);
17209
+ const visibleDisplayLines = displayLines.slice(startIndex, endIndex);
17210
+ let lineY = 1;
17211
+ for (let i = 0;i < visibleDisplayLines.length; i++) {
17212
+ if (lineY >= this.consoleHeight)
17213
+ break;
17214
+ const displayLine = visibleDisplayLines[i];
17215
+ const absoluteLineIndex = startIndex + i;
17216
+ let levelColor = this._rgbaDefault;
17217
+ switch (displayLine.level) {
17218
+ case "INFO" /* INFO */:
17219
+ levelColor = this._rgbaInfo;
17220
+ break;
17221
+ case "WARN" /* WARN */:
17222
+ levelColor = this._rgbaWarn;
17223
+ break;
17224
+ case "ERROR" /* ERROR */:
17225
+ levelColor = this._rgbaError;
17226
+ break;
17227
+ case "DEBUG" /* DEBUG */:
17228
+ levelColor = this._rgbaDebug;
17229
+ break;
17230
+ }
17231
+ const linePrefix = displayLine.indent ? " ".repeat(INDENT_WIDTH) : "";
17232
+ const textToDraw = displayLine.text;
17233
+ const textAvailableWidth = this.consoleWidth - 1 - (displayLine.indent ? INDENT_WIDTH : 0);
17234
+ const showCursor = this.isFocused && lineY - 1 === this.currentLineIndex;
17235
+ if (showCursor) {
17236
+ this.frameBuffer.drawText(">", 0, lineY, this._rgbaCursor, this.backgroundColor);
17237
+ } else {
17238
+ this.frameBuffer.drawText(" ", 0, lineY, this._rgbaDefault, this.backgroundColor);
17239
+ }
17240
+ const fullText = `${linePrefix}${textToDraw.substring(0, textAvailableWidth)}`;
17241
+ const selectionRange = this.getLineSelectionRange(absoluteLineIndex);
17242
+ if (selectionRange) {
17243
+ const adjustedStart = Math.max(0, selectionRange.start);
17244
+ const adjustedEnd = Math.min(fullText.length, selectionRange.end);
17245
+ if (adjustedStart > 0) {
17246
+ this.frameBuffer.drawText(fullText.substring(0, adjustedStart), 1, lineY, levelColor);
17247
+ }
17248
+ if (adjustedStart < adjustedEnd) {
17249
+ this.frameBuffer.fillRect(1 + adjustedStart, lineY, adjustedEnd - adjustedStart, 1, this._rgbaSelection);
17250
+ this.frameBuffer.drawText(fullText.substring(adjustedStart, adjustedEnd), 1 + adjustedStart, lineY, levelColor, this._rgbaSelection);
17251
+ }
17252
+ if (adjustedEnd < fullText.length) {
17253
+ this.frameBuffer.drawText(fullText.substring(adjustedEnd), 1 + adjustedEnd, lineY, levelColor);
17254
+ }
17255
+ } else {
17256
+ this.frameBuffer.drawText(fullText, 1, lineY, levelColor);
17257
+ }
17258
+ lineY++;
17259
+ }
17260
+ }
17261
+ renderToBuffer(buffer) {
17262
+ if (!this.isVisible || !this.frameBuffer)
17263
+ return;
17264
+ if (this._needsFrameBufferUpdate) {
17265
+ this.updateFrameBuffer();
17266
+ this._needsFrameBufferUpdate = false;
17267
+ }
17268
+ buffer.drawFrameBuffer(this.consoleX, this.consoleY, this.frameBuffer);
17269
+ }
17270
+ setDebugMode(enabled) {
17271
+ this._debugModeEnabled = enabled;
17272
+ terminalConsoleCache.setCollectCallerInfo(enabled);
17273
+ if (this.isVisible) {
17274
+ this.markNeedsRerender();
17275
+ }
17276
+ }
17277
+ toggleDebugMode() {
17278
+ this.setDebugMode(!this._debugModeEnabled);
17279
+ }
17280
+ set keyBindings(bindings) {
17281
+ this._keyBindings = bindings;
17282
+ this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, bindings);
17283
+ this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap);
17284
+ this.markNeedsRerender();
17285
+ }
17286
+ set keyAliasMap(aliases) {
17287
+ this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases);
16317
17288
  this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings);
16318
17289
  this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap);
16319
- this._actionHandlers = this.buildActionHandlers();
16320
- this._updateConsoleDimensions();
16321
- this._scrollToBottom(true);
16322
- this._entryListener = (logEntry) => {
16323
- this._handleNewLog(logEntry);
16324
- };
16325
- terminalConsoleCache.on("entry", this._entryListener);
16326
- if (env.SHOW_CONSOLE) {
16327
- this.show();
16328
- }
17290
+ this.markNeedsRerender();
16329
17291
  }
16330
- buildActionHandlers() {
16331
- return new Map([
16332
- ["scroll-up", () => this.scrollUp()],
16333
- ["scroll-down", () => this.scrollDown()],
16334
- ["scroll-to-top", () => this.scrollToTop()],
16335
- ["scroll-to-bottom", () => this.scrollToBottomAction()],
16336
- ["position-previous", () => this.positionPrevious()],
16337
- ["position-next", () => this.positionNext()],
16338
- ["size-increase", () => this.sizeIncrease()],
16339
- ["size-decrease", () => this.sizeDecrease()],
16340
- ["save-logs", () => this.saveLogsAction()],
16341
- ["copy-selection", () => this.triggerCopyAction()]
16342
- ]);
17292
+ set onCopySelection(callback) {
17293
+ this.options.onCopySelection = callback;
16343
17294
  }
16344
- activate() {
16345
- terminalConsoleCache.activate();
17295
+ get onCopySelection() {
17296
+ return this.options.onCopySelection;
16346
17297
  }
16347
- deactivate() {
16348
- terminalConsoleCache.deactivate();
17298
+ _scrollToBottom(forceCursorToLastLine = false) {
17299
+ const displayLineCount = this._displayLines.length;
17300
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
17301
+ const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
17302
+ this.scrollTopIndex = maxScrollTop;
17303
+ this.isScrolledToBottom = true;
17304
+ const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex);
17305
+ if (forceCursorToLastLine || this.currentLineIndex >= visibleLineCount) {
17306
+ this.currentLineIndex = Math.max(0, visibleLineCount - 1);
17307
+ }
16349
17308
  }
16350
- _handleNewLog(logEntry) {
16351
- if (!this.isVisible)
16352
- return;
16353
- this._allLogEntries.push(logEntry);
17309
+ _processLogEntry(logEntry) {
17310
+ const [date, level, args, callerInfo] = logEntry;
17311
+ const displayLines = [];
17312
+ const timestamp = this.formatTimestamp(date);
17313
+ const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown";
17314
+ const prefix = `[${timestamp}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " ";
17315
+ const formattedArgs = this.formatArguments(args);
17316
+ const initialLines = formattedArgs.split(`
17317
+ `);
17318
+ for (let i = 0;i < initialLines.length; i++) {
17319
+ const lineText = initialLines[i];
17320
+ const isFirstLineOfEntry = i === 0;
17321
+ const availableWidth = this.consoleWidth - 1 - (isFirstLineOfEntry ? 0 : INDENT_WIDTH);
17322
+ const linePrefix = isFirstLineOfEntry ? prefix : " ".repeat(INDENT_WIDTH);
17323
+ const textToWrap = isFirstLineOfEntry ? linePrefix + lineText : lineText;
17324
+ let currentPos = 0;
17325
+ while (currentPos < textToWrap.length || isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0) {
17326
+ const segment = textToWrap.substring(currentPos, currentPos + availableWidth);
17327
+ const isFirstSegmentOfLine = currentPos === 0;
17328
+ displayLines.push({
17329
+ text: isFirstSegmentOfLine && !isFirstLineOfEntry ? linePrefix + segment : segment,
17330
+ level,
17331
+ indent: !isFirstLineOfEntry || !isFirstSegmentOfLine
17332
+ });
17333
+ currentPos += availableWidth;
17334
+ if (isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0)
17335
+ break;
17336
+ }
17337
+ }
17338
+ return displayLines;
17339
+ }
17340
+ _processCachedLogs() {
17341
+ const logsToProcess = [...terminalConsoleCache.cachedLogs];
17342
+ terminalConsoleCache.clearConsole();
17343
+ this._allLogEntries.push(...logsToProcess);
16354
17344
  if (this._allLogEntries.length > this.options.maxStoredLogs) {
16355
17345
  this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs);
16356
17346
  }
16357
- const newDisplayLines = this._processLogEntry(logEntry);
16358
- this._displayLines.push(...newDisplayLines);
17347
+ for (const logEntry of logsToProcess) {
17348
+ const processed = this._processLogEntry(logEntry);
17349
+ this._displayLines.push(...processed);
17350
+ }
16359
17351
  if (this._displayLines.length > this.options.maxDisplayLines) {
16360
17352
  this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines);
16361
- const linesRemoved = this._displayLines.length - this.options.maxDisplayLines;
16362
- this.scrollTopIndex = Math.max(0, this.scrollTopIndex - linesRemoved);
16363
17353
  }
16364
- if (this.isScrolledToBottom) {
16365
- this._scrollToBottom();
17354
+ }
17355
+ hasSelection() {
17356
+ if (this._selectionStart === null || this._selectionEnd === null)
17357
+ return false;
17358
+ return this._selectionStart.line !== this._selectionEnd.line || this._selectionStart.col !== this._selectionEnd.col;
17359
+ }
17360
+ normalizeSelection() {
17361
+ if (!this._selectionStart || !this._selectionEnd)
17362
+ return null;
17363
+ const start = this._selectionStart;
17364
+ const end = this._selectionEnd;
17365
+ const startBeforeEnd = start.line < end.line || start.line === end.line && start.col <= end.col;
17366
+ if (startBeforeEnd) {
17367
+ return {
17368
+ startLine: start.line,
17369
+ startCol: start.col,
17370
+ endLine: end.line,
17371
+ endCol: end.col
17372
+ };
17373
+ } else {
17374
+ return {
17375
+ startLine: end.line,
17376
+ startCol: end.col,
17377
+ endLine: start.line,
17378
+ endCol: start.col
17379
+ };
16366
17380
  }
16367
- this.markNeedsRerender();
16368
17381
  }
16369
- _updateConsoleDimensions(termWidth, termHeight) {
16370
- const width = termWidth ?? this.renderer.width;
16371
- const height = termHeight ?? this.renderer.height;
16372
- const sizePercent = this.options.sizePercent / 100;
16373
- switch (this.options.position) {
16374
- case "top" /* TOP */:
16375
- this.consoleX = 0;
16376
- this.consoleY = 0;
16377
- this.consoleWidth = width;
16378
- this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
16379
- break;
16380
- case "bottom" /* BOTTOM */:
16381
- this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
16382
- this.consoleWidth = width;
16383
- this.consoleX = 0;
16384
- this.consoleY = height - this.consoleHeight;
16385
- break;
16386
- case "left" /* LEFT */:
16387
- this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
16388
- this.consoleHeight = height;
16389
- this.consoleX = 0;
16390
- this.consoleY = 0;
16391
- break;
16392
- case "right" /* RIGHT */:
16393
- this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
16394
- this.consoleHeight = height;
16395
- this.consoleY = 0;
16396
- this.consoleX = width - this.consoleWidth;
16397
- break;
17382
+ getSelectedText() {
17383
+ const selection2 = this.normalizeSelection();
17384
+ if (!selection2)
17385
+ return "";
17386
+ const lines = [];
17387
+ for (let i = selection2.startLine;i <= selection2.endLine; i++) {
17388
+ if (i < 0 || i >= this._displayLines.length)
17389
+ continue;
17390
+ const line = this._displayLines[i];
17391
+ const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : "";
17392
+ const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0);
17393
+ const fullText = linePrefix + line.text.substring(0, textAvailableWidth);
17394
+ let text = fullText;
17395
+ if (i === selection2.startLine && i === selection2.endLine) {
17396
+ text = fullText.substring(selection2.startCol, selection2.endCol);
17397
+ } else if (i === selection2.startLine) {
17398
+ text = fullText.substring(selection2.startCol);
17399
+ } else if (i === selection2.endLine) {
17400
+ text = fullText.substring(0, selection2.endCol);
17401
+ }
17402
+ lines.push(text);
16398
17403
  }
16399
- this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, this.consoleHeight - 1));
17404
+ return lines.join(`
17405
+ `);
16400
17406
  }
16401
- handleKeyPress(event) {
16402
- if (event.name === "escape") {
16403
- this.blur();
16404
- return;
17407
+ clearSelection() {
17408
+ this._selectionStart = null;
17409
+ this._selectionEnd = null;
17410
+ this._isDragging = false;
17411
+ this.stopAutoScroll();
17412
+ }
17413
+ stopAutoScroll() {
17414
+ if (this._autoScrollInterval !== null) {
17415
+ this.clock.clearInterval(this._autoScrollInterval);
17416
+ this._autoScrollInterval = null;
16405
17417
  }
16406
- const bindingKey = getKeyBindingKey({
16407
- name: event.name,
16408
- ctrl: event.ctrl,
16409
- shift: event.shift,
16410
- meta: event.meta,
16411
- super: event.super,
16412
- action: "scroll-up"
16413
- });
16414
- const action = this._keyBindingsMap.get(bindingKey);
16415
- if (action) {
16416
- const handler = this._actionHandlers.get(action);
16417
- if (handler) {
16418
- handler();
16419
- return;
17418
+ }
17419
+ startAutoScroll(direction) {
17420
+ this.stopAutoScroll();
17421
+ this._autoScrollInterval = this.clock.setInterval(() => {
17422
+ if (direction === "up") {
17423
+ if (this.scrollTopIndex > 0) {
17424
+ this.scrollTopIndex--;
17425
+ this.isScrolledToBottom = false;
17426
+ if (this._selectionEnd) {
17427
+ this._selectionEnd = {
17428
+ line: this.scrollTopIndex,
17429
+ col: this._selectionEnd.col
17430
+ };
17431
+ }
17432
+ this.markNeedsRerender();
17433
+ } else {
17434
+ this.stopAutoScroll();
17435
+ }
17436
+ } else {
17437
+ const displayLineCount = this._displayLines.length;
17438
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
17439
+ const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
17440
+ if (this.scrollTopIndex < maxScrollTop) {
17441
+ this.scrollTopIndex++;
17442
+ this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
17443
+ if (this._selectionEnd) {
17444
+ const maxLine = this.scrollTopIndex + logAreaHeight - 1;
17445
+ this._selectionEnd = {
17446
+ line: Math.min(maxLine, displayLineCount - 1),
17447
+ col: this._selectionEnd.col
17448
+ };
17449
+ }
17450
+ this.markNeedsRerender();
17451
+ } else {
17452
+ this.stopAutoScroll();
17453
+ }
16420
17454
  }
16421
- }
17455
+ }, 50);
16422
17456
  }
16423
- scrollUp() {
16424
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16425
- if (this.currentLineIndex > 0) {
16426
- this.currentLineIndex--;
16427
- this.markNeedsRerender();
16428
- } else if (this.scrollTopIndex > 0) {
16429
- this.scrollTopIndex--;
16430
- this.isScrolledToBottom = false;
17457
+ triggerCopy() {
17458
+ if (!this.hasSelection())
17459
+ return;
17460
+ const text = this.getSelectedText();
17461
+ if (text && this.options.onCopySelection) {
17462
+ try {
17463
+ this.options.onCopySelection(text);
17464
+ } catch {}
17465
+ this.clearSelection();
16431
17466
  this.markNeedsRerender();
16432
17467
  }
16433
- return true;
16434
17468
  }
16435
- scrollDown() {
16436
- const displayLineCount = this._displayLines.length;
16437
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16438
- const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
16439
- const canCursorMoveDown = this.currentLineIndex < logAreaHeight - 1 && this.scrollTopIndex + this.currentLineIndex < displayLineCount - 1;
16440
- if (canCursorMoveDown) {
16441
- this.currentLineIndex++;
16442
- this.markNeedsRerender();
16443
- } else if (this.scrollTopIndex < maxScrollTop) {
16444
- this.scrollTopIndex++;
16445
- this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
16446
- this.markNeedsRerender();
17469
+ getLineSelectionRange(lineIndex) {
17470
+ const selection2 = this.normalizeSelection();
17471
+ if (!selection2)
17472
+ return null;
17473
+ if (lineIndex < selection2.startLine || lineIndex > selection2.endLine) {
17474
+ return null;
16447
17475
  }
16448
- return true;
17476
+ const line = this._displayLines[lineIndex];
17477
+ if (!line)
17478
+ return null;
17479
+ const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : "";
17480
+ const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0);
17481
+ const fullTextLength = linePrefix.length + Math.min(line.text.length, textAvailableWidth);
17482
+ let start = 0;
17483
+ let end = fullTextLength;
17484
+ if (lineIndex === selection2.startLine) {
17485
+ start = Math.max(0, selection2.startCol);
17486
+ }
17487
+ if (lineIndex === selection2.endLine) {
17488
+ end = Math.min(fullTextLength, selection2.endCol);
17489
+ }
17490
+ if (start >= end)
17491
+ return null;
17492
+ return { start, end };
16449
17493
  }
16450
- scrollToTop() {
16451
- if (this.scrollTopIndex > 0 || this.currentLineIndex > 0) {
16452
- this.scrollTopIndex = 0;
16453
- this.currentLineIndex = 0;
16454
- this.isScrolledToBottom = this._displayLines.length <= Math.max(1, this.consoleHeight - 1);
17494
+ handleMouse(event) {
17495
+ if (!this.isVisible)
17496
+ return false;
17497
+ const localX = event.x - this.consoleX;
17498
+ const localY = event.y - this.consoleY;
17499
+ if (localX < 0 || localX >= this.consoleWidth || localY < 0 || localY >= this.consoleHeight) {
17500
+ return false;
17501
+ }
17502
+ if (event.type === "scroll" && event.scroll) {
17503
+ if (event.scroll.direction === "up") {
17504
+ this.scrollUp();
17505
+ } else if (event.scroll.direction === "down") {
17506
+ this.scrollDown();
17507
+ }
17508
+ return true;
17509
+ }
17510
+ if (localY === 0) {
17511
+ if (event.type === "down" && event.button === 0 && localX >= this._copyButtonBounds.x && localX < this._copyButtonBounds.x + this._copyButtonBounds.width) {
17512
+ this.triggerCopy();
17513
+ return true;
17514
+ }
17515
+ return true;
17516
+ }
17517
+ const lineIndex = this.scrollTopIndex + (localY - 1);
17518
+ const colIndex = Math.max(0, localX - 1);
17519
+ if (event.type === "down" && event.button === 0) {
17520
+ this.clearSelection();
17521
+ this._selectionStart = { line: lineIndex, col: colIndex };
17522
+ this._selectionEnd = { line: lineIndex, col: colIndex };
17523
+ this._isDragging = true;
16455
17524
  this.markNeedsRerender();
17525
+ return true;
16456
17526
  }
16457
- return true;
16458
- }
16459
- scrollToBottomAction() {
16460
- const logAreaHeightForScroll = Math.max(1, this.consoleHeight - 1);
16461
- const maxScrollPossible = Math.max(0, this._displayLines.length - logAreaHeightForScroll);
16462
- if (this.scrollTopIndex < maxScrollPossible || !this.isScrolledToBottom) {
16463
- this._scrollToBottom(true);
17527
+ if (event.type === "drag" && this._isDragging) {
17528
+ this._selectionEnd = { line: lineIndex, col: colIndex };
17529
+ const logAreaHeight = Math.max(1, this.consoleHeight - 1);
17530
+ const relativeY = localY - 1;
17531
+ if (relativeY <= 0) {
17532
+ this.startAutoScroll("up");
17533
+ } else if (relativeY >= logAreaHeight - 1) {
17534
+ this.startAutoScroll("down");
17535
+ } else {
17536
+ this.stopAutoScroll();
17537
+ }
16464
17538
  this.markNeedsRerender();
17539
+ return true;
17540
+ }
17541
+ if (event.type === "up") {
17542
+ if (this._isDragging) {
17543
+ this._selectionEnd = { line: lineIndex, col: colIndex };
17544
+ this._isDragging = false;
17545
+ this.stopAutoScroll();
17546
+ this.markNeedsRerender();
17547
+ }
17548
+ return true;
16465
17549
  }
16466
17550
  return true;
16467
17551
  }
16468
- positionPrevious() {
16469
- const currentPositionIndex = this._positions.indexOf(this.options.position);
16470
- const prevIndex = (currentPositionIndex - 1 + this._positions.length) % this._positions.length;
16471
- this.options.position = this._positions[prevIndex];
16472
- this.resize(this.renderer.width, this.renderer.height);
16473
- return true;
16474
- }
16475
- positionNext() {
16476
- const currentPositionIndex = this._positions.indexOf(this.options.position);
16477
- const nextIndex = (currentPositionIndex + 1) % this._positions.length;
16478
- this.options.position = this._positions[nextIndex];
16479
- this.resize(this.renderer.width, this.renderer.height);
16480
- return true;
16481
- }
16482
- sizeIncrease() {
16483
- this.options.sizePercent = Math.min(100, this.options.sizePercent + 5);
16484
- this.resize(this.renderer.width, this.renderer.height);
16485
- return true;
16486
- }
16487
- sizeDecrease() {
16488
- this.options.sizePercent = Math.max(10, this.options.sizePercent - 5);
16489
- this.resize(this.renderer.width, this.renderer.height);
16490
- return true;
16491
- }
16492
- saveLogsAction() {
16493
- this.saveLogsToFile();
16494
- return true;
16495
- }
16496
- triggerCopyAction() {
16497
- this.triggerCopy();
16498
- return true;
16499
- }
16500
- attachStdin() {
16501
- if (this.isFocused)
16502
- return;
16503
- this.renderer.keyInput.on("keypress", this.keyHandler);
16504
- this.isFocused = true;
16505
- }
16506
- detachStdin() {
16507
- if (!this.isFocused)
16508
- return;
16509
- this.renderer.keyInput.off("keypress", this.keyHandler);
16510
- this.isFocused = false;
17552
+ get visible() {
17553
+ return this.isVisible;
16511
17554
  }
16512
- formatTimestamp(date) {
16513
- return new Intl.DateTimeFormat("en-US", {
16514
- hour: "2-digit",
16515
- minute: "2-digit",
16516
- second: "2-digit",
16517
- hour12: false
16518
- }).format(date);
17555
+ get bounds() {
17556
+ return {
17557
+ x: this.consoleX,
17558
+ y: this.consoleY,
17559
+ width: this.consoleWidth,
17560
+ height: this.consoleHeight
17561
+ };
16519
17562
  }
16520
- formatArguments(args) {
16521
- return args.map((arg) => {
16522
- if (arg instanceof Error) {
16523
- const errorProps = arg;
16524
- return `Error: ${errorProps.message}
16525
- ` + (errorProps.stack ? `${errorProps.stack}
16526
- ` : "");
16527
- }
16528
- if (typeof arg === "object" && arg !== null) {
16529
- try {
16530
- return util2.inspect(arg, { depth: 2 });
16531
- } catch (e) {
16532
- return String(arg);
16533
- }
16534
- }
16535
- try {
16536
- return util2.inspect(arg, { depth: 2 });
16537
- } catch (e) {
16538
- return String(arg);
17563
+ saveLogsToFile() {
17564
+ try {
17565
+ const timestamp = Date.now();
17566
+ const filename = `_console_${timestamp}.log`;
17567
+ const filepath = path5.join(process.cwd(), filename);
17568
+ const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
17569
+ const logLines = [];
17570
+ for (const [date, level, args, callerInfo] of allLogEntries) {
17571
+ const timestampStr = this.formatTimestamp(date);
17572
+ const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown";
17573
+ const prefix = `[${timestampStr}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " ";
17574
+ const formattedArgs = this.formatArguments(args);
17575
+ logLines.push(prefix + formattedArgs);
16539
17576
  }
16540
- }).join(" ");
17577
+ const content = logLines.join(`
17578
+ `);
17579
+ fs.writeFileSync(filepath, content, "utf8");
17580
+ console.info(`Console logs saved to: ${filename}`);
17581
+ } catch (error) {
17582
+ console.error(`Failed to save console logs:`, error);
17583
+ }
16541
17584
  }
16542
- resize(width, height) {
16543
- this._updateConsoleDimensions(width, height);
16544
- if (this.frameBuffer) {
16545
- this.frameBuffer.resize(this.consoleWidth, this.consoleHeight);
16546
- const displayLineCount = this._displayLines.length;
16547
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16548
- const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
16549
- this.scrollTopIndex = Math.min(this.scrollTopIndex, maxScrollTop);
16550
- this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
16551
- const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex);
16552
- this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, visibleLineCount - 1));
16553
- if (this.isVisible) {
16554
- this.markNeedsRerender();
17585
+ }
17586
+
17587
+ // src/renderables/EditBufferRenderable.ts
17588
+ var BrandedEditBufferRenderable = Symbol.for("@opentui/core/EditBufferRenderable");
17589
+ var EditBufferRenderableEvents;
17590
+ ((EditBufferRenderableEvents2) => {
17591
+ EditBufferRenderableEvents2["TRAITS_CHANGED"] = "traits-changed";
17592
+ })(EditBufferRenderableEvents ||= {});
17593
+ function sameCapture(a, b) {
17594
+ if (a === b)
17595
+ return true;
17596
+ if (!a || !b)
17597
+ return !a && !b;
17598
+ if (a.length !== b.length)
17599
+ return false;
17600
+ return a.every((item, i) => item === b[i]);
17601
+ }
17602
+ function sameTraits(a, b) {
17603
+ return a.suspend === b.suspend && a.status === b.status && sameCapture(a.capture, b.capture);
17604
+ }
17605
+ function isEditBufferRenderable(obj) {
17606
+ return !!(obj && typeof obj === "object" && (BrandedEditBufferRenderable in obj));
17607
+ }
17608
+
17609
+ class EditBufferRenderable extends Renderable {
17610
+ [BrandedEditBufferRenderable] = true;
17611
+ _focusable = true;
17612
+ selectable = true;
17613
+ _traits = {};
17614
+ _textColor;
17615
+ _backgroundColor;
17616
+ _defaultAttributes;
17617
+ _selectionBg;
17618
+ _selectionFg;
17619
+ _wrapMode = "word";
17620
+ _scrollMargin = 0.2;
17621
+ _showCursor = true;
17622
+ _cursorColor;
17623
+ _cursorStyle;
17624
+ lastLocalSelection = null;
17625
+ _tabIndicator;
17626
+ _tabIndicatorColor;
17627
+ _cursorChangeListener = undefined;
17628
+ _contentChangeListener = undefined;
17629
+ _autoScrollVelocity = 0;
17630
+ _autoScrollAccumulator = 0;
17631
+ _scrollSpeed = 16;
17632
+ _keyboardSelectionActive = false;
17633
+ editBuffer;
17634
+ editorView;
17635
+ _defaultOptions = {
17636
+ textColor: RGBA.fromValues(1, 1, 1, 1),
17637
+ backgroundColor: "transparent",
17638
+ selectionBg: undefined,
17639
+ selectionFg: undefined,
17640
+ selectable: true,
17641
+ attributes: 0,
17642
+ wrapMode: "word",
17643
+ scrollMargin: 0.2,
17644
+ scrollSpeed: 16,
17645
+ showCursor: true,
17646
+ cursorColor: RGBA.fromValues(1, 1, 1, 1),
17647
+ cursorStyle: {
17648
+ style: "block",
17649
+ blinking: true
17650
+ },
17651
+ tabIndicator: undefined,
17652
+ tabIndicatorColor: undefined
17653
+ };
17654
+ constructor(ctx, options) {
17655
+ super(ctx, options);
17656
+ this._textColor = parseColor(options.textColor ?? this._defaultOptions.textColor);
17657
+ this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor);
17658
+ this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
17659
+ this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
17660
+ this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
17661
+ this.selectable = options.selectable ?? this._defaultOptions.selectable;
17662
+ this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
17663
+ this._scrollMargin = options.scrollMargin ?? this._defaultOptions.scrollMargin;
17664
+ this._scrollSpeed = options.scrollSpeed ?? this._defaultOptions.scrollSpeed;
17665
+ this._showCursor = options.showCursor ?? this._defaultOptions.showCursor;
17666
+ this._cursorColor = parseColor(options.cursorColor ?? this._defaultOptions.cursorColor);
17667
+ this._cursorStyle = options.cursorStyle ?? this._defaultOptions.cursorStyle;
17668
+ this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator;
17669
+ this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor;
17670
+ this.editBuffer = EditBuffer.create(this._ctx.widthMethod);
17671
+ this.editorView = EditorView.create(this.editBuffer, this.width || 80, this.height || 24);
17672
+ this.editorView.setWrapMode(this._wrapMode);
17673
+ this.editorView.setScrollMargin(this._scrollMargin);
17674
+ this.editBuffer.setDefaultFg(this._textColor);
17675
+ this.editBuffer.setDefaultBg(this._backgroundColor);
17676
+ this.editBuffer.setDefaultAttributes(this._defaultAttributes);
17677
+ if (options.syntaxStyle) {
17678
+ this.editBuffer.setSyntaxStyle(options.syntaxStyle);
17679
+ }
17680
+ if (this._tabIndicator !== undefined) {
17681
+ this.editorView.setTabIndicator(this._tabIndicator);
17682
+ }
17683
+ if (this._tabIndicatorColor !== undefined) {
17684
+ this.editorView.setTabIndicatorColor(this._tabIndicatorColor);
17685
+ }
17686
+ this.setupMeasureFunc();
17687
+ this.setupEventListeners(options);
17688
+ }
17689
+ get lineInfo() {
17690
+ return this.editorView.getLogicalLineInfo();
17691
+ }
17692
+ setupEventListeners(options) {
17693
+ this._cursorChangeListener = options.onCursorChange;
17694
+ this._contentChangeListener = options.onContentChange;
17695
+ this.editBuffer.on("cursor-changed", () => {
17696
+ if (this._cursorChangeListener) {
17697
+ const cursor = this.editBuffer.getCursorPosition();
17698
+ this._cursorChangeListener({
17699
+ line: cursor.row,
17700
+ visualColumn: cursor.col
17701
+ });
16555
17702
  }
16556
- }
17703
+ });
17704
+ this.editBuffer.on("content-changed", () => {
17705
+ this.yogaNode.markDirty();
17706
+ this.requestRender();
17707
+ this.emit("line-info-change");
17708
+ if (this._contentChangeListener) {
17709
+ this._contentChangeListener({});
17710
+ }
17711
+ });
16557
17712
  }
16558
- clear() {
16559
- terminalConsoleCache.clearConsole();
16560
- this._allLogEntries = [];
16561
- this._displayLines = [];
16562
- this.markNeedsRerender();
17713
+ get lineCount() {
17714
+ return this.editBuffer.getLineCount();
16563
17715
  }
16564
- toggle() {
16565
- if (this.isVisible) {
16566
- if (this.isFocused) {
16567
- this.hide();
16568
- } else {
16569
- this.focus();
16570
- }
16571
- } else {
16572
- this.show();
16573
- }
16574
- if (!this.renderer.isRunning) {
16575
- this.renderer.requestRender();
16576
- }
17716
+ get virtualLineCount() {
17717
+ return this.editorView.getVirtualLineCount();
16577
17718
  }
16578
- focus() {
16579
- this.attachStdin();
16580
- this._scrollToBottom(true);
16581
- this.markNeedsRerender();
17719
+ get scrollY() {
17720
+ return this.editorView.getViewport().offsetY;
16582
17721
  }
16583
- blur() {
16584
- this.detachStdin();
16585
- this.markNeedsRerender();
17722
+ get plainText() {
17723
+ return this.editBuffer.getText();
16586
17724
  }
16587
- show() {
16588
- if (!this.isVisible) {
16589
- this.isVisible = true;
16590
- this._processCachedLogs();
16591
- terminalConsoleCache.setCachingEnabled(false);
16592
- if (!this.frameBuffer) {
16593
- this.frameBuffer = OptimizedBuffer.create(this.consoleWidth, this.consoleHeight, this.renderer.widthMethod, {
16594
- respectAlpha: this.backgroundColor.a < 1,
16595
- id: "console framebuffer"
16596
- });
16597
- }
16598
- const logCount = terminalConsoleCache.cachedLogs.length;
16599
- const visibleLogLines = Math.min(this.consoleHeight, logCount);
16600
- this.currentLineIndex = Math.max(0, visibleLogLines - 1);
16601
- this.scrollTopIndex = 0;
16602
- this._scrollToBottom(true);
16603
- this.focus();
16604
- this.markNeedsRerender();
17725
+ get logicalCursor() {
17726
+ return this.editBuffer.getCursorPosition();
17727
+ }
17728
+ get visualCursor() {
17729
+ return this.editorView.getVisualCursor();
17730
+ }
17731
+ get cursorOffset() {
17732
+ return this.editorView.getVisualCursor().offset;
17733
+ }
17734
+ set cursorOffset(offset) {
17735
+ this.editorView.setCursorByOffset(offset);
17736
+ this.requestRender();
17737
+ }
17738
+ get cursorCharacterOffset() {
17739
+ const len = this.plainText.length;
17740
+ if (len <= 0)
17741
+ return;
17742
+ const cursor = this.logicalCursor;
17743
+ const offset = this.cursorOffset;
17744
+ if (offset >= len) {
17745
+ if (cursor.col > 0)
17746
+ return len - 1;
17747
+ return 0;
16605
17748
  }
17749
+ if (this.plainText[offset] === `
17750
+ ` && cursor.col > 0) {
17751
+ return offset - 1;
17752
+ }
17753
+ return offset;
16606
17754
  }
16607
- hide() {
16608
- if (this.isVisible) {
16609
- this.isVisible = false;
16610
- this.blur();
16611
- terminalConsoleCache.setCachingEnabled(true);
17755
+ get textColor() {
17756
+ return this._textColor;
17757
+ }
17758
+ set textColor(value) {
17759
+ const newColor = parseColor(value ?? this._defaultOptions.textColor);
17760
+ if (this._textColor !== newColor) {
17761
+ this._textColor = newColor;
17762
+ this.editBuffer.setDefaultFg(newColor);
17763
+ this.requestRender();
16612
17764
  }
16613
17765
  }
16614
- destroy() {
16615
- this.stopAutoScroll();
16616
- this.hide();
16617
- this.deactivate();
16618
- terminalConsoleCache.off("entry", this._entryListener);
17766
+ get selectionBg() {
17767
+ return this._selectionBg;
16619
17768
  }
16620
- getCachedLogs() {
16621
- return terminalConsoleCache.cachedLogs.map((logEntry) => logEntry[0].toISOString() + " " + logEntry.slice(1).join(" ")).join(`
16622
- `);
17769
+ get traits() {
17770
+ return this._traits;
16623
17771
  }
16624
- updateFrameBuffer() {
16625
- if (!this.frameBuffer)
17772
+ set traits(value) {
17773
+ if (sameTraits(this._traits, value))
16626
17774
  return;
16627
- this.frameBuffer.clear(this.backgroundColor);
16628
- const displayLines = this._displayLines;
16629
- const displayLineCount = displayLines.length;
16630
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16631
- this.frameBuffer.fillRect(0, 0, this.consoleWidth, 1, this._rgbaTitleBar);
16632
- const dynamicTitle = `${this._title}${this.isFocused ? " (Focused)" : ""}`;
16633
- const titleX = Math.max(0, Math.floor((this.consoleWidth - dynamicTitle.length) / 2));
16634
- this.frameBuffer.drawText(dynamicTitle, titleX, 0, this._rgbaTitleBarText, this._rgbaTitleBar);
16635
- const copyLabel = this.getCopyButtonLabel();
16636
- const copyButtonX = this.consoleWidth - copyLabel.length - 1;
16637
- if (copyButtonX >= 0) {
16638
- const copyButtonEnabled = this.hasSelection();
16639
- const disabledColor = RGBA.fromInts(100, 100, 100, 255);
16640
- const copyColor = copyButtonEnabled ? this._rgbaCopyButton : disabledColor;
16641
- this.frameBuffer.drawText(copyLabel, copyButtonX, 0, copyColor, this._rgbaTitleBar);
16642
- this._copyButtonBounds = { x: copyButtonX, y: 0, width: copyLabel.length, height: 1 };
16643
- } else {
16644
- this._copyButtonBounds = { x: -1, y: -1, width: 0, height: 0 };
17775
+ const prev = this._traits;
17776
+ this._traits = value;
17777
+ this.emit("traits-changed" /* TRAITS_CHANGED */, value, prev);
17778
+ }
17779
+ set selectionBg(value) {
17780
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
17781
+ if (this._selectionBg !== newColor) {
17782
+ this._selectionBg = newColor;
17783
+ this.refreshSelectionStyle();
17784
+ this.requestRender();
16645
17785
  }
16646
- const startIndex = this.scrollTopIndex;
16647
- const endIndex = Math.min(startIndex + logAreaHeight, displayLineCount);
16648
- const visibleDisplayLines = displayLines.slice(startIndex, endIndex);
16649
- let lineY = 1;
16650
- for (let i = 0;i < visibleDisplayLines.length; i++) {
16651
- if (lineY >= this.consoleHeight)
16652
- break;
16653
- const displayLine = visibleDisplayLines[i];
16654
- const absoluteLineIndex = startIndex + i;
16655
- let levelColor = this._rgbaDefault;
16656
- switch (displayLine.level) {
16657
- case "INFO" /* INFO */:
16658
- levelColor = this._rgbaInfo;
16659
- break;
16660
- case "WARN" /* WARN */:
16661
- levelColor = this._rgbaWarn;
16662
- break;
16663
- case "ERROR" /* ERROR */:
16664
- levelColor = this._rgbaError;
16665
- break;
16666
- case "DEBUG" /* DEBUG */:
16667
- levelColor = this._rgbaDebug;
16668
- break;
16669
- }
16670
- const linePrefix = displayLine.indent ? " ".repeat(INDENT_WIDTH) : "";
16671
- const textToDraw = displayLine.text;
16672
- const textAvailableWidth = this.consoleWidth - 1 - (displayLine.indent ? INDENT_WIDTH : 0);
16673
- const showCursor = this.isFocused && lineY - 1 === this.currentLineIndex;
16674
- if (showCursor) {
16675
- this.frameBuffer.drawText(">", 0, lineY, this._rgbaCursor, this.backgroundColor);
16676
- } else {
16677
- this.frameBuffer.drawText(" ", 0, lineY, this._rgbaDefault, this.backgroundColor);
16678
- }
16679
- const fullText = `${linePrefix}${textToDraw.substring(0, textAvailableWidth)}`;
16680
- const selectionRange = this.getLineSelectionRange(absoluteLineIndex);
16681
- if (selectionRange) {
16682
- const adjustedStart = Math.max(0, selectionRange.start);
16683
- const adjustedEnd = Math.min(fullText.length, selectionRange.end);
16684
- if (adjustedStart > 0) {
16685
- this.frameBuffer.drawText(fullText.substring(0, adjustedStart), 1, lineY, levelColor);
16686
- }
16687
- if (adjustedStart < adjustedEnd) {
16688
- this.frameBuffer.fillRect(1 + adjustedStart, lineY, adjustedEnd - adjustedStart, 1, this._rgbaSelection);
16689
- this.frameBuffer.drawText(fullText.substring(adjustedStart, adjustedEnd), 1 + adjustedStart, lineY, levelColor, this._rgbaSelection);
16690
- }
16691
- if (adjustedEnd < fullText.length) {
16692
- this.frameBuffer.drawText(fullText.substring(adjustedEnd), 1 + adjustedEnd, lineY, levelColor);
16693
- }
16694
- } else {
16695
- this.frameBuffer.drawText(fullText, 1, lineY, levelColor);
16696
- }
16697
- lineY++;
17786
+ }
17787
+ get selectionFg() {
17788
+ return this._selectionFg;
17789
+ }
17790
+ set selectionFg(value) {
17791
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
17792
+ if (this._selectionFg !== newColor) {
17793
+ this._selectionFg = newColor;
17794
+ this.refreshSelectionStyle();
17795
+ this.requestRender();
16698
17796
  }
16699
17797
  }
16700
- renderToBuffer(buffer) {
16701
- if (!this.isVisible || !this.frameBuffer)
16702
- return;
16703
- if (this._needsFrameBufferUpdate) {
16704
- this.updateFrameBuffer();
16705
- this._needsFrameBufferUpdate = false;
17798
+ get backgroundColor() {
17799
+ return this._backgroundColor;
17800
+ }
17801
+ set backgroundColor(value) {
17802
+ const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
17803
+ if (this._backgroundColor !== newColor) {
17804
+ this._backgroundColor = newColor;
17805
+ this.editBuffer.setDefaultBg(newColor);
17806
+ this.requestRender();
16706
17807
  }
16707
- buffer.drawFrameBuffer(this.consoleX, this.consoleY, this.frameBuffer);
16708
17808
  }
16709
- setDebugMode(enabled) {
16710
- this._debugModeEnabled = enabled;
16711
- terminalConsoleCache.setCollectCallerInfo(enabled);
16712
- if (this.isVisible) {
16713
- this.markNeedsRerender();
17809
+ get attributes() {
17810
+ return this._defaultAttributes;
17811
+ }
17812
+ set attributes(value) {
17813
+ if (this._defaultAttributes !== value) {
17814
+ this._defaultAttributes = value;
17815
+ this.editBuffer.setDefaultAttributes(value);
17816
+ this.requestRender();
16714
17817
  }
16715
17818
  }
16716
- toggleDebugMode() {
16717
- this.setDebugMode(!this._debugModeEnabled);
17819
+ get wrapMode() {
17820
+ return this._wrapMode;
16718
17821
  }
16719
- set keyBindings(bindings) {
16720
- this._keyBindings = bindings;
16721
- this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, bindings);
16722
- this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap);
16723
- this.markNeedsRerender();
17822
+ set wrapMode(value) {
17823
+ if (this._wrapMode !== value) {
17824
+ this._wrapMode = value;
17825
+ this.editorView.setWrapMode(value);
17826
+ this.yogaNode.markDirty();
17827
+ this.requestRender();
17828
+ }
16724
17829
  }
16725
- set keyAliasMap(aliases) {
16726
- this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases);
16727
- this._mergedKeyBindings = mergeKeyBindings(defaultConsoleKeybindings, this._keyBindings);
16728
- this._keyBindingsMap = buildKeyBindingsMap(this._mergedKeyBindings, this._keyAliasMap);
16729
- this.markNeedsRerender();
17830
+ get showCursor() {
17831
+ return this._showCursor;
16730
17832
  }
16731
- set onCopySelection(callback) {
16732
- this.options.onCopySelection = callback;
17833
+ set showCursor(value) {
17834
+ if (this._showCursor !== value) {
17835
+ this._showCursor = value;
17836
+ if (!value && this._focused) {
17837
+ this._ctx.setCursorPosition(0, 0, false);
17838
+ }
17839
+ this.requestRender();
17840
+ }
16733
17841
  }
16734
- get onCopySelection() {
16735
- return this.options.onCopySelection;
17842
+ get cursorColor() {
17843
+ return this._cursorColor;
16736
17844
  }
16737
- _scrollToBottom(forceCursorToLastLine = false) {
16738
- const displayLineCount = this._displayLines.length;
16739
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16740
- const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
16741
- this.scrollTopIndex = maxScrollTop;
16742
- this.isScrolledToBottom = true;
16743
- const visibleLineCount = Math.min(logAreaHeight, displayLineCount - this.scrollTopIndex);
16744
- if (forceCursorToLastLine || this.currentLineIndex >= visibleLineCount) {
16745
- this.currentLineIndex = Math.max(0, visibleLineCount - 1);
17845
+ set cursorColor(value) {
17846
+ const newColor = parseColor(value);
17847
+ if (this._cursorColor !== newColor) {
17848
+ this._cursorColor = newColor;
17849
+ if (this._focused) {
17850
+ this.requestRender();
17851
+ }
16746
17852
  }
16747
17853
  }
16748
- _processLogEntry(logEntry) {
16749
- const [date, level, args, callerInfo] = logEntry;
16750
- const displayLines = [];
16751
- const timestamp = this.formatTimestamp(date);
16752
- const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown";
16753
- const prefix = `[${timestamp}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " ";
16754
- const formattedArgs = this.formatArguments(args);
16755
- const initialLines = formattedArgs.split(`
16756
- `);
16757
- for (let i = 0;i < initialLines.length; i++) {
16758
- const lineText = initialLines[i];
16759
- const isFirstLineOfEntry = i === 0;
16760
- const availableWidth = this.consoleWidth - 1 - (isFirstLineOfEntry ? 0 : INDENT_WIDTH);
16761
- const linePrefix = isFirstLineOfEntry ? prefix : " ".repeat(INDENT_WIDTH);
16762
- const textToWrap = isFirstLineOfEntry ? linePrefix + lineText : lineText;
16763
- let currentPos = 0;
16764
- while (currentPos < textToWrap.length || isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0) {
16765
- const segment = textToWrap.substring(currentPos, currentPos + availableWidth);
16766
- const isFirstSegmentOfLine = currentPos === 0;
16767
- displayLines.push({
16768
- text: isFirstSegmentOfLine && !isFirstLineOfEntry ? linePrefix + segment : segment,
16769
- level,
16770
- indent: !isFirstLineOfEntry || !isFirstSegmentOfLine
16771
- });
16772
- currentPos += availableWidth;
16773
- if (isFirstLineOfEntry && currentPos === 0 && textToWrap.length === 0)
16774
- break;
17854
+ get cursorStyle() {
17855
+ return this._cursorStyle;
17856
+ }
17857
+ set cursorStyle(style) {
17858
+ const newStyle = style;
17859
+ if (this.cursorStyle.style !== newStyle.style || this.cursorStyle.blinking !== newStyle.blinking) {
17860
+ this._cursorStyle = newStyle;
17861
+ if (this._focused) {
17862
+ this.requestRender();
16775
17863
  }
16776
17864
  }
16777
- return displayLines;
16778
17865
  }
16779
- _processCachedLogs() {
16780
- const logsToProcess = [...terminalConsoleCache.cachedLogs];
16781
- terminalConsoleCache.clearConsole();
16782
- this._allLogEntries.push(...logsToProcess);
16783
- if (this._allLogEntries.length > this.options.maxStoredLogs) {
16784
- this._allLogEntries.splice(0, this._allLogEntries.length - this.options.maxStoredLogs);
17866
+ get tabIndicator() {
17867
+ return this._tabIndicator;
17868
+ }
17869
+ set tabIndicator(value) {
17870
+ if (this._tabIndicator !== value) {
17871
+ this._tabIndicator = value;
17872
+ if (value !== undefined) {
17873
+ this.editorView.setTabIndicator(value);
17874
+ }
17875
+ this.requestRender();
16785
17876
  }
16786
- for (const logEntry of logsToProcess) {
16787
- const processed = this._processLogEntry(logEntry);
16788
- this._displayLines.push(...processed);
17877
+ }
17878
+ get tabIndicatorColor() {
17879
+ return this._tabIndicatorColor;
17880
+ }
17881
+ set tabIndicatorColor(value) {
17882
+ const newColor = value ? parseColor(value) : undefined;
17883
+ if (this._tabIndicatorColor !== newColor) {
17884
+ this._tabIndicatorColor = newColor;
17885
+ if (newColor !== undefined) {
17886
+ this.editorView.setTabIndicatorColor(newColor);
17887
+ }
17888
+ this.requestRender();
17889
+ }
17890
+ }
17891
+ get scrollSpeed() {
17892
+ return this._scrollSpeed;
17893
+ }
17894
+ set scrollSpeed(value) {
17895
+ this._scrollSpeed = Math.max(0, value);
17896
+ }
17897
+ onMouseEvent(event) {
17898
+ if (event.type === "scroll") {
17899
+ this.handleScroll(event);
17900
+ }
17901
+ }
17902
+ handleScroll(event) {
17903
+ if (!event.scroll)
17904
+ return;
17905
+ const { direction, delta } = event.scroll;
17906
+ const viewport = this.editorView.getViewport();
17907
+ if (direction === "up") {
17908
+ const newOffsetY = Math.max(0, viewport.offsetY - delta);
17909
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true);
17910
+ this.requestRender();
17911
+ } else if (direction === "down") {
17912
+ const totalVirtualLines = this.editorView.getTotalVirtualLineCount();
17913
+ const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height);
17914
+ const newOffsetY = Math.min(viewport.offsetY + delta, maxOffsetY);
17915
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true);
17916
+ this.requestRender();
17917
+ }
17918
+ if (this._wrapMode === "none") {
17919
+ if (direction === "left") {
17920
+ const newOffsetX = Math.max(0, viewport.offsetX - delta);
17921
+ this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true);
17922
+ this.requestRender();
17923
+ } else if (direction === "right") {
17924
+ const newOffsetX = viewport.offsetX + delta;
17925
+ this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true);
17926
+ this.requestRender();
17927
+ }
16789
17928
  }
16790
- if (this._displayLines.length > this.options.maxDisplayLines) {
16791
- this._displayLines.splice(0, this._displayLines.length - this.options.maxDisplayLines);
17929
+ }
17930
+ onResize(width, height) {
17931
+ this.editorView.setViewportSize(width, height);
17932
+ }
17933
+ refreshLocalSelection() {
17934
+ if (this.lastLocalSelection) {
17935
+ return this.updateLocalSelection(this.lastLocalSelection);
16792
17936
  }
17937
+ return false;
16793
17938
  }
16794
- hasSelection() {
16795
- if (this._selectionStart === null || this._selectionEnd === null)
17939
+ updateLocalSelection(localSelection) {
17940
+ if (!localSelection?.isActive) {
17941
+ this.editorView.resetLocalSelection();
17942
+ return true;
17943
+ }
17944
+ return this.editorView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, false);
17945
+ }
17946
+ shouldStartSelection(x, y) {
17947
+ if (!this.selectable)
16796
17948
  return false;
16797
- return this._selectionStart.line !== this._selectionEnd.line || this._selectionStart.col !== this._selectionEnd.col;
17949
+ const localX = x - this.x;
17950
+ const localY = y - this.y;
17951
+ return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
16798
17952
  }
16799
- normalizeSelection() {
16800
- if (!this._selectionStart || !this._selectionEnd)
16801
- return null;
16802
- const start = this._selectionStart;
16803
- const end = this._selectionEnd;
16804
- const startBeforeEnd = start.line < end.line || start.line === end.line && start.col <= end.col;
16805
- if (startBeforeEnd) {
16806
- return {
16807
- startLine: start.line,
16808
- startCol: start.col,
16809
- endLine: end.line,
16810
- endCol: end.col
16811
- };
17953
+ onSelectionChanged(selection2) {
17954
+ const localSelection = convertGlobalToLocalSelection(selection2, this.x, this.y);
17955
+ this.lastLocalSelection = localSelection;
17956
+ const updateCursor = true;
17957
+ const followCursor = this._keyboardSelectionActive;
17958
+ let changed;
17959
+ if (!localSelection?.isActive) {
17960
+ this._keyboardSelectionActive = false;
17961
+ this.editorView.resetLocalSelection();
17962
+ changed = true;
17963
+ } else if (selection2?.isStart) {
17964
+ changed = this.editorView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, updateCursor, followCursor);
16812
17965
  } else {
16813
- return {
16814
- startLine: end.line,
16815
- startCol: end.col,
16816
- endLine: start.line,
16817
- endCol: start.col
16818
- };
17966
+ changed = this.editorView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg, updateCursor, followCursor);
17967
+ }
17968
+ if (changed && localSelection?.isActive && selection2?.isDragging) {
17969
+ const viewport = this.editorView.getViewport();
17970
+ const focusY = localSelection.focusY;
17971
+ const scrollMargin = Math.max(1, Math.floor(viewport.height * this._scrollMargin));
17972
+ if (focusY < scrollMargin) {
17973
+ this._autoScrollVelocity = -this._scrollSpeed;
17974
+ } else if (focusY >= viewport.height - scrollMargin) {
17975
+ this._autoScrollVelocity = this._scrollSpeed;
17976
+ } else {
17977
+ this._autoScrollVelocity = 0;
17978
+ }
17979
+ } else {
17980
+ this._keyboardSelectionActive = false;
17981
+ this._autoScrollVelocity = 0;
17982
+ this._autoScrollAccumulator = 0;
16819
17983
  }
16820
- }
16821
- getSelectedText() {
16822
- const selection2 = this.normalizeSelection();
16823
- if (!selection2)
16824
- return "";
16825
- const lines = [];
16826
- for (let i = selection2.startLine;i <= selection2.endLine; i++) {
16827
- if (i < 0 || i >= this._displayLines.length)
16828
- continue;
16829
- const line = this._displayLines[i];
16830
- const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : "";
16831
- const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0);
16832
- const fullText = linePrefix + line.text.substring(0, textAvailableWidth);
16833
- let text = fullText;
16834
- if (i === selection2.startLine && i === selection2.endLine) {
16835
- text = fullText.substring(selection2.startCol, selection2.endCol);
16836
- } else if (i === selection2.startLine) {
16837
- text = fullText.substring(selection2.startCol);
16838
- } else if (i === selection2.endLine) {
16839
- text = fullText.substring(0, selection2.endCol);
17984
+ if (changed) {
17985
+ this.requestRender();
17986
+ }
17987
+ return this.hasSelection();
17988
+ }
17989
+ onUpdate(deltaTime) {
17990
+ super.onUpdate(deltaTime);
17991
+ if (this._autoScrollVelocity !== 0 && this.hasSelection()) {
17992
+ const deltaSeconds = deltaTime / 1000;
17993
+ this._autoScrollAccumulator += this._autoScrollVelocity * deltaSeconds;
17994
+ const linesToScroll = Math.floor(Math.abs(this._autoScrollAccumulator));
17995
+ if (linesToScroll > 0) {
17996
+ const direction = this._autoScrollVelocity > 0 ? 1 : -1;
17997
+ const viewport = this.editorView.getViewport();
17998
+ const totalVirtualLines = this.editorView.getTotalVirtualLineCount();
17999
+ const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height);
18000
+ const newOffsetY = Math.max(0, Math.min(viewport.offsetY + direction * linesToScroll, maxOffsetY));
18001
+ if (newOffsetY !== viewport.offsetY) {
18002
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, false);
18003
+ this._ctx.requestSelectionUpdate();
18004
+ }
18005
+ this._autoScrollAccumulator -= direction * linesToScroll;
16840
18006
  }
16841
- lines.push(text);
16842
18007
  }
16843
- return lines.join(`
16844
- `);
16845
18008
  }
16846
- clearSelection() {
16847
- this._selectionStart = null;
16848
- this._selectionEnd = null;
16849
- this._isDragging = false;
16850
- this.stopAutoScroll();
18009
+ getSelectedText() {
18010
+ return this.editorView.getSelectedText();
16851
18011
  }
16852
- stopAutoScroll() {
16853
- if (this._autoScrollInterval !== null) {
16854
- this.clock.clearInterval(this._autoScrollInterval);
16855
- this._autoScrollInterval = null;
18012
+ hasSelection() {
18013
+ return this.editorView.hasSelection();
18014
+ }
18015
+ getSelection() {
18016
+ return this.editorView.getSelection();
18017
+ }
18018
+ refreshSelectionStyle() {
18019
+ if (this.lastLocalSelection) {
18020
+ this.updateLocalSelection(this.lastLocalSelection);
18021
+ return;
16856
18022
  }
18023
+ const selection2 = this.getSelection();
18024
+ if (!selection2)
18025
+ return;
18026
+ this.editorView.setSelection(selection2.start, selection2.end, this._selectionBg, this._selectionFg);
16857
18027
  }
16858
- startAutoScroll(direction) {
16859
- this.stopAutoScroll();
16860
- this._autoScrollInterval = this.clock.setInterval(() => {
16861
- if (direction === "up") {
16862
- if (this.scrollTopIndex > 0) {
16863
- this.scrollTopIndex--;
16864
- this.isScrolledToBottom = false;
16865
- if (this._selectionEnd) {
16866
- this._selectionEnd = {
16867
- line: this.scrollTopIndex,
16868
- col: this._selectionEnd.col
16869
- };
16870
- }
16871
- this.markNeedsRerender();
16872
- } else {
16873
- this.stopAutoScroll();
16874
- }
16875
- } else {
16876
- const displayLineCount = this._displayLines.length;
16877
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16878
- const maxScrollTop = Math.max(0, displayLineCount - logAreaHeight);
16879
- if (this.scrollTopIndex < maxScrollTop) {
16880
- this.scrollTopIndex++;
16881
- this.isScrolledToBottom = this.scrollTopIndex === maxScrollTop;
16882
- if (this._selectionEnd) {
16883
- const maxLine = this.scrollTopIndex + logAreaHeight - 1;
16884
- this._selectionEnd = {
16885
- line: Math.min(maxLine, displayLineCount - 1),
16886
- col: this._selectionEnd.col
16887
- };
16888
- }
16889
- this.markNeedsRerender();
16890
- } else {
16891
- this.stopAutoScroll();
16892
- }
16893
- }
16894
- }, 50);
18028
+ deleteSelectedText() {
18029
+ this.editorView.deleteSelectedText();
18030
+ this._ctx.clearSelection();
18031
+ this.requestRender();
16895
18032
  }
16896
- triggerCopy() {
18033
+ setSelection(start, end) {
18034
+ this.lastLocalSelection = null;
18035
+ this.editorView.resetLocalSelection();
18036
+ this._ctx.clearSelection();
18037
+ this.editorView.setSelection(start, end, this._selectionBg, this._selectionFg);
18038
+ this.requestRender();
18039
+ }
18040
+ setSelectionInclusive(start, end) {
18041
+ this.setSelection(Math.min(start, end), Math.max(start, end) + 1);
18042
+ }
18043
+ clearSelection() {
18044
+ const had = this.hasSelection();
18045
+ this.lastLocalSelection = null;
18046
+ this.editorView.resetSelection();
18047
+ this.editorView.resetLocalSelection();
18048
+ this._ctx.clearSelection();
18049
+ if (had) {
18050
+ this.requestRender();
18051
+ }
18052
+ return had;
18053
+ }
18054
+ deleteSelection() {
16897
18055
  if (!this.hasSelection())
16898
- return;
16899
- const text = this.getSelectedText();
16900
- if (text && this.options.onCopySelection) {
16901
- try {
16902
- this.options.onCopySelection(text);
16903
- } catch {}
16904
- this.clearSelection();
16905
- this.markNeedsRerender();
18056
+ return false;
18057
+ this.lastLocalSelection = null;
18058
+ this.deleteSelectedText();
18059
+ return true;
18060
+ }
18061
+ setCursor(row, col) {
18062
+ this.editBuffer.setCursor(row, col);
18063
+ this.requestRender();
18064
+ }
18065
+ insertChar(char) {
18066
+ if (this.hasSelection()) {
18067
+ this.deleteSelectedText();
16906
18068
  }
18069
+ this.editBuffer.insertChar(char);
18070
+ this.requestRender();
16907
18071
  }
16908
- getLineSelectionRange(lineIndex) {
16909
- const selection2 = this.normalizeSelection();
16910
- if (!selection2)
16911
- return null;
16912
- if (lineIndex < selection2.startLine || lineIndex > selection2.endLine) {
16913
- return null;
18072
+ insertText(text) {
18073
+ if (this.hasSelection()) {
18074
+ this.deleteSelectedText();
16914
18075
  }
16915
- const line = this._displayLines[lineIndex];
16916
- if (!line)
16917
- return null;
16918
- const linePrefix = line.indent ? " ".repeat(INDENT_WIDTH) : "";
16919
- const textAvailableWidth = this.consoleWidth - 1 - (line.indent ? INDENT_WIDTH : 0);
16920
- const fullTextLength = linePrefix.length + Math.min(line.text.length, textAvailableWidth);
16921
- let start = 0;
16922
- let end = fullTextLength;
16923
- if (lineIndex === selection2.startLine) {
16924
- start = Math.max(0, selection2.startCol);
18076
+ this.editBuffer.insertText(text);
18077
+ this.requestRender();
18078
+ }
18079
+ deleteChar() {
18080
+ if (this.hasSelection()) {
18081
+ this.deleteSelectedText();
18082
+ return true;
16925
18083
  }
16926
- if (lineIndex === selection2.endLine) {
16927
- end = Math.min(fullTextLength, selection2.endCol);
18084
+ this._ctx.clearSelection();
18085
+ this.editBuffer.deleteChar();
18086
+ this.requestRender();
18087
+ return true;
18088
+ }
18089
+ deleteCharBackward() {
18090
+ if (this.hasSelection()) {
18091
+ this.deleteSelectedText();
18092
+ return true;
16928
18093
  }
16929
- if (start >= end)
16930
- return null;
16931
- return { start, end };
18094
+ this._ctx.clearSelection();
18095
+ this.editBuffer.deleteCharBackward();
18096
+ this.requestRender();
18097
+ return true;
16932
18098
  }
16933
- handleMouse(event) {
16934
- if (!this.isVisible)
16935
- return false;
16936
- const localX = event.x - this.consoleX;
16937
- const localY = event.y - this.consoleY;
16938
- if (localX < 0 || localX >= this.consoleWidth || localY < 0 || localY >= this.consoleHeight) {
16939
- return false;
18099
+ newLine() {
18100
+ this._ctx.clearSelection();
18101
+ this.editBuffer.newLine();
18102
+ this.requestRender();
18103
+ return true;
18104
+ }
18105
+ deleteLine() {
18106
+ this._ctx.clearSelection();
18107
+ this.editBuffer.deleteLine();
18108
+ this.requestRender();
18109
+ return true;
18110
+ }
18111
+ moveCursorLeft(options) {
18112
+ const select = options?.select ?? false;
18113
+ if (!select && this.hasSelection()) {
18114
+ const selection2 = this.getSelection();
18115
+ this.editBuffer.setCursorByOffset(selection2.start);
18116
+ this._ctx.clearSelection();
18117
+ this.requestRender();
18118
+ return true;
16940
18119
  }
16941
- if (event.type === "scroll" && event.scroll) {
16942
- if (event.scroll.direction === "up") {
16943
- this.scrollUp();
16944
- } else if (event.scroll.direction === "down") {
16945
- this.scrollDown();
16946
- }
18120
+ this.updateSelectionForMovement(select, true);
18121
+ this.editBuffer.moveCursorLeft();
18122
+ this.updateSelectionForMovement(select, false);
18123
+ this.requestRender();
18124
+ return true;
18125
+ }
18126
+ moveCursorRight(options) {
18127
+ const select = options?.select ?? false;
18128
+ if (!select && this.hasSelection()) {
18129
+ const selection2 = this.getSelection();
18130
+ const targetOffset = this.cursorOffset === selection2.start ? selection2.end - 1 : selection2.end;
18131
+ this.editBuffer.setCursorByOffset(targetOffset);
18132
+ this._ctx.clearSelection();
18133
+ this.requestRender();
16947
18134
  return true;
16948
18135
  }
16949
- if (localY === 0) {
16950
- if (event.type === "down" && event.button === 0 && localX >= this._copyButtonBounds.x && localX < this._copyButtonBounds.x + this._copyButtonBounds.width) {
16951
- this.triggerCopy();
16952
- return true;
16953
- }
18136
+ this.updateSelectionForMovement(select, true);
18137
+ this.editBuffer.moveCursorRight();
18138
+ this.updateSelectionForMovement(select, false);
18139
+ this.requestRender();
18140
+ return true;
18141
+ }
18142
+ moveCursorUp(options) {
18143
+ const select = options?.select ?? false;
18144
+ this.updateSelectionForMovement(select, true);
18145
+ this.editorView.moveUpVisual();
18146
+ this.updateSelectionForMovement(select, false);
18147
+ this.requestRender();
18148
+ return true;
18149
+ }
18150
+ moveCursorDown(options) {
18151
+ const select = options?.select ?? false;
18152
+ this.updateSelectionForMovement(select, true);
18153
+ this.editorView.moveDownVisual();
18154
+ this.updateSelectionForMovement(select, false);
18155
+ this.requestRender();
18156
+ return true;
18157
+ }
18158
+ gotoLine(line) {
18159
+ this.editBuffer.gotoLine(line);
18160
+ this.requestRender();
18161
+ }
18162
+ gotoLineStart() {
18163
+ this.setCursor(this.logicalCursor.row, 0);
18164
+ }
18165
+ gotoLineTextEnd() {
18166
+ const eol = this.editBuffer.getEOL();
18167
+ this.setCursor(eol.row, eol.col);
18168
+ }
18169
+ gotoLineHome(options) {
18170
+ const select = options?.select ?? false;
18171
+ this.updateSelectionForMovement(select, true);
18172
+ const cursor = this.editorView.getCursor();
18173
+ if (cursor.col === 0 && cursor.row > 0) {
18174
+ this.editBuffer.setCursor(cursor.row - 1, 0);
18175
+ const prevLineEol = this.editBuffer.getEOL();
18176
+ this.editBuffer.setCursor(prevLineEol.row, prevLineEol.col);
18177
+ } else {
18178
+ this.editBuffer.setCursor(cursor.row, 0);
18179
+ }
18180
+ this.updateSelectionForMovement(select, false);
18181
+ this.requestRender();
18182
+ return true;
18183
+ }
18184
+ gotoLineEnd(options) {
18185
+ const select = options?.select ?? false;
18186
+ this.updateSelectionForMovement(select, true);
18187
+ const cursor = this.editorView.getCursor();
18188
+ const eol = this.editBuffer.getEOL();
18189
+ const lineCount = this.editBuffer.getLineCount();
18190
+ if (cursor.col === eol.col && cursor.row < lineCount - 1) {
18191
+ this.editBuffer.setCursor(cursor.row + 1, 0);
18192
+ } else {
18193
+ this.editBuffer.setCursor(eol.row, eol.col);
18194
+ }
18195
+ this.updateSelectionForMovement(select, false);
18196
+ this.requestRender();
18197
+ return true;
18198
+ }
18199
+ gotoVisualLineHome(options) {
18200
+ const select = options?.select ?? false;
18201
+ this.updateSelectionForMovement(select, true);
18202
+ const sol = this.editorView.getVisualSOL();
18203
+ this.editBuffer.setCursor(sol.logicalRow, sol.logicalCol);
18204
+ this.updateSelectionForMovement(select, false);
18205
+ this.requestRender();
18206
+ return true;
18207
+ }
18208
+ gotoVisualLineEnd(options) {
18209
+ const select = options?.select ?? false;
18210
+ this.updateSelectionForMovement(select, true);
18211
+ const eol = this.editorView.getVisualEOL();
18212
+ this.editBuffer.setCursor(eol.logicalRow, eol.logicalCol);
18213
+ this.updateSelectionForMovement(select, false);
18214
+ this.requestRender();
18215
+ return true;
18216
+ }
18217
+ gotoBufferHome(options) {
18218
+ const select = options?.select ?? false;
18219
+ this.updateSelectionForMovement(select, true);
18220
+ this.editBuffer.setCursor(0, 0);
18221
+ this.updateSelectionForMovement(select, false);
18222
+ this.requestRender();
18223
+ return true;
18224
+ }
18225
+ gotoBufferEnd(options) {
18226
+ const select = options?.select ?? false;
18227
+ this.updateSelectionForMovement(select, true);
18228
+ this.editBuffer.gotoLine(999999);
18229
+ this.updateSelectionForMovement(select, false);
18230
+ this.requestRender();
18231
+ return true;
18232
+ }
18233
+ selectAll() {
18234
+ this.updateSelectionForMovement(false, true);
18235
+ this.editBuffer.setCursor(0, 0);
18236
+ return this.gotoBufferEnd({ select: true });
18237
+ }
18238
+ deleteToLineEnd() {
18239
+ const cursor = this.editorView.getCursor();
18240
+ const eol = this.editBuffer.getEOL();
18241
+ if (eol.col > cursor.col) {
18242
+ this.editBuffer.deleteRange(cursor.row, cursor.col, eol.row, eol.col);
18243
+ }
18244
+ this.requestRender();
18245
+ return true;
18246
+ }
18247
+ deleteToLineStart() {
18248
+ const cursor = this.editorView.getCursor();
18249
+ if (cursor.col > 0) {
18250
+ this.editBuffer.deleteRange(cursor.row, 0, cursor.row, cursor.col);
18251
+ }
18252
+ this.requestRender();
18253
+ return true;
18254
+ }
18255
+ undo() {
18256
+ this._ctx.clearSelection();
18257
+ this.editBuffer.undo();
18258
+ this.requestRender();
18259
+ return true;
18260
+ }
18261
+ redo() {
18262
+ this._ctx.clearSelection();
18263
+ this.editBuffer.redo();
18264
+ this.requestRender();
18265
+ return true;
18266
+ }
18267
+ moveWordForward(options) {
18268
+ const select = options?.select ?? false;
18269
+ this.updateSelectionForMovement(select, true);
18270
+ const nextWord = this.editBuffer.getNextWordBoundary();
18271
+ this.editBuffer.setCursorByOffset(nextWord.offset);
18272
+ this.updateSelectionForMovement(select, false);
18273
+ this.requestRender();
18274
+ return true;
18275
+ }
18276
+ moveWordBackward(options) {
18277
+ const select = options?.select ?? false;
18278
+ this.updateSelectionForMovement(select, true);
18279
+ const prevWord = this.editBuffer.getPrevWordBoundary();
18280
+ this.editBuffer.setCursorByOffset(prevWord.offset);
18281
+ this.updateSelectionForMovement(select, false);
18282
+ this.requestRender();
18283
+ return true;
18284
+ }
18285
+ deleteWordForward() {
18286
+ if (this.hasSelection()) {
18287
+ this.deleteSelectedText();
16954
18288
  return true;
16955
18289
  }
16956
- const lineIndex = this.scrollTopIndex + (localY - 1);
16957
- const colIndex = Math.max(0, localX - 1);
16958
- if (event.type === "down" && event.button === 0) {
16959
- this.clearSelection();
16960
- this._selectionStart = { line: lineIndex, col: colIndex };
16961
- this._selectionEnd = { line: lineIndex, col: colIndex };
16962
- this._isDragging = true;
16963
- this.markNeedsRerender();
18290
+ const currentCursor = this.editBuffer.getCursorPosition();
18291
+ const nextWord = this.editBuffer.getNextWordBoundary();
18292
+ if (nextWord.offset > currentCursor.offset) {
18293
+ this.editBuffer.deleteRange(currentCursor.row, currentCursor.col, nextWord.row, nextWord.col);
18294
+ }
18295
+ this._ctx.clearSelection();
18296
+ this.requestRender();
18297
+ return true;
18298
+ }
18299
+ deleteWordBackward() {
18300
+ if (this.hasSelection()) {
18301
+ this.deleteSelectedText();
16964
18302
  return true;
16965
18303
  }
16966
- if (event.type === "drag" && this._isDragging) {
16967
- this._selectionEnd = { line: lineIndex, col: colIndex };
16968
- const logAreaHeight = Math.max(1, this.consoleHeight - 1);
16969
- const relativeY = localY - 1;
16970
- if (relativeY <= 0) {
16971
- this.startAutoScroll("up");
16972
- } else if (relativeY >= logAreaHeight - 1) {
16973
- this.startAutoScroll("down");
18304
+ const currentCursor = this.editBuffer.getCursorPosition();
18305
+ const prevWord = this.editBuffer.getPrevWordBoundary();
18306
+ if (prevWord.offset < currentCursor.offset) {
18307
+ this.editBuffer.deleteRange(prevWord.row, prevWord.col, currentCursor.row, currentCursor.col);
18308
+ }
18309
+ this._ctx.clearSelection();
18310
+ this.requestRender();
18311
+ return true;
18312
+ }
18313
+ setupMeasureFunc() {
18314
+ const measureFunc = (width, widthMode, height, heightMode) => {
18315
+ let effectiveWidth;
18316
+ if (widthMode === MeasureMode.Undefined || isNaN(width)) {
18317
+ effectiveWidth = 0;
16974
18318
  } else {
16975
- this.stopAutoScroll();
18319
+ effectiveWidth = width;
16976
18320
  }
16977
- this.markNeedsRerender();
16978
- return true;
16979
- }
16980
- if (event.type === "up") {
16981
- if (this._isDragging) {
16982
- this._selectionEnd = { line: lineIndex, col: colIndex };
16983
- this._isDragging = false;
16984
- this.stopAutoScroll();
16985
- this.markNeedsRerender();
18321
+ const effectiveHeight = isNaN(height) ? 1 : height;
18322
+ const measureResult = this.editorView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight));
18323
+ const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1;
18324
+ const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1;
18325
+ if (widthMode === MeasureMode.AtMost && this._positionType !== "absolute") {
18326
+ return {
18327
+ width: Math.min(effectiveWidth, measuredWidth),
18328
+ height: Math.min(effectiveHeight, measuredHeight)
18329
+ };
16986
18330
  }
16987
- return true;
18331
+ return {
18332
+ width: measuredWidth,
18333
+ height: measuredHeight
18334
+ };
18335
+ };
18336
+ this.yogaNode.setMeasureFunc(measureFunc);
18337
+ }
18338
+ render(buffer, deltaTime) {
18339
+ if (!this.visible)
18340
+ return;
18341
+ if (this.isDestroyed)
18342
+ return;
18343
+ this.markClean();
18344
+ this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
18345
+ this.renderSelf(buffer);
18346
+ this.renderCursor(buffer);
18347
+ }
18348
+ renderSelf(buffer) {
18349
+ buffer.drawEditorView(this.editorView, this.x, this.y);
18350
+ }
18351
+ renderCursor(buffer) {
18352
+ if (!this._showCursor || !this._focused)
18353
+ return;
18354
+ const visualCursor = this.editorView.getVisualCursor();
18355
+ const cursorX = this.x + visualCursor.visualCol + 1;
18356
+ const cursorY = this.y + visualCursor.visualRow + 1;
18357
+ this._ctx.setCursorPosition(cursorX, cursorY, true);
18358
+ this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor });
18359
+ }
18360
+ focus() {
18361
+ super.focus();
18362
+ this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor });
18363
+ this.requestRender();
18364
+ }
18365
+ blur() {
18366
+ super.blur();
18367
+ this._ctx.setCursorPosition(0, 0, false);
18368
+ this.requestRender();
18369
+ }
18370
+ onRemove() {
18371
+ if (this._focused) {
18372
+ this._ctx.setCursorPosition(0, 0, false);
16988
18373
  }
16989
- return true;
16990
18374
  }
16991
- get visible() {
16992
- return this.isVisible;
18375
+ destroy() {
18376
+ if (this.isDestroyed)
18377
+ return;
18378
+ this.traits = {};
18379
+ if (this._focused) {
18380
+ this._ctx.setCursorPosition(0, 0, false);
18381
+ this.blur();
18382
+ }
18383
+ this.editorView.destroy();
18384
+ this.editBuffer.destroy();
18385
+ super.destroy();
16993
18386
  }
16994
- get bounds() {
16995
- return {
16996
- x: this.consoleX,
16997
- y: this.consoleY,
16998
- width: this.consoleWidth,
16999
- height: this.consoleHeight
17000
- };
18387
+ set onCursorChange(handler) {
18388
+ this._cursorChangeListener = handler;
17001
18389
  }
17002
- saveLogsToFile() {
17003
- try {
17004
- const timestamp = Date.now();
17005
- const filename = `_console_${timestamp}.log`;
17006
- const filepath = path5.join(process.cwd(), filename);
17007
- const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
17008
- const logLines = [];
17009
- for (const [date, level, args, callerInfo] of allLogEntries) {
17010
- const timestampStr = this.formatTimestamp(date);
17011
- const callerSource = callerInfo ? `${callerInfo.fileName}:${callerInfo.lineNumber}` : "unknown";
17012
- const prefix = `[${timestampStr}] [${level}]` + (this._debugModeEnabled ? ` [${callerSource}]` : "") + " ";
17013
- const formattedArgs = this.formatArguments(args);
17014
- logLines.push(prefix + formattedArgs);
18390
+ get onCursorChange() {
18391
+ return this._cursorChangeListener;
18392
+ }
18393
+ set onContentChange(handler) {
18394
+ this._contentChangeListener = handler;
18395
+ }
18396
+ get onContentChange() {
18397
+ return this._contentChangeListener;
18398
+ }
18399
+ get syntaxStyle() {
18400
+ return this.editBuffer.getSyntaxStyle();
18401
+ }
18402
+ set syntaxStyle(style) {
18403
+ this.editBuffer.setSyntaxStyle(style);
18404
+ this.requestRender();
18405
+ }
18406
+ addHighlight(lineIdx, highlight) {
18407
+ this.editBuffer.addHighlight(lineIdx, highlight);
18408
+ this.requestRender();
18409
+ }
18410
+ addHighlightByCharRange(highlight) {
18411
+ this.editBuffer.addHighlightByCharRange(highlight);
18412
+ this.requestRender();
18413
+ }
18414
+ removeHighlightsByRef(hlRef) {
18415
+ this.editBuffer.removeHighlightsByRef(hlRef);
18416
+ this.requestRender();
18417
+ }
18418
+ clearLineHighlights(lineIdx) {
18419
+ this.editBuffer.clearLineHighlights(lineIdx);
18420
+ this.requestRender();
18421
+ }
18422
+ clearAllHighlights() {
18423
+ this.editBuffer.clearAllHighlights();
18424
+ this.requestRender();
18425
+ }
18426
+ getLineHighlights(lineIdx) {
18427
+ return this.editBuffer.getLineHighlights(lineIdx);
18428
+ }
18429
+ setText(text) {
18430
+ this.editBuffer.setText(text);
18431
+ this.yogaNode.markDirty();
18432
+ this.requestRender();
18433
+ }
18434
+ replaceText(text) {
18435
+ this.editBuffer.replaceText(text);
18436
+ this.yogaNode.markDirty();
18437
+ this.requestRender();
18438
+ }
18439
+ clear() {
18440
+ this.editBuffer.clear();
18441
+ this.editBuffer.clearAllHighlights();
18442
+ this.yogaNode.markDirty();
18443
+ this.requestRender();
18444
+ }
18445
+ deleteRange(startLine, startCol, endLine, endCol) {
18446
+ this.editBuffer.deleteRange(startLine, startCol, endLine, endCol);
18447
+ this.yogaNode.markDirty();
18448
+ this.requestRender();
18449
+ }
18450
+ getTextRange(startOffset, endOffset) {
18451
+ return this.editBuffer.getTextRange(startOffset, endOffset);
18452
+ }
18453
+ getTextRangeByCoords(startRow, startCol, endRow, endCol) {
18454
+ return this.editBuffer.getTextRangeByCoords(startRow, startCol, endRow, endCol);
18455
+ }
18456
+ updateSelectionForMovement(shiftPressed, isBeforeMovement) {
18457
+ if (!this.selectable)
18458
+ return;
18459
+ if (!shiftPressed) {
18460
+ this._keyboardSelectionActive = false;
18461
+ this._ctx.clearSelection();
18462
+ return;
18463
+ }
18464
+ this._keyboardSelectionActive = true;
18465
+ const visualCursor = this.editorView.getVisualCursor();
18466
+ const cursorX = this.x + visualCursor.visualCol;
18467
+ const cursorY = this.y + visualCursor.visualRow;
18468
+ if (isBeforeMovement) {
18469
+ if (!this._ctx.hasSelection) {
18470
+ this._ctx.startSelection(this, cursorX, cursorY);
17015
18471
  }
17016
- const content = logLines.join(`
17017
- `);
17018
- fs.writeFileSync(filepath, content, "utf8");
17019
- console.info(`Console logs saved to: ${filename}`);
17020
- } catch (error) {
17021
- console.error(`Failed to save console logs:`, error);
18472
+ return;
17022
18473
  }
18474
+ this._ctx.updateSelection(this, cursorX, cursorY, { finishDragging: true });
17023
18475
  }
17024
18476
  }
17025
18477
 
@@ -17071,7 +18523,7 @@ class Clipboard {
17071
18523
  }
17072
18524
 
17073
18525
  // src/renderer.ts
17074
- import { EventEmitter as EventEmitter8 } from "events";
18526
+ import { EventEmitter as EventEmitter9 } from "events";
17075
18527
 
17076
18528
  // src/lib/objects-in-viewport.ts
17077
18529
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -17209,25 +18661,25 @@ function parsePixelResolution(sequence) {
17209
18661
  // src/renderer.ts
17210
18662
  registerEnvVar({
17211
18663
  name: "OTUI_DUMP_CAPTURES",
17212
- description: "Dump captured output when the renderer exits.",
18664
+ description: "Dump captured stdout and console caches when the renderer exit handler runs.",
17213
18665
  type: "boolean",
17214
18666
  default: false
17215
18667
  });
17216
18668
  registerEnvVar({
17217
18669
  name: "OTUI_NO_NATIVE_RENDER",
17218
- description: "Disable native rendering. This will not actually output ansi and is useful for debugging.",
18670
+ description: "Skip the Zig/native frame renderer. Useful for debugging the render loop; split-footer stdout flushing may still write ANSI.",
17219
18671
  type: "boolean",
17220
18672
  default: false
17221
18673
  });
17222
18674
  registerEnvVar({
17223
18675
  name: "OTUI_USE_ALTERNATE_SCREEN",
17224
- description: "Use the terminal alternate screen buffer.",
18676
+ description: "When explicitly set, force screen mode selection: true=alternate-screen, false=main-screen.",
17225
18677
  type: "boolean",
17226
18678
  default: true
17227
18679
  });
17228
18680
  registerEnvVar({
17229
18681
  name: "OTUI_OVERRIDE_STDOUT",
17230
- description: "Override the stdout stream. This is useful for debugging.",
18682
+ description: "When explicitly set, force stdout routing: false=passthrough, true=capture in split-footer mode.",
17231
18683
  type: "boolean",
17232
18684
  default: true
17233
18685
  });
@@ -17243,6 +18695,39 @@ registerEnvVar({
17243
18695
  type: "boolean",
17244
18696
  default: false
17245
18697
  });
18698
+ var DEFAULT_FOOTER_HEIGHT = 12;
18699
+ function normalizeFooterHeight(footerHeight) {
18700
+ if (footerHeight === undefined) {
18701
+ return DEFAULT_FOOTER_HEIGHT;
18702
+ }
18703
+ if (!Number.isFinite(footerHeight)) {
18704
+ throw new Error("footerHeight must be a finite number");
18705
+ }
18706
+ const normalizedFooterHeight = Math.trunc(footerHeight);
18707
+ if (normalizedFooterHeight <= 0) {
18708
+ throw new Error("footerHeight must be greater than 0");
18709
+ }
18710
+ return normalizedFooterHeight;
18711
+ }
18712
+ function resolveModes(config) {
18713
+ let screenMode = config.screenMode ?? "alternate-screen";
18714
+ if (process.env.OTUI_USE_ALTERNATE_SCREEN !== undefined) {
18715
+ screenMode = env.OTUI_USE_ALTERNATE_SCREEN ? "alternate-screen" : "main-screen";
18716
+ }
18717
+ const footerHeight = screenMode === "split-footer" ? normalizeFooterHeight(config.footerHeight) : DEFAULT_FOOTER_HEIGHT;
18718
+ let externalOutputMode = config.externalOutputMode ?? (screenMode === "split-footer" ? "capture-stdout" : "passthrough");
18719
+ if (process.env.OTUI_OVERRIDE_STDOUT !== undefined) {
18720
+ externalOutputMode = env.OTUI_OVERRIDE_STDOUT && screenMode === "split-footer" ? "capture-stdout" : "passthrough";
18721
+ }
18722
+ if (externalOutputMode === "capture-stdout" && screenMode !== "split-footer") {
18723
+ throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
18724
+ }
18725
+ return {
18726
+ screenMode,
18727
+ footerHeight,
18728
+ externalOutputMode
18729
+ };
18730
+ }
17246
18731
  var DEFAULT_FORWARDED_ENV_KEYS = [
17247
18732
  "TMUX",
17248
18733
  "TERM",
@@ -17360,9 +18845,10 @@ async function createCliRenderer(config = {}) {
17360
18845
  }
17361
18846
  const stdin = config.stdin || process.stdin;
17362
18847
  const stdout = config.stdout || process.stdout;
18848
+ const { screenMode, footerHeight } = resolveModes(config);
17363
18849
  const width = stdout.columns || 80;
17364
18850
  const height = stdout.rows || 24;
17365
- const renderHeight = config.experimental_splitHeight && config.experimental_splitHeight > 0 ? config.experimental_splitHeight : height;
18851
+ const renderHeight = screenMode === "split-footer" ? footerHeight : height;
17366
18852
  const ziglib = resolveRenderLib();
17367
18853
  const rendererPtr = ziglib.createRenderer(width, renderHeight, {
17368
18854
  remote: config.remote ?? false,
@@ -17392,6 +18878,7 @@ var CliRenderEvents;
17392
18878
  CliRenderEvents2["RESIZE"] = "resize";
17393
18879
  CliRenderEvents2["FOCUS"] = "focus";
17394
18880
  CliRenderEvents2["BLUR"] = "blur";
18881
+ CliRenderEvents2["FOCUSED_EDITOR"] = "focused_editor";
17395
18882
  CliRenderEvents2["THEME_MODE"] = "theme_mode";
17396
18883
  CliRenderEvents2["CAPABILITIES"] = "capabilities";
17397
18884
  CliRenderEvents2["SELECTION"] = "selection";
@@ -17409,7 +18896,7 @@ var RendererControlState;
17409
18896
  RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
17410
18897
  })(RendererControlState ||= {});
17411
18898
 
17412
- class CliRenderer extends EventEmitter8 {
18899
+ class CliRenderer extends EventEmitter9 {
17413
18900
  static animationFrameId = 0;
17414
18901
  lib;
17415
18902
  rendererPtr;
@@ -17421,11 +18908,12 @@ class CliRenderer extends EventEmitter8 {
17421
18908
  _isDestroyed = false;
17422
18909
  _destroyPending = false;
17423
18910
  _destroyFinalized = false;
18911
+ _destroyCleanupPrepared = false;
17424
18912
  nextRenderBuffer;
17425
18913
  currentRenderBuffer;
17426
18914
  _isRunning = false;
17427
- targetFps = 30;
17428
- maxFps = 60;
18915
+ _targetFps = 30;
18916
+ _maxFps = 60;
17429
18917
  automaticMemorySnapshot = false;
17430
18918
  memorySnapshotInterval;
17431
18919
  memorySnapshotTimer = null;
@@ -17452,8 +18940,8 @@ class CliRenderer extends EventEmitter8 {
17452
18940
  frameCount = 0;
17453
18941
  lastFpsTime = 0;
17454
18942
  currentFps = 0;
17455
- targetFrameTime = 1000 / this.targetFps;
17456
- minTargetFrameTime = 1000 / this.maxFps;
18943
+ targetFrameTime = 1000 / this._targetFps;
18944
+ minTargetFrameTime = 1000 / this._maxFps;
17457
18945
  immediateRerenderRequested = false;
17458
18946
  updateScheduled = false;
17459
18947
  liveRequestCounter = 0;
@@ -17482,7 +18970,9 @@ class CliRenderer extends EventEmitter8 {
17482
18970
  enableMouseMovement = false;
17483
18971
  _useMouse = true;
17484
18972
  autoFocus = true;
17485
- _useAlternateScreen = env.OTUI_USE_ALTERNATE_SCREEN;
18973
+ _screenMode = "alternate-screen";
18974
+ _footerHeight = DEFAULT_FOOTER_HEIGHT;
18975
+ _externalOutputMode = "passthrough";
17486
18976
  _suspendedMouseEnabled = false;
17487
18977
  _previousControlState = "idle" /* IDLE */;
17488
18978
  capturedRenderable;
@@ -17581,13 +19071,9 @@ Captured output:
17581
19071
  this.width = width;
17582
19072
  this.height = height;
17583
19073
  this._useThread = config.useThread === undefined ? false : config.useThread;
17584
- this._splitHeight = config.experimental_splitHeight || 0;
17585
- if (this._splitHeight > 0) {
17586
- capture.on("write", this.captureCallback);
17587
- this.renderOffset = height - this._splitHeight;
17588
- this.height = this._splitHeight;
17589
- lib.setRenderOffset(rendererPtr, this.renderOffset);
17590
- }
19074
+ const { screenMode, footerHeight, externalOutputMode } = resolveModes(config);
19075
+ this._footerHeight = footerHeight;
19076
+ this._screenMode = screenMode;
17591
19077
  this.rendererPtr = rendererPtr;
17592
19078
  const forwardEnvKeys = config.forwardEnvKeys ?? [...DEFAULT_FORWARDED_ENV_KEYS];
17593
19079
  for (const key of forwardEnvKeys) {
@@ -17605,15 +19091,12 @@ Captured output:
17605
19091
  "SIGHUP",
17606
19092
  "SIGBREAK",
17607
19093
  "SIGPIPE",
17608
- "SIGBUS",
17609
- "SIGFPE"
19094
+ "SIGBUS"
17610
19095
  ];
17611
19096
  this.clipboard = new Clipboard(this.lib, this.rendererPtr);
17612
19097
  this.resizeDebounceDelay = config.debounceDelay || 100;
17613
19098
  this.targetFps = config.targetFps || 30;
17614
19099
  this.maxFps = config.maxFps || 60;
17615
- this.targetFrameTime = 1000 / this.targetFps;
17616
- this.minTargetFrameTime = 1000 / this.maxFps;
17617
19100
  this.clock = config.clock ?? new SystemClock;
17618
19101
  this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
17619
19102
  this.gatherStats = config.gatherStats || false;
@@ -17621,7 +19104,6 @@ Captured output:
17621
19104
  this.enableMouseMovement = config.enableMouseMovement ?? true;
17622
19105
  this._useMouse = config.useMouse ?? true;
17623
19106
  this.autoFocus = config.autoFocus ?? true;
17624
- this._useAlternateScreen = config.useAlternateScreen ?? env.OTUI_USE_ALTERNATE_SCREEN;
17625
19107
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
17626
19108
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
17627
19109
  this.postProcessFns = config.postProcessFns || [];
@@ -17630,9 +19112,6 @@ Captured output:
17630
19112
  if (this.memorySnapshotInterval > 0) {
17631
19113
  this.startMemorySnapshotTimer();
17632
19114
  }
17633
- if (env.OTUI_OVERRIDE_STDOUT) {
17634
- this.stdout.write = this.interceptStdoutWrite.bind(this);
17635
- }
17636
19115
  process.on("SIGWINCH", this.sigwinchHandler);
17637
19116
  process.on("warning", this.warningHandler);
17638
19117
  process.on("uncaughtException", this.handleError);
@@ -17652,7 +19131,7 @@ Captured output:
17652
19131
  this.addExitListeners();
17653
19132
  const stdinParserMaxBufferBytes = config.stdinParserMaxBufferBytes ?? DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES;
17654
19133
  this.stdinParser = new StdinParser({
17655
- timeoutMs: 10,
19134
+ timeoutMs: 20,
17656
19135
  maxPendingBytes: stdinParserMaxBufferBytes,
17657
19136
  armTimeouts: true,
17658
19137
  onTimeoutFlush: () => {
@@ -17671,7 +19150,9 @@ Captured output:
17671
19150
  ...config.consoleOptions ?? {},
17672
19151
  clock: this.clock
17673
19152
  });
17674
- this.useConsole = config.useConsole ?? true;
19153
+ this.consoleMode = config.consoleMode ?? "console-overlay";
19154
+ this.applyScreenMode(screenMode, false, false);
19155
+ this.externalOutputMode = externalOutputMode;
17675
19156
  this._openConsoleOnError = config.openConsoleOnError ?? true;
17676
19157
  this._onDestroy = config.onDestroy;
17677
19158
  global.requestAnimationFrame = (callback) => {
@@ -17728,6 +19209,13 @@ Captured output:
17728
19209
  get currentFocusedRenderable() {
17729
19210
  return this._currentFocusedRenderable;
17730
19211
  }
19212
+ get currentFocusedEditor() {
19213
+ if (!this._currentFocusedRenderable)
19214
+ return null;
19215
+ if (!isEditBufferRenderable(this._currentFocusedRenderable))
19216
+ return null;
19217
+ return this._currentFocusedRenderable;
19218
+ }
17731
19219
  normalizeClockTime(now, fallback) {
17732
19220
  if (Number.isFinite(now)) {
17733
19221
  return now;
@@ -17743,10 +19231,15 @@ Captured output:
17743
19231
  focusRenderable(renderable) {
17744
19232
  if (this._currentFocusedRenderable === renderable)
17745
19233
  return;
19234
+ const prev = this.currentFocusedEditor;
17746
19235
  if (this._currentFocusedRenderable) {
17747
19236
  this._currentFocusedRenderable.blur();
17748
19237
  }
17749
19238
  this._currentFocusedRenderable = renderable;
19239
+ const next = this.currentFocusedEditor;
19240
+ if (prev !== next) {
19241
+ this.emit("focused_editor" /* FOCUSED_EDITOR */, next, prev);
19242
+ }
17750
19243
  }
17751
19244
  setCapturedRenderable(renderable) {
17752
19245
  if (this.capturedRenderable === renderable) {
@@ -17807,16 +19300,23 @@ Captured output:
17807
19300
  }
17808
19301
  }
17809
19302
  async activateFrame() {
17810
- await this.loop();
17811
- this.updateScheduled = false;
17812
- this.resolveIdleIfNeeded();
19303
+ if (!this.updateScheduled) {
19304
+ this.resolveIdleIfNeeded();
19305
+ return;
19306
+ }
19307
+ try {
19308
+ await this.loop();
19309
+ } finally {
19310
+ this.updateScheduled = false;
19311
+ this.resolveIdleIfNeeded();
19312
+ }
17813
19313
  }
17814
- get useConsole() {
17815
- return this._useConsole;
19314
+ get consoleMode() {
19315
+ return this._useConsole ? "console-overlay" : "disabled";
17816
19316
  }
17817
- set useConsole(value) {
17818
- this._useConsole = value;
17819
- if (value) {
19317
+ set consoleMode(mode) {
19318
+ this._useConsole = mode === "console-overlay";
19319
+ if (this._useConsole) {
17820
19320
  this.console.activate();
17821
19321
  } else {
17822
19322
  this.console.deactivate();
@@ -17866,6 +19366,20 @@ Captured output:
17866
19366
  get useThread() {
17867
19367
  return this._useThread;
17868
19368
  }
19369
+ get targetFps() {
19370
+ return this._targetFps;
19371
+ }
19372
+ set targetFps(targetFps) {
19373
+ this._targetFps = targetFps;
19374
+ this.targetFrameTime = 1000 / this._targetFps;
19375
+ }
19376
+ get maxFps() {
19377
+ return this._maxFps;
19378
+ }
19379
+ set maxFps(maxFps) {
19380
+ this._maxFps = maxFps;
19381
+ this.minTargetFrameTime = 1000 / this._maxFps;
19382
+ }
17869
19383
  get useMouse() {
17870
19384
  return this._useMouse;
17871
19385
  }
@@ -17879,8 +19393,37 @@ Captured output:
17879
19393
  this.disableMouse();
17880
19394
  }
17881
19395
  }
17882
- get experimental_splitHeight() {
17883
- return this._splitHeight;
19396
+ get screenMode() {
19397
+ return this._screenMode;
19398
+ }
19399
+ set screenMode(mode) {
19400
+ if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") {
19401
+ throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
19402
+ }
19403
+ this.applyScreenMode(mode);
19404
+ }
19405
+ get footerHeight() {
19406
+ return this._footerHeight;
19407
+ }
19408
+ set footerHeight(footerHeight) {
19409
+ const normalizedFooterHeight = normalizeFooterHeight(footerHeight);
19410
+ if (normalizedFooterHeight === this._footerHeight) {
19411
+ return;
19412
+ }
19413
+ this._footerHeight = normalizedFooterHeight;
19414
+ if (this.screenMode === "split-footer") {
19415
+ this.applyScreenMode("split-footer");
19416
+ }
19417
+ }
19418
+ get externalOutputMode() {
19419
+ return this._externalOutputMode;
19420
+ }
19421
+ set externalOutputMode(mode) {
19422
+ if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
19423
+ throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
19424
+ }
19425
+ this._externalOutputMode = mode;
19426
+ this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
17884
19427
  }
17885
19428
  get liveRequestCount() {
17886
19429
  return this.liveRequestCounter;
@@ -17904,61 +19447,75 @@ Captured output:
17904
19447
  const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0;
17905
19448
  this.lib.setKittyKeyboardFlags(this.rendererPtr, flags);
17906
19449
  }
17907
- set experimental_splitHeight(splitHeight) {
17908
- if (splitHeight < 0)
17909
- splitHeight = 0;
19450
+ interceptStdoutWrite = (chunk, encoding, callback) => {
19451
+ const text = chunk.toString();
19452
+ capture.write("stdout", text);
19453
+ if (this._splitHeight > 0) {
19454
+ this.requestRender();
19455
+ }
19456
+ if (typeof callback === "function") {
19457
+ process.nextTick(callback);
19458
+ }
19459
+ return true;
19460
+ };
19461
+ applyScreenMode(screenMode, emitResize = true, requestRender = true) {
19462
+ const prevScreenMode = this._screenMode;
17910
19463
  const prevSplitHeight = this._splitHeight;
17911
- if (splitHeight > 0) {
17912
- this._splitHeight = splitHeight;
17913
- this.renderOffset = this._terminalHeight - this._splitHeight;
17914
- this.height = this._splitHeight;
17915
- if (prevSplitHeight === 0) {
17916
- this.useConsole = false;
17917
- capture.on("write", this.captureCallback);
17918
- const freedLines = this._terminalHeight - this._splitHeight;
19464
+ const nextSplitHeight = screenMode === "split-footer" ? this._footerHeight : 0;
19465
+ if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) {
19466
+ return;
19467
+ }
19468
+ const prevUseAlternateScreen = prevScreenMode === "alternate-screen";
19469
+ const nextUseAlternateScreen = screenMode === "alternate-screen";
19470
+ const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen;
19471
+ const leavingSplitFooter = prevSplitHeight > 0 && nextSplitHeight === 0;
19472
+ if (this._terminalIsSetup && leavingSplitFooter) {
19473
+ this.flushStdoutCache(this._terminalHeight, true);
19474
+ }
19475
+ if (this._terminalIsSetup && !terminalScreenModeChanged) {
19476
+ if (prevSplitHeight === 0 && nextSplitHeight > 0) {
19477
+ const freedLines = this._terminalHeight - nextSplitHeight;
17919
19478
  const scrollDown = ANSI.scrollDown(freedLines);
17920
19479
  this.writeOut(scrollDown);
17921
- } else if (prevSplitHeight > this._splitHeight) {
17922
- const freedLines = prevSplitHeight - this._splitHeight;
19480
+ } else if (prevSplitHeight > nextSplitHeight && nextSplitHeight > 0) {
19481
+ const freedLines = prevSplitHeight - nextSplitHeight;
17923
19482
  const scrollDown = ANSI.scrollDown(freedLines);
17924
19483
  this.writeOut(scrollDown);
17925
- } else if (prevSplitHeight < this._splitHeight) {
17926
- const additionalLines = this._splitHeight - prevSplitHeight;
19484
+ } else if (prevSplitHeight < nextSplitHeight && prevSplitHeight > 0) {
19485
+ const additionalLines = nextSplitHeight - prevSplitHeight;
17927
19486
  const scrollUp = ANSI.scrollUp(additionalLines);
17928
19487
  this.writeOut(scrollUp);
17929
19488
  }
17930
- } else {
17931
- if (prevSplitHeight > 0) {
17932
- this.flushStdoutCache(this._terminalHeight, true);
17933
- capture.off("write", this.captureCallback);
17934
- this.useConsole = true;
17935
- }
17936
- this._splitHeight = 0;
17937
- this.renderOffset = 0;
17938
- this.height = this._terminalHeight;
17939
19489
  }
19490
+ if (prevSplitHeight === 0 && nextSplitHeight > 0) {
19491
+ capture.on("write", this.captureCallback);
19492
+ } else if (prevSplitHeight > 0 && nextSplitHeight === 0) {
19493
+ capture.off("write", this.captureCallback);
19494
+ }
19495
+ this._screenMode = screenMode;
19496
+ this._splitHeight = nextSplitHeight;
19497
+ this.renderOffset = nextSplitHeight > 0 ? this._terminalHeight - nextSplitHeight : 0;
17940
19498
  this.width = this._terminalWidth;
19499
+ this.height = nextSplitHeight > 0 ? nextSplitHeight : this._terminalHeight;
17941
19500
  this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
17942
19501
  this.lib.resizeRenderer(this.rendererPtr, this.width, this.height);
17943
19502
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
19503
+ this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
17944
19504
  this._console.resize(this.width, this.height);
17945
19505
  this.root.resize(this.width, this.height);
17946
- this.emit("resize" /* RESIZE */, this.width, this.height);
17947
- this.requestRender();
17948
- }
17949
- interceptStdoutWrite = (chunk, encoding, callback) => {
17950
- const text = chunk.toString();
17951
- capture.write("stdout", text);
17952
- if (this._splitHeight > 0) {
17953
- this.requestRender();
19506
+ if (terminalScreenModeChanged) {
19507
+ this.lib.suspendRenderer(this.rendererPtr);
19508
+ this.lib.setupTerminal(this.rendererPtr, nextUseAlternateScreen);
19509
+ if (this._useMouse) {
19510
+ this.enableMouse();
19511
+ }
17954
19512
  }
17955
- if (typeof callback === "function") {
17956
- process.nextTick(callback);
19513
+ if (emitResize) {
19514
+ this.emit("resize" /* RESIZE */, this.width, this.height);
19515
+ }
19516
+ if (requestRender) {
19517
+ this.requestRender();
17957
19518
  }
17958
- return true;
17959
- };
17960
- disableStdoutInterception() {
17961
- this.stdout.write = this.realStdoutWrite;
17962
19519
  }
17963
19520
  flushStdoutCache(space, force = false) {
17964
19521
  if (capture.size === 0 && !force)
@@ -18012,7 +19569,7 @@ Captured output:
18012
19569
  privateCapabilityRepliesActive: true,
18013
19570
  explicitWidthCprActive: true
18014
19571
  });
18015
- this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
19572
+ this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen");
18016
19573
  this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
18017
19574
  if (this.debugOverlay.enabled) {
18018
19575
  this.lib.setDebugOverlay(this.rendererPtr, true, this.debugOverlay.corner);
@@ -18585,6 +20142,7 @@ Captured output:
18585
20142
  internalStart() {
18586
20143
  if (!this._isRunning && !this._isDestroyed) {
18587
20144
  this._isRunning = true;
20145
+ this.updateScheduled = false;
18588
20146
  if (this.memorySnapshotInterval > 0) {
18589
20147
  this.startMemorySnapshotTimer();
18590
20148
  }
@@ -18672,15 +20230,15 @@ Captured output:
18672
20230
  this._isDestroyed = true;
18673
20231
  this._destroyPending = true;
18674
20232
  if (this.rendering) {
20233
+ this.prepareDestroyDuringRender();
18675
20234
  return;
18676
20235
  }
18677
20236
  this.finalizeDestroy();
18678
20237
  }
18679
- finalizeDestroy() {
18680
- if (this._destroyFinalized)
20238
+ cleanupBeforeDestroy() {
20239
+ if (this._destroyCleanupPrepared)
18681
20240
  return;
18682
- this._destroyFinalized = true;
18683
- this._destroyPending = false;
20241
+ this._destroyCleanupPrepared = true;
18684
20242
  process.removeListener("SIGWINCH", this.sigwinchHandler);
18685
20243
  process.removeListener("uncaughtException", this.handleError);
18686
20244
  process.removeListener("unhandledRejection", this.handleError);
@@ -18698,14 +20256,8 @@ Captured output:
18698
20256
  }
18699
20257
  if (this.memorySnapshotTimer) {
18700
20258
  this.clock.clearInterval(this.memorySnapshotTimer);
20259
+ this.memorySnapshotTimer = null;
18701
20260
  }
18702
- if (this._paletteDetector) {
18703
- this._paletteDetector.cleanup();
18704
- this._paletteDetector = null;
18705
- }
18706
- this._paletteDetectionPromise = null;
18707
- this._cachedPalette = null;
18708
- this.emit("destroy" /* DESTROY */);
18709
20261
  if (this.renderTimeout) {
18710
20262
  this.clock.clearTimeout(this.renderTimeout);
18711
20263
  this.renderTimeout = null;
@@ -18718,23 +20270,41 @@ Captured output:
18718
20270
  explicitWidthCprActive: false
18719
20271
  }, true);
18720
20272
  this.setCapturedRenderable(undefined);
20273
+ this.stdin.removeListener("data", this.stdinListener);
20274
+ if (this.stdin.setRawMode) {
20275
+ this.stdin.setRawMode(false);
20276
+ }
20277
+ this.externalOutputMode = "passthrough";
20278
+ if (this._splitHeight > 0) {
20279
+ this.flushStdoutCache(this._splitHeight, true);
20280
+ }
20281
+ }
20282
+ prepareDestroyDuringRender() {
20283
+ this.cleanupBeforeDestroy();
20284
+ this.lib.suspendRenderer(this.rendererPtr);
20285
+ }
20286
+ finalizeDestroy() {
20287
+ if (this._destroyFinalized)
20288
+ return;
20289
+ this._destroyFinalized = true;
20290
+ this._destroyPending = false;
20291
+ this.cleanupBeforeDestroy();
20292
+ if (this._paletteDetector) {
20293
+ this._paletteDetector.cleanup();
20294
+ this._paletteDetector = null;
20295
+ }
20296
+ this._paletteDetectionPromise = null;
20297
+ this._cachedPalette = null;
20298
+ this.emit("destroy" /* DESTROY */);
18721
20299
  try {
18722
20300
  this.root.destroyRecursively();
18723
20301
  } catch (e) {
18724
20302
  console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
18725
20303
  }
18726
- this.stdin.removeListener("data", this.stdinListener);
18727
- if (this.stdin.setRawMode) {
18728
- this.stdin.setRawMode(false);
18729
- }
18730
20304
  this.stdinParser?.destroy();
18731
20305
  this.stdinParser = null;
18732
20306
  this.oscSubscribers.clear();
18733
20307
  this._console.destroy();
18734
- this.disableStdoutInterception();
18735
- if (this._splitHeight > 0) {
18736
- this.flushStdoutCache(this._splitHeight, true);
18737
- }
18738
20308
  this.lib.destroyRenderer(this.rendererPtr);
18739
20309
  rendererTracker.removeRenderer(this);
18740
20310
  if (this._onDestroy) {
@@ -19029,7 +20599,7 @@ Captured output:
19029
20599
  }
19030
20600
  }
19031
20601
 
19032
- export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, decodePasteBytes, stripAnsiSequences, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, ANSI, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingKey, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
20602
+ export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, decodePasteBytes, stripAnsiSequences, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, EditBuffer, EditorView, ANSI, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingKey, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, EditBufferRenderableEvents, isEditBufferRenderable, EditBufferRenderable, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
19033
20603
 
19034
- //# debugId=65A16F2A818D8FA964756E2164756E21
19035
- //# sourceMappingURL=index-km01g6g8.js.map
20604
+ //# debugId=8662AB2ADD41165D64756E2164756E21
20605
+ //# sourceMappingURL=index-8z2zcznw.js.map