mirror of https://github.com/microsoft/vscode.git
Revert "Revert "Merge branch 'main' of https://github.com/microsoft/vscode into main""
This reverts commit 7c01395da1
.
This commit is contained in:
parent
8822790908
commit
473cfe28bf
|
@ -226,7 +226,11 @@
|
|||
},
|
||||
"output.selfClosingStyle": {
|
||||
"type": "string",
|
||||
"enum": ["html", "xhtml", "xml"],
|
||||
"enum": [
|
||||
"html",
|
||||
"xhtml",
|
||||
"xml"
|
||||
],
|
||||
"default": "html",
|
||||
"markdownDescription": "%emmetPreferencesOutputSelfClosingStyle%"
|
||||
},
|
||||
|
|
|
@ -54,9 +54,9 @@
|
|||
integrity sha1-Rs/+oRmgoAMxKiHC2bVijLX81EI=
|
||||
|
||||
"@types/node@14.x":
|
||||
version "14.14.43"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
|
||||
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
|
||||
version "14.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.1.tgz#5e07e0cb2ff793aa7a1b41deae76221e6166049f"
|
||||
integrity sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw==
|
||||
|
||||
emmet@^2.3.0:
|
||||
version "2.3.4"
|
||||
|
@ -77,9 +77,9 @@ jsonc-parser@^2.3.0:
|
|||
integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==
|
||||
|
||||
vscode-emmet-helper@^2.3.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.6.2.tgz#777b471a7851ba0ca8e4151533be7f92511f39b0"
|
||||
integrity sha512-SkL1WjZZsA+bfTo52QH4PgqXCQAJSqzOmJtAY3rOl17MKbY6iJhVv2T26PshjmUnHoXnXMNa7PcLMCS75RsQDQ==
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.6.4.tgz#bea47f17649bba26b412f3d1fac18aaee43eba25"
|
||||
integrity sha512-fP0nunW1RUWEKGf4gqiYLOVNFFGXSRHjCl0pikxtwCFlty8WwimM+RBJ5o0aIiwerrYD30HqeaVyvDW027Sseg==
|
||||
dependencies:
|
||||
emmet "^2.3.0"
|
||||
jsonc-parser "^2.3.0"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
}
|
||||
},
|
||||
"contributes": {
|
||||
"notebookOutputRenderer": [
|
||||
"notebookRenderer": [
|
||||
{
|
||||
"id": "markdownItRenderer",
|
||||
"displayName": "Markdown it renderer",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
},
|
||||
"contributes": {
|
||||
"notebookOutputRenderer": [
|
||||
"notebookRenderer": [
|
||||
{
|
||||
"id": "markdownItRenderer-katex",
|
||||
"displayName": "Markdown it katex renderer",
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'mocha';
|
|||
import * as assert from 'assert';
|
||||
import * as vscode from 'vscode';
|
||||
import { createRandomFile, asPromise, disposeAll, closeAllEditors, revertAllDirty, saveAllEditors, assertNoRpc } from '../utils';
|
||||
import { TextDecoder } from 'util';
|
||||
|
||||
async function createRandomNotebookFile() {
|
||||
return createRandomFile('', undefined, '.vsctestnb');
|
||||
|
@ -60,13 +61,13 @@ class Kernel {
|
|||
task.executionOrder = 1;
|
||||
if (cell.notebook.uri.path.endsWith('customRenderer.vsctestnb')) {
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/custom', ['test'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('test', 'text/custom', undefined)
|
||||
])]);
|
||||
return;
|
||||
}
|
||||
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', ['my output'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('my output', 'text/plain', undefined)
|
||||
])]);
|
||||
task.end({ success: true });
|
||||
}
|
||||
|
@ -129,7 +130,7 @@ suite('Notebook API tests', function () {
|
|||
kind: vscode.NotebookCellKind.Code,
|
||||
outputs: [
|
||||
new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', 'Hello World', { testOutputItemMetadata: true })
|
||||
vscode.NotebookCellOutputItem.text('Hello World', 'text/plain', { testOutputItemMetadata: true })
|
||||
],
|
||||
{ testOutputMetadata: true })
|
||||
],
|
||||
|
@ -182,7 +183,7 @@ suite('Notebook API tests', function () {
|
|||
const task = this.controller.createNotebookCellExecutionTask(cell);
|
||||
task.start();
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', ['my second output'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('my second output', 'text/plain', undefined)
|
||||
])]);
|
||||
task.end({ success: true });
|
||||
}
|
||||
|
@ -476,7 +477,7 @@ suite('Notebook API tests', function () {
|
|||
assert.deepStrictEqual(secondCell!.outputs[0].metadata, { testOutputMetadata: true });
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs[0].value, 'Hello World');
|
||||
assert.strictEqual(new TextDecoder().decode(secondCell!.outputs[0].outputs[0].data), 'Hello World');
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].outputs[0].metadata, { testOutputItemMetadata: true });
|
||||
assert.strictEqual(secondCell!.executionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell!.executionSummary?.success, true);
|
||||
|
@ -747,9 +748,7 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, [
|
||||
'my output'
|
||||
]);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'my output');
|
||||
});
|
||||
|
||||
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
|
||||
|
@ -759,9 +758,7 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, [
|
||||
'my second output'
|
||||
]);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'my second output');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -779,7 +776,7 @@ suite('Notebook API tests', function () {
|
|||
task.start();
|
||||
task.token.onCancellationRequested(async () => {
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', ['Canceled'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('Canceled', 'text/plain', undefined)
|
||||
])]);
|
||||
task.end({});
|
||||
});
|
||||
|
@ -801,9 +798,7 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, [
|
||||
'Canceled'
|
||||
]);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'Canceled');
|
||||
});
|
||||
|
||||
cancelableKernel.controller.dispose();
|
||||
|
@ -826,7 +821,7 @@ suite('Notebook API tests', function () {
|
|||
|
||||
async interrupt() {
|
||||
await this._task!.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', ['Interrupted'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('Interrupted', 'text/plain', undefined)
|
||||
])]);
|
||||
this._task!.end({});
|
||||
}
|
||||
|
@ -845,9 +840,7 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, [
|
||||
'Interrupted'
|
||||
]);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'Interrupted');
|
||||
});
|
||||
|
||||
interruptableKernel.controller.dispose();
|
||||
|
@ -1188,10 +1181,10 @@ suite('Notebook API tests', function () {
|
|||
const task = this.controller.createNotebookCellExecutionTask(cell);
|
||||
task.start();
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/plain', ['Some output'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('Some output', 'text/plain', undefined)
|
||||
])]);
|
||||
assert.strictEqual(cell.notebook.cellAt(0).outputs.length, 1);
|
||||
assert.deepStrictEqual(cell.notebook.cellAt(0).outputs[0].outputs[0].value, ['Some output']);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.notebook.cellAt(0).outputs[0].outputs[0].data), 'Some output');
|
||||
task.end({});
|
||||
called = true;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"notebookOutputRenderer": [
|
||||
"notebookRenderer": [
|
||||
{
|
||||
"id": "notebookCoreTestRenderer",
|
||||
"displayName": "Notebook Core Test Renderer",
|
||||
|
|
|
@ -69,7 +69,7 @@ export function activate(context: vscode.ExtensionContext): any {
|
|||
const task = controller.createNotebookCellExecutionTask(cell);
|
||||
task.start();
|
||||
task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
new vscode.NotebookCellOutputItem('text/html', ['test output'], undefined)
|
||||
vscode.NotebookCellOutputItem.text('test output', 'text/html', undefined)
|
||||
])]);
|
||||
task.end({ success: true });
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
"capabilities": {
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"virtualWorkspaces": true
|
||||
},
|
||||
"contributes": {
|
||||
"resourceLabelFormatters": [
|
||||
|
@ -88,7 +89,7 @@
|
|||
"statusBar/remoteIndicator": [
|
||||
{
|
||||
"command": "vscode-testresolver.newWindow",
|
||||
"when": "!remoteName",
|
||||
"when": "!remoteName && !virtualWorkspace",
|
||||
"group": "remote_90_test_1_local@2"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview:; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https: ws:; font-src 'self' https: vscode-remote-resource:;">
|
||||
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookOutputRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
|
||||
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
|
||||
</head>
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview:; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https: ws:; font-src 'self' https: vscode-remote-resource:;">
|
||||
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookOutputRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
|
||||
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
|
||||
</head>
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
|
|
@ -10,6 +10,7 @@ import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { OperatingSystem } from 'vs/base/common/platform';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const terminalProfileBaseProperties: IJSONSchemaMap = {
|
||||
args: {
|
||||
|
@ -372,7 +373,7 @@ export function registerTerminalDefaultProfileConfiguration(detectedProfiles?: {
|
|||
}
|
||||
|
||||
function createProfileDescription(profile: ITerminalProfile): string {
|
||||
let description = `$(${profile.icon || Codicon.terminal.id}) ${profile.profileName}\n- path: ${profile.path}`;
|
||||
let description = `$(${ThemeIcon.isThemeIcon(profile.icon) ? profile.icon.id : profile.icon ? profile.icon : Codicon.terminal.id}) ${profile.profileName}\n- path: ${profile.path}`;
|
||||
if (profile.args) {
|
||||
if (typeof profile.args === 'string') {
|
||||
description += `\n- args: "${profile.args}"`;
|
||||
|
|
|
@ -37,6 +37,7 @@ export function detectAvailableProfiles(
|
|||
safeConfigProvider<boolean>(TerminalSettingId.UseWslProfiles) !== false,
|
||||
safeConfigProvider(TerminalSettingId.ProfilesWindows),
|
||||
safeConfigProvider(TerminalSettingId.DefaultProfileWindows),
|
||||
testPaths,
|
||||
variableResolver
|
||||
);
|
||||
}
|
||||
|
@ -58,6 +59,7 @@ async function detectAvailableWindowsProfiles(
|
|||
useWslProfiles?: boolean,
|
||||
configProfiles?: { [key: string]: ITerminalProfileObject },
|
||||
defaultProfileName?: string,
|
||||
testPaths?: string[],
|
||||
variableResolver?: (text: string[]) => Promise<string[]>
|
||||
): Promise<ITerminalProfile[]> {
|
||||
// Determine the correct System32 path. We want to point to Sysnative
|
||||
|
@ -73,7 +75,7 @@ async function detectAvailableWindowsProfiles(
|
|||
useWSLexe = true;
|
||||
}
|
||||
|
||||
await initializeWindowsProfiles();
|
||||
await initializeWindowsProfiles(testPaths);
|
||||
|
||||
const detectedProfiles: Map<string, ITerminalProfileObject> = new Map();
|
||||
|
||||
|
@ -175,7 +177,7 @@ async function transformToTerminalProfiles(
|
|||
return resultProfiles;
|
||||
}
|
||||
|
||||
async function initializeWindowsProfiles(): Promise<void> {
|
||||
async function initializeWindowsProfiles(testPaths?: string[]): Promise<void> {
|
||||
if (profileSources) {
|
||||
return;
|
||||
}
|
||||
|
@ -197,7 +199,7 @@ async function initializeWindowsProfiles(): Promise<void> {
|
|||
});
|
||||
profileSources.set('PowerShell', {
|
||||
profileName: 'PowerShell',
|
||||
paths: await getPowershellPaths(),
|
||||
paths: testPaths || await getPowershellPaths(),
|
||||
icon: ThemeIcon.asThemeIcon(Codicon.terminalPowershell)
|
||||
});
|
||||
}
|
||||
|
@ -245,23 +247,25 @@ async function getWslProfiles(wslPath: string, defaultProfileName: string | unde
|
|||
profileName,
|
||||
path: wslPath,
|
||||
args: [`-d`, `${distroName}`],
|
||||
isDefault: profileName === defaultProfileName
|
||||
isDefault: profileName === defaultProfileName,
|
||||
icon: getWslIcon(distroName)
|
||||
};
|
||||
if (distroName.includes('Ubuntu')) {
|
||||
profile.icon = ThemeIcon.asThemeIcon(Codicon.terminalUbuntu);
|
||||
}
|
||||
else if (distroName.includes('Debian')) {
|
||||
profile.icon = ThemeIcon.asThemeIcon(Codicon.terminalDebian);
|
||||
} else {
|
||||
profile.icon = ThemeIcon.asThemeIcon(Codicon.terminalLinux);
|
||||
}
|
||||
|
||||
// Add the profile
|
||||
profiles.push(profile);
|
||||
}
|
||||
return profiles;
|
||||
}
|
||||
|
||||
function getWslIcon(distroName: string): ThemeIcon {
|
||||
if (distroName.includes('Ubuntu')) {
|
||||
return ThemeIcon.asThemeIcon(Codicon.terminalUbuntu);
|
||||
} else if (distroName.includes('Debian')) {
|
||||
return ThemeIcon.asThemeIcon(Codicon.terminalDebian);
|
||||
} else {
|
||||
return ThemeIcon.asThemeIcon(Codicon.terminalLinux);
|
||||
}
|
||||
}
|
||||
|
||||
async function detectAvailableUnixProfiles(
|
||||
fsProvider: IFsProvider,
|
||||
logService?: ILogService,
|
||||
|
|
|
@ -1247,11 +1247,12 @@ declare module 'vscode' {
|
|||
*
|
||||
* *Note* that an UTF-8 encoder is used to create bytes for the string.
|
||||
*
|
||||
* @param value A string/
|
||||
* @param value A string.
|
||||
* @param mime Optional MIME type, defaults to `text/plain`.
|
||||
* @param metadata Optional metadata.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
static text(value: string, mime?: string): NotebookCellOutputItem;
|
||||
static text(value: string, mime?: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Factory function to create a `NotebookCellOutputItem` from
|
||||
|
@ -1263,46 +1264,40 @@ declare module 'vscode' {
|
|||
*
|
||||
* @param value A JSON-stringifyable value.
|
||||
* @param mime Optional MIME type, defaults to `application/json`
|
||||
* @param metadata Optional metadata.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
static json(value: any, mime?: string): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Factory function to create a `NotebookCellOutputItem` from bytes.
|
||||
*
|
||||
* @param value An array of unsigned 8-bit integers.
|
||||
* @param mime Optional MIME type, defaults to `application/octet-stream`.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
//todo@API better names: bytes, raw, buffer?
|
||||
static bytes(value: Uint8Array, mime?: string): NotebookCellOutputItem;
|
||||
static json(value: any, mime?: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Factory function to create a `NotebookCellOutputItem` that uses
|
||||
* uses the `application/vnd.code.notebook.stdout` mime type.
|
||||
*
|
||||
* @param value A string.
|
||||
* @param metadata Optional metadata.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
static stdout(value: string): NotebookCellOutputItem;
|
||||
static stdout(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Factory function to create a `NotebookCellOutputItem` that uses
|
||||
* uses the `application/vnd.code.notebook.stderr` mime type.
|
||||
*
|
||||
* @param value A string.
|
||||
* @param metadata Optional metadata.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
static stderr(value: string): NotebookCellOutputItem;
|
||||
static stderr(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Factory function to create a `NotebookCellOutputItem` that uses
|
||||
* uses the `application/vnd.code.notebook.error` mime type.
|
||||
*
|
||||
* @param value An error object.
|
||||
* @param metadata Optional metadata.
|
||||
* @returns A new output item object.
|
||||
*/
|
||||
static error(value: Error): NotebookCellOutputItem;
|
||||
static error(value: Error, metadata?: { [key: string]: any }): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* The mime type which determines how the {@link NotebookCellOutputItem.value `value`}-property
|
||||
|
@ -1314,21 +1309,26 @@ declare module 'vscode' {
|
|||
mime: string;
|
||||
|
||||
/**
|
||||
* The value of this output item. Must always be an array of unsigned 8-bit integers.
|
||||
* The data of this output item. Must always be an array of unsigned 8-bit integers.
|
||||
*/
|
||||
//todo@API only Unit8Array
|
||||
value: Uint8Array | unknown;
|
||||
data: Uint8Array;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
value: unknown;
|
||||
|
||||
//todo@API
|
||||
metadata?: { [key: string]: any };
|
||||
|
||||
/**
|
||||
* Create a new notbook cell output item.
|
||||
*
|
||||
* @param data The value of the output item.
|
||||
* @param mime The mime type of the output item.
|
||||
* @param value The value of the output item.
|
||||
* @param metadata Optional metadata for this output item.
|
||||
*/
|
||||
constructor(mime: string, value: Uint8Array | unknown, metadata?: { [key: string]: any });
|
||||
constructor(data: Uint8Array, mime: string, metadata?: { [key: string]: any });
|
||||
}
|
||||
|
||||
// @jrieken transient
|
||||
|
@ -1563,6 +1563,9 @@ declare module 'vscode' {
|
|||
|
||||
/**
|
||||
* The identifier of this notebook controller.
|
||||
*
|
||||
* _Note_ that controllers are remembered by their identifier and that extensions should use
|
||||
* stable identifiers across sessions.
|
||||
*/
|
||||
readonly id: string;
|
||||
|
||||
|
@ -1654,6 +1657,7 @@ declare module 'vscode' {
|
|||
* @param cell The notebook cell for which to create the execution.
|
||||
* @returns A notebook cell execution.
|
||||
*/
|
||||
// todo@API rename to NotebookCellExecution
|
||||
createNotebookCellExecutionTask(cell: NotebookCell): NotebookCellExecutionTask;
|
||||
|
||||
// todo@API find a better name than "preloads"
|
||||
|
|
|
@ -350,7 +350,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
|
|||
|
||||
public getDefaultShellArgs(useAutomationShell: boolean): string[] | string {
|
||||
const profile = useAutomationShell ? this._defaultAutomationProfile : this._defaultProfile;
|
||||
return profile?.args || [''];
|
||||
return profile?.args || [];
|
||||
}
|
||||
|
||||
public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import * as htmlContent from 'vs/base/common/htmlContent';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import * as marked from 'vs/base/common/marked/marked';
|
||||
|
@ -1536,9 +1535,9 @@ export namespace NotebookCellOutputItem {
|
|||
export function from(item: types.NotebookCellOutputItem): notebooks.IOutputItemDto {
|
||||
let value: unknown;
|
||||
let valueBytes: number[] | undefined;
|
||||
if (item.value instanceof Uint8Array) {
|
||||
if (item.data instanceof Uint8Array) {
|
||||
//todo@jrieken this HACKY and SLOW... hoist VSBuffer instead
|
||||
valueBytes = Array.from(item.value);
|
||||
valueBytes = Array.from(item.data);
|
||||
} else {
|
||||
value = item.value;
|
||||
}
|
||||
|
@ -1551,15 +1550,13 @@ export namespace NotebookCellOutputItem {
|
|||
}
|
||||
|
||||
export function to(item: notebooks.IOutputItemDto): types.NotebookCellOutputItem {
|
||||
|
||||
let value: Uint8Array | unknown;
|
||||
if (item.value instanceof VSBuffer) {
|
||||
value = item.value.buffer;
|
||||
let value: Uint8Array | any;
|
||||
if (Array.isArray(item.valueBytes)) {
|
||||
value = new Uint8Array(item.valueBytes);
|
||||
} else {
|
||||
value = item.value;
|
||||
}
|
||||
|
||||
return new types.NotebookCellOutputItem(item.mime, value, item.metadata);
|
||||
return new types.NotebookCellOutputItem(value, item.mime, item.metadata);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3112,44 +3112,50 @@ export class NotebookCellOutputItem {
|
|||
return typeof (<vscode.NotebookCellOutputItem>obj).mime === 'string';
|
||||
}
|
||||
|
||||
static error(err: Error | { name: string, message?: string, stack?: string }): NotebookCellOutputItem {
|
||||
static error(err: Error | { name: string, message?: string, stack?: string }, metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
const obj = {
|
||||
name: err.name,
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
};
|
||||
return NotebookCellOutputItem.json(obj, 'application/vnd.code.notebook.error');
|
||||
return NotebookCellOutputItem.json(obj, 'application/vnd.code.notebook.error', metadata);
|
||||
}
|
||||
|
||||
static stdout(value: string): NotebookCellOutputItem {
|
||||
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stdout');
|
||||
static stdout(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stdout', metadata);
|
||||
}
|
||||
|
||||
static stderr(value: string): NotebookCellOutputItem {
|
||||
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stderr');
|
||||
static stderr(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stderr', metadata);
|
||||
}
|
||||
|
||||
static bytes(value: Uint8Array, mime: string = 'application/octet-stream'): NotebookCellOutputItem {
|
||||
return new NotebookCellOutputItem(mime, value);
|
||||
static bytes(value: Uint8Array, mime: string = 'application/octet-stream', metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
return new NotebookCellOutputItem(value, mime, metadata);
|
||||
}
|
||||
|
||||
static #encoder = new TextEncoder();
|
||||
|
||||
static text(value: string, mime: string = 'text/plain'): NotebookCellOutputItem {
|
||||
static text(value: string, mime: string = 'text/plain', metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
const bytes = NotebookCellOutputItem.#encoder.encode(String(value));
|
||||
return new NotebookCellOutputItem(mime, bytes);
|
||||
return new NotebookCellOutputItem(bytes, mime, metadata);
|
||||
}
|
||||
|
||||
static json(value: any, mime: string = 'application/json'): NotebookCellOutputItem {
|
||||
static json(value: any, mime: string = 'application/json', metadata?: { [key: string]: any }): NotebookCellOutputItem {
|
||||
const rawStr = JSON.stringify(value, undefined, '\t');
|
||||
return NotebookCellOutputItem.text(rawStr, mime);
|
||||
return NotebookCellOutputItem.text(rawStr, mime, metadata);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public value: Uint8Array | unknown; // JSON'able
|
||||
|
||||
constructor(
|
||||
public data: Uint8Array,
|
||||
public mime: string,
|
||||
public value: Uint8Array | unknown, // JSON'able
|
||||
public metadata?: Record<string, any>
|
||||
public metadata?: { [key: string]: any }
|
||||
) {
|
||||
if (!(data instanceof Uint8Array)) {
|
||||
this.value = data;
|
||||
}
|
||||
if (isFalsyOrWhitespace(this.mime)) {
|
||||
throw new Error('INVALID mime type, must not be empty or falsy');
|
||||
}
|
||||
|
|
|
@ -192,6 +192,6 @@ export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint
|
|||
|
||||
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
|
||||
{
|
||||
extensionPoint: 'notebookOutputRenderer',
|
||||
extensionPoint: 'notebookRenderer',
|
||||
jsonSchema: notebookRendererContribution
|
||||
});
|
||||
|
|
|
@ -425,7 +425,7 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay.cell-statusbar-hidden .cell-statusbar-container {
|
||||
.monaco-workbench .notebookOverlay .cell-statusbar-hidden .cell-statusbar-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEd
|
|||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { NotebookService } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
|
||||
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled, ShowCellStatusBarAfterExecuteKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
|
||||
|
@ -582,6 +582,12 @@ configurationRegistry.registerConfiguration({
|
|||
default: true,
|
||||
tags: ['notebookLayout']
|
||||
},
|
||||
[ShowCellStatusBarAfterExecuteKey]: {
|
||||
description: nls.localize('notebook.showCellStatusbarAfterExecute.description', "Whether the cell status bar should be shown after the cell has been executed."),
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
tags: ['notebookLayout']
|
||||
},
|
||||
[NotebookTextDiffEditorPreview]: {
|
||||
description: nls.localize('notebook.diff.enablePreview.description', "Whether to use the enhanced text diff editor for notebook."),
|
||||
type: 'boolean',
|
||||
|
|
|
@ -235,6 +235,7 @@ export interface MarkdownCellLayoutInfo {
|
|||
readonly fontInfo: FontInfo | null;
|
||||
readonly editorWidth: number;
|
||||
readonly editorHeight: number;
|
||||
readonly previewHeight: number;
|
||||
readonly bottomToolbarOffset: number;
|
||||
readonly totalHeight: number;
|
||||
}
|
||||
|
@ -242,6 +243,8 @@ export interface MarkdownCellLayoutInfo {
|
|||
export interface MarkdownCellLayoutChangeEvent {
|
||||
font?: FontInfo;
|
||||
outerWidth?: number;
|
||||
editorHeight?: number;
|
||||
previewHeight?: number;
|
||||
totalHeight?: number;
|
||||
}
|
||||
|
||||
|
|
|
@ -511,9 +511,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
const cellToolbarLocation = this._notebookOptions.computeCellToolbarLocation(this.viewModel?.viewType);
|
||||
this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocation}`);
|
||||
|
||||
const showCellStatusBar = this._notebookOptions.getLayoutConfiguration().showCellStatusBar;
|
||||
this._overlayContainer.classList.toggle('cell-statusbar-hidden', !showCellStatusBar);
|
||||
|
||||
const cellToolbarInteraction = this._notebookOptions.getLayoutConfiguration().cellToolbarInteraction;
|
||||
let cellToolbarInteractionState = 'hover';
|
||||
this._overlayContainer.classList.remove('cell-toolbar-hover');
|
||||
|
@ -555,6 +552,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
cellRunGutter,
|
||||
cellBottomMargin,
|
||||
codeCellLeftMargin,
|
||||
markdownCellGutter,
|
||||
markdownCellLeftMargin,
|
||||
markdownCellBottomMargin,
|
||||
markdownCellTopMargin,
|
||||
|
@ -565,7 +563,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
focusIndicator,
|
||||
insertToolbarPosition,
|
||||
insertToolbarAlignment,
|
||||
fontSize
|
||||
fontSize,
|
||||
focusIndicatorLeftMargin
|
||||
} = this._notebookOptions.getLayoutConfiguration();
|
||||
|
||||
const styleSheets: string[] = [];
|
||||
|
@ -643,12 +642,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
height: 100%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-left:before {
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
}
|
||||
`);
|
||||
|
||||
// left and right border margins
|
||||
|
@ -659,6 +652,14 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-right:before {
|
||||
top: 0px; height: 100%;
|
||||
}`);
|
||||
|
||||
styleSheets.push(`
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-left:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.selected .cell-focus-indicator-left:before {
|
||||
border-left: 3px solid transparent;
|
||||
border-radius: 2px;
|
||||
margin-left: ${focusIndicatorLeftMargin}px;
|
||||
}`);
|
||||
}
|
||||
|
||||
// between cell insert toolbar
|
||||
|
@ -727,7 +728,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .execution-count-label { left: ${codeCellLeftMargin}px; width: ${cellRunGutter}px; }`);
|
||||
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${cellRunGutter}px; }`);
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellLeftMargin - 20) / 2}px; }`);
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellGutter - 20) / 2 + markdownCellLeftMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row :not(.webview-backed-markdown-cell) .cell-focus-indicator-top { height: ${cellTopMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${bottomCellToolbarGap}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left,
|
||||
|
@ -2484,10 +2485,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
const cell = this.getCellById(cellId);
|
||||
const layoutConfiguration = this._notebookOptions.getLayoutConfiguration();
|
||||
if (cell && cell instanceof MarkdownCellViewModel) {
|
||||
if (height + layoutConfiguration.bottomToolbarGap !== cell.layoutInfo.totalHeight) {
|
||||
this._debug('updateMarkdownCellHeight', cell.handle, height + layoutConfiguration.bottomToolbarGap, isInit);
|
||||
cell.renderedMarkdownHeight = height;
|
||||
}
|
||||
this._debug('updateMarkdownCellHeight', cell.handle, height + layoutConfiguration.bottomToolbarGap, isInit);
|
||||
cell.renderedMarkdownHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -349,13 +349,13 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||
for (const extension of renderers) {
|
||||
for (const notebookContribution of extension.value) {
|
||||
if (!notebookContribution.entrypoint) { // avoid crashing
|
||||
console.error(`Cannot register renderer for ${extension.description.identifier.value} since it did not have an entrypoint. This is now required: https://github.com/microsoft/vscode/issues/102644`);
|
||||
extension.collector.error(`Notebook renderer does not specify entry point`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const id = notebookContribution.id ?? notebookContribution.viewType;
|
||||
if (!id) {
|
||||
console.error(`Notebook renderer from ${extension.description.identifier.value} is missing an 'id'`);
|
||||
extension.collector.error(`Notebook renderer does not specify id-property`);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -521,6 +521,8 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
|||
templateData.focusIndicatorBottom.style.top = `${indicatorPostion.bottomIndicatorTop}px`;
|
||||
templateData.focusIndicatorLeft.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
|
||||
templateData.container.classList.toggle('cell-statusbar-hidden', element.getEditorStatusbarHeight() === 0);
|
||||
}
|
||||
|
||||
private updateForHover(element: MarkdownCellViewModel, templateData: MarkdownCellRenderTemplate): void {
|
||||
|
@ -852,7 +854,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
}
|
||||
}
|
||||
|
||||
private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate, editorOptions: CellEditorOptions): void {
|
||||
private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void {
|
||||
if (!this.notebookEditor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
|
@ -894,6 +896,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
templateData.outputContainer.style.top = `${element.layoutInfo.outputContainerOffset}px`;
|
||||
templateData.outputShowMoreContainer.style.top = `${element.layoutInfo.outputShowMoreContainerOffset}px`;
|
||||
templateData.dragHandle.style.height = `${element.layoutInfo.totalHeight - layoutInfo.bottomToolbarGap}px`;
|
||||
|
||||
templateData.container.classList.toggle('cell-statusbar-hidden', element.getEditorStatusbarHeight() === 0);
|
||||
}
|
||||
|
||||
renderElement(element: CodeCellViewModel, index: number, templateData: CodeCellRenderTemplate, height: number | undefined): void {
|
||||
|
@ -959,13 +963,14 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
this.updateForLayout(element, templateData);
|
||||
}));
|
||||
|
||||
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
|
||||
this.updateForInternalMetadata(element, templateData);
|
||||
this.updateForHover(element, templateData);
|
||||
this.updateForFocus(element, templateData);
|
||||
cellEditorOptions.setLineNumbers(element.lineNumbers);
|
||||
elementDisposables.add(element.onDidChangeState((e) => {
|
||||
if (e.internalMetadataChanged) {
|
||||
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
|
||||
this.updateForInternalMetadata(element, templateData);
|
||||
this.updateForLayout(element, templateData);
|
||||
}
|
||||
|
||||
if (e.outputIsHoveredChanged) {
|
||||
|
|
|
@ -250,6 +250,7 @@ export class StatefulMarkdownCell extends Disposable {
|
|||
|
||||
private updateFoldingIconShowClass() {
|
||||
const showFoldingIcon = this.notebookEditor.notebookOptions.getLayoutConfiguration().showFoldingControls;
|
||||
this.templateData.foldingIndicator.classList.remove('mouseover', 'always');
|
||||
this.templateData.foldingIndicator.classList.add(showFoldingIcon);
|
||||
}
|
||||
|
||||
|
|
|
@ -468,8 +468,10 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
|
||||
text(): string;
|
||||
json(): any;
|
||||
bytes(): Uint8Array
|
||||
data(): Uint8Array;
|
||||
blob(): Blob;
|
||||
/** @deprecated */
|
||||
bytes(): Uint8Array;
|
||||
}
|
||||
|
||||
interface IDestroyCellInfo {
|
||||
|
@ -492,7 +494,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
postKernelMessage: (data: unknown) => postNotebookMessage('customKernelMessage', { message: data }),
|
||||
};
|
||||
|
||||
const ttPolicy = window.trustedTypes?.createPolicy('notebookOutputRenderer', {
|
||||
const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
|
||||
createHTML: value => value,
|
||||
createScript: value => value,
|
||||
});
|
||||
|
@ -643,9 +645,10 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
mime: content.mimeType,
|
||||
value: content.value,
|
||||
metadata: content.metadata,
|
||||
bytes() {
|
||||
data() {
|
||||
return content.valueBytes;
|
||||
},
|
||||
bytes() { return this.data(); },
|
||||
text() {
|
||||
return new TextDecoder().decode(content.valueBytes)
|
||||
|| String(content.value); //todo@jrieken remove this once `value` is gone!
|
||||
|
@ -1038,8 +1041,9 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
outputId: undefined,
|
||||
text() { return content; },
|
||||
json() { return undefined; },
|
||||
bytes() { return new Uint8Array(); },
|
||||
blob() { return new Blob(); },
|
||||
bytes() { return this.data(); },
|
||||
data() { return new TextEncoder().encode(content); },
|
||||
blob() { return new Blob([this.data()], { type: this.mime }); },
|
||||
});
|
||||
}
|
||||
}();
|
||||
|
|
|
@ -144,10 +144,8 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
|
||||
this._register(model.onDidChangeInternalMetadata(e => {
|
||||
this._onDidChangeState.fire({ internalMetadataChanged: true, runStateChanged: e.runStateChanged });
|
||||
}));
|
||||
|
||||
this._register(this._viewContext.notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility || e.insertToolbarPosition) {
|
||||
if (e.runStateChanged || e.lastRunSuccessChanged) {
|
||||
// Statusbar visibility may change
|
||||
this.layoutChange({});
|
||||
}
|
||||
}));
|
||||
|
@ -160,7 +158,17 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
}
|
||||
|
||||
getEditorStatusbarHeight() {
|
||||
return this._viewContext.notebookOptions.computeStatusBarHeight();
|
||||
return this.statusBarIsVisible() ? this._viewContext.notebookOptions.computeStatusBarHeight() : 0;
|
||||
}
|
||||
|
||||
private statusBarIsVisible(): boolean {
|
||||
if (this._viewContext.notebookOptions.getLayoutConfiguration().showCellStatusBar) {
|
||||
return true;
|
||||
} else if (this._viewContext.notebookOptions.getLayoutConfiguration().showCellStatusBarAfterExecute) {
|
||||
return typeof this.internalMetadata.lastRunSuccess === 'boolean' || this.internalMetadata.runState !== undefined;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
abstract hasDynamicHeight(): boolean;
|
||||
|
|
|
@ -126,6 +126,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
}
|
||||
}));
|
||||
|
||||
this._register(this.viewContext.notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility || e.cellStatusBarAfterExecuteVisibility || e.insertToolbarPosition) {
|
||||
this.layoutChange({});
|
||||
}
|
||||
}));
|
||||
|
||||
this._outputCollection = new Array(this.model.outputs.length);
|
||||
|
||||
this._layoutInfo = {
|
||||
|
@ -152,6 +158,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
const outputShowMoreContainerHeight = state.outputShowMoreContainerHeight ? state.outputShowMoreContainerHeight : this._layoutInfo.outputShowMoreContainerHeight;
|
||||
let outputTotalHeight = Math.max(this._outputMinHeight, this.metadata.outputCollapsed ? notebookLayoutConfiguration.collapsedIndicatorHeight : this._outputsTop!.getTotalValue());
|
||||
|
||||
const originalLayout = this.layoutInfo;
|
||||
if (!this.metadata.inputCollapsed) {
|
||||
let newState: CodeCellLayoutState;
|
||||
let editorHeight: number;
|
||||
|
@ -235,10 +242,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
};
|
||||
}
|
||||
|
||||
if (state.editorHeight || state.outputHeight) {
|
||||
state.totalHeight = true;
|
||||
}
|
||||
|
||||
state.totalHeight = this.layoutInfo.totalHeight !== originalLayout.totalHeight;
|
||||
state.source = source;
|
||||
|
||||
this._fireOnDidChangeLayout(state);
|
||||
|
|
|
@ -27,33 +27,25 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
return this._layoutInfo;
|
||||
}
|
||||
|
||||
private _previewHeight = 0;
|
||||
|
||||
set renderedMarkdownHeight(newHeight: number) {
|
||||
if (this.getEditState() === CellEditState.Preview) {
|
||||
const newTotalHeight = newHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap; // BOTTOM_CELL_TOOLBAR_GAP;
|
||||
this.totalHeight = newTotalHeight;
|
||||
this._previewHeight = newHeight;
|
||||
this._updateTotalHeight(this._previewHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap);
|
||||
}
|
||||
}
|
||||
|
||||
private set totalHeight(newHeight: number) {
|
||||
if (newHeight !== this.layoutInfo.totalHeight) {
|
||||
this.layoutChange({ totalHeight: newHeight });
|
||||
}
|
||||
}
|
||||
|
||||
private get totalHeight() {
|
||||
throw new Error('MarkdownCellViewModel.totalHeight is write only');
|
||||
}
|
||||
|
||||
private _editorHeight = 0;
|
||||
set editorHeight(newHeight: number) {
|
||||
this._editorHeight = newHeight;
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
|
||||
this.totalHeight = this._editorHeight
|
||||
this._updateTotalHeight(this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin // MARKDOWN_CELL_TOP_MARGIN
|
||||
+ layoutConfiguration.markdownCellBottomMargin // MARKDOWN_CELL_BOTTOM_MARGIN
|
||||
+ layoutConfiguration.bottomToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight();
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight());
|
||||
}
|
||||
|
||||
get editorHeight() {
|
||||
|
@ -116,6 +108,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
|
||||
this._layoutInfo = {
|
||||
editorHeight: 0,
|
||||
previewHeight: 0,
|
||||
fontInfo: initialNotebookLayoutInfo?.fontInfo || null,
|
||||
editorWidth: initialNotebookLayoutInfo?.width
|
||||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(initialNotebookLayoutInfo.width)
|
||||
|
@ -133,6 +126,21 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
this._onDidHideInput.fire();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this.viewContext.notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility || e.cellStatusBarAfterExecuteVisibility || e.insertToolbarPosition) {
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
if (this.getEditState() === CellEditState.Editing) {
|
||||
this._updateTotalHeight(this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin
|
||||
+ layoutConfiguration.markdownCellBottomMargin
|
||||
+ layoutConfiguration.bottomToolbarGap
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight());
|
||||
} else {
|
||||
this._updateTotalHeight(this._previewHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,6 +159,12 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
this._onDidChangeState.fire({ foldingStateChanged: true });
|
||||
}
|
||||
|
||||
private _updateTotalHeight(newHeight: number) {
|
||||
if (newHeight !== this.layoutInfo.totalHeight) {
|
||||
this.layoutChange({ totalHeight: newHeight });
|
||||
}
|
||||
}
|
||||
|
||||
layoutChange(state: MarkdownCellLayoutChangeEvent) {
|
||||
// recompute
|
||||
if (!this.metadata.inputCollapsed) {
|
||||
|
@ -158,10 +172,12 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
|
||||
: this._layoutInfo.editorWidth;
|
||||
const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight;
|
||||
const previewHeight = this._previewHeight;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font || this._layoutInfo.fontInfo,
|
||||
editorWidth,
|
||||
previewHeight,
|
||||
editorHeight: this._editorHeight,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
|
||||
totalHeight
|
||||
|
@ -178,6 +194,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
fontInfo: state.font || this._layoutInfo.fontInfo,
|
||||
editorWidth,
|
||||
editorHeight: this._editorHeight,
|
||||
previewHeight: this._previewHeight,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
|
||||
totalHeight
|
||||
};
|
||||
|
@ -193,6 +210,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
this._layoutInfo = {
|
||||
fontInfo: this._layoutInfo.fontInfo,
|
||||
editorWidth: this._layoutInfo.editorWidth,
|
||||
previewHeight: this._layoutInfo.previewHeight,
|
||||
bottomToolbarOffset: this._layoutInfo.bottomToolbarOffset,
|
||||
totalHeight: totalHeight,
|
||||
editorHeight: this._editorHeight
|
||||
|
|
|
@ -59,13 +59,14 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
|
||||
set internalMetadata(newInternalMetadata: NotebookCellInternalMetadata) {
|
||||
const runStateChanged = this._internalMetadata.runState !== newInternalMetadata.runState;
|
||||
const lastRunSuccessChanged = this._internalMetadata.lastRunSuccess !== newInternalMetadata.lastRunSuccess;
|
||||
newInternalMetadata = {
|
||||
...newInternalMetadata,
|
||||
...{ runStartTimeAdjustment: computeRunStartTimeAdjustment(this._internalMetadata, newInternalMetadata) }
|
||||
};
|
||||
this._internalMetadata = newInternalMetadata;
|
||||
this._hash = null;
|
||||
this._onDidChangeInternalMetadata.fire({ runStateChanged });
|
||||
this._onDidChangeInternalMetadata.fire({ runStateChanged, lastRunSuccessChanged });
|
||||
}
|
||||
|
||||
get language() {
|
||||
|
|
|
@ -189,6 +189,7 @@ export interface ICellOutput {
|
|||
|
||||
export interface CellInternalMetadataChangedEvent {
|
||||
readonly runStateChanged?: boolean;
|
||||
readonly lastRunSuccessChanged?: boolean;
|
||||
}
|
||||
|
||||
export interface ICell {
|
||||
|
@ -903,6 +904,7 @@ export const DisplayOrderKey = 'notebook.displayOrder';
|
|||
export const CellToolbarLocKey = 'notebook.cellToolbarLocation';
|
||||
export const CellToolbarVisibility = 'notebook.cellToolbarVisibility';
|
||||
export const ShowCellStatusBarKey = 'notebook.showCellStatusBar';
|
||||
export const ShowCellStatusBarAfterExecuteKey = 'notebook.showCellStatusBarAfterExecute';
|
||||
export const NotebookTextDiffEditorPreview = 'notebook.diff.enablePreview';
|
||||
export const ExperimentalUseMarkdownRenderer = 'notebook.experimental.useMarkdownRenderer';
|
||||
export const ExperimentalInsertToolbarAlignment = 'notebook.experimental.insertToolbarAlignment';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, DragAndDropEnabled, FocusIndicator, GlobalToolbar, ExperimentalInsertToolbarAlignment, InsertToolbarPosition, ShowFoldingControls, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, DragAndDropEnabled, ExperimentalInsertToolbarAlignment, FocusIndicator, GlobalToolbar, InsertToolbarPosition, ShowCellStatusBarAfterExecuteKey, ShowCellStatusBarKey, ShowFoldingControls } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
const SCROLLABLE_ELEMENT_PADDING_TOP = 18;
|
||||
|
||||
|
@ -32,6 +32,7 @@ export interface NotebookLayoutConfiguration {
|
|||
cellOutputPadding: number;
|
||||
codeCellLeftMargin: number;
|
||||
markdownCellLeftMargin: number;
|
||||
markdownCellGutter: number;
|
||||
markdownCellTopMargin: number;
|
||||
markdownCellBottomMargin: number;
|
||||
markdownPreviewPadding: number;
|
||||
|
@ -43,6 +44,7 @@ export interface NotebookLayoutConfiguration {
|
|||
editorBottomPaddingWithoutStatusBar: number;
|
||||
collapsedIndicatorHeight: number;
|
||||
showCellStatusBar: boolean;
|
||||
showCellStatusBarAfterExecute: boolean;
|
||||
cellStatusBarHeight: number;
|
||||
cellToolbarLocation: string | { [key: string]: string };
|
||||
cellToolbarInteraction: string;
|
||||
|
@ -55,10 +57,12 @@ export interface NotebookLayoutConfiguration {
|
|||
showFoldingControls: 'always' | 'mouseover';
|
||||
dragAndDropEnabled: boolean;
|
||||
fontSize: number;
|
||||
focusIndicatorLeftMargin: number;
|
||||
}
|
||||
|
||||
interface NotebookOptionsChangeEvent {
|
||||
cellStatusBarVisibility?: boolean;
|
||||
cellStatusBarAfterExecuteVisibility?: boolean;
|
||||
cellToolbarLocation?: boolean;
|
||||
cellToolbarInteraction?: boolean;
|
||||
editorTopPadding?: boolean;
|
||||
|
@ -78,15 +82,19 @@ const defaultConfigConstants = {
|
|||
cellRunGutter: 32,
|
||||
markdownCellTopMargin: 8,
|
||||
markdownCellBottomMargin: 8,
|
||||
markdownCellLeftMargin: 32,
|
||||
markdownCellLeftMargin: 0,
|
||||
markdownCellGutter: 32,
|
||||
focusIndicatorLeftMargin: 4
|
||||
};
|
||||
|
||||
const compactConfigConstants = {
|
||||
codeCellLeftMargin: 0,
|
||||
codeCellLeftMargin: 8,
|
||||
cellRunGutter: 32,
|
||||
markdownCellTopMargin: 6,
|
||||
markdownCellBottomMargin: 6,
|
||||
markdownCellLeftMargin: 32,
|
||||
markdownCellLeftMargin: 8,
|
||||
markdownCellGutter: 32,
|
||||
focusIndicatorLeftMargin: 4
|
||||
};
|
||||
|
||||
export class NotebookOptions {
|
||||
|
@ -97,6 +105,7 @@ export class NotebookOptions {
|
|||
|
||||
constructor(private readonly configurationService: IConfigurationService) {
|
||||
const showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
const showCellStatusBarAfterExecute = this.configurationService.getValue<boolean>(ShowCellStatusBarAfterExecuteKey);
|
||||
const globalToolbar = this.configurationService.getValue<boolean | undefined>(GlobalToolbar) ?? false;
|
||||
const consolidatedOutputButton = this.configurationService.getValue<boolean | undefined>(ConsolidatedOutputButton) ?? true;
|
||||
const dragAndDropEnabled = this.configurationService.getValue<boolean | undefined>(DragAndDropEnabled) ?? true;
|
||||
|
@ -127,6 +136,7 @@ export class NotebookOptions {
|
|||
editorBottomPaddingWithoutStatusBar: 12,
|
||||
collapsedIndicatorHeight: 24,
|
||||
showCellStatusBar,
|
||||
showCellStatusBarAfterExecute,
|
||||
globalToolbar,
|
||||
consolidatedOutputButton,
|
||||
dragAndDropEnabled,
|
||||
|
@ -154,6 +164,7 @@ export class NotebookOptions {
|
|||
|
||||
private _updateConfiguration(e: IConfigurationChangeEvent) {
|
||||
const cellStatusBarVisibility = e.affectsConfiguration(ShowCellStatusBarKey);
|
||||
const cellStatusBarAfterExecuteVisibility = e.affectsConfiguration(ShowCellStatusBarAfterExecuteKey);
|
||||
const cellToolbarLocation = e.affectsConfiguration(CellToolbarLocKey);
|
||||
const cellToolbarInteraction = e.affectsConfiguration(CellToolbarVisibility);
|
||||
const compactView = e.affectsConfiguration(CompactView);
|
||||
|
@ -168,6 +179,7 @@ export class NotebookOptions {
|
|||
|
||||
if (
|
||||
!cellStatusBarVisibility
|
||||
&& !cellStatusBarAfterExecuteVisibility
|
||||
&& !cellToolbarLocation
|
||||
&& !cellToolbarInteraction
|
||||
&& !compactView
|
||||
|
@ -188,6 +200,10 @@ export class NotebookOptions {
|
|||
configuration.showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
}
|
||||
|
||||
if (cellStatusBarAfterExecuteVisibility) {
|
||||
configuration.showCellStatusBarAfterExecute = this.configurationService.getValue<boolean>(ShowCellStatusBarAfterExecuteKey);
|
||||
}
|
||||
|
||||
if (cellToolbarLocation) {
|
||||
configuration.cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey);
|
||||
}
|
||||
|
@ -244,6 +260,7 @@ export class NotebookOptions {
|
|||
// trigger event
|
||||
this._onDidChangeOptions.fire({
|
||||
cellStatusBarVisibility,
|
||||
cellStatusBarAfterExecuteVisibility,
|
||||
cellToolbarLocation,
|
||||
cellToolbarInteraction,
|
||||
compactView,
|
||||
|
@ -329,11 +346,7 @@ export class NotebookOptions {
|
|||
}
|
||||
|
||||
computeStatusBarHeight(): number {
|
||||
if (this._layoutConfiguration.showCellStatusBar) {
|
||||
return this._layoutConfiguration.cellStatusBarHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return this._layoutConfiguration.cellStatusBarHeight;
|
||||
}
|
||||
|
||||
computeCellToolbarLocation(viewType?: string): 'right' | 'left' | 'hidden' {
|
||||
|
@ -384,7 +397,7 @@ export class NotebookOptions {
|
|||
outputNodePadding: this._layoutConfiguration.cellOutputPadding,
|
||||
outputNodeLeftPadding: this._layoutConfiguration.cellOutputPadding,
|
||||
previewNodePadding: this._layoutConfiguration.markdownPreviewPadding,
|
||||
markdownLeftMargin: this._layoutConfiguration.markdownCellLeftMargin,
|
||||
markdownLeftMargin: this._layoutConfiguration.markdownCellGutter + this._layoutConfiguration.markdownCellLeftMargin,
|
||||
leftMargin: this._layoutConfiguration.codeCellLeftMargin,
|
||||
rightMargin: this._layoutConfiguration.cellRightMargin,
|
||||
runGutter: this._layoutConfiguration.cellRunGutter,
|
||||
|
|
|
@ -92,7 +92,25 @@ export class SettingsEditor2 extends EditorPane {
|
|||
private static CONFIG_SCHEMA_UPDATE_DELAYER = 500;
|
||||
|
||||
private static readonly SUGGESTIONS: string[] = [
|
||||
`@${MODIFIED_SETTING_TAG}`, '@tag:usesOnlineServices', '@tag:sync', `@tag:${REQUIRE_TRUSTED_WORKSPACE_SETTING_TAG}`, `@${ID_SETTING_TAG}`, `@${EXTENSION_SETTING_TAG}`, `@${FEATURE_SETTING_TAG}scm`, `@${FEATURE_SETTING_TAG}explorer`, `@${FEATURE_SETTING_TAG}search`, `@${FEATURE_SETTING_TAG}debug`, `@${FEATURE_SETTING_TAG}extensions`, `@${FEATURE_SETTING_TAG}terminal`, `@${FEATURE_SETTING_TAG}task`, `@${FEATURE_SETTING_TAG}problems`, `@${FEATURE_SETTING_TAG}output`, `@${FEATURE_SETTING_TAG}comments`, `@${FEATURE_SETTING_TAG}remote`, `@${FEATURE_SETTING_TAG}timeline`
|
||||
`@${MODIFIED_SETTING_TAG}`,
|
||||
'@tag:usesOnlineServices',
|
||||
'@tag:sync',
|
||||
`@tag:${REQUIRE_TRUSTED_WORKSPACE_SETTING_TAG}`,
|
||||
`@${ID_SETTING_TAG}`,
|
||||
`@${EXTENSION_SETTING_TAG}`,
|
||||
`@${FEATURE_SETTING_TAG}scm`,
|
||||
`@${FEATURE_SETTING_TAG}explorer`,
|
||||
`@${FEATURE_SETTING_TAG}search`,
|
||||
`@${FEATURE_SETTING_TAG}debug`,
|
||||
`@${FEATURE_SETTING_TAG}extensions`,
|
||||
`@${FEATURE_SETTING_TAG}terminal`,
|
||||
`@${FEATURE_SETTING_TAG}task`,
|
||||
`@${FEATURE_SETTING_TAG}problems`,
|
||||
`@${FEATURE_SETTING_TAG}output`,
|
||||
`@${FEATURE_SETTING_TAG}comments`,
|
||||
`@${FEATURE_SETTING_TAG}remote`,
|
||||
`@${FEATURE_SETTING_TAG}timeline`,
|
||||
`@${FEATURE_SETTING_TAG}notebook`,
|
||||
];
|
||||
|
||||
private static shouldSettingUpdateFast(type: SettingValueType | SettingValueType[]): boolean {
|
||||
|
|
|
@ -701,7 +701,7 @@ export class SearchResultModel extends SettingsTreeModel {
|
|||
const isRemote = !!this.environmentService.remoteAuthority;
|
||||
|
||||
this.root.children = this.root.children
|
||||
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAnyExtension(this._viewState.extensionFilters) && child.matchesAnyId(this._viewState.idFilters) && (this.containsValidFeature() ? child.matchesAnyFeature(this._viewState.featureFilters) : true));
|
||||
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAnyExtension(this._viewState.extensionFilters) && child.matchesAnyId(this._viewState.idFilters) && child.matchesAnyFeature(this._viewState.featureFilters));
|
||||
|
||||
if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) {
|
||||
const resultExtensionIds = this.newExtensionSearchResults.filterMatches
|
||||
|
@ -715,22 +715,6 @@ export class SearchResultModel extends SettingsTreeModel {
|
|||
}
|
||||
}
|
||||
|
||||
private containsValidFeature(): boolean {
|
||||
if (!this._viewState.featureFilters || !this._viewState.featureFilters.size || !tocData.children) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const features = tocData.children.find(child => child.id === 'features');
|
||||
|
||||
if (features && features.children) {
|
||||
return Array.from(this._viewState.featureFilters).some(filter => {
|
||||
return features.children?.find(feature => 'features/' + filter === feature.id);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private getFlatSettings(): ISetting[] {
|
||||
const flatSettings: ISetting[] = [];
|
||||
arrays.coalesce(this.getUniqueResults())
|
||||
|
|
|
@ -25,7 +25,7 @@ import { isWeb } from 'vs/base/common/platform';
|
|||
import { once } from 'vs/base/common/functional';
|
||||
import { truncate } from 'vs/base/common/strings';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { getVirtualWorkspaceLocation } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { getRemoteName, getVirtualWorkspaceLocation, getVirtualWorkspaceScheme } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions';
|
||||
|
@ -53,6 +53,9 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
private remoteMenuActionsGroups: ActionGroup[] | undefined;
|
||||
|
||||
private readonly remoteAuthority = this.environmentService.remoteAuthority;
|
||||
|
||||
private virtualWorkspaceScheme: string | undefined = undefined;
|
||||
|
||||
private connectionState: 'initializing' | 'connected' | 'reconnecting' | 'disconnected' | undefined = undefined;
|
||||
private readonly connectionStateContextKey = new RawContextKey<'' | 'initializing' | 'disconnected' | 'connected'>('remoteConnectionState', '').bindTo(this.contextKeyService);
|
||||
|
||||
|
@ -80,6 +83,8 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
if (this.remoteAuthority) {
|
||||
this.connectionState = 'initializing';
|
||||
this.connectionStateContextKey.set(this.connectionState);
|
||||
} else {
|
||||
this.updateVirtualWorkspaceScheme();
|
||||
}
|
||||
|
||||
this.registerActions();
|
||||
|
@ -107,7 +112,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
});
|
||||
|
||||
// Close Remote Connection
|
||||
if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID && this.remoteAuthority) {
|
||||
if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID) {
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -117,17 +122,18 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
f1: true
|
||||
});
|
||||
}
|
||||
run = () => that.remoteAuthority && that.hostService.openWindow({ forceReuseWindow: true, remoteAuthority: null });
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
group: '6_close',
|
||||
command: {
|
||||
id: RemoteStatusIndicator.CLOSE_REMOTE_COMMAND_ID,
|
||||
title: nls.localize({ key: 'miCloseRemote', comment: ['&& denotes a mnemonic'] }, "Close Re&&mote Connection")
|
||||
},
|
||||
order: 3.5
|
||||
run = () => that.hostService.openWindow({ forceReuseWindow: true, remoteAuthority: null });
|
||||
});
|
||||
if (this.remoteAuthority) {
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
group: '6_close',
|
||||
command: {
|
||||
id: RemoteStatusIndicator.CLOSE_REMOTE_COMMAND_ID,
|
||||
title: nls.localize({ key: 'miCloseRemote', comment: ['&& denotes a mnemonic'] }, "Close Re&&mote Connection")
|
||||
},
|
||||
order: 3.5
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.extensionGalleryService.isEnabled()) {
|
||||
|
@ -196,10 +202,17 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
}));
|
||||
}
|
||||
} else {
|
||||
this._register(this.workspaceContextService.onDidChangeWorkbenchState(() => this.updateRemoteStatusIndicator()));
|
||||
this._register(this.workspaceContextService.onDidChangeWorkbenchState(() => {
|
||||
this.updateVirtualWorkspaceScheme();
|
||||
this.updateRemoteStatusIndicator();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private updateVirtualWorkspaceScheme() {
|
||||
this.virtualWorkspaceScheme = getVirtualWorkspaceScheme(this.workspaceContextService.getWorkspace());
|
||||
}
|
||||
|
||||
private async updateWhenInstalledExtensionsRegistered(): Promise<void> {
|
||||
await this.extensionService.whenInstalledExtensionsRegistered();
|
||||
|
||||
|
@ -280,13 +293,13 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
this.renderRemoteStatusIndicator(`$(remote) ${truncate(hostLabel, RemoteStatusIndicator.REMOTE_STATUS_LABEL_MAX_LENGTH)}`, nls.localize('host.tooltip', "Editing on {0}", hostLabel));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Workspace with label: indicate editing source
|
||||
const workspaceLabel = this.getWorkspaceLabel();
|
||||
if (workspaceLabel) {
|
||||
this.renderRemoteStatusIndicator(`$(remote) ${truncate(workspaceLabel, RemoteStatusIndicator.REMOTE_STATUS_LABEL_MAX_LENGTH)}`, nls.localize('workspace.tooltip', "Editing on {0}", workspaceLabel));
|
||||
return;
|
||||
} else if (this.virtualWorkspaceScheme) {
|
||||
// Workspace with label: indicate editing source
|
||||
const workspaceLabel = this.getWorkspaceLabel();
|
||||
if (workspaceLabel) {
|
||||
this.renderRemoteStatusIndicator(`$(remote) ${truncate(workspaceLabel, RemoteStatusIndicator.REMOTE_STATUS_LABEL_MAX_LENGTH)}`, nls.localize('workspace.tooltip', "Editing on {0}", workspaceLabel));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Remote actions: offer menu
|
||||
|
@ -342,11 +355,37 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
return undefined;
|
||||
};
|
||||
|
||||
const matchCurrentRemote = () => {
|
||||
if (this.remoteAuthority) {
|
||||
return new RegExp(`^remote_\\d\\d_${getRemoteName(this.remoteAuthority)}_`);
|
||||
} else if (this.virtualWorkspaceScheme) {
|
||||
if (this.virtualWorkspaceScheme === 'vscode-vfs') {
|
||||
return new RegExp(`^remote_\\d\\d_vfs_`);
|
||||
} else {
|
||||
return new RegExp(`^virtualfs_\\d\\d_${this.virtualWorkspaceScheme}_`);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const computeItems = () => {
|
||||
const actionGroups = this.getRemoteMenuActions(true);
|
||||
let actionGroups = this.getRemoteMenuActions(true);
|
||||
|
||||
const items: (IQuickPickItem | IQuickPickSeparator)[] = [];
|
||||
|
||||
const currentRemoteMatcher = matchCurrentRemote();
|
||||
if (currentRemoteMatcher) {
|
||||
// commands for the current remote go first
|
||||
actionGroups = actionGroups.sort((g1, g2) => {
|
||||
const isCurrentRemote1 = currentRemoteMatcher.test(g1[0]);
|
||||
const isCurrentRemote2 = currentRemoteMatcher.test(g2[0]);
|
||||
if (isCurrentRemote1 !== isCurrentRemote2) {
|
||||
return isCurrentRemote1 ? -1 : 1;
|
||||
}
|
||||
return g1[0].localeCompare(g2[0]);
|
||||
});
|
||||
}
|
||||
|
||||
let lastCategoryName: string | undefined = undefined;
|
||||
|
||||
for (let actionGroup of actionGroups) {
|
||||
|
@ -371,25 +410,38 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
}
|
||||
}
|
||||
|
||||
if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID && this.remoteAuthority) {
|
||||
if (items.length) {
|
||||
items.push({ type: 'separator' });
|
||||
}
|
||||
if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID) {
|
||||
if (this.remoteAuthority) {
|
||||
if (items.length) {
|
||||
items.push({ type: 'separator' });
|
||||
}
|
||||
|
||||
items.push({
|
||||
type: 'item',
|
||||
id: RemoteStatusIndicator.CLOSE_REMOTE_COMMAND_ID,
|
||||
label: nls.localize('closeRemote.title', 'Close Remote Connection')
|
||||
});
|
||||
|
||||
if (this.connectionState === 'disconnected') {
|
||||
items.push({
|
||||
type: 'item',
|
||||
id: ReloadWindowAction.ID,
|
||||
label: nls.localize('reloadWindow', 'Reload Window')
|
||||
id: RemoteStatusIndicator.CLOSE_REMOTE_COMMAND_ID,
|
||||
label: nls.localize('closeRemoteConnection.title', 'Close Remote Connection')
|
||||
});
|
||||
|
||||
if (this.connectionState === 'disconnected') {
|
||||
items.push({
|
||||
type: 'item',
|
||||
id: ReloadWindowAction.ID,
|
||||
label: nls.localize('reloadWindow', 'Reload Window')
|
||||
});
|
||||
}
|
||||
} else if (this.virtualWorkspaceScheme) {
|
||||
if (items.length) {
|
||||
items.push({ type: 'separator' });
|
||||
}
|
||||
|
||||
items.push({
|
||||
type: 'item',
|
||||
id: RemoteStatusIndicator.CLOSE_REMOTE_COMMAND_ID,
|
||||
label: nls.localize('closeRemoteWindow.title', 'Close Remote')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.remoteAuthority && this.extensionGalleryService.isEnabled()) {
|
||||
items.push({
|
||||
type: 'separator'
|
||||
|
|
|
@ -17,6 +17,7 @@ import type { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
|
|||
import { ITerminalStatusList } from 'vs/workbench/contrib/terminal/browser/terminalStatusList';
|
||||
import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
||||
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||
import { IEditableData } from 'vs/workbench/common/views';
|
||||
|
||||
export const ITerminalService = createDecorator<ITerminalService>('terminalService');
|
||||
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
|
||||
|
@ -206,6 +207,8 @@ export interface ITerminalService {
|
|||
|
||||
requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): Promise<ITerminalLaunchError | undefined>;
|
||||
isAttachedToTerminal(remoteTerm: IRemoteTerminalAttachTarget): boolean;
|
||||
getEditableData(stat: ITerminalInstance): IEditableData | undefined;
|
||||
setEditable(stat: ITerminalInstance, data: IEditableData | null): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IRemoteTerminalService extends IOffProcessTerminalService {
|
||||
|
@ -600,12 +603,13 @@ export interface ITerminalInstance {
|
|||
registerLinkProvider(provider: ITerminalExternalLinkProvider): IDisposable;
|
||||
|
||||
/**
|
||||
* Triggers a quick pick to rename this terminal.
|
||||
* Sets the terminal name to the provided title or triggers a quick pick
|
||||
* to take user input.
|
||||
*/
|
||||
rename(): Promise<void>;
|
||||
rename(title?: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Triggers a quick pick to rename this terminal.
|
||||
* Triggers a quick pick to change the icon of this terminal.
|
||||
*/
|
||||
changeIcon(): Promise<void>;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
|
|||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IPickOptions, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ILocalTerminalService, ITerminalProfile, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal';
|
||||
|
@ -811,9 +811,30 @@ export function registerTerminalActions() {
|
|||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor) {
|
||||
return getSelectedInstances(accessor)?.[0].rename();
|
||||
const terminalService = accessor.get(ITerminalService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
|
||||
const instance = getSelectedInstances(accessor)?.[0];
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
await terminalService.setEditable(instance, {
|
||||
validationMessage: value => validateTerminalName(value),
|
||||
onFinish: async (value, success) => {
|
||||
if (success) {
|
||||
try {
|
||||
await instance.rename(value);
|
||||
} catch (e) {
|
||||
notificationService.error(e);
|
||||
}
|
||||
}
|
||||
await terminalService.setEditable(instance, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -1830,3 +1851,14 @@ function focusNext(accessor: ServicesAccessor): void {
|
|||
const listService = accessor.get(IListService);
|
||||
listService.lastFocusedList?.focusNext();
|
||||
}
|
||||
|
||||
export function validateTerminalName(name: string): { content: string, severity: Severity } | null {
|
||||
if (!name || name.trim().length === 0) {
|
||||
return {
|
||||
content: localize('emptyTerminalNameError', "A name must be provided."),
|
||||
severity: Severity.Error
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -775,7 +775,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
|
||||
private _initDragAndDrop(container: HTMLElement) {
|
||||
this._dndObserver?.dispose();
|
||||
const dndController = new TerminalInstanceDropAndDropController(container);
|
||||
const dndController = new TerminalInstanceDragAndDropController(container);
|
||||
dndController.onDropTerminal(e => this._onRequestAddInstanceToGroup.fire(e));
|
||||
dndController.onDropFile(async path => {
|
||||
const preparedPath = await this._terminalInstanceService.preparePathForTerminalAsync(path, this.shellLaunchConfig.executable, this.title, this.shellType, this.isRemote);
|
||||
|
@ -1789,13 +1789,15 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
return this._linkManager.registerExternalLinkProvider(this, provider);
|
||||
}
|
||||
|
||||
async rename() {
|
||||
const name = await this._quickInputService.input({
|
||||
value: this.title,
|
||||
prompt: nls.localize('workbench.action.terminal.rename.prompt', "Enter terminal name"),
|
||||
});
|
||||
if (name) {
|
||||
this.setTitle(name, TitleEventSource.Api);
|
||||
async rename(title?: string) {
|
||||
if (!title) {
|
||||
title = await this._quickInputService.input({
|
||||
value: this.title,
|
||||
prompt: nls.localize('workbench.action.terminal.rename.prompt', "Enter terminal name"),
|
||||
});
|
||||
}
|
||||
if (title) {
|
||||
this.setTitle(title, TitleEventSource.Api);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1843,7 +1845,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
}
|
||||
}
|
||||
items.push({ type: 'separator' });
|
||||
const showAllColorsItem = { label: 'Show all colors' };
|
||||
const showAllColorsItem = { label: 'Reset to default' };
|
||||
items.push(showAllColorsItem);
|
||||
styleElement.textContent = css;
|
||||
document.body.appendChild(styleElement);
|
||||
|
@ -1870,7 +1872,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
}
|
||||
}
|
||||
|
||||
class TerminalInstanceDropAndDropController extends Disposable implements IDragAndDropObserverCallbacks {
|
||||
class TerminalInstanceDragAndDropController extends Disposable implements IDragAndDropObserverCallbacks {
|
||||
private _dropOverlay?: HTMLElement;
|
||||
|
||||
private readonly _onDropFile = new Emitter<string>();
|
||||
|
|
|
@ -19,7 +19,7 @@ import { IKeyMods, IPickOptions, IQuickInputButton, IQuickInputService, IQuickPi
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ILocalTerminalService, IOffProcessTerminalService, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IEditableData, IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IRemoteTerminalService, ITerminalExternalLinkProvider, ITerminalInstance, ITerminalService, ITerminalGroup, TerminalConnectionState } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
|
||||
|
@ -69,6 +69,8 @@ export class TerminalService implements ITerminalService {
|
|||
private _localTerminalsInitPromise: Promise<void> | undefined;
|
||||
private _connectionState: TerminalConnectionState;
|
||||
|
||||
private _editable: { instance: ITerminalInstance, data: IEditableData } | undefined;
|
||||
|
||||
public get activeGroupIndex(): number { return this._activeGroupIndex; }
|
||||
public get terminalGroups(): ITerminalGroup[] { return this._terminalGroups; }
|
||||
public get isProcessSupportRegistered(): boolean { return !!this._processSupportContextKey.get(); }
|
||||
|
@ -316,6 +318,25 @@ export class TerminalService implements ITerminalService {
|
|||
return activeInstance ? activeInstance : this.createTerminal(undefined);
|
||||
}
|
||||
|
||||
async setEditable(instance: ITerminalInstance, data?: IEditableData | null): Promise<void> {
|
||||
if (!data) {
|
||||
this._editable = undefined;
|
||||
} else {
|
||||
this._editable = { instance: instance, data };
|
||||
}
|
||||
const pane = this._viewsService.getActiveViewWithId<TerminalViewPane>(TERMINAL_VIEW_ID);
|
||||
const isEditing = this._isEditable(instance);
|
||||
pane?.terminalTabbedView?.setEditable(isEditing);
|
||||
}
|
||||
|
||||
private _isEditable(instance: ITerminalInstance | undefined): boolean {
|
||||
return !!this._editable && (this._editable.instance === instance || !instance);
|
||||
}
|
||||
|
||||
getEditableData(instance: ITerminalInstance): IEditableData | undefined {
|
||||
return this._editable && this._editable.instance === instance ? this._editable.data : undefined;
|
||||
}
|
||||
|
||||
requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): Promise<ITerminalLaunchError | undefined> {
|
||||
// The initial request came from the extension host, no need to wait for it
|
||||
return new Promise<ITerminalLaunchError | undefined>(callback => {
|
||||
|
|
|
@ -288,7 +288,7 @@ export class TerminalTabbedView extends Disposable {
|
|||
const hasText = this._tabListElement.clientWidth > TerminalTabsListSizes.MidpointViewWidth;
|
||||
this._tabContainer.classList.toggle('has-text', hasText);
|
||||
this._terminalIsTabsNarrowContextKey.set(!hasText);
|
||||
this._tabList.render();
|
||||
this._tabList.refresh();
|
||||
}
|
||||
|
||||
private _addSashListener() {
|
||||
|
@ -469,6 +469,13 @@ export class TerminalTabbedView extends Disposable {
|
|||
];
|
||||
}
|
||||
|
||||
setEditable(isEditing: boolean): void {
|
||||
if (!isEditing) {
|
||||
this._tabList.domFocus();
|
||||
}
|
||||
return this._tabList.refresh();
|
||||
}
|
||||
|
||||
focusTabs(): void {
|
||||
if (!this._shouldShowTabs()) {
|
||||
return;
|
||||
|
|
|
@ -26,7 +26,7 @@ import { DEFAULT_LABELS_CONTAINER, IResourceLabel, ResourceLabels } from 'vs/wor
|
|||
import { IDecorationsService } from 'vs/workbench/services/decorations/browser/decorations';
|
||||
import { IHoverAction, IHoverService } from 'vs/workbench/services/hover/browser/hover';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IListDragAndDrop, IListDragOverReaction, IListRenderer, ListDragOverEffect } from 'vs/base/browser/ui/list/list';
|
||||
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { disposableTimeout } from 'vs/base/common/async';
|
||||
|
@ -34,6 +34,13 @@ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { getColorClass, getIconId, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IEditableData } from 'vs/workbench/common/views';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
|
@ -89,13 +96,13 @@ export class TerminalTabList extends WorkbenchList<ITerminalInstance> {
|
|||
configurationService,
|
||||
keybindingService,
|
||||
);
|
||||
this._terminalService.onInstancesChanged(() => this.render());
|
||||
this._terminalService.onGroupsChanged(() => this.render());
|
||||
this._terminalService.onInstanceTitleChanged(() => this.render());
|
||||
this._terminalService.onInstanceIconChanged(() => this.render());
|
||||
this._terminalService.onInstancePrimaryStatusChanged(() => this.render());
|
||||
this._terminalService.onDidChangeConnectionState(() => this.render());
|
||||
this._themeService.onDidColorThemeChange(() => this.render());
|
||||
this._terminalService.onInstancesChanged(() => this.refresh());
|
||||
this._terminalService.onGroupsChanged(() => this.refresh());
|
||||
this._terminalService.onInstanceTitleChanged(() => this.refresh());
|
||||
this._terminalService.onInstanceIconChanged(() => this.refresh());
|
||||
this._terminalService.onInstancePrimaryStatusChanged(() => this.refresh());
|
||||
this._terminalService.onDidChangeConnectionState(() => this.refresh());
|
||||
this._themeService.onDidColorThemeChange(() => this.refresh());
|
||||
this._terminalService.onActiveInstanceChanged(e => {
|
||||
if (e) {
|
||||
const i = this._terminalService.terminalInstances.indexOf(e);
|
||||
|
@ -157,10 +164,10 @@ export class TerminalTabList extends WorkbenchList<ITerminalInstance> {
|
|||
this._decorationsProvider = instantiationService.createInstance(TerminalDecorationsProvider);
|
||||
_decorationsService.registerDecorationsProvider(this._decorationsProvider);
|
||||
}
|
||||
this.render();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
render(): void {
|
||||
refresh(): void {
|
||||
this.splice(0, this.length, this._terminalService.terminalInstances);
|
||||
}
|
||||
|
||||
|
@ -182,7 +189,8 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
|
|||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@IListService private readonly _listService: IListService,
|
||||
@IThemeService private readonly _themeService: IThemeService
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
@IContextViewService private readonly _contextViewService: IContextViewService
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -231,6 +239,12 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
|
|||
}
|
||||
|
||||
renderElement(instance: ITerminalInstance, index: number, template: ITerminalTabEntryTemplate): void {
|
||||
const editableData = this._terminalService.getEditableData(instance);
|
||||
if (editableData) {
|
||||
template.label.element.style.display = 'none';
|
||||
this._renderInputBox(template.label.element.parentElement!, instance, editableData);
|
||||
return;
|
||||
}
|
||||
const group = this._terminalService.getGroupForInstance(instance);
|
||||
if (!group) {
|
||||
throw new Error(`Could not find group for instance "${instance.instanceId}"`);
|
||||
|
@ -239,6 +253,10 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
|
|||
const hasText = !this.shouldHideText();
|
||||
template.element.classList.toggle('has-text', hasText);
|
||||
|
||||
if (template.label.element.style.display = 'none') {
|
||||
template.label.element.style.display = '';
|
||||
}
|
||||
|
||||
let prefix: string = '';
|
||||
if (group.terminalInstances.length > 1) {
|
||||
const terminalIndex = group.terminalInstances.indexOf(instance);
|
||||
|
@ -323,6 +341,84 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
|
|||
});
|
||||
}
|
||||
|
||||
private _renderInputBox(container: HTMLElement, instance: ITerminalInstance, editableData: IEditableData): IDisposable {
|
||||
|
||||
const label = this._labels.create(container);
|
||||
const value = instance.title || '';
|
||||
|
||||
const inputBox = new InputBox(label.element, this._contextViewService, {
|
||||
validationOptions: {
|
||||
validation: (value) => {
|
||||
const message = editableData.validationMessage(value);
|
||||
if (!message || message.severity !== Severity.Error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
content: message.content,
|
||||
formatContent: true,
|
||||
type: MessageType.ERROR
|
||||
};
|
||||
}
|
||||
},
|
||||
ariaLabel: localize('terminalInputAriaLabel', "Type terminal name. Press Enter to confirm or Escape to cancel.")
|
||||
});
|
||||
const styler = attachInputBoxStyler(inputBox, this._themeService);
|
||||
|
||||
inputBox.value = value;
|
||||
inputBox.focus();
|
||||
inputBox.select({ start: 0, end: value.length });
|
||||
|
||||
const done = once((success: boolean, finishEditing: boolean) => {
|
||||
inputBox.element.style.display = 'none';
|
||||
const value = inputBox.value;
|
||||
dispose(toDispose);
|
||||
inputBox.element.remove();
|
||||
if (finishEditing) {
|
||||
editableData.onFinish(value, success);
|
||||
}
|
||||
});
|
||||
|
||||
const showInputBoxNotification = () => {
|
||||
if (inputBox.isInputValid()) {
|
||||
const message = editableData.validationMessage(inputBox.value);
|
||||
if (message) {
|
||||
inputBox.showMessage({
|
||||
content: message.content,
|
||||
formatContent: true,
|
||||
type: message.severity === Severity.Info ? MessageType.INFO : message.severity === Severity.Warning ? MessageType.WARNING : MessageType.ERROR
|
||||
});
|
||||
} else {
|
||||
inputBox.hideMessage();
|
||||
}
|
||||
}
|
||||
};
|
||||
showInputBoxNotification();
|
||||
|
||||
const toDispose = [
|
||||
inputBox,
|
||||
DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => {
|
||||
if (e.equals(KeyCode.Enter)) {
|
||||
done(inputBox.isInputValid(), true);
|
||||
} else if (e.equals(KeyCode.Escape)) {
|
||||
done(false, true);
|
||||
}
|
||||
}),
|
||||
DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_UP, (e: IKeyboardEvent) => {
|
||||
showInputBoxNotification();
|
||||
}),
|
||||
DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => {
|
||||
done(inputBox.isInputValid(), true);
|
||||
}),
|
||||
label,
|
||||
styler
|
||||
];
|
||||
|
||||
return toDisposable(() => {
|
||||
done(false, false);
|
||||
});
|
||||
}
|
||||
|
||||
disposeElement(instance: ITerminalInstance, index: number, templateData: ITerminalTabEntryTemplate): void {
|
||||
templateData.elementDispoables?.dispose();
|
||||
templateData.elementDispoables = undefined;
|
||||
|
|
|
@ -115,36 +115,36 @@ suite('Workbench - TerminalProfiles', () => {
|
|||
} as ITestTerminalConfig) as ITerminalConfiguration;
|
||||
|
||||
test('should prefer pwsh 7 to Windows PowerShell', async () => {
|
||||
const fsProvider = createFsProvider([
|
||||
const expectedPaths = [
|
||||
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
|
||||
'C:\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
|
||||
'C:\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
|
||||
]);
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), fsProvider, undefined, undefined, undefined);
|
||||
];
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), undefined, undefined, undefined, expectedPaths);
|
||||
const expected = [
|
||||
{ profileName: 'PowerShell', path: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', isDefault: true }
|
||||
];
|
||||
profilesEqual(profiles, expected);
|
||||
});
|
||||
test('should prefer pwsh 7 to pwsh 6', async () => {
|
||||
const fsProvider = createFsProvider([
|
||||
const expectedPaths = [
|
||||
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
|
||||
'C:\\Program Files\\PowerShell\\6\\pwsh.exe',
|
||||
'C:\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
|
||||
'C:\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
|
||||
]);
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), fsProvider, undefined, undefined, undefined);
|
||||
];
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), undefined, undefined, undefined, expectedPaths);
|
||||
const expected = [
|
||||
{ profileName: 'PowerShell', path: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', isDefault: true }
|
||||
];
|
||||
profilesEqual(profiles, expected);
|
||||
});
|
||||
test.skip('should fallback to Windows PowerShell', async () => {
|
||||
const fsProvider = createFsProvider([
|
||||
test('should fallback to Windows PowerShell', async () => {
|
||||
const expectedPaths = [
|
||||
'C:\\Windows\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
|
||||
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
|
||||
]);
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), fsProvider, undefined, undefined, undefined);
|
||||
];
|
||||
const profiles = await detectAvailableProfiles(false, buildTestSafeConfigProvider(pwshSourceConfig), undefined, undefined, undefined, expectedPaths);
|
||||
strictEqual(profiles.length, 1);
|
||||
strictEqual(profiles[0].profileName, 'PowerShell');
|
||||
});
|
||||
|
@ -228,7 +228,7 @@ suite('Workbench - TerminalProfiles', () => {
|
|||
},
|
||||
async readFile(path: string): Promise<Buffer> {
|
||||
if (path !== '/etc/shells') {
|
||||
fail('Unexected path');
|
||||
fail('Unexepected path');
|
||||
}
|
||||
return Buffer.from(etcShellsContent);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories {
|
||||
padding: 12px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer.animationReady .gettingStartedSlide {
|
||||
|
@ -557,14 +557,11 @@
|
|||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link .codicon-arrow-small-right {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
left: 2px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link .codicon-check-all {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .skip {
|
||||
|
@ -606,6 +603,11 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .done-next-container {
|
||||
display: flex;
|
||||
padding: 8px 16px 16px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
|
@ -616,9 +618,13 @@
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .done-next-container .button-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link.next {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link:hover {
|
||||
|
@ -645,7 +651,7 @@
|
|||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .gettingStartedContainer .getting-started-category .codicon {
|
||||
top: 0;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .getting-started-category .codicon::before{
|
||||
|
|
|
@ -202,6 +202,11 @@ export class WorkspaceTrustManagementService extends Disposable implements IWork
|
|||
}
|
||||
|
||||
getUriTrustInfo(uri: URI): IWorkspaceTrustUriInfo {
|
||||
// Return trusted when workspace trust is disabled
|
||||
if (!isWorkspaceTrustEnabled(this.configurationService)) {
|
||||
return { trusted: true, uri };
|
||||
}
|
||||
|
||||
let resultState = false;
|
||||
let maxLength = -1;
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { MarkdownString, NotebookCellOutputItem } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { isEmptyObject } from 'vs/base/common/types';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
|
||||
|
@ -81,4 +82,23 @@ suite('ExtHostTypeConverter', function () {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('NotebookCellOutputItem', function () {
|
||||
|
||||
const item = extHostTypes.NotebookCellOutputItem.text('Hello', 'foo/bar');
|
||||
|
||||
const dto = NotebookCellOutputItem.from(item);
|
||||
|
||||
assert.strictEqual(dto.mime, 'foo/bar');
|
||||
assert.strictEqual(dto.metadata, undefined);
|
||||
assert.strictEqual(dto.value, undefined);
|
||||
assert.deepStrictEqual(dto.valueBytes, Array.from(new TextEncoder().encode('Hello')));
|
||||
|
||||
const item2 = NotebookCellOutputItem.to(dto);
|
||||
|
||||
assert.strictEqual(item2.mime, item.mime);
|
||||
assert.strictEqual(item2.metadata, item.metadata);
|
||||
assert.strictEqual(item2.value, item.value);
|
||||
assert.deepStrictEqual(item2.data, item.data);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -696,28 +696,28 @@ suite('ExtHostTypes', function () {
|
|||
|
||||
item = types.NotebookCellOutputItem.json(1);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode(JSON.stringify(1)));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(1)));
|
||||
|
||||
item = types.NotebookCellOutputItem.json(1, 'foo');
|
||||
assert.strictEqual(item.mime, 'foo');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode(JSON.stringify(1)));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(1)));
|
||||
|
||||
item = types.NotebookCellOutputItem.json(true);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode(JSON.stringify(true)));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify(true)));
|
||||
|
||||
item = types.NotebookCellOutputItem.json([true, 1, 'ddd']);
|
||||
assert.strictEqual(item.mime, 'application/json');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode(JSON.stringify([true, 1, 'ddd'], undefined, '\t')));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode(JSON.stringify([true, 1, 'ddd'], undefined, '\t')));
|
||||
|
||||
// --- text
|
||||
|
||||
item = types.NotebookCellOutputItem.text('Hęłlö');
|
||||
assert.strictEqual(item.mime, 'text/plain');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode('Hęłlö'));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode('Hęłlö'));
|
||||
|
||||
item = types.NotebookCellOutputItem.text('Hęłlö', 'foo/bar');
|
||||
assert.strictEqual(item.mime, 'foo/bar');
|
||||
assert.deepStrictEqual(item.value, new TextEncoder().encode('Hęłlö'));
|
||||
assert.deepStrictEqual(item.data, new TextEncoder().encode('Hęłlö'));
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue