Skip to content

Commit

Permalink
Adopts injected text for debug inline values.
Browse files Browse the repository at this point in the history
  • Loading branch information
hediet committed Nov 8, 2021
1 parent e607ae4 commit 9bb262c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
45 changes: 25 additions & 20 deletions src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import { distinct, flatten } from 'vs/base/common/arrays';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { DEFAULT_WORD_REGEXP } from 'vs/editor/common/model/wordHelper';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType, IPartialEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
import { IDecorationOptions } from 'vs/editor/common/editorCommon';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { Range } from 'vs/editor/common/core/range';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
Expand All @@ -33,7 +31,7 @@ import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands';
import { memoize } from 'vs/base/common/decorators';
import { IEditorHoverOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { DebugHoverWidget } from 'vs/workbench/contrib/debug/browser/debugHover';
import { ITextModel } from 'vs/editor/common/model';
import { IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { basename } from 'vs/base/common/path';
Expand All @@ -44,13 +42,12 @@ import { Event } from 'vs/base/common/event';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { addDisposableListener } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { noBreakWhitespace } from 'vs/base/common/strings';

const LAUNCH_JSON_REGEX = /\.vscode\/launch\.json$/;
const INLINE_VALUE_DECORATION_KEY = 'inlinevaluedecoration';
const MAX_NUM_INLINE_VALUES = 100; // JS Global scope can have 700+ entries. We want to limit ourselves for perf reasons
const MAX_INLINE_DECORATOR_LENGTH = 150; // Max string length of each inline decorator when debugging. If exceeded ... is added
const MAX_TOKENIZATION_LINE_LEN = 500; // If line is too long, then inline values for the line are skipped
Expand All @@ -72,7 +69,7 @@ class InlineSegment {
}
}

function createInlineValueDecoration(lineNumber: number, contentText: string, column = Constants.MAX_SAFE_SMALL_INTEGER): IDecorationOptions {
function createInlineValueDecoration(lineNumber: number, contentText: string, column = Constants.MAX_SAFE_SMALL_INTEGER): IModelDeltaDecoration {
// If decoratorText is too long, trim and add ellipses. This could happen for minified files with everything on a single line
if (contentText.length > MAX_INLINE_DECORATOR_LENGTH) {
contentText = contentText.substr(0, MAX_INLINE_DECORATOR_LENGTH) + '...';
Expand All @@ -85,18 +82,23 @@ function createInlineValueDecoration(lineNumber: number, contentText: string, co
startColumn: column,
endColumn: column
},
renderOptions: {
options: {
description: 'debug-inline-value-decoration',
after: {
contentText,
backgroundColor: themeColorFromId(debugInlineBackground),
margin: '10px',
color: themeColorFromId(debugInlineForeground)
}
content: replaceWsWithNoBreakWs(contentText),
inlineClassName: 'debug-inline-value',
inlineClassNameAffectsLetterSpacing: true,
},
showIfCollapsed: true
}
};
}

function createInlineValueDecorationsInsideRange(expressions: ReadonlyArray<IExpression>, range: Range, model: ITextModel, wordToLineNumbersMap: Map<string, number[]>): IDecorationOptions[] {
function replaceWsWithNoBreakWs(str: string): string {
return str.replace(/[ \t]/g, noBreakWhitespace);
}

function createInlineValueDecorationsInsideRange(expressions: ReadonlyArray<IExpression>, range: Range, model: ITextModel, wordToLineNumbersMap: Map<string, number[]>): IModelDeltaDecoration[] {
const nameValueMap = new Map<string, string>();
for (let expr of expressions) {
nameValueMap.set(expr.name, expr.value);
Expand Down Expand Up @@ -126,7 +128,7 @@ function createInlineValueDecorationsInsideRange(expressions: ReadonlyArray<IExp
}
});

const decorations: IDecorationOptions[] = [];
const decorations: IModelDeltaDecoration[] = [];
// Compute decorators for each line
lineToNamesMap.forEach((names, line) => {
const contentText = names.sort((first, second) => {
Expand Down Expand Up @@ -196,13 +198,13 @@ export class DebugEditorContribution implements IDebugEditorContribution {
private configurationWidget: FloatingClickWidget | undefined;
private altListener: IDisposable | undefined;
private altPressed = false;
private oldDecorations: string[] = [];

constructor(
private editor: ICodeEditor,
@IDebugService private readonly debugService: IDebugService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ICommandService private readonly commandService: ICommandService,
@ICodeEditorService private readonly codeEditorService: ICodeEditorService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IHostService private readonly hostService: IHostService,
Expand All @@ -213,7 +215,6 @@ export class DebugEditorContribution implements IDebugEditorContribution {
this.toDispose = [];
this.registerListeners();
this.updateConfigurationWidgetVisibility();
this.codeEditorService.registerDecorationType('debug-inline-value-decoration', INLINE_VALUE_DECORATION_KEY, {});
this.exceptionWidgetVisible = CONTEXT_EXCEPTION_WIDGET_VISIBLE.bindTo(contextKeyService);
this.toggleExceptionWidget();
}
Expand Down Expand Up @@ -575,7 +576,9 @@ export class DebugEditorContribution implements IDebugEditorContribution {
@memoize
private get removeInlineValuesScheduler(): RunOnceScheduler {
return new RunOnceScheduler(
() => this.editor.removeDecorations(INLINE_VALUE_DECORATION_KEY),
() => {
this.oldDecorations = this.editor.deltaDecorations(this.oldDecorations, []);
},
100
);
}
Expand Down Expand Up @@ -605,7 +608,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {

this.removeInlineValuesScheduler.cancel();

let allDecorations: IDecorationOptions[];
let allDecorations: IModelDeltaDecoration[];

if (InlineValuesProviderRegistry.has(model)) {

Expand Down Expand Up @@ -717,10 +720,10 @@ export class DebugEditorContribution implements IDebugEditorContribution {

allDecorations = distinct(decorationsPerScope.reduce((previous, current) => previous.concat(current), []),
// Deduplicate decorations since same variable can appear in multiple scopes, leading to duplicated decorations #129770
decoration => `${decoration.range.startLineNumber}:${decoration.renderOptions?.after?.contentText}`);
decoration => `${decoration.range.startLineNumber}:${decoration?.options.after?.content}`);
}

this.editor.setDecorations('debug-inline-value-decoration', INLINE_VALUE_DECORATION_KEY, allDecorations);
this.oldDecorations = this.editor.deltaDecorations(this.oldDecorations, allDecorations);
}

dispose(): void {
Expand All @@ -731,5 +734,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
this.configurationWidget.dispose();
}
this.toDispose = dispose(this.toDispose);

this.oldDecorations = this.editor.deltaDecorations(this.oldDecorations, []);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,9 @@
.monaco-workbench .monaco-list-row .expression .unavailable {
font-style: italic;
}

.monaco-workbench .debug-inline-value {
background-color: var(--vscode-editor-inlineValuesBackground);
margin: 10px;
color: var(--vscode-editor-inlineValuesForeground);
}

0 comments on commit 9bb262c

Please sign in to comment.