diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 332faeb0226..f24776d1624 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -31,6 +31,7 @@ interface JavaScriptRenderingHook { interface RenderOptions { readonly lineLimit: number; readonly outputScrolling: boolean; + readonly outputWordWrap: boolean; } function clearContainer(container: HTMLElement) { @@ -149,6 +150,9 @@ function renderError(outputInfo: OutputItem, container: HTMLElement, ctx: Render if (err.stack) { const stack = document.createElement('pre'); stack.classList.add('traceback'); + if (ctx.settings.outputWordWrap) { + stack.classList.add('wordWrap'); + } stack.style.margin = '8px 0'; const element = document.createElement('span'); insertOutput(outputInfo.id, [err.stack ?? ''], ctx.settings.lineLimit, false, element, true); @@ -190,6 +194,11 @@ function renderStream(outputInfo: OutputItem, container: HTMLElement, error: boo const text = outputInfo.text(); const element = existing ?? document.createElement('span'); element.classList.add('output-stream'); + if (ctx.settings.outputWordWrap) { + element.classList.add('wordWrap'); + } else { + element.classList.remove('wordWrap'); + } element.setAttribute('output-item-id', outputInfo.id); insertOutput(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, element, false); outputElement.appendChild(element); @@ -199,6 +208,9 @@ function renderStream(outputInfo: OutputItem, container: HTMLElement, error: boo const element = document.createElement('span'); element.classList.add('output-stream'); + if (ctx.settings.outputWordWrap) { + element.classList.add('wordWrap'); + } element.setAttribute('output-item-id', outputInfo.id); const text = outputInfo.text(); @@ -217,6 +229,9 @@ function renderText(outputInfo: OutputItem, container: HTMLElement, ctx: Rendere clearContainer(container); const contentNode = document.createElement('div'); contentNode.classList.add('output-plaintext'); + if (ctx.settings.outputWordWrap) { + contentNode.classList.add('wordWrap'); + } const text = outputInfo.text(); insertOutput(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, contentNode, false); container.appendChild(contentNode); @@ -244,6 +259,12 @@ export const activate: ActivationFunction = (ctx) => { -ms-user-select: text; cursor: auto; } + .output-plaintext.wordWrap span, + .output-stream.wordWrap span, + .traceback.wordWrap span { + white-space: pre-wrap !important; + word-break: break-all; + } .output-plaintext, .output-stream { white-space: pre-wrap; diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 238b5e2880c..6ea12228fbc 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -892,7 +892,13 @@ configurationRegistry.registerConfiguration({ type: 'boolean', tags: ['notebookLayout'], default: false - } + }, + [NotebookSetting.outputWordWrap]: { + markdownDescription: nls.localize('notebook.outputWordWrap', "Controls whether the lines in output should wrap."), + type: 'boolean', + tags: ['notebookLayout'], + default: false + }, } }); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts b/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts index 3df4dcbe2b7..e9d1ef61314 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts @@ -75,6 +75,7 @@ export interface NotebookLayoutConfiguration { focusIndicatorGap: number; interactiveWindowCollapseCodeCells: InteractiveWindowCollapseCodeCells; outputScrolling: boolean; + outputWordWrap: boolean; outputLineLimit: number; } @@ -154,6 +155,7 @@ export class NotebookOptions extends Disposable { const interactiveWindowCollapseCodeCells: InteractiveWindowCollapseCodeCells = this.configurationService.getValue(NotebookSetting.interactiveWindowCollapseCodeCells); const outputLineHeight = this._computeOutputLineHeight(); const outputScrolling = this.configurationService.getValue(NotebookSetting.outputScrolling); + const outputWordWrap = this.configurationService.getValue(NotebookSetting.outputWordWrap); const outputLineLimit = this.configurationService.getValue(NotebookSetting.textOutputLineLimit) ?? 30; this._layoutConfiguration = { @@ -193,6 +195,7 @@ export class NotebookOptions extends Disposable { interactiveWindowCollapseCodeCells, markdownFoldHintHeight: 22, outputScrolling: outputScrolling, + outputWordWrap: outputWordWrap, outputLineLimit: outputLineLimit }; @@ -582,6 +585,7 @@ export class NotebookOptions extends Disposable { markupFontSize: this._layoutConfiguration.markupFontSize, outputLineHeight: this._layoutConfiguration.outputLineHeight, outputScrolling: this._layoutConfiguration.outputScrolling, + outputWordWrap: this._layoutConfiguration.outputWordWrap, outputLineLimit: this._layoutConfiguration.outputLineLimit, }; } @@ -602,6 +606,7 @@ export class NotebookOptions extends Disposable { markupFontSize: this._layoutConfiguration.markupFontSize, outputLineHeight: this._layoutConfiguration.outputLineHeight, outputScrolling: this._layoutConfiguration.outputScrolling, + outputWordWrap: this._layoutConfiguration.outputWordWrap, outputLineLimit: this._layoutConfiguration.outputLineLimit, }; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index bfbb1132eaf..cac752e9192 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -107,6 +107,7 @@ interface BacklayerWebviewOptions { readonly markupFontSize: number; readonly outputLineHeight: number; readonly outputScrolling: boolean; + readonly outputWordWrap: boolean; readonly outputLineLimit: number; } @@ -264,7 +265,8 @@ export class BackLayerWebView extends Themable { const preloadsData = this.getStaticPreloadsData(); const renderOptions = { lineLimit: this.options.outputLineLimit, - outputScrolling: this.options.outputScrolling + outputScrolling: this.options.outputScrolling, + outputWordWrap: this.options.outputWordWrap }; const preloadScript = preloadsScriptStr( this.options, diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 485b6f262cc..50dd53e28aa 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -67,6 +67,7 @@ export interface PreloadOptions { export interface RenderOptions { readonly lineLimit: number; readonly outputScrolling: boolean; + readonly outputWordWrap: boolean; } interface PreloadContext { @@ -89,6 +90,7 @@ async function webviewPreloads(ctx: PreloadContext) { let isWorkspaceTrusted = ctx.isWorkspaceTrusted; const lineLimit = ctx.renderOptions.lineLimit; const outputScrolling = ctx.renderOptions.outputScrolling; + const outputWordWrap = ctx.renderOptions.outputWordWrap; const acquireVsCodeApi = globalThis.acquireVsCodeApi; const vscode = acquireVsCodeApi(); @@ -1353,6 +1355,7 @@ async function webviewPreloads(ctx: PreloadContext) { settings: { get lineLimit() { return lineLimit; }, get outputScrolling() { return outputScrolling; }, + get outputWordWrap() { return outputWordWrap; }, } }; diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 3c349b700fc..1cc134ca882 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -929,6 +929,7 @@ export const NotebookSetting = { outputFontFamily: 'notebook.outputFontFamily', kernelPickerType: 'notebook.kernelPicker.type', outputScrolling: 'notebook.experimental.outputScrolling', + outputWordWrap: 'notebook.output.wordWrap', logging: 'notebook.logging', } as const;