Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add generic marker sequence and markers/decorations for problems #152671

Merged
merged 31 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2bb881a
add markers for problems
meganrogge Jun 20, 2022
9d01a4f
fix tests
meganrogge Jun 20, 2022
5812177
actually fix tests
meganrogge Jun 20, 2022
1e58802
Update src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts
meganrogge Jun 20, 2022
b9579bf
Update src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts
meganrogge Jun 20, 2022
451b646
put marker in better spot
meganrogge Jun 20, 2022
4797afb
get much closer
meganrogge Jun 20, 2022
fed7318
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 20, 2022
69a565c
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 20, 2022
686b40c
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 22, 2022
5a3f512
register it as a command
meganrogge Jun 22, 2022
b1a4f1a
enable a custom hover
meganrogge Jun 22, 2022
b98d81d
invalidate command
meganrogge Jun 22, 2022
7887b6a
use number of matches
meganrogge Jun 22, 2022
04092be
tidy
meganrogge Jun 22, 2022
df5e8b4
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 22, 2022
7c9a7b3
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 22, 2022
60a7c31
fix test
meganrogge Jun 22, 2022
23d13aa
Update src/vs/platform/terminal/common/capabilities/capabilities.ts
meganrogge Jun 22, 2022
5040888
Merge branch 'main' into merogge/problem-marker
meganrogge Jun 22, 2022
b82fe91
Update src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts
meganrogge Jun 23, 2022
7a0271e
Update src/vs/workbench/contrib/terminal/browser/xterm/decorationAddo…
meganrogge Jun 23, 2022
be9e602
add e to file name
meganrogge Jun 23, 2022
3cb3fcb
cleanup
meganrogge Jun 23, 2022
5f80b23
big refactor
meganrogge Jun 23, 2022
66a8c5c
fix merge conflicts
meganrogge Jun 23, 2022
88ae78c
refactor
meganrogge Jun 23, 2022
29c5f3c
copy marker to capabilities file
meganrogge Jun 23, 2022
5316b57
handle marker in taskTerminalStatus
meganrogge Jun 23, 2022
4040a3b
Update src/vs/workbench/contrib/terminal/browser/terminal.ts
meganrogge Jun 23, 2022
c10717a
h
meganrogge Jun 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/vs/platform/terminal/common/capabilities/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import { Event } from 'vs/base/common/event';
import { IGenericMarkProperties, ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess';
// Importing types is safe in any layer
// eslint-disable-next-line code-import-patterns
import type { IMarker } from 'xterm-headless';
meganrogge marked this conversation as resolved.
Show resolved Hide resolved

/**
* Primarily driven by the shell integration feature, a terminal capability is the mechanism for
Expand Down Expand Up @@ -117,9 +120,9 @@ export interface ICommandDetectionCapability {
handleRightPromptStart(): void;
handleRightPromptEnd(): void;
handleCommandStart(): void;
handleGenericCommand(properties: IGenericMarkProperties): void;
handleGenericCommand(marker: IMarker | undefined, properties: IGenericMarkProperties): void;
handleCommandExecuted(): void;
handleCommandFinished(exitCode: number | undefined, genericMarkProperties?: IGenericMarkProperties): void;
handleCommandFinished(exitCode: number | undefined, marker?: IMarker, genericMarkProperties?: IGenericMarkProperties): void;
invalidateCurrentCommand(request: ICommandInvalidationRequest): void;
/**
* Set the command line explicitly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
return reversed.find(c => c.marker!.line <= line - 1)?.cwd;
}

handlePromptStart(): void {
this._currentCommand.promptStartMarker = this._terminal.registerMarker(0);
handlePromptStart(marker?: IMarker): void {
this._currentCommand.promptStartMarker = marker || this._terminal.registerMarker(0);
this._logService.debug('CommandDetectionCapability#handlePromptStart', this._terminal.buffer.active.cursorX, this._currentCommand.promptStartMarker?.line);
}

Expand Down Expand Up @@ -300,8 +300,9 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
this._logService.debug('CommandDetectionCapability#handleRightPromptEnd', this._currentCommand.commandRightPromptEndX);
}

handleCommandStart(genericMarkProperties?: IGenericMarkProperties): void {
handleCommandStart(marker?: IMarker, genericMarkProperties?: IGenericMarkProperties): void {
// Only update the column if the line has already been set
this._currentCommand.commandStartMarker = marker || this._currentCommand.commandStartMarker;
if (this._currentCommand.commandStartMarker?.line === this._terminal.buffer.active.cursorY) {
this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX;
this._logService.debug('CommandDetectionCapability#handleCommandStart', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line);
Expand All @@ -312,8 +313,8 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
return;
}
this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX;
this._currentCommand.commandStartMarker = this._terminal.registerMarker(0);
this._onCommandStarted.fire({ marker: this._currentCommand.commandStartMarker, genericMarkProperties } as ITerminalCommand);
this._currentCommand.commandStartMarker = marker || this._terminal.registerMarker(0);
this._onCommandStarted.fire({ marker: marker || this._currentCommand.commandStartMarker, genericMarkProperties } as ITerminalCommand);
this._logService.debug('CommandDetectionCapability#handleCommandStart', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line);
}

Expand Down Expand Up @@ -348,23 +349,23 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
});
}

handleGenericCommand(properties: IGenericMarkProperties): void {
handleGenericCommand(marker: IMarker, properties: IGenericMarkProperties): void {
if (properties.disableCommandStorage) {
this.setIsCommandStorageDisabled();
}
this.handlePromptStart();
this.handleCommandStart(properties);
this.handleCommandExecuted();
this.handleCommandFinished(undefined, properties);
this.handlePromptStart(marker);
this.handleCommandStart(marker, properties);
this.handleCommandExecuted(marker);
this.handleCommandFinished(undefined, marker, properties);
}

handleCommandExecuted(): void {
handleCommandExecuted(marker?: IMarker): void {
if (this._isWindowsPty) {
this._handleCommandExecutedWindows();
return;
}

this._currentCommand.commandExecutedMarker = this._terminal.registerMarker(0);
this._currentCommand.commandExecutedMarker = marker || this._terminal.registerMarker(0);
this._currentCommand.commandExecutedX = this._terminal.buffer.active.cursorX;
this._logService.debug('CommandDetectionCapability#handleCommandExecuted', this._currentCommand.commandExecutedX, this._currentCommand.commandExecutedMarker?.line);

Expand Down Expand Up @@ -408,12 +409,12 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
this._onCurrentCommandInvalidated.fire(request);
}

handleCommandFinished(exitCode: number | undefined, genericMarkProperties?: IGenericMarkProperties): void {
handleCommandFinished(exitCode: number | undefined, marker?: IMarker, genericMarkProperties?: IGenericMarkProperties): void {
if (this._isWindowsPty) {
this._preHandleCommandFinishedWindows();
}

this._currentCommand.commandFinishedMarker = this._terminal.registerMarker(0);
this._currentCommand.commandFinishedMarker = marker || this._terminal.registerMarker(0);
const command = this._currentCommand.command;
this._logService.debug('CommandDetectionCapability#handleCommandFinished', this._terminal.buffer.active.cursorX, this._currentCommand.commandFinishedMarker?.line, this._currentCommand.command, this._currentCommand);
this._exitCode = exitCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
const [command, hoverMessage, disableCommandStorage] = data.split(';');
switch (command) {
case ITermOscPt.SetMark: {
this._createOrGetCommandDetection(this._terminal).handleGenericCommand({ hoverMessage: hoverMessage || '', disableCommandStorage: disableCommandStorage === 'true' ? true : false });
this._createOrGetCommandDetection(this._terminal).handleGenericCommand(undefined, { hoverMessage: hoverMessage || '', disableCommandStorage: disableCommandStorage === 'true' ? true : false });
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/termina
import { ITerminalStatus } from 'vs/workbench/contrib/terminal/browser/terminalStatusList';
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
import { spinningLoading } from 'vs/platform/theme/common/iconRegistry';
import { CommandInvalidationReason, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';

interface ITerminalData {
terminal: ITerminalInstance;
Expand Down Expand Up @@ -54,8 +53,8 @@ export class TaskTerminalStatus extends Disposable {
addTerminal(task: Task, terminal: ITerminalInstance, problemMatcher: AbstractProblemCollector) {
const status: ITerminalStatus = { id: TASK_TERMINAL_STATUS_ID, severity: Severity.Info };
terminal.statusList.add(status);
problemMatcher.onDidFindMatch(() => terminal.addGenericMarker({ hoverMessage: nls.localize('task.watchFirstError', "First error"), disableCommandStorage: true }));
problemMatcher.onDidInvalidateMatch(() => terminal.capabilities.get(TerminalCapability.CommandDetection)?.invalidateCurrentCommand({ reason: CommandInvalidationReason.NoProblemsReported }));
problemMatcher.onDidFindFirstMatch(() => terminal.addGenericMarker());
problemMatcher.onDidFindErrors(() => terminal.addDecoration({ hoverMessage: nls.localize('task.watchFirstError', "First error"), disableCommandStorage: true }));
this.terminalMap.set(task._id, { terminal, task, status, problemMatcher, taskRunEnded: false });
}

Expand Down
14 changes: 7 additions & 7 deletions src/vs/workbench/contrib/tasks/common/problemCollectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ export abstract class AbstractProblemCollector implements IDisposable {

protected _onDidStateChange: Emitter<IProblemCollectorEvent>;

protected readonly _onDidFindMatch = new Emitter<void>();
readonly onDidFindMatch = this._onDidFindMatch.event;
protected readonly _onDidFindFirstMatch = new Emitter<void>();
readonly onDidFindFirstMatch = this._onDidFindFirstMatch.event;

protected readonly _onDidInvalidateMatch = new Emitter<void>();
readonly onDidInvalidateMatch = this._onDidInvalidateMatch.event;
protected readonly _onDidFindErrors = new Emitter<void>();
readonly onDidFindErrors = this._onDidFindErrors.event;

constructor(public readonly problemMatchers: ProblemMatcher[], protected markerService: IMarkerService, protected modelService: IModelService, fileService?: IFileService) {
this.matchers = Object.create(null);
Expand Down Expand Up @@ -498,7 +498,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement
}
this._activeBackgroundMatchers.add(background.key);
result = true;
this._onDidFindMatch.fire();
this._onDidFindFirstMatch.fire();
this.lines = [];
this.lines.push(line);
this._onDidStateChange.fire(IProblemCollectorEvent.create(ProblemCollectorEventKind.BackgroundProcessingBegins));
Expand All @@ -522,8 +522,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement
for (const background of this.backgroundPatterns) {
const matches = background.end.regexp.exec(line);
if (matches) {
if (this._numberOfMatches === 0) {
this._onDidInvalidateMatch.fire();
if (this._numberOfMatches > 0) {
this._onDidFindErrors.fire();
}
if (this._activeBackgroundMatchers.has(background.key)) {
this._activeBackgroundMatchers.delete(background.key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TestTask extends CommonTask {

class TestProblemCollector implements Partial<AbstractProblemCollector> {
private readonly _onDidFindMatch = new Emitter<void>();
readonly onDidFindMatch = this._onDidFindMatch.event;
readonly onDidFindFirstMatch = this._onDidFindMatch.event;
private readonly _onDidInvalidateMatch = new Emitter<void>();
readonly onDidInvalidateMatch = this._onDidInvalidateMatch.event;
}
Expand Down
16 changes: 14 additions & 2 deletions src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { IEditableData } from 'vs/workbench/common/views';
import { ITerminalStatusList } from 'vs/workbench/contrib/terminal/browser/terminalStatusList';
import { INavigationMode, IRegisterContributedProfileArgs, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalBackend, ITerminalConfigHelper, ITerminalFont, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal';
import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { IMarker } from 'xterm';

export const ITerminalService = createDecorator<ITerminalService>('terminalService');
export const ITerminalEditorService = createDecorator<ITerminalEditorService>('terminalEditorService');
Expand Down Expand Up @@ -637,9 +638,15 @@ export interface ITerminalInstance {
showEnvironmentInfoHover(): void;

/**
* Adds a generic marker and decoration to the buffer
* Adds a generic marker to the buffer
*/
addGenericMarker(genericMarkProperties: IGenericMarkProperties): void;
addGenericMarker(): void;
meganrogge marked this conversation as resolved.
Show resolved Hide resolved

/**
* Adds a decoration to the buffer
* @param genericMarkProperties
*/
addDecoration(genericMarkProperties: IGenericMarkProperties): void;

/**
* Dispose the terminal instance, removing it from the panel/service and freeing up resources.
Expand Down Expand Up @@ -932,6 +939,11 @@ export interface IXtermTerminal {
*/
clearActiveSearchDecoration(): void;

/**
* Adds a decoration at the @param marker with the given properties
* @param properties
*/
addDecoration(marker: IMarker, properties: IGenericMarkProperties): void;
}

export interface IInternalXtermTerminal {
Expand Down
16 changes: 12 additions & 4 deletions src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkbenchLayoutService, Position } from 'vs/workbench/services/layout/browser/layoutService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import type { ITerminalAddon, Terminal as XTermTerminal } from 'xterm';
import { ITermOscPt, ITermSequence } from 'vs/workbench/contrib/terminal/browser/terminalEscapeSequences';
import type { IMarker, ITerminalAddon, Terminal as XTermTerminal } from 'xterm';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess';

Expand Down Expand Up @@ -214,6 +213,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private _target?: TerminalLocation | undefined;
private _disableShellIntegrationReporting: boolean | undefined;
private _usedShellIntegrationInjection: boolean = false;
private _genericMarker: IMarker | undefined;

readonly capabilities = new TerminalCapabilityStoreMultiplexer();
readonly statusList: ITerminalStatusList;
Expand Down Expand Up @@ -1590,8 +1590,16 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
}

public addGenericMarker(genericMarkProperties: IGenericMarkProperties): void {
this.xterm?.raw.write(`${ITermSequence(ITermOscPt.SetMark, `${genericMarkProperties.hoverMessage || ''};${genericMarkProperties.disableCommandStorage ? true : false}`)}`);
public addGenericMarker(): void {
this._genericMarker = this.xterm?.raw.registerMarker(0);
}

public addDecoration(genericMarkProperties: IGenericMarkProperties): void {
if (this._genericMarker) {
this.xterm?.addDecoration(this._genericMarker, genericMarkProperties);
} else {
throw new Error(`No marker for decoration, ${genericMarkProperties}`);
}
}

private _onProcessData(ev: IProcessDataEvent): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import type { IBuffer, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm';
import type { IBuffer, IMarker, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm';
import type { ISearchOptions, SearchAddon as SearchAddonType } from 'xterm-addon-search';
import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11';
import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl';
Expand Down Expand Up @@ -35,6 +35,7 @@ import { DecorationAddon } from 'vs/workbench/contrib/terminal/browser/xterm/dec
import { ITerminalCapabilityStore, ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
import { Emitter } from 'vs/base/common/event';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess';

// How long in milliseconds should an average frame take to render for a notification to appear
// which suggests the fallback DOM-based renderer
Expand Down Expand Up @@ -179,6 +180,10 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
this.raw.loadAddon(this._shellIntegrationAddon);
}

addDecoration(marker: IMarker, properties: IGenericMarkProperties): void {
this._capabilities.get(TerminalCapability.CommandDetection)?.handleGenericCommand(marker, properties);
}

async getSelectionAsHtml(command?: ITerminalCommand): Promise<string> {
if (!this._serializeAddon) {
const Addon = await this._getSerializeAddonConstructor();
Expand Down