@codingame/monaco-vscode-xterm-addons-common 28.4.1 → 29.1.0
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.
- package/package.json +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContext.d.ts +7 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContext.js +11 -37
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugAttachment.js +4 -51
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.js +24 -18
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.js +25 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.js +48 -34
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders.js +234 -14
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugEvents.d.ts +58 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugEvents.js +135 -0
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.js +16 -16
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.js +20 -4
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { IChatDebugEvent } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatDebugService";
|
|
2
|
+
/**
|
|
3
|
+
* Descriptions of each debug event kind for the model. Adding a new event kind
|
|
4
|
+
* to {@link IChatDebugEvent} without adding an entry here will cause a compile error.
|
|
5
|
+
*/
|
|
6
|
+
export declare const debugEventKindDescriptions: Record<IChatDebugEvent["kind"], string>;
|
|
7
|
+
/**
|
|
8
|
+
* Formats debug events into a compact log-style summary for context attachment.
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatDebugEventsForContext(events: readonly IChatDebugEvent[]): string;
|
|
11
|
+
/**
|
|
12
|
+
* Constructs the model description for the debug events attachment,
|
|
13
|
+
* explaining to the model how to use the resolveDebugEventDetails tool.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getDebugEventsModelDescription(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Checks whether a debug event matches a single text search term.
|
|
18
|
+
* Used by both the debug panel filter and the listDebugEvents tool.
|
|
19
|
+
*/
|
|
20
|
+
export declare function debugEventMatchesText(event: IChatDebugEvent, term: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Parse a `before:YYYY[-MM[-DD[THH[:MM[:SS]]]]]` or `after:…` token from
|
|
23
|
+
* free-form filter text. Each component after the year is optional.
|
|
24
|
+
*
|
|
25
|
+
* For `before:`, the timestamp is rounded **up** to the end of the most
|
|
26
|
+
* specific unit given (e.g. `before:2026-03` → end-of-March).
|
|
27
|
+
* For `after:`, the timestamp is the **start** of the most specific unit.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTimeToken(text: string, prefix: string): number | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Strips `before:…` and `after:…` timestamp tokens from filter text,
|
|
32
|
+
* returning only the plain text search portion.
|
|
33
|
+
*/
|
|
34
|
+
export declare function stripTimestampTokens(text: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Filters debug events by comma-separated text terms and optional
|
|
37
|
+
* `before:`/`after:` timestamp tokens.
|
|
38
|
+
*
|
|
39
|
+
* Terms prefixed with `!` are exclusions; all others are inclusions.
|
|
40
|
+
* At least one inclusion term must match (if any are present).
|
|
41
|
+
* Timestamp tokens are parsed and applied as date-range bounds, then
|
|
42
|
+
* stripped before text matching.
|
|
43
|
+
*/
|
|
44
|
+
export declare function filterDebugEventsByText(events: readonly IChatDebugEvent[], filterText: string): readonly IChatDebugEvent[];
|
|
45
|
+
/**
|
|
46
|
+
* Description of the text filter syntax for tool schemas and documentation.
|
|
47
|
+
*/
|
|
48
|
+
export declare const debugEventFilterDescription = "Comma-separated text search terms. Prefix a term with ! to exclude it. Matches against event kind, tool names, model names, agent names, categories, event names, and message content. Also supports before:YYYY[-MM[-DD[THH[:MM[:SS]]]]] and after:YYYY[-MM[-DD[THH[:MM[:SS]]]]] to filter by timestamp.";
|
|
49
|
+
export interface DebugEventFilterOptions {
|
|
50
|
+
readonly kind?: string;
|
|
51
|
+
readonly filter?: string;
|
|
52
|
+
readonly limit?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Applies kind, text, and limit filters to debug events.
|
|
56
|
+
* Used by the listDebugEvents tool to consolidate all filtering in one place.
|
|
57
|
+
*/
|
|
58
|
+
export declare function filterDebugEvents(events: readonly IChatDebugEvent[], options: DebugEventFilterOptions): readonly IChatDebugEvent[];
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const debugEventKindDescriptions = {
|
|
4
|
+
generic: "- generic (category: \"discovery\"): File discovery for instructions, skills, agents, hooks. Resolving returns a fileList with full file paths, load status, skip reasons, and source folders. Always resolve these for questions about customization files.\n" + "- generic (other): Miscellaneous logs. Resolving returns additional text details.",
|
|
5
|
+
toolCall: "- toolCall: A tool invocation. Resolving returns tool name, input, output, status, and duration.",
|
|
6
|
+
modelTurn: "- modelTurn: An LLM round-trip. Resolving returns model name, token usage, timing, errors, and prompt sections.",
|
|
7
|
+
subagentInvocation: "- subagentInvocation: A sub-agent spawn. Resolving returns agent name, status, duration, and counts.",
|
|
8
|
+
userMessage: "- userMessage: The full prompt sent to the model. Resolving returns the complete message and all prompt sections (system prompt, instructions, context). Essential for understanding what the model received.",
|
|
9
|
+
agentResponse: "- agentResponse: The model's response. Resolving returns the full response text and sections."
|
|
10
|
+
};
|
|
11
|
+
function formatDebugEventsForContext(events) {
|
|
12
|
+
const lines = [];
|
|
13
|
+
for (const event of events) {
|
|
14
|
+
const ts = event.created.toISOString();
|
|
15
|
+
const id = event.id ? ` [id=${event.id}]` : "";
|
|
16
|
+
switch (event.kind) {
|
|
17
|
+
case "generic":
|
|
18
|
+
lines.push(
|
|
19
|
+
`[${ts}]${id} ${event.level >= 3 ? "ERROR" : event.level >= 2 ? "WARN" : "INFO"}: ${event.name}${event.details ? " - " + event.details : ""}${event.category ? " (category: " + event.category + ")" : ""}`
|
|
20
|
+
);
|
|
21
|
+
break;
|
|
22
|
+
case "toolCall":
|
|
23
|
+
lines.push(
|
|
24
|
+
`[${ts}]${id} TOOL_CALL: ${event.toolName}${event.result ? " result=" + event.result : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
25
|
+
);
|
|
26
|
+
break;
|
|
27
|
+
case "modelTurn":
|
|
28
|
+
lines.push(
|
|
29
|
+
`[${ts}]${id} MODEL_TURN: ${event.requestName ?? "unknown"}${event.model ? " model=" + event.model : ""}${event.inputTokens !== undefined ? " tokens(in=" + event.inputTokens + ",out=" + (event.outputTokens ?? "?") + ")" : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
30
|
+
);
|
|
31
|
+
break;
|
|
32
|
+
case "subagentInvocation":
|
|
33
|
+
lines.push(
|
|
34
|
+
`[${ts}]${id} SUBAGENT: ${event.agentName}${event.status ? " status=" + event.status : ""}${event.durationInMillis !== undefined ? " duration=" + event.durationInMillis + "ms" : ""}`
|
|
35
|
+
);
|
|
36
|
+
break;
|
|
37
|
+
case "userMessage":
|
|
38
|
+
lines.push(
|
|
39
|
+
`[${ts}]${id} USER_MESSAGE: ${event.message.substring(0, 200)}${event.message.length > 200 ? "..." : ""} (${event.sections.length} sections)`
|
|
40
|
+
);
|
|
41
|
+
break;
|
|
42
|
+
case "agentResponse":
|
|
43
|
+
lines.push(
|
|
44
|
+
`[${ts}]${id} AGENT_RESPONSE: ${event.message.substring(0, 200)}${event.message.length > 200 ? "..." : ""} (${event.sections.length} sections)`
|
|
45
|
+
);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
function getDebugEventsModelDescription() {
|
|
52
|
+
return "These are the debug event logs from the current chat conversation. Analyze them to help answer the user's troubleshooting question.\n" + "\n" + "CRITICAL INSTRUCTION: You MUST call the resolveDebugEventDetails tool on relevant events BEFORE answering. The log lines below are only summaries — they do NOT contain the actual data (file paths, prompt content, tool I/O, etc.). The real information is only available by resolving events. Never answer based solely on the summary lines. Always resolve first, then answer.\n" + "\n" + "Call resolveDebugEventDetails in parallel on all events that could be relevant to the user's question. When in doubt, resolve more events rather than fewer.\n" + "\n" + "IMPORTANT: Do NOT mention event IDs, tool resolution steps, or internal debug mechanics in your response. The user does not know about debug events or event IDs. Present your findings directly and naturally, as if you simply know the answer. Never say things like \"I need to resolve events\" or show event IDs.\n" + "\n" + "Event types and what resolving them returns:\n" + ( Object.values(debugEventKindDescriptions)).join("\n");
|
|
53
|
+
}
|
|
54
|
+
function debugEventMatchesText(event, term) {
|
|
55
|
+
if (event.kind.toLowerCase().includes(term)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
switch (event.kind) {
|
|
59
|
+
case "toolCall":
|
|
60
|
+
return event.toolName.toLowerCase().includes(term) || (event.input?.toLowerCase().includes(term) ?? false) || (event.output?.toLowerCase().includes(term) ?? false);
|
|
61
|
+
case "modelTurn":
|
|
62
|
+
return (event.model?.toLowerCase().includes(term) ?? false) || (event.requestName?.toLowerCase().includes(term) ?? false);
|
|
63
|
+
case "generic":
|
|
64
|
+
return event.name.toLowerCase().includes(term) || (event.details?.toLowerCase().includes(term) ?? false) || (event.category?.toLowerCase().includes(term) ?? false);
|
|
65
|
+
case "subagentInvocation":
|
|
66
|
+
return event.agentName.toLowerCase().includes(term) || (event.description?.toLowerCase().includes(term) ?? false);
|
|
67
|
+
case "userMessage":
|
|
68
|
+
case "agentResponse":
|
|
69
|
+
return event.message.toLowerCase().includes(term) || ( event.sections.some(
|
|
70
|
+
s => s.name.toLowerCase().includes(term) || s.content.toLowerCase().includes(term)
|
|
71
|
+
));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const timestampTokenPattern = /\b(?:before|after):\d{4}(?:-\d{2}(?:-\d{2}(?:t\d{1,2}(?::\d{2}(?::\d{2})?)?)?)?)?(\b|$)/g;
|
|
75
|
+
function parseTimeToken(text, prefix) {
|
|
76
|
+
const regex = ( new RegExp(
|
|
77
|
+
`${prefix}:(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:t(\\d{1,2})(?::(\\d{2})(?::(\\d{2}))?)?)?)?)?(?!\\w)`
|
|
78
|
+
));
|
|
79
|
+
const m = regex.exec(text);
|
|
80
|
+
if (!m) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const year = parseInt(m[1], 10);
|
|
84
|
+
const month = m[2] !== undefined ? parseInt(m[2], 10) - 1 : undefined;
|
|
85
|
+
const day = m[3] !== undefined ? parseInt(m[3], 10) : undefined;
|
|
86
|
+
const hour = m[4] !== undefined ? parseInt(m[4], 10) : undefined;
|
|
87
|
+
const minute = m[5] !== undefined ? parseInt(m[5], 10) : undefined;
|
|
88
|
+
const second = m[6] !== undefined ? parseInt(m[6], 10) : undefined;
|
|
89
|
+
if (prefix === "before") {
|
|
90
|
+
if (second !== undefined) {
|
|
91
|
+
return ( new Date(year, month, day, hour, minute, second, 999)).getTime();
|
|
92
|
+
} else if (minute !== undefined) {
|
|
93
|
+
return ( new Date(year, month, day, hour, minute, 59, 999)).getTime();
|
|
94
|
+
} else if (hour !== undefined) {
|
|
95
|
+
return ( new Date(year, month, day, hour, 59, 59, 999)).getTime();
|
|
96
|
+
} else if (day !== undefined) {
|
|
97
|
+
return ( new Date(year, month, day, 23, 59, 59, 999)).getTime();
|
|
98
|
+
} else if (month !== undefined) {
|
|
99
|
+
return ( new Date(year, month + 1, 0, 23, 59, 59, 999)).getTime();
|
|
100
|
+
} else {
|
|
101
|
+
return ( new Date(year, 11, 31, 23, 59, 59, 999)).getTime();
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
return ( new Date(year, month ?? 0, day ?? 1, hour ?? 0, minute ?? 0, second ?? 0, 0)).getTime();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function stripTimestampTokens(text) {
|
|
108
|
+
return text.replace(timestampTokenPattern, "").trim();
|
|
109
|
+
}
|
|
110
|
+
function filterDebugEventsByText(events, filterText) {
|
|
111
|
+
const beforeTimestamp = parseTimeToken(filterText, "before");
|
|
112
|
+
const afterTimestamp = parseTimeToken(filterText, "after");
|
|
113
|
+
const textOnly = stripTimestampTokens(filterText);
|
|
114
|
+
const terms = textOnly.split(/\s*,\s*/).filter(t => t.length > 0);
|
|
115
|
+
const includeTerms = ( terms.filter(t => !t.startsWith("!")).map(t => t.trim()));
|
|
116
|
+
const excludeTerms = ( terms.filter(t => t.startsWith("!")).map(t => t.slice(1).trim())).filter(t => t.length > 0);
|
|
117
|
+
return events.filter(e => {
|
|
118
|
+
const time = e.created.getTime();
|
|
119
|
+
if (beforeTimestamp !== undefined && time > beforeTimestamp) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (afterTimestamp !== undefined && time < afterTimestamp) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
if (( excludeTerms.some(term => debugEventMatchesText(e, term)))) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (includeTerms.length > 0) {
|
|
129
|
+
return ( includeTerms.some(term => debugEventMatchesText(e, term)));
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { debugEventKindDescriptions, debugEventMatchesText, filterDebugEventsByText, formatDebugEventsForContext, getDebugEventsModelDescription, parseTimeToken, stripTimestampTokens };
|
|
@@ -410,7 +410,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
410
410
|
})];
|
|
411
411
|
}
|
|
412
412
|
_getContextMenuActions() {
|
|
413
|
-
const label = ( localize(
|
|
413
|
+
const label = ( localize(13450, "Toggle Visibility"));
|
|
414
414
|
return [{
|
|
415
415
|
class: undefined,
|
|
416
416
|
tooltip: label,
|
|
@@ -433,7 +433,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
433
433
|
actions.push(attachToChatAction, ( new Separator()));
|
|
434
434
|
}
|
|
435
435
|
if (command.command !== "") {
|
|
436
|
-
const labelRun = ( localize(
|
|
436
|
+
const labelRun = ( localize(13451, "Rerun Command"));
|
|
437
437
|
actions.push({
|
|
438
438
|
class: undefined,
|
|
439
439
|
tooltip: labelRun,
|
|
@@ -446,11 +446,11 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
446
446
|
}
|
|
447
447
|
if (!command.isTrusted) {
|
|
448
448
|
const shouldRun = await ( new Promise(r => {
|
|
449
|
-
this._notificationService.prompt(Severity.Info, ( localize(
|
|
450
|
-
label: ( localize(
|
|
449
|
+
this._notificationService.prompt(Severity.Info, ( localize(13452, "Do you want to run the command: {0}", command.command)), [{
|
|
450
|
+
label: ( localize(13453, "Yes")),
|
|
451
451
|
run: () => r(true)
|
|
452
452
|
}, {
|
|
453
|
-
label: ( localize(
|
|
453
|
+
label: ( localize(13454, "No")),
|
|
454
454
|
run: () => r(false)
|
|
455
455
|
}]);
|
|
456
456
|
}));
|
|
@@ -464,7 +464,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
464
464
|
}
|
|
465
465
|
});
|
|
466
466
|
actions.push(( new Separator()));
|
|
467
|
-
const labelCopy = ( localize(
|
|
467
|
+
const labelCopy = ( localize(13455, "Copy Command"));
|
|
468
468
|
actions.push({
|
|
469
469
|
class: undefined,
|
|
470
470
|
tooltip: labelCopy,
|
|
@@ -475,7 +475,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
475
475
|
});
|
|
476
476
|
}
|
|
477
477
|
if (command.hasOutput()) {
|
|
478
|
-
const labelCopyCommandAndOutput = ( localize(
|
|
478
|
+
const labelCopyCommandAndOutput = ( localize(13456, "Copy Command and Output"));
|
|
479
479
|
actions.push({
|
|
480
480
|
class: undefined,
|
|
481
481
|
tooltip: labelCopyCommandAndOutput,
|
|
@@ -489,7 +489,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
489
489
|
}
|
|
490
490
|
}
|
|
491
491
|
});
|
|
492
|
-
const labelText = ( localize(
|
|
492
|
+
const labelText = ( localize(13457, "Copy Output"));
|
|
493
493
|
actions.push({
|
|
494
494
|
class: undefined,
|
|
495
495
|
tooltip: labelText,
|
|
@@ -503,7 +503,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
505
|
});
|
|
506
|
-
const labelHtml = ( localize(
|
|
506
|
+
const labelHtml = ( localize(13458, "Copy Output as HTML"));
|
|
507
507
|
actions.push({
|
|
508
508
|
class: undefined,
|
|
509
509
|
tooltip: labelHtml,
|
|
@@ -518,7 +518,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
518
518
|
if (actions.length > 0) {
|
|
519
519
|
actions.push(( new Separator()));
|
|
520
520
|
}
|
|
521
|
-
const labelRunRecent = ( localize(
|
|
521
|
+
const labelRunRecent = ( localize(13459, "Run Recent Command"));
|
|
522
522
|
actions.push({
|
|
523
523
|
class: undefined,
|
|
524
524
|
tooltip: labelRunRecent,
|
|
@@ -527,7 +527,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
527
527
|
enabled: true,
|
|
528
528
|
run: () => this._commandService.executeCommand("workbench.action.terminal.runRecentCommand")
|
|
529
529
|
});
|
|
530
|
-
const labelGoToRecent = ( localize(
|
|
530
|
+
const labelGoToRecent = ( localize(13460, "Go To Recent Directory"));
|
|
531
531
|
actions.push({
|
|
532
532
|
class: undefined,
|
|
533
533
|
tooltip: labelRunRecent,
|
|
@@ -537,7 +537,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
537
537
|
run: () => this._commandService.executeCommand("workbench.action.terminal.goToRecentDirectory")
|
|
538
538
|
});
|
|
539
539
|
actions.push(( new Separator()));
|
|
540
|
-
const labelAbout = ( localize(
|
|
540
|
+
const labelAbout = ( localize(13461, "Learn About Shell Integration"));
|
|
541
541
|
actions.push({
|
|
542
542
|
class: undefined,
|
|
543
543
|
tooltip: labelAbout,
|
|
@@ -553,7 +553,7 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
553
553
|
if (!chatIsEnabled) {
|
|
554
554
|
return undefined;
|
|
555
555
|
}
|
|
556
|
-
const labelAttachToChat = ( localize(
|
|
556
|
+
const labelAttachToChat = ( localize(13462, "Attach To Chat"));
|
|
557
557
|
return {
|
|
558
558
|
class: undefined,
|
|
559
559
|
tooltip: labelAttachToChat,
|
|
@@ -595,14 +595,14 @@ let DecorationAddon = class DecorationAddon extends Disposable {
|
|
|
595
595
|
quickPick.hideInput = true;
|
|
596
596
|
quickPick.hideCheckAll = true;
|
|
597
597
|
quickPick.canSelectMany = true;
|
|
598
|
-
quickPick.title = ( localize(
|
|
598
|
+
quickPick.title = ( localize(13463, "Toggle visibility"));
|
|
599
599
|
const configValue = this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled);
|
|
600
600
|
const gutterIcon = {
|
|
601
|
-
label: ( localize(
|
|
601
|
+
label: ( localize(13464, "Gutter command decorations")),
|
|
602
602
|
picked: configValue !== "never" && configValue !== "overviewRuler"
|
|
603
603
|
};
|
|
604
604
|
const overviewRulerIcon = {
|
|
605
|
-
label: ( localize(
|
|
605
|
+
label: ( localize(13465, "Overview ruler command decorations")),
|
|
606
606
|
picked: configValue !== "never" && configValue !== "gutter"
|
|
607
607
|
};
|
|
608
608
|
quickPick.items = [gutterIcon, overviewRulerIcon];
|
|
@@ -92,6 +92,7 @@ export declare class XtermTerminal extends Disposable implements IXtermTerminal,
|
|
|
92
92
|
} | undefined;
|
|
93
93
|
get isStdinDisabled(): boolean;
|
|
94
94
|
get isGpuAccelerated(): boolean;
|
|
95
|
+
get isImageAddonLoaded(): boolean;
|
|
95
96
|
private readonly _onDidRequestRunCommand;
|
|
96
97
|
readonly onDidRequestRunCommand: Event<{
|
|
97
98
|
command: ITerminalCommand;
|
|
@@ -43,6 +43,7 @@ import '@codingame/monaco-vscode-api/vscode/vs/platform/theme/common/colors/sear
|
|
|
43
43
|
import { XtermAddonImporter } from './xtermAddonImporter.js';
|
|
44
44
|
import { equals } from '@codingame/monaco-vscode-api/vscode/vs/base/common/objects';
|
|
45
45
|
import { isNumber } from '@codingame/monaco-vscode-api/vscode/vs/base/common/types';
|
|
46
|
+
import { clamp } from '@codingame/monaco-vscode-api/vscode/vs/base/common/numbers';
|
|
46
47
|
|
|
47
48
|
var XtermTerminal_1;
|
|
48
49
|
var RenderConstants;
|
|
@@ -102,6 +103,9 @@ let XtermTerminal = class XtermTerminal extends Disposable {
|
|
|
102
103
|
get isGpuAccelerated() {
|
|
103
104
|
return !!this._webglAddon;
|
|
104
105
|
}
|
|
106
|
+
get isImageAddonLoaded() {
|
|
107
|
+
return !!this._imageAddon;
|
|
108
|
+
}
|
|
105
109
|
get markTracker() {
|
|
106
110
|
return this._markNavigationAddon;
|
|
107
111
|
}
|
|
@@ -746,7 +750,7 @@ let XtermTerminal = class XtermTerminal extends Disposable {
|
|
|
746
750
|
await this._clipboardService.writeText(this.raw.getSelection());
|
|
747
751
|
}
|
|
748
752
|
} else {
|
|
749
|
-
this._notificationService.warn(( localize(
|
|
753
|
+
this._notificationService.warn(( localize(13476, "The terminal has no selection to copy")));
|
|
750
754
|
}
|
|
751
755
|
}
|
|
752
756
|
_setCursorBlink(blink) {
|
|
@@ -845,6 +849,10 @@ let XtermTerminal = class XtermTerminal extends Disposable {
|
|
|
845
849
|
const AddonCtor = await this._xtermAddonLoader.importAddon("image");
|
|
846
850
|
this._imageAddon = ( new AddonCtor());
|
|
847
851
|
this.raw.loadAddon(this._imageAddon);
|
|
852
|
+
this._telemetryService.publicLog2("terminal/imageAddonActivated");
|
|
853
|
+
this._register(this._imageAddon.onImageAdded(() => {
|
|
854
|
+
this._telemetryService.publicLog2("terminal/imageAdded");
|
|
855
|
+
}));
|
|
848
856
|
}
|
|
849
857
|
} else {
|
|
850
858
|
try {
|
|
@@ -871,16 +879,24 @@ let XtermTerminal = class XtermTerminal extends Disposable {
|
|
|
871
879
|
this._serializeAddon = ( new Addon());
|
|
872
880
|
this.raw.loadAddon(this._serializeAddon);
|
|
873
881
|
}
|
|
882
|
+
const lastLine = this.raw.buffer.active.length - 1;
|
|
883
|
+
if (lastLine < 0) {
|
|
884
|
+
return "";
|
|
885
|
+
}
|
|
874
886
|
const hasValidEndMarker = isNumber(endMarker?.line);
|
|
875
|
-
const start =
|
|
887
|
+
const start = clamp(
|
|
888
|
+
isNumber(startMarker?.line) && startMarker.line > -1 ? startMarker.line : 0,
|
|
889
|
+
0,
|
|
890
|
+
lastLine
|
|
891
|
+
);
|
|
876
892
|
let end = hasValidEndMarker ? endMarker.line : this.raw.buffer.active.length - 1;
|
|
877
893
|
if (skipLastLine && hasValidEndMarker) {
|
|
878
894
|
end = end - 1;
|
|
879
895
|
}
|
|
880
|
-
end = Math.max(end, start);
|
|
896
|
+
end = clamp(Math.max(end, start), start, lastLine);
|
|
881
897
|
return this._serializeAddon.serialize({
|
|
882
898
|
range: {
|
|
883
|
-
start
|
|
899
|
+
start,
|
|
884
900
|
end
|
|
885
901
|
}
|
|
886
902
|
});
|