@fairyhunter13/opentui-core 0.1.101 → 0.1.103

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