Skip to content

Commit 4ee6836

Browse files
authored
Fix multiline strings not rendered correctly in console when wordwrap disabled (microsoft#160622)
Fix microsoft#151768
1 parent 59b4249 commit 4ee6836

File tree

3 files changed

+85
-34
lines changed

3 files changed

+85
-34
lines changed

src/vs/workbench/contrib/debug/browser/repl.ts

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { IAction } from 'vs/base/common/actions';
1313
import { RunOnceScheduler } from 'vs/base/common/async';
1414
import { CancellationToken } from 'vs/base/common/cancellation';
1515
import { memoize } from 'vs/base/common/decorators';
16+
import { Emitter } from 'vs/base/common/event';
1617
import { FuzzyScore } from 'vs/base/common/filters';
1718
import { HistoryNavigator } from 'vs/base/common/history';
1819
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
@@ -62,7 +63,7 @@ import { debugConsoleClearAll, debugConsoleEvaluationPrompt } from 'vs/workbench
6263
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
6364
import { ReplFilter, ReplFilterActionViewItem, ReplFilterState } from 'vs/workbench/contrib/debug/browser/replFilter';
6465
import { ReplAccessibilityProvider, ReplDataSource, ReplDelegate, ReplEvaluationInputsRenderer, ReplEvaluationResultsRenderer, ReplGroupRenderer, ReplRawObjectsRenderer, ReplSimpleElementsRenderer, ReplVariablesRenderer } from 'vs/workbench/contrib/debug/browser/replViewer';
65-
import { CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_REPL, CONTEXT_MULTI_SESSION_REPL, DEBUG_SCHEME, getStateLabel, IDebugConfiguration, IDebugService, IDebugSession, IReplElement, REPL_VIEW_ID, State } from 'vs/workbench/contrib/debug/common/debug';
66+
import { CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_REPL, CONTEXT_MULTI_SESSION_REPL, DEBUG_SCHEME, getStateLabel, IDebugConfiguration, IDebugService, IDebugSession, IReplConfiguration, IReplElement, IReplOptions, REPL_VIEW_ID, State } from 'vs/workbench/contrib/debug/common/debug';
6667
import { Variable } from 'vs/workbench/contrib/debug/common/debugModel';
6768
import { ReplGroup } from 'vs/workbench/contrib/debug/common/replModel';
6869
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
@@ -91,6 +92,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
9192

9293
private history: HistoryNavigator<string>;
9394
private tree!: WorkbenchAsyncDataTree<IDebugSession, IReplElement, FuzzyScore>;
95+
private replOptions: ReplOptions;
9496
private previousTreeScrollHeight: number = 0;
9597
private replDelegate!: ReplDelegate;
9698
private container!: HTMLElement;
@@ -141,6 +143,8 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
141143
this.filterState = new ReplFilterState(this);
142144
this.filter.filterQuery = this.filterState.filterText = this.storageService.get(FILTER_VALUE_STORAGE_KEY, StorageScope.WORKSPACE, '');
143145
this.multiSessionRepl = CONTEXT_MULTI_SESSION_REPL.bindTo(contextKeyService);
146+
this.replOptions = this._register(this.instantiationService.createInstance(ReplOptions, this.id, () => this.getBackgroundColor()));
147+
this._register(this.replOptions.onDidChange(() => this.onDidStyleChange()));
144148

145149
codeEditorService.registerDecorationType('repl-decoration', DECORATION_KEY, {});
146150
this.multiSessionRepl.set(this.isMultiSessionView);
@@ -191,8 +195,6 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
191195
this.treeContainer.innerText = '';
192196
dom.clearNode(this.treeContainer);
193197
this.createReplTree();
194-
} else if (e.affectsConfiguration('debug.console.lineHeight') || e.affectsConfiguration('debug.console.fontSize') || e.affectsConfiguration('debug.console.fontFamily')) {
195-
this.onDidStyleChange();
196198
}
197199
if (e.affectsConfiguration('debug.console.acceptSuggestionOnEnter')) {
198200
const config = this.configurationService.getValue<IDebugConfiguration>('debug');
@@ -202,16 +204,6 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
202204
}
203205
}));
204206

205-
this._register(this.themeService.onDidColorThemeChange(e => {
206-
this.onDidStyleChange();
207-
}));
208-
209-
this._register(this.viewDescriptorService.onDidChangeLocation(e => {
210-
if (e.views.some(v => v.id === this.id)) {
211-
this.onDidStyleChange();
212-
}
213-
}));
214-
215207
this._register(this.editorService.onDidActiveEditorChange(() => {
216208
this.setMode();
217209
}));
@@ -346,16 +338,10 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
346338

347339
private onDidStyleChange(): void {
348340
if (this.styleElement) {
349-
const debugConsole = this.configurationService.getValue<IDebugConfiguration>('debug').console;
350-
const fontSize = debugConsole.fontSize;
351-
const fontFamily = debugConsole.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : `${debugConsole.fontFamily}`;
352-
const lineHeight = debugConsole.lineHeight ? `${debugConsole.lineHeight}px` : '1.4em';
353-
const backgroundColor = this.themeService.getColorTheme().getColor(this.getBackgroundColor());
354-
355341
this.replInput.updateOptions({
356-
fontSize,
357-
lineHeight: debugConsole.lineHeight,
358-
fontFamily: debugConsole.fontFamily === 'default' ? EDITOR_FONT_DEFAULTS.fontFamily : debugConsole.fontFamily
342+
fontSize: this.replOptions.replConfiguration.fontSize,
343+
lineHeight: this.replOptions.replConfiguration.lineHeight,
344+
fontFamily: this.replOptions.replConfiguration.fontFamily === 'default' ? EDITOR_FONT_DEFAULTS.fontFamily : this.replOptions.replConfiguration.fontFamily
359345
});
360346

361347
const replInputLineHeight = this.replInput.getOption(EditorOption.lineHeight);
@@ -367,13 +353,14 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
367353
}
368354
369355
.repl .repl-input-wrapper .monaco-editor .lines-content {
370-
background-color: ${backgroundColor};
356+
background-color: ${this.replOptions.replConfiguration.backgroundColor};
371357
}
372358
`;
373-
this.container.style.setProperty(`--vscode-repl-font-family`, fontFamily);
374-
this.container.style.setProperty(`--vscode-repl-font-size`, `${fontSize}px`);
375-
this.container.style.setProperty(`--vscode-repl-font-size-for-twistie`, `${fontSize * 1.4 / 2 - 8}px`);
376-
this.container.style.setProperty(`--vscode-repl-line-height`, lineHeight);
359+
const cssFontFamily = this.replOptions.replConfiguration.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : this.replOptions.replConfiguration.fontFamily;
360+
this.container.style.setProperty(`--vscode-repl-font-family`, cssFontFamily);
361+
this.container.style.setProperty(`--vscode-repl-font-size`, `${this.replOptions.replConfiguration.fontSize}px`);
362+
this.container.style.setProperty(`--vscode-repl-font-size-for-twistie`, `${this.replOptions.replConfiguration.fontSizeForTwistie}px`);
363+
this.container.style.setProperty(`--vscode-repl-line-height`, this.replOptions.replConfiguration.cssLineHeight);
377364

378365
this.tree.rerender();
379366

@@ -566,7 +553,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
566553
}
567554

568555
private createReplTree(): void {
569-
this.replDelegate = new ReplDelegate(this.configurationService);
556+
this.replDelegate = new ReplDelegate(this.configurationService, this.replOptions);
570557
const wordWrap = this.configurationService.getValue<IDebugConfiguration>('debug').console.wordWrap;
571558
this.treeContainer.classList.toggle('word-wrap', wordWrap);
572559
const linkDetector = this.instantiationService.createInstance(LinkDetector);
@@ -750,6 +737,54 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
750737
}
751738
}
752739

740+
class ReplOptions extends Disposable implements IReplOptions {
741+
private static readonly lineHeightEm = 1.4;
742+
743+
private readonly _onDidChange = this._register(new Emitter<void>());
744+
readonly onDidChange = this._onDidChange.event;
745+
746+
private _replConfig!: IReplConfiguration;
747+
public get replConfiguration(): IReplConfiguration {
748+
return this._replConfig;
749+
}
750+
751+
constructor(
752+
viewId: string,
753+
private readonly backgroundColorDelegate: () => string,
754+
@IConfigurationService private readonly configurationService: IConfigurationService,
755+
@IThemeService private readonly themeService: IThemeService,
756+
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService
757+
) {
758+
super();
759+
760+
this._register(this.themeService.onDidColorThemeChange(e => this.update()));
761+
this._register(this.viewDescriptorService.onDidChangeLocation(e => {
762+
if (e.views.some(v => v.id === viewId)) {
763+
this.update();
764+
}
765+
}));
766+
this._register(this.configurationService.onDidChangeConfiguration(e => {
767+
if (e.affectsConfiguration('debug.console.lineHeight') || e.affectsConfiguration('debug.console.fontSize') || e.affectsConfiguration('debug.console.fontFamily')) {
768+
this.update();
769+
}
770+
}));
771+
this.update();
772+
}
773+
774+
private update() {
775+
const debugConsole = this.configurationService.getValue<IDebugConfiguration>('debug').console;
776+
this._replConfig = {
777+
fontSize: debugConsole.fontSize,
778+
fontFamily: debugConsole.fontFamily,
779+
lineHeight: debugConsole.lineHeight ? debugConsole.lineHeight : ReplOptions.lineHeightEm * debugConsole.fontSize,
780+
cssLineHeight: debugConsole.lineHeight ? `${debugConsole.lineHeight}px` : `${ReplOptions.lineHeightEm}em`,
781+
backgroundColor: this.themeService.getColorTheme().getColor(this.backgroundColorDelegate()),
782+
fontSizeForTwistie: debugConsole.fontSize * ReplOptions.lineHeightEm / 2 - 8
783+
};
784+
this._onDidChange.fire();
785+
}
786+
}
787+
753788
// Repl actions and commands
754789

755790
class AcceptReplInputAction extends EditorAction {

src/vs/workbench/contrib/debug/browser/replViewer.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { AbstractExpressionsRenderer, IExpressionTemplateData, IInputBoxOptions,
2222
import { handleANSIOutput } from 'vs/workbench/contrib/debug/browser/debugANSIHandling';
2323
import { debugConsoleEvaluationInput } from 'vs/workbench/contrib/debug/browser/debugIcons';
2424
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
25-
import { IDebugConfiguration, IDebugService, IDebugSession, IExpression, IExpressionContainer, IReplElement, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug';
25+
import { IDebugConfiguration, IDebugService, IDebugSession, IExpression, IExpressionContainer, IReplElement, IReplElementSource, IReplOptions } from 'vs/workbench/contrib/debug/common/debug';
2626
import { Variable } from 'vs/workbench/contrib/debug/common/debugModel';
2727
import { RawObjectReplElement, ReplEvaluationInput, ReplEvaluationResult, ReplGroup, SimpleReplElement } from 'vs/workbench/contrib/debug/common/replModel';
2828
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
@@ -295,7 +295,10 @@ function isNestedVariable(element: IReplElement) {
295295

296296
export class ReplDelegate extends CachedListVirtualDelegate<IReplElement> {
297297

298-
constructor(private configurationService: IConfigurationService) {
298+
constructor(
299+
private readonly configurationService: IConfigurationService,
300+
private readonly replOptions: IReplOptions
301+
) {
299302
super();
300303
}
301304

@@ -310,8 +313,7 @@ export class ReplDelegate extends CachedListVirtualDelegate<IReplElement> {
310313
}
311314

312315
protected estimateHeight(element: IReplElement, ignoreValueLength = false): number {
313-
const config = this.configurationService.getValue<IDebugConfiguration>('debug');
314-
const rowHeight = Math.ceil(1.3 * config.console.fontSize);
316+
const lineHeight = this.replOptions.replConfiguration.lineHeight;
315317
const countNumberOfLines = (str: string) => Math.max(1, (str && str.match(/\r\n|\n/g) || []).length);
316318
const hasValue = (e: any): e is { value: string } => typeof e.value === 'string';
317319

@@ -321,10 +323,10 @@ export class ReplDelegate extends CachedListVirtualDelegate<IReplElement> {
321323
const value = element.value;
322324
const valueRows = countNumberOfLines(value) + (ignoreValueLength ? 0 : Math.floor(value.length / 70));
323325

324-
return valueRows * rowHeight;
326+
return valueRows * lineHeight;
325327
}
326328

327-
return rowHeight;
329+
return lineHeight;
328330
}
329331

330332
getTemplateId(element: IReplElement): string {

src/vs/workbench/contrib/debug/common/debug.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { IAction } from 'vs/base/common/actions';
77
import { VSBuffer } from 'vs/base/common/buffer';
88
import { CancellationToken } from 'vs/base/common/cancellation';
9+
import { Color } from 'vs/base/common/color';
910
import { Event } from 'vs/base/common/event';
1011
import { IJSONSchemaSnippet } from 'vs/base/common/jsonSchema';
1112
import { IDisposable } from 'vs/base/common/lifecycle';
@@ -1142,3 +1143,16 @@ export interface IBreakpointEditorContribution extends editorCommon.IEditorContr
11421143
closeBreakpointWidget(): void;
11431144
getContextMenuActionsAtPosition(lineNumber: number, model: EditorIModel): IAction[];
11441145
}
1146+
1147+
export interface IReplConfiguration {
1148+
readonly fontSize: number;
1149+
readonly fontFamily: string;
1150+
readonly lineHeight: number;
1151+
readonly cssLineHeight: string;
1152+
readonly backgroundColor: Color | undefined;
1153+
readonly fontSizeForTwistie: number;
1154+
}
1155+
1156+
export interface IReplOptions {
1157+
readonly replConfiguration: IReplConfiguration;
1158+
}

0 commit comments

Comments
 (0)