Merge remote-tracking branch 'origin/main' into notebook/dev
This commit is contained in:
commit
ef1e9bfa2c
|
@ -223,6 +223,11 @@
|
|||
"default": false,
|
||||
"description": "%emmetPreferencesOutputReverseAttributes%"
|
||||
},
|
||||
"output.selfClosingStyle": {
|
||||
"type": "string",
|
||||
"default": "html",
|
||||
"description": "%emmetPreferencesOutputSelfClosingStyle%"
|
||||
},
|
||||
"css.color.short": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
|
|
|
@ -57,5 +57,6 @@
|
|||
"emmetOptimizeStylesheetParsing": "When set to `false`, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to `true`, only the content around the current position in CSS/SCSS/Less files is parsed.",
|
||||
"emmetPreferencesOutputInlineBreak": "The number of sibling inline elements needed for line breaks to be placed between those elements. If `0`, inline elements are always expanded onto a single line.",
|
||||
"emmetPreferencesOutputReverseAttributes": "If `true`, reverses attribute merging directions when resolving snippets.",
|
||||
"emmetPreferencesOutputSelfClosingStyle": "Style of self-closing tags: html (`<br>`), xml (`<br/>`) or xhtml (`<br />`).",
|
||||
"emmetPreferencesCssColorShort": "If `true`, color values like #f will be expanded to #fff instead of #ffffff."
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export function nextItemHTML(document: vscode.TextDocument, selectionStart: vsco
|
|||
if (currentNode.type !== 'comment') {
|
||||
// If cursor is in the tag name, select tag
|
||||
if (currentNode.open &&
|
||||
selectionEndOffset < currentNode.open.start + currentNode.name.length) {
|
||||
selectionEndOffset <= currentNode.open.start + currentNode.name.length) {
|
||||
return getSelectionFromNode(document, currentNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -439,7 +439,7 @@ suite('Tests for jsx, xml and xsl', () => {
|
|||
return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {
|
||||
editor.selection = new Selection(0, 6, 0, 6);
|
||||
await expandEmmetAbbreviation({ language: 'javascriptreact' });
|
||||
assert.strictEqual(editor.document.getText(), '<img src="" alt=""/>');
|
||||
assert.strictEqual(editor.document.getText(), '<img src="" alt="" />');
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
@ -449,7 +449,7 @@ suite('Tests for jsx, xml and xsl', () => {
|
|||
return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {
|
||||
editor.selection = new Selection(0, 6, 0, 6);
|
||||
await expandEmmetAbbreviation({ language: 'javascriptreact' });
|
||||
assert.strictEqual(editor.document.getText(), '<img src=\'\' alt=\'\'/>');
|
||||
assert.strictEqual(editor.document.getText(), '<img src=\'\' alt=\'\' />');
|
||||
return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -84,19 +84,19 @@ export function migrateEmmetExtensionsPath() {
|
|||
* Mapping between languages that support Emmet and completion trigger characters
|
||||
*/
|
||||
export const LANGUAGE_MODES: { [id: string]: string[] } = {
|
||||
'html': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'jade': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'slim': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'haml': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'xml': ['.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'xsl': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'html': ['!', '.', '}', ':', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'jade': ['!', '.', '}', ':', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'slim': ['!', '.', '}', ':', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'haml': ['!', '.', '}', ':', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'xml': ['.', '}', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'xsl': ['!', '.', '}', '*', '$', '/', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'css': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'scss': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'sass': [':', '!', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'less': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'stylus': [':', '!', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'javascriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'typescriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
'javascriptreact': ['!', '.', '}', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
'typescriptreact': ['!', '.', '}', '*', '$', ']', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
};
|
||||
|
||||
export function isStyleSheet(syntax: string): boolean {
|
||||
|
@ -376,32 +376,36 @@ export const allowedMimeTypesInScriptTag = ['text/html', 'text/plain', 'text/x-t
|
|||
* If position is inside a script tag of type template, then it will be parsed to find the inner HTML node as well
|
||||
*/
|
||||
export function getHtmlFlatNode(documentText: string, root: FlatNode | undefined, offset: number, includeNodeBoundary: boolean): HtmlFlatNode | undefined {
|
||||
const currentNode: HtmlFlatNode | undefined = <HtmlFlatNode | undefined>getFlatNode(root, offset, includeNodeBoundary);
|
||||
let currentNode: HtmlFlatNode | undefined = <HtmlFlatNode | undefined>getFlatNode(root, offset, includeNodeBoundary);
|
||||
if (!currentNode) { return; }
|
||||
|
||||
const isTemplateScript = currentNode.name === 'script' &&
|
||||
(currentNode.attributes &&
|
||||
currentNode.attributes.some(x => x.name.toString() === 'type'
|
||||
&& allowedMimeTypesInScriptTag.includes(x.value.toString())));
|
||||
if (isTemplateScript
|
||||
&& currentNode.open
|
||||
&& offset > currentNode.open.end
|
||||
&& (!currentNode.close || offset < currentNode.close.start)) {
|
||||
// blank out the rest of the document and search for the node within
|
||||
const beforePadding = ' '.repeat(currentNode.open.end);
|
||||
const endToUse = currentNode.close ? currentNode.close.start : currentNode.end;
|
||||
const scriptBodyText = beforePadding + documentText.substring(currentNode.open.end, endToUse);
|
||||
const innerRoot: HtmlFlatNode = parse(scriptBodyText);
|
||||
const scriptBodyNode = getHtmlFlatNode(scriptBodyText, innerRoot, offset, includeNodeBoundary);
|
||||
if (scriptBodyNode) {
|
||||
scriptBodyNode.parent = currentNode;
|
||||
currentNode.children.push(scriptBodyNode);
|
||||
return scriptBodyNode;
|
||||
}
|
||||
// If the currentNode is a script one, first set up its subtree and then find HTML node.
|
||||
if (currentNode.name === 'script' && currentNode.children.length === 0) {
|
||||
setUpScriptNodeSubtree(documentText, currentNode);
|
||||
currentNode = <HtmlFlatNode | undefined>getFlatNode(currentNode, offset, includeNodeBoundary) ?? currentNode;
|
||||
}
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
export function setUpScriptNodeSubtree(documentText: string, scriptNode: HtmlFlatNode): void {
|
||||
const isTemplateScript = scriptNode.name === 'script' &&
|
||||
(scriptNode.attributes &&
|
||||
scriptNode.attributes.some(x => x.name.toString() === 'type'
|
||||
&& allowedMimeTypesInScriptTag.includes(x.value.toString())));
|
||||
if (isTemplateScript
|
||||
&& scriptNode.open) {
|
||||
// blank out the rest of the document and generate the subtree.
|
||||
const beforePadding = ' '.repeat(scriptNode.open.end);
|
||||
const endToUse = scriptNode.close ? scriptNode.close.start : scriptNode.end;
|
||||
const scriptBodyText = beforePadding + documentText.substring(scriptNode.open.end, endToUse);
|
||||
const innerRoot: HtmlFlatNode = parse(scriptBodyText);
|
||||
innerRoot.children.forEach(child => {
|
||||
scriptNode.children.push(child);
|
||||
child.parent = scriptNode;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function isOffsetInsideOpenOrCloseTag(node: FlatNode, offset: number): boolean {
|
||||
const htmlNode = node as HtmlFlatNode;
|
||||
if ((htmlNode.open && offset > htmlNode.open.start && offset < htmlNode.open.end)
|
||||
|
@ -579,7 +583,7 @@ export function getEmmetConfiguration(syntax: string) {
|
|||
) {
|
||||
syntaxProfiles[syntax] = {
|
||||
...syntaxProfiles[syntax],
|
||||
selfClosingStyle: 'xml'
|
||||
selfClosingStyle: syntax === 'jsx' ? 'xhtml' : 'xml'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,9 +77,9 @@ jsonc-parser@^2.3.0:
|
|||
integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==
|
||||
|
||||
vscode-emmet-helper@^2.3.0:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.4.3.tgz#c536006b7a36deec746725bde10331dca733936a"
|
||||
integrity sha512-9VpzAMSF99TMqXrhptHu9reCoyAgELk1mw5Jdyaf9jFL2dGwrejY+636jLdIwCGLmZBOZVJ1ZV9R44Elx2HIoA==
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.4.4.tgz#f255120de921e2a017c5d48ca2f06e021430af99"
|
||||
integrity sha512-I7yjgf4vMJRXFD1fN6kWt8WgCidjmcxGa4h+1nO0gSrtoj1/f0FNJ06o64HWt+2rTkwp8eQ9OU3imt5kQkdZ5A==
|
||||
dependencies:
|
||||
emmet "^2.3.0"
|
||||
jsonc-parser "^2.3.0"
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as which from 'which';
|
|||
import { EventEmitter } from 'events';
|
||||
import * as iconv from 'iconv-lite-umd';
|
||||
import * as filetype from 'file-type';
|
||||
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
|
||||
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter, Versions } from './util';
|
||||
import { CancellationToken, Progress, Uri } from 'vscode';
|
||||
import { detectEncoding } from './encoding';
|
||||
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
|
||||
|
@ -377,6 +377,10 @@ export class Git {
|
|||
this.env = options.env || {};
|
||||
}
|
||||
|
||||
compareGitVersionTo(version: string): -1 | 0 | 1 {
|
||||
return Versions.compare(Versions.fromString(this.version), Versions.fromString(version));
|
||||
}
|
||||
|
||||
open(repository: string, dotGit: string): Repository {
|
||||
return new Repository(this, repository, dotGit);
|
||||
}
|
||||
|
@ -1977,7 +1981,16 @@ export class Repository {
|
|||
return this.getHEAD();
|
||||
}
|
||||
|
||||
const args = ['for-each-ref', '--format=%(refname)%00%(upstream:short)%00%(upstream:track)%00%(objectname)'];
|
||||
const args = ['for-each-ref'];
|
||||
|
||||
let supportsAheadBehind = true;
|
||||
if (this._git.compareGitVersionTo('1.9.0') === -1) {
|
||||
args.push('--format=%(refname)%00%(upstream:short)%00%(objectname)');
|
||||
supportsAheadBehind = false;
|
||||
} else {
|
||||
args.push('--format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)');
|
||||
}
|
||||
|
||||
if (/^refs\/(head|remotes)\//i.test(name)) {
|
||||
args.push(name);
|
||||
} else {
|
||||
|
@ -1986,7 +1999,7 @@ export class Repository {
|
|||
|
||||
const result = await this.exec(args);
|
||||
const branches: Branch[] = result.stdout.trim().split('\n').map<Branch | undefined>(line => {
|
||||
let [branchName, upstream, status, ref] = line.trim().split('\0');
|
||||
let [branchName, upstream, ref, status] = line.trim().split('\0');
|
||||
|
||||
if (branchName.startsWith('refs/heads/')) {
|
||||
branchName = branchName.substring(11);
|
||||
|
@ -2026,7 +2039,19 @@ export class Repository {
|
|||
}).filter((b?: Branch): b is Branch => !!b);
|
||||
|
||||
if (branches.length) {
|
||||
return branches[0];
|
||||
const [branch] = branches;
|
||||
|
||||
if (!supportsAheadBehind && branch.upstream) {
|
||||
try {
|
||||
const result = await this.exec(['rev-list', '--left-right', '--count', `${branch.name}...${branch.upstream.remote}/${branch.upstream.name}`]);
|
||||
const [ahead, behind] = result.stdout.trim().split('\t');
|
||||
|
||||
(branch as any).ahead = Number(ahead) || 0;
|
||||
(branch as any).behind = Number(behind) || 0;
|
||||
} catch { }
|
||||
}
|
||||
|
||||
return branch;
|
||||
}
|
||||
|
||||
return Promise.reject<Branch>(new Error('No such branch'));
|
||||
|
|
|
@ -414,3 +414,56 @@ export class PromiseSource<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Versions {
|
||||
declare type VersionComparisonResult = -1 | 0 | 1;
|
||||
|
||||
export interface Version {
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
pre?: string;
|
||||
}
|
||||
|
||||
export function compare(v1: string | Version, v2: string | Version): VersionComparisonResult {
|
||||
if (typeof v1 === 'string') {
|
||||
v1 = fromString(v1);
|
||||
}
|
||||
if (typeof v2 === 'string') {
|
||||
v2 = fromString(v2);
|
||||
}
|
||||
|
||||
if (v1.major > v2.major) { return 1; }
|
||||
if (v1.major < v2.major) { return -1; }
|
||||
|
||||
if (v1.minor > v2.minor) { return 1; }
|
||||
if (v1.minor < v2.minor) { return -1; }
|
||||
|
||||
if (v1.patch > v2.patch) { return 1; }
|
||||
if (v1.patch < v2.patch) { return -1; }
|
||||
|
||||
if (v1.pre === undefined && v2.pre !== undefined) { return 1; }
|
||||
if (v1.pre !== undefined && v2.pre === undefined) { return -1; }
|
||||
|
||||
if (v1.pre !== undefined && v2.pre !== undefined) {
|
||||
return v1.pre.localeCompare(v2.pre) as VersionComparisonResult;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function from(major: string | number, minor: string | number, patch?: string | number, pre?: string): Version {
|
||||
return {
|
||||
major: typeof major === 'string' ? parseInt(major, 10) : major,
|
||||
minor: typeof minor === 'string' ? parseInt(minor, 10) : minor,
|
||||
patch: patch === undefined || patch === null ? 0 : typeof patch === 'string' ? parseInt(patch, 10) : patch,
|
||||
pre: pre,
|
||||
};
|
||||
}
|
||||
|
||||
export function fromString(version: string): Version {
|
||||
const [ver, pre] = version.split('-');
|
||||
const [major, minor, patch] = ver.split('.');
|
||||
return from(major, minor, patch, pre);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export class TypeScriptVersionManager extends Disposable {
|
|||
}
|
||||
} else {
|
||||
setImmediate(() => {
|
||||
vscode.workspace.requireWorkspaceTrust({ modal: false })
|
||||
vscode.workspace.requestWorkspaceTrust({ modal: false })
|
||||
.then(trustState => {
|
||||
if (trustState === vscode.WorkspaceTrustState.Trusted && this.versionProvider.localVersion) {
|
||||
this.updateActiveVersion(this.versionProvider.localVersion);
|
||||
|
@ -120,7 +120,7 @@ export class TypeScriptVersionManager extends Disposable {
|
|||
description: version.displayName,
|
||||
detail: version.pathLabel,
|
||||
run: async () => {
|
||||
const trustState = await vscode.workspace.requireWorkspaceTrust();
|
||||
const trustState = await vscode.workspace.requestWorkspaceTrust();
|
||||
if (trustState === vscode.WorkspaceTrustState.Trusted) {
|
||||
await this.workspaceState.update(useWorkspaceTsdkStorageKey, true);
|
||||
const tsConfig = vscode.workspace.getConfiguration('typescript');
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
std::tuple_element<0, std::pair<pugi::xml_node, std::map<std::basic_string<char>, pugi::xml_node, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, pugi::xml_node> > > > >::type dnode
|
||||
|
||||
std::_Rb_tree_iterator<std::pair<const long, std::pair<pugi::xml_node, std::map<std::basic_string<char>, pugi::xml_node, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, pugi::xml_node> > > > > > dnode_it = dnodes_.find(uid.position)
|
|
@ -1,24 +0,0 @@
|
|||
[
|
||||
{
|
||||
"c": "std::tuple_element<0, std::pair<pugi::xml_node, std::map<std::basic_string<char>, pugi::xml_node, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, pugi::xml_node> > > > >::type dnode",
|
||||
"t": "source.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "std::_Rb_tree_iterator<std::pair<const long, std::pair<pugi::xml_node, std::map<std::basic_string<char>, pugi::xml_node, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, pugi::xml_node> > > > > > dnode_it = dnodes_.find(uid.position)",
|
||||
"t": "source.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.56.0",
|
||||
"distro": "0f81994093bec05b2cf192fc9fdb76ce5f114fcf",
|
||||
"distro": "307045ac2e7717469648489b42182dfca29bdb30",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
|
@ -79,7 +79,7 @@
|
|||
"tas-client-umd": "0.1.4",
|
||||
"v8-inspect-profiler": "^0.0.20",
|
||||
"vscode-oniguruma": "1.3.1",
|
||||
"vscode-proxy-agent": "^0.9.0",
|
||||
"vscode-proxy-agent": "^0.8.2",
|
||||
"vscode-regexpp": "^3.1.0",
|
||||
"vscode-ripgrep": "^1.11.1",
|
||||
"vscode-sqlite3": "4.0.10",
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
},
|
||||
{
|
||||
"name": "ms-vscode.js-debug",
|
||||
"version": "1.55.1",
|
||||
"version": "1.55.2",
|
||||
"repo": "https://github.com/microsoft/vscode-js-debug",
|
||||
"metadata": {
|
||||
"id": "25629058-ddac-4e17-abba-74678e126c5d",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"spdlog": "^0.11.1",
|
||||
"tas-client-umd": "0.1.4",
|
||||
"vscode-oniguruma": "1.3.1",
|
||||
"vscode-proxy-agent": "^0.9.0",
|
||||
"vscode-proxy-agent": "^0.8.2",
|
||||
"vscode-regexpp": "^3.1.0",
|
||||
"vscode-ripgrep": "^1.11.1",
|
||||
"vscode-textmate": "5.2.0",
|
||||
|
|
186
remote/yarn.lock
186
remote/yarn.lock
|
@ -2,11 +2,6 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@tootallnate/once@1", "@tootallnate/once@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
||||
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
|
||||
|
||||
agent-base@4:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce"
|
||||
|
@ -19,13 +14,6 @@ agent-base@5:
|
|||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c"
|
||||
integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==
|
||||
|
||||
agent-base@6, agent-base@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
||||
dependencies:
|
||||
debug "4"
|
||||
|
||||
agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
|
@ -33,6 +21,13 @@ agent-base@^4.3.0:
|
|||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
agent-base@~4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
|
||||
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
anymatch@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
|
||||
|
@ -94,16 +89,6 @@ cookie@^0.4.0:
|
|||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
data-uri-to-buffer@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
|
||||
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
|
||||
|
||||
debug@3.1.0, debug@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
|
@ -118,13 +103,6 @@ debug@4:
|
|||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
diagnostic-channel-publishers@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
|
@ -161,11 +139,6 @@ file-uri-to-path@1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
||||
|
||||
file-uri-to-path@2:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba"
|
||||
integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
|
@ -173,40 +146,11 @@ fill-range@^7.0.1:
|
|||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
fs-extra@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fsevents@~2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f"
|
||||
integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==
|
||||
|
||||
ftp@^0.3.10:
|
||||
version "0.3.10"
|
||||
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
|
||||
integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
|
||||
dependencies:
|
||||
readable-stream "1.1.x"
|
||||
xregexp "2.0.0"
|
||||
|
||||
get-uri@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c"
|
||||
integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==
|
||||
dependencies:
|
||||
"@tootallnate/once" "1"
|
||||
data-uri-to-buffer "3"
|
||||
debug "4"
|
||||
file-uri-to-path "2"
|
||||
fs-extra "^8.1.0"
|
||||
ftp "^0.3.10"
|
||||
|
||||
glob-parent@~5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2"
|
||||
|
@ -219,11 +163,6 @@ graceful-fs@4.2.3:
|
|||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
|
||||
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
|
@ -232,15 +171,6 @@ http-proxy-agent@^2.1.0:
|
|||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
http-proxy-agent@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
|
||||
integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
|
||||
dependencies:
|
||||
"@tootallnate/once" "1"
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
|
@ -257,24 +187,11 @@ https-proxy-agent@^4.0.0:
|
|||
agent-base "5"
|
||||
debug "4"
|
||||
|
||||
https-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
|
||||
integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
|
||||
dependencies:
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
iconv-lite-umd@0.6.8:
|
||||
version "0.6.8"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
|
||||
integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
|
||||
|
||||
inherits@~2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
|
@ -304,23 +221,11 @@ is-number@^7.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
|
||||
|
||||
jschardet@2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.3.0.tgz#06e2636e16c8ada36feebbdc08aa34e6a9b3ff75"
|
||||
integrity sha512-6I6xT7XN/7sBB7q8ObzKbmv5vN+blzLcboDE1BNEsEfmRXJValMxO6OIRT69ylPBRemS3rw6US+CMCar0OBc9g==
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
|
@ -338,7 +243,7 @@ ms@2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@2.1.2, ms@^2.1.1:
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
@ -407,16 +312,6 @@ proxy-from-env@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
readable-stream@1.1.x:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
|
||||
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readdirp@~3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
|
||||
|
@ -429,27 +324,26 @@ semver@^5.3.0:
|
|||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
|
||||
|
||||
smart-buffer@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba"
|
||||
integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==
|
||||
smart-buffer@4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d"
|
||||
integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==
|
||||
|
||||
socks-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60"
|
||||
integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==
|
||||
socks-proxy-agent@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386"
|
||||
integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==
|
||||
dependencies:
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
socks "^2.3.3"
|
||||
agent-base "~4.2.1"
|
||||
socks "~2.3.2"
|
||||
|
||||
socks@^2.3.3:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.0.tgz#6b984928461d39871b3666754b9000ecf39dfac2"
|
||||
integrity sha512-mNmr9owlinMplev0Wd7UHFlqI4ofnBnNzFuzrm63PPaHgbkqCFe4T5LzwKmtQ/f2tX0NTpcdVLyD/FHxFBstYw==
|
||||
socks@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e"
|
||||
integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==
|
||||
dependencies:
|
||||
ip "^1.1.5"
|
||||
smart-buffer "^4.1.0"
|
||||
smart-buffer "4.0.2"
|
||||
|
||||
spdlog@^0.11.1:
|
||||
version "0.11.1"
|
||||
|
@ -460,11 +354,6 @@ spdlog@^0.11.1:
|
|||
mkdirp "^0.5.1"
|
||||
nan "^2.14.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
tas-client-umd@0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.4.tgz#49db4130dd63a8342fabf77185a740fc6a7bea80"
|
||||
|
@ -477,28 +366,20 @@ to-regex-range@^5.0.1:
|
|||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
vscode-oniguruma@1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.3.1.tgz#e2383879c3485b19f533ec34efea9d7a2b14be8f"
|
||||
integrity sha512-gz6ZBofA7UXafVA+m2Yt2zHKgXC2qedArprIsHAPKByTkwq9l5y/izAGckqxYml7mSbYxTRTfdRwsFq3cwF4LQ==
|
||||
|
||||
vscode-proxy-agent@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-proxy-agent/-/vscode-proxy-agent-0.9.0.tgz#da6501b0bb9a6c8cc2fe0e31756c91eb4d5d900b"
|
||||
integrity sha512-DvLLaYNy8MBlm7O2CBUpmSpQCnNH88f95yXT1l9ovKO7GmTKkbbEJ6ZtzatUezqOlUuOFI0CwenhGGPYAlJ37A==
|
||||
vscode-proxy-agent@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-proxy-agent/-/vscode-proxy-agent-0.8.2.tgz#5125e7f1efedd84e0114abe9f38cef3f7b33eb50"
|
||||
integrity sha512-pRNhgAqrgMB4k1rZTHthCLVH+CtJ3TFlKKhFlt4IMxDRZnMEAbPiAGthvEt/Ku6qS4Vuca8b2PqT+rJlbmnznQ==
|
||||
dependencies:
|
||||
"@tootallnate/once" "^1.1.2"
|
||||
agent-base "^6.0.2"
|
||||
debug "^4.3.1"
|
||||
get-uri "^3.0.2"
|
||||
http-proxy-agent "^4.0.1"
|
||||
https-proxy-agent "^5.0.0"
|
||||
socks-proxy-agent "^5.0.0"
|
||||
debug "^3.1.0"
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.3"
|
||||
socks-proxy-agent "^4.0.1"
|
||||
|
||||
vscode-regexpp@^3.1.0:
|
||||
version "3.1.0"
|
||||
|
@ -537,11 +418,6 @@ windows-process-tree@0.2.4:
|
|||
dependencies:
|
||||
nan "^2.13.2"
|
||||
|
||||
xregexp@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
|
||||
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
|
||||
|
||||
xterm-addon-search@0.9.0-beta.1:
|
||||
version "0.9.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.1.tgz#139515da723a129c6d27c4e1a2319ef1344d76a6"
|
||||
|
|
20
src/bootstrap-window.js
vendored
20
src/bootstrap-window.js
vendored
|
@ -34,11 +34,9 @@
|
|||
* @param {string[]} modulePaths
|
||||
* @param {(result: unknown, configuration: import('./vs/base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => Promise<unknown> | undefined} resultCallback
|
||||
* @param {{
|
||||
* forceEnableDeveloperKeybindings?: boolean,
|
||||
* disallowReloadKeybinding?: boolean,
|
||||
* removeDeveloperKeybindingsAfterLoad?: boolean,
|
||||
* configureDeveloperKeybindings?: (config: import('./vs/base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('./vs/base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => void,
|
||||
* beforeLoaderConfig?: (config: import('./vs/base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration, loaderConfig: object) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }} [options]
|
||||
*/
|
||||
|
@ -55,11 +53,12 @@
|
|||
const configuration = await preloadGlobals.context.configuration;
|
||||
performance.mark('code/didWaitForWindowConfig');
|
||||
|
||||
// Developer tools
|
||||
const enableDeveloperKeybindings = safeProcess.env['VSCODE_DEV'] || configuration.forceEnableDeveloperKeybindings || options?.forceEnableDeveloperKeybindings;
|
||||
// Developer keybindings
|
||||
const { forceEnableDeveloperKeybindings, disallowReloadKeybinding, removeDeveloperKeybindingsAfterLoad } = typeof options?.configureDeveloperKeybindings === 'function' ? options.configureDeveloperKeybindings(configuration) : { forceEnableDeveloperKeybindings: false, disallowReloadKeybinding: false, removeDeveloperKeybindingsAfterLoad: false };
|
||||
const enableDeveloperKeybindings = safeProcess.env['VSCODE_DEV'] || forceEnableDeveloperKeybindings;
|
||||
let developerDeveloperKeybindingsDisposable;
|
||||
if (enableDeveloperKeybindings) {
|
||||
developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(options?.disallowReloadKeybinding);
|
||||
developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(disallowReloadKeybinding);
|
||||
}
|
||||
|
||||
// Enable ASAR support
|
||||
|
@ -143,7 +142,7 @@
|
|||
|
||||
// Signal before require.config()
|
||||
if (typeof options?.beforeLoaderConfig === 'function') {
|
||||
options.beforeLoaderConfig(configuration, loaderConfig);
|
||||
options.beforeLoaderConfig(loaderConfig);
|
||||
}
|
||||
|
||||
// Configure loader
|
||||
|
@ -177,7 +176,7 @@
|
|||
if (callbackResult instanceof Promise) {
|
||||
await callbackResult;
|
||||
|
||||
if (developerDeveloperKeybindingsDisposable && options?.removeDeveloperKeybindingsAfterLoad) {
|
||||
if (developerDeveloperKeybindingsDisposable && removeDeveloperKeybindingsAfterLoad) {
|
||||
developerDeveloperKeybindingsDisposable();
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +266,6 @@
|
|||
}
|
||||
|
||||
return {
|
||||
load,
|
||||
globals
|
||||
load
|
||||
};
|
||||
}));
|
||||
|
|
|
@ -680,12 +680,12 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
if (this.supportDynamicHeights) {
|
||||
this._rerender(this.scrollTop, this.renderHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
161
src/vs/base/common/product.ts
Normal file
161
src/vs/base/common/product.ts
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
|
||||
export interface IBuiltInExtension {
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly repo: string;
|
||||
readonly metadata: any;
|
||||
}
|
||||
|
||||
export type ConfigurationSyncStore = {
|
||||
url: string,
|
||||
insidersUrl: string,
|
||||
stableUrl: string,
|
||||
canSwitch: boolean,
|
||||
authenticationProviders: IStringDictionary<{ scopes: string[] }>
|
||||
};
|
||||
|
||||
export interface IProductConfiguration {
|
||||
readonly version: string;
|
||||
readonly date?: string;
|
||||
readonly quality?: string;
|
||||
readonly commit?: string;
|
||||
|
||||
readonly nameShort: string;
|
||||
readonly nameLong: string;
|
||||
|
||||
readonly win32AppUserModelId?: string;
|
||||
readonly win32MutexName?: string;
|
||||
readonly applicationName: string;
|
||||
|
||||
readonly urlProtocol: string;
|
||||
readonly dataFolderName: string; // location for extensions (e.g. ~/.vscode-insiders)
|
||||
|
||||
readonly builtInExtensions?: IBuiltInExtension[];
|
||||
|
||||
readonly downloadUrl?: string;
|
||||
readonly updateUrl?: string;
|
||||
readonly webEndpointUrl?: string;
|
||||
readonly target?: string;
|
||||
|
||||
readonly settingsSearchBuildId?: number;
|
||||
readonly settingsSearchUrl?: string;
|
||||
|
||||
readonly tasConfig?: {
|
||||
endpoint: string;
|
||||
telemetryEventName: string;
|
||||
featuresTelemetryPropertyName: string;
|
||||
assignmentContextTelemetryPropertyName: string;
|
||||
};
|
||||
|
||||
readonly experimentsUrl?: string;
|
||||
|
||||
readonly extensionsGallery?: {
|
||||
readonly serviceUrl: string;
|
||||
readonly itemUrl: string;
|
||||
readonly controlUrl: string;
|
||||
readonly recommendationsUrl: string;
|
||||
};
|
||||
|
||||
readonly extensionTips?: { [id: string]: string; };
|
||||
readonly extensionImportantTips?: IStringDictionary<ImportantExtensionTip>;
|
||||
readonly configBasedExtensionTips?: { [id: string]: IConfigBasedExtensionTip; };
|
||||
readonly exeBasedExtensionTips?: { [id: string]: IExeBasedExtensionTip; };
|
||||
readonly remoteExtensionTips?: { [remoteName: string]: IRemoteExtensionTip; };
|
||||
readonly extensionKeywords?: { [extension: string]: readonly string[]; };
|
||||
readonly keymapExtensionTips?: readonly string[];
|
||||
readonly trustedExtensionUrlPublicKeys?: { [id: string]: string[]; };
|
||||
|
||||
readonly crashReporter?: {
|
||||
readonly companyName: string;
|
||||
readonly productName: string;
|
||||
};
|
||||
|
||||
readonly enableTelemetry?: boolean;
|
||||
readonly aiConfig?: {
|
||||
readonly asimovKey: string;
|
||||
};
|
||||
|
||||
readonly sendASmile?: {
|
||||
readonly reportIssueUrl: string,
|
||||
readonly requestFeatureUrl: string
|
||||
};
|
||||
|
||||
readonly documentationUrl?: string;
|
||||
readonly releaseNotesUrl?: string;
|
||||
readonly keyboardShortcutsUrlMac?: string;
|
||||
readonly keyboardShortcutsUrlLinux?: string;
|
||||
readonly keyboardShortcutsUrlWin?: string;
|
||||
readonly introductoryVideosUrl?: string;
|
||||
readonly tipsAndTricksUrl?: string;
|
||||
readonly newsletterSignupUrl?: string;
|
||||
readonly twitterUrl?: string;
|
||||
readonly requestFeatureUrl?: string;
|
||||
readonly reportIssueUrl?: string;
|
||||
readonly reportMarketplaceIssueUrl?: string;
|
||||
readonly licenseUrl?: string;
|
||||
readonly privacyStatementUrl?: string;
|
||||
readonly telemetryOptOutUrl?: string;
|
||||
|
||||
readonly npsSurveyUrl?: string;
|
||||
readonly cesSurveyUrl?: string;
|
||||
readonly surveys?: readonly ISurveyData[];
|
||||
|
||||
readonly checksums?: { [path: string]: string; };
|
||||
readonly checksumFailMoreInfoUrl?: string;
|
||||
|
||||
readonly appCenter?: IAppCenterConfiguration;
|
||||
|
||||
readonly portable?: string;
|
||||
|
||||
readonly extensionKind?: { readonly [extensionId: string]: ('ui' | 'workspace' | 'web')[]; };
|
||||
readonly extensionSyncedKeys?: { readonly [extensionId: string]: string[]; };
|
||||
readonly extensionAllowedProposedApi?: readonly string[];
|
||||
|
||||
readonly msftInternalDomains?: string[];
|
||||
readonly linkProtectionTrustedDomains?: readonly string[];
|
||||
|
||||
readonly 'configurationSync.store'?: ConfigurationSyncStore;
|
||||
|
||||
readonly darwinUniversalAssetId?: string;
|
||||
}
|
||||
|
||||
export type ImportantExtensionTip = { name: string; languages?: string[]; pattern?: string; isExtensionPack?: boolean };
|
||||
|
||||
export interface IAppCenterConfiguration {
|
||||
readonly 'win32-ia32': string;
|
||||
readonly 'win32-x64': string;
|
||||
readonly 'linux-x64': string;
|
||||
readonly 'darwin': string;
|
||||
}
|
||||
|
||||
export interface IConfigBasedExtensionTip {
|
||||
configPath: string;
|
||||
configName: string;
|
||||
recommendations: IStringDictionary<{ name: string, remotes?: string[], important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IExeBasedExtensionTip {
|
||||
friendlyName: string;
|
||||
windowsPath?: string;
|
||||
important?: boolean;
|
||||
recommendations: IStringDictionary<{ name: string, important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IRemoteExtensionTip {
|
||||
friendlyName: string;
|
||||
extensionId: string;
|
||||
}
|
||||
|
||||
export interface ISurveyData {
|
||||
surveyId: string;
|
||||
surveyUrl: string;
|
||||
languageId: string;
|
||||
editCount: number;
|
||||
userProbability: number;
|
||||
}
|
|
@ -24,6 +24,4 @@ export interface ISandboxConfiguration {
|
|||
zoomLevel?: number;
|
||||
|
||||
nodeCachedDataDir?: string;
|
||||
|
||||
forceEnableDeveloperKeybindings?: boolean;
|
||||
}
|
||||
|
|
|
@ -238,6 +238,7 @@
|
|||
|
||||
try {
|
||||
if (validateIPC(windowConfigIpcChannel)) {
|
||||
/** @type {import('../common/sandboxTypes').ISandboxConfiguration} */
|
||||
const configuration = await ipcRenderer.invoke(windowConfigIpcChannel);
|
||||
|
||||
// Apply zoom level early before even building the
|
||||
|
|
|
@ -7,11 +7,13 @@ import * as assert from 'assert';
|
|||
import { ipcRenderer, crashReporter, webFrame, context, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
|
||||
suite('Sandbox', () => {
|
||||
test('globals', () => {
|
||||
test('globals', async () => {
|
||||
assert.ok(typeof ipcRenderer.send === 'function');
|
||||
assert.ok(typeof crashReporter.addExtraParameter === 'function');
|
||||
assert.ok(typeof webFrame.setZoomLevel === 'function');
|
||||
assert.ok(context.configuration instanceof Promise);
|
||||
assert.ok(typeof process.platform === 'string');
|
||||
|
||||
const config = await context.configuration;
|
||||
assert.ok(config);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,7 +28,16 @@
|
|||
|
||||
/**
|
||||
* @returns {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown) => Promise<unknown>
|
||||
* load: (
|
||||
* modules: string[],
|
||||
* resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown,
|
||||
* options?: {
|
||||
* configureDeveloperKeybindings?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }
|
||||
* ) => Promise<unknown>
|
||||
* }}
|
||||
*/
|
||||
function bootstrapWindowLib() {
|
||||
|
|
|
@ -32,11 +32,16 @@
|
|||
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
|
||||
},
|
||||
{
|
||||
removeDeveloperKeybindingsAfterLoad: true,
|
||||
configureDeveloperKeybindings: function (windowConfig) {
|
||||
return {
|
||||
forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath),
|
||||
removeDeveloperKeybindingsAfterLoad: true
|
||||
};
|
||||
},
|
||||
canModifyDOM: function (windowConfig) {
|
||||
showPartsSplash(windowConfig);
|
||||
},
|
||||
beforeLoaderConfig: function (windowConfig, loaderConfig) {
|
||||
beforeLoaderConfig: function (loaderConfig) {
|
||||
loaderConfig.recordStats = true;
|
||||
},
|
||||
beforeRequire: function () {
|
||||
|
@ -66,7 +71,16 @@
|
|||
|
||||
/**
|
||||
* @returns {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: import('../../../platform/windows/common/windows').INativeWindowConfiguration) => unknown, options: object) => Promise<unknown>
|
||||
* load: (
|
||||
* modules: string[],
|
||||
* resultCallback: (result, configuration: import('../../../platform/windows/common/windows').INativeWindowConfiguration) => unknown,
|
||||
* options?: {
|
||||
* configureDeveloperKeybindings?: (config: import('../../../platform/windows/common/windows').INativeWindowConfiguration & object) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('../../../platform/windows/common/windows').INativeWindowConfiguration & object) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }
|
||||
* ) => Promise<unknown>
|
||||
* }}
|
||||
*/
|
||||
function bootstrapWindowLib() {
|
||||
|
|
|
@ -11,12 +11,30 @@
|
|||
|
||||
// Load issue reporter into window
|
||||
bootstrapWindow.load(['vs/code/electron-sandbox/issue/issueReporterMain'], function (issueReporter, configuration) {
|
||||
issueReporter.startup(configuration);
|
||||
}, { forceEnableDeveloperKeybindings: true, disallowReloadKeybinding: true });
|
||||
return issueReporter.startup(configuration);
|
||||
},
|
||||
{
|
||||
configureDeveloperKeybindings: function () {
|
||||
return {
|
||||
forceEnableDeveloperKeybindings: true,
|
||||
disallowReloadKeybinding: true
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @returns {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown, options?: { forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean }) => Promise<unknown>
|
||||
* load: (
|
||||
* modules: string[],
|
||||
* resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown,
|
||||
* options?: {
|
||||
* configureDeveloperKeybindings?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }
|
||||
* ) => Promise<unknown>
|
||||
* }}
|
||||
*/
|
||||
function bootstrapWindowLib() {
|
||||
|
|
|
@ -11,12 +11,27 @@
|
|||
|
||||
// Load process explorer into window
|
||||
bootstrapWindow.load(['vs/code/electron-sandbox/processExplorer/processExplorerMain'], function (processExplorer, configuration) {
|
||||
processExplorer.startup(configuration);
|
||||
}, { forceEnableDeveloperKeybindings: true });
|
||||
return processExplorer.startup(configuration);
|
||||
}, {
|
||||
configureDeveloperKeybindings: function () {
|
||||
return {
|
||||
forceEnableDeveloperKeybindings: true
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @returns {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown, options?: { forceEnableDeveloperKeybindings?: boolean }) => Promise<unknown>
|
||||
* load: (
|
||||
* modules: string[],
|
||||
* resultCallback: (result, configuration: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => unknown,
|
||||
* options?: {
|
||||
* configureDeveloperKeybindings?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('../../../base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }
|
||||
* ) => Promise<unknown>
|
||||
* }}
|
||||
*/
|
||||
function bootstrapWindowLib() {
|
||||
|
|
|
@ -32,11 +32,16 @@
|
|||
return require('vs/workbench/electron-sandbox/desktop.main').main(configuration);
|
||||
},
|
||||
{
|
||||
removeDeveloperKeybindingsAfterLoad: true,
|
||||
configureDeveloperKeybindings: function (windowConfig) {
|
||||
return {
|
||||
forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath),
|
||||
removeDeveloperKeybindingsAfterLoad: true
|
||||
};
|
||||
},
|
||||
canModifyDOM: function (windowConfig) {
|
||||
// TODO@sandbox part-splash is non-sandboxed only
|
||||
},
|
||||
beforeLoaderConfig: function (windowConfig, loaderConfig) {
|
||||
beforeLoaderConfig: function (loaderConfig) {
|
||||
loaderConfig.recordStats = true;
|
||||
},
|
||||
beforeRequire: function () {
|
||||
|
@ -66,7 +71,16 @@
|
|||
|
||||
/**
|
||||
* @returns {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: import('../../../platform/windows/common/windows').INativeWindowConfiguration) => unknown, options: object) => Promise<unknown>
|
||||
* load: (
|
||||
* modules: string[],
|
||||
* resultCallback: (result, configuration: import('../../../platform/windows/common/windows').INativeWindowConfiguration) => unknown,
|
||||
* options?: {
|
||||
* configureDeveloperKeybindings?: (config: import('../../../platform/windows/common/windows').INativeWindowConfiguration & object) => {forceEnableDeveloperKeybindings?: boolean, disallowReloadKeybinding?: boolean, removeDeveloperKeybindingsAfterLoad?: boolean},
|
||||
* canModifyDOM?: (config: import('../../../platform/windows/common/windows').INativeWindowConfiguration & object) => void,
|
||||
* beforeLoaderConfig?: (loaderConfig: object) => void,
|
||||
* beforeRequire?: () => void
|
||||
* }
|
||||
* ) => Promise<unknown>
|
||||
* }}
|
||||
*/
|
||||
function bootstrapWindowLib() {
|
||||
|
|
|
@ -2106,10 +2106,42 @@ export class TextModel extends Disposable implements model.ITextModel {
|
|||
return this._matchBracket(this.validatePosition(position));
|
||||
}
|
||||
|
||||
private _establishBracketSearchOffsets(position: Position, lineTokens: LineTokens, modeBrackets: RichEditBrackets, tokenIndex: number) {
|
||||
const tokenCount = lineTokens.getCount();
|
||||
const currentLanguageId = lineTokens.getLanguageId(tokenIndex);
|
||||
|
||||
// limit search to not go before `maxBracketLength`
|
||||
let searchStartOffset = Math.max(0, position.column - 1 - modeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex - 1; i >= 0; i--) {
|
||||
const tokenEndOffset = lineTokens.getEndOffset(i);
|
||||
if (tokenEndOffset <= searchStartOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i)) || lineTokens.getLanguageId(i) !== currentLanguageId) {
|
||||
searchStartOffset = tokenEndOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// limit search to not go after `maxBracketLength`
|
||||
let searchEndOffset = Math.min(lineTokens.getLineContent().length, position.column - 1 + modeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex + 1; i < tokenCount; i++) {
|
||||
const tokenStartOffset = lineTokens.getStartOffset(i);
|
||||
if (tokenStartOffset >= searchEndOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i)) || lineTokens.getLanguageId(i) !== currentLanguageId) {
|
||||
searchEndOffset = tokenStartOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { searchStartOffset, searchEndOffset };
|
||||
}
|
||||
|
||||
private _matchBracket(position: Position): [Range, Range] | null {
|
||||
const lineNumber = position.lineNumber;
|
||||
const lineTokens = this._getLineTokens(lineNumber);
|
||||
const tokenCount = lineTokens.getCount();
|
||||
const lineText = this._buffer.getLineContent(lineNumber);
|
||||
|
||||
const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
|
||||
|
@ -2120,19 +2152,8 @@ export class TextModel extends Disposable implements model.ITextModel {
|
|||
|
||||
// check that the token is not to be ignored
|
||||
if (currentModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex))) {
|
||||
// limit search to not go before `maxBracketLength`
|
||||
let searchStartOffset = Math.max(0, position.column - 1 - currentModeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex - 1; i >= 0; i--) {
|
||||
const tokenEndOffset = lineTokens.getEndOffset(i);
|
||||
if (tokenEndOffset <= searchStartOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
|
||||
searchStartOffset = tokenEndOffset;
|
||||
}
|
||||
}
|
||||
// limit search to not go after `maxBracketLength`
|
||||
const searchEndOffset = Math.min(lineText.length, position.column - 1 + currentModeBrackets.maxBracketLength);
|
||||
|
||||
let { searchStartOffset, searchEndOffset } = this._establishBracketSearchOffsets(position, lineTokens, currentModeBrackets, tokenIndex);
|
||||
|
||||
// it might be the case that [currentTokenStart -> currentTokenEnd] contains multiple brackets
|
||||
// `bestResult` will contain the most right-side result
|
||||
|
@ -2171,18 +2192,9 @@ export class TextModel extends Disposable implements model.ITextModel {
|
|||
|
||||
// check that previous token is not to be ignored
|
||||
if (prevModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(prevTokenIndex))) {
|
||||
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
|
||||
const searchStartOffset = Math.max(0, position.column - 1 - prevModeBrackets.maxBracketLength);
|
||||
let searchEndOffset = Math.min(lineText.length, position.column - 1 + prevModeBrackets.maxBracketLength);
|
||||
for (let i = prevTokenIndex + 1; i < tokenCount; i++) {
|
||||
const tokenStartOffset = lineTokens.getStartOffset(i);
|
||||
if (tokenStartOffset >= searchEndOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
|
||||
searchEndOffset = tokenStartOffset;
|
||||
}
|
||||
}
|
||||
|
||||
let { searchStartOffset, searchEndOffset } = this._establishBracketSearchOffsets(position, lineTokens, prevModeBrackets, prevTokenIndex);
|
||||
|
||||
const foundBracket = BracketsUtils.findPrevBracketInRange(prevModeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
|
||||
// check that we didn't hit a bracket too far away from position
|
||||
|
|
|
@ -313,11 +313,21 @@ export class ThemeTrieElementRule {
|
|||
export class ExternalThemeTrieElement {
|
||||
|
||||
public readonly mainRule: ThemeTrieElementRule;
|
||||
public readonly children: { [segment: string]: ExternalThemeTrieElement };
|
||||
public readonly children: Map<string, ExternalThemeTrieElement>;
|
||||
|
||||
constructor(mainRule: ThemeTrieElementRule, children?: { [segment: string]: ExternalThemeTrieElement }) {
|
||||
constructor(
|
||||
mainRule: ThemeTrieElementRule,
|
||||
children: Map<string, ExternalThemeTrieElement> | { [key: string]: ExternalThemeTrieElement } = new Map<string, ExternalThemeTrieElement>()
|
||||
) {
|
||||
this.mainRule = mainRule;
|
||||
this.children = children || Object.create(null);
|
||||
if (children instanceof Map) {
|
||||
this.children = children;
|
||||
} else {
|
||||
this.children = new Map<string, ExternalThemeTrieElement>();
|
||||
for (const key in children) {
|
||||
this.children.set(key, children[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,9 +346,9 @@ export class ThemeTrieElement {
|
|||
* used for testing purposes
|
||||
*/
|
||||
public toExternalThemeTrieElement(): ExternalThemeTrieElement {
|
||||
let children: { [segment: string]: ExternalThemeTrieElement } = Object.create(null);
|
||||
const children = new Map<string, ExternalThemeTrieElement>();
|
||||
this._children.forEach((element, index) => {
|
||||
children[index] = element.toExternalThemeTrieElement();
|
||||
children.set(index, element.toExternalThemeTrieElement());
|
||||
});
|
||||
return new ExternalThemeTrieElement(this._mainRule, children);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -22,7 +21,7 @@ export interface ILanguageExtensionPoint {
|
|||
configuration?: URI;
|
||||
}
|
||||
|
||||
export interface ILanguageSelection extends IDisposable {
|
||||
export interface ILanguageSelection {
|
||||
readonly languageIdentifier: LanguageIdentifier;
|
||||
readonly onDidChange: Event<LanguageIdentifier>;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { FrankensteinMode } from 'vs/editor/common/modes/abstractMode';
|
||||
|
@ -13,20 +13,28 @@ import { LanguagesRegistry } from 'vs/editor/common/services/languagesRegistry';
|
|||
import { ILanguageSelection, IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { firstOrDefault } from 'vs/base/common/arrays';
|
||||
|
||||
class LanguageSelection extends Disposable implements ILanguageSelection {
|
||||
class LanguageSelection implements ILanguageSelection {
|
||||
|
||||
public languageIdentifier: LanguageIdentifier;
|
||||
|
||||
private readonly _selector: () => LanguageIdentifier;
|
||||
|
||||
private readonly _onDidChange: Emitter<LanguageIdentifier> = this._register(new Emitter<LanguageIdentifier>());
|
||||
public readonly onDidChange: Event<LanguageIdentifier> = this._onDidChange.event;
|
||||
private readonly _onDidChange: Emitter<LanguageIdentifier>;
|
||||
public readonly onDidChange: Event<LanguageIdentifier>;
|
||||
|
||||
constructor(onLanguagesMaybeChanged: Event<void>, selector: () => LanguageIdentifier) {
|
||||
super();
|
||||
this._selector = selector;
|
||||
this.languageIdentifier = this._selector();
|
||||
this._register(onLanguagesMaybeChanged(() => this._evaluate()));
|
||||
|
||||
let listener: IDisposable;
|
||||
this._onDidChange = new Emitter<LanguageIdentifier>({
|
||||
onFirstListenerAdd: () => {
|
||||
listener = onLanguagesMaybeChanged(() => this._evaluate());
|
||||
},
|
||||
onLastListenerRemove: () => {
|
||||
listener.dispose();
|
||||
}
|
||||
});
|
||||
this.onDidChange = this._onDidChange.event;
|
||||
}
|
||||
|
||||
private _evaluate(): void {
|
||||
|
|
|
@ -78,10 +78,6 @@ class ModelData implements IDisposable {
|
|||
this._languageSelectionListener.dispose();
|
||||
this._languageSelectionListener = null;
|
||||
}
|
||||
if (this._languageSelection) {
|
||||
this._languageSelection.dispose();
|
||||
this._languageSelection = null;
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
|
|
@ -28,5 +28,4 @@ export class MockMode extends Disposable implements IMode {
|
|||
export class StaticLanguageSelector implements ILanguageSelection {
|
||||
readonly onDidChange: Event<LanguageIdentifier> = Event.None;
|
||||
constructor(public readonly languageIdentifier: LanguageIdentifier) { }
|
||||
public dispose(): void { }
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { TokenizationResult2 } from 'vs/editor/common/core/token';
|
||||
|
@ -337,6 +337,97 @@ suite('TextModelWithTokens', () => {
|
|||
registration.dispose();
|
||||
});
|
||||
|
||||
test('issue #95843: Highlighting of closing braces is indicating wrong brace when cursor is behind opening brace', () => {
|
||||
const mode1 = new LanguageIdentifier('testMode1', 3);
|
||||
const mode2 = new LanguageIdentifier('testMode2', 4);
|
||||
const otherMetadata1 = (
|
||||
(mode1.id << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET)
|
||||
) >>> 0;
|
||||
const otherMetadata2 = (
|
||||
(mode2.id << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET)
|
||||
) >>> 0;
|
||||
|
||||
const tokenizationSupport: ITokenizationSupport = {
|
||||
getInitialState: () => NULL_STATE,
|
||||
tokenize: undefined!,
|
||||
tokenize2: (line, hasEOL, state) => {
|
||||
switch (line) {
|
||||
case 'function f() {': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1,
|
||||
8, otherMetadata1,
|
||||
9, otherMetadata1,
|
||||
10, otherMetadata1,
|
||||
11, otherMetadata1,
|
||||
12, otherMetadata1,
|
||||
13, otherMetadata1,
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
case ' return <p>{true}</p>;': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1,
|
||||
2, otherMetadata1,
|
||||
8, otherMetadata1,
|
||||
9, otherMetadata2,
|
||||
10, otherMetadata2,
|
||||
11, otherMetadata2,
|
||||
12, otherMetadata2,
|
||||
13, otherMetadata1,
|
||||
17, otherMetadata2,
|
||||
18, otherMetadata2,
|
||||
20, otherMetadata2,
|
||||
21, otherMetadata2,
|
||||
22, otherMetadata2,
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
case '}': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
}
|
||||
throw new Error(`Unexpected`);
|
||||
}
|
||||
};
|
||||
|
||||
const disposableStore = new DisposableStore();
|
||||
|
||||
disposableStore.add(TokenizationRegistry.register(mode1.language, tokenizationSupport));
|
||||
disposableStore.add(LanguageConfigurationRegistry.register(mode1, {
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
}));
|
||||
disposableStore.add(LanguageConfigurationRegistry.register(mode2, {
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
}));
|
||||
|
||||
const model = disposableStore.add(createTextModel([
|
||||
'function f() {',
|
||||
' return <p>{true}</p>;',
|
||||
'}',
|
||||
].join('\n'), undefined, mode1));
|
||||
|
||||
model.forceTokenization(1);
|
||||
model.forceTokenization(2);
|
||||
model.forceTokenization(3);
|
||||
|
||||
assert.deepStrictEqual(model.matchBracket(new Position(2, 14)), [new Range(2, 13, 2, 14), new Range(2, 18, 2, 19)]);
|
||||
|
||||
disposableStore.dispose();
|
||||
});
|
||||
|
||||
test('issue #88075: TypeScript brace matching is incorrect in `${}` strings', () => {
|
||||
const mode = new LanguageIdentifier('testMode', 3);
|
||||
const otherMetadata = (
|
||||
|
|
|
@ -243,60 +243,60 @@ suite('Token theme resolving', () => {
|
|||
});
|
||||
|
||||
test('defaults are inherited', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.NotSet, 'ff0000', null)
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _C, _B))
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('same rules get merged', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', 1, FontStyle.Bold, null, null),
|
||||
new ParsedTokenThemeRule('var', 0, FontStyle.NotSet, 'ff0000', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _C, _B))
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('rules are inherited 1', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.Bold, 'ff0000', null),
|
||||
new ParsedTokenThemeRule('var.identifier', -1, FontStyle.NotSet, '00ff00', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
const _D = colorMap.getId('00ff00');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _C, _B), {
|
||||
'identifier': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _D, _B))
|
||||
})
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('rules are inherited 2', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.Bold, 'ff0000', null),
|
||||
new ParsedTokenThemeRule('var.identifier', -1, FontStyle.NotSet, '00ff00', null),
|
||||
|
@ -306,7 +306,7 @@ suite('Token theme resolving', () => {
|
|||
new ParsedTokenThemeRule('constant.numeric.oct', 7, FontStyle.Bold | FontStyle.Italic | FontStyle.Underline, null, null),
|
||||
new ParsedTokenThemeRule('constant.numeric.dec', 8, FontStyle.None, '300000', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('100000');
|
||||
|
@ -315,7 +315,7 @@ suite('Token theme resolving', () => {
|
|||
const _F = colorMap.getId('ff0000');
|
||||
const _G = colorMap.getId('00ff00');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _F, _B), {
|
||||
'identifier': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _G, _B))
|
||||
}),
|
||||
|
@ -327,7 +327,7 @@ suite('Token theme resolving', () => {
|
|||
})
|
||||
})
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('custom colors are first in color map', () => {
|
||||
|
|
|
@ -763,6 +763,9 @@ var AMDLoader;
|
|||
require.resolve = function resolve(request, options) {
|
||||
return Module._resolveFilename(request, mod, false, options);
|
||||
};
|
||||
require.resolve.paths = function paths(request) {
|
||||
return Module._resolveLookupPaths(request, mod);
|
||||
};
|
||||
require.main = process.mainModule;
|
||||
require.extensions = Module._extensions;
|
||||
require.cache = Module._cache;
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IProductService, IConfigBasedExtensionTip as IRawConfigBasedExtensionTip } from 'vs/platform/product/common/productService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IConfigBasedExtensionTip as IRawConfigBasedExtensionTip } from 'vs/base/common/product';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { IExtensionTipsService, IExecutableBasedExtensionTip, IWorkspaceTips, IConfigBasedExtensionTip } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
|
|
|
@ -189,18 +189,9 @@ export class IssueMainService implements ICommonIssueService {
|
|||
if (this.issueReporterParentWindow) {
|
||||
const issueReporterDisposables = new DisposableStore();
|
||||
|
||||
interface IIssueReporterWindowConfig extends ISandboxConfiguration {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
const issueReporterWindowConfigUrl = issueReporterDisposables.add(this.protocolMainService.createIPCObjectUrl<IIssueReporterWindowConfig>());
|
||||
const position = this.getWindowPosition(this.issueReporterParentWindow, 700, 800);
|
||||
|
||||
this.issueReporterWindow = this.createBrowserWindow(position, issueReporterWindowConfigUrl, data.styles.backgroundColor, localize('issueReporter', "Issue Reporter"), data.zoomLevel);
|
||||
|
||||
const configuration: IIssueReporterWindowConfig = {
|
||||
const configuration = {
|
||||
appRoot: this.environmentMainService.appRoot,
|
||||
windowId: this.issueReporterWindow.id,
|
||||
windowId: 0, // filled in later
|
||||
machineId: this.machineId,
|
||||
userEnv: this.userEnv,
|
||||
data,
|
||||
|
@ -221,6 +212,14 @@ export class IssueMainService implements ICommonIssueService {
|
|||
}
|
||||
};
|
||||
|
||||
interface IIssueReporterWindowConfig extends ISandboxConfiguration, Extract<typeof configuration, any> { }
|
||||
|
||||
const issueReporterWindowConfigUrl = issueReporterDisposables.add(this.protocolMainService.createIPCObjectUrl<IIssueReporterWindowConfig>());
|
||||
const position = this.getWindowPosition(this.issueReporterParentWindow, 700, 800);
|
||||
|
||||
this.issueReporterWindow = this.createBrowserWindow(position, issueReporterWindowConfigUrl, data.styles.backgroundColor, localize('issueReporter', "Issue Reporter"), data.zoomLevel);
|
||||
configuration.windowId = this.issueReporterWindow.id;
|
||||
|
||||
// Store into config object URL
|
||||
issueReporterWindowConfigUrl.update(configuration);
|
||||
|
||||
|
@ -254,22 +253,21 @@ export class IssueMainService implements ICommonIssueService {
|
|||
if (this.processExplorerParentWindow) {
|
||||
const processExplorerDisposables = new DisposableStore();
|
||||
|
||||
interface IProcessExplorerWindowConfig extends ISandboxConfiguration {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
const configuration = {
|
||||
appRoot: this.environmentMainService.appRoot,
|
||||
windowId: 0, // filled in later
|
||||
userEnv: this.userEnv,
|
||||
machineId: this.machineId,
|
||||
data
|
||||
};
|
||||
|
||||
interface IProcessExplorerWindowConfig extends ISandboxConfiguration, Extract<typeof configuration, any> { }
|
||||
|
||||
const processExplorerWindowConfigUrl = processExplorerDisposables.add(this.protocolMainService.createIPCObjectUrl<IProcessExplorerWindowConfig>());
|
||||
const position = this.getWindowPosition(this.processExplorerParentWindow, 800, 500);
|
||||
|
||||
this.processExplorerWindow = this.createBrowserWindow(position, processExplorerWindowConfigUrl, data.styles.backgroundColor, localize('issueReporter', "Issue Reporter"), data.zoomLevel);
|
||||
|
||||
const configuration: IProcessExplorerWindowConfig = {
|
||||
appRoot: this.environmentMainService.appRoot,
|
||||
windowId: this.processExplorerWindow.id,
|
||||
userEnv: this.userEnv,
|
||||
machineId: this.machineId,
|
||||
data
|
||||
};
|
||||
configuration.windowId = this.processExplorerWindow.id;
|
||||
|
||||
// Store into config object URL
|
||||
processExplorerWindowConfigUrl.update(configuration);
|
||||
|
|
|
@ -7,7 +7,7 @@ import { FileAccess } from 'vs/base/common/network';
|
|||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { env } from 'vs/base/common/process';
|
||||
import { dirname, joinPath } from 'vs/base/common/resources';
|
||||
import { IProductConfiguration } from 'vs/platform/product/common/productService';
|
||||
import { IProductConfiguration } from 'vs/base/common/product';
|
||||
|
||||
let product: IProductConfiguration;
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ExtensionKind } from 'vs/platform/extensions/common/extensions';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IProductConfiguration } from 'vs/base/common/product';
|
||||
|
||||
export const IProductService = createDecorator<IProductService>('productService');
|
||||
|
||||
|
@ -14,158 +13,3 @@ export interface IProductService extends Readonly<IProductConfiguration> {
|
|||
readonly _serviceBrand: undefined;
|
||||
|
||||
}
|
||||
|
||||
export interface IBuiltInExtension {
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly repo: string;
|
||||
readonly metadata: any;
|
||||
}
|
||||
|
||||
export type ConfigurationSyncStore = {
|
||||
url: string,
|
||||
insidersUrl: string,
|
||||
stableUrl: string,
|
||||
canSwitch: boolean,
|
||||
authenticationProviders: IStringDictionary<{ scopes: string[] }>
|
||||
};
|
||||
|
||||
export interface IProductConfiguration {
|
||||
readonly version: string;
|
||||
readonly date?: string;
|
||||
readonly quality?: string;
|
||||
readonly commit?: string;
|
||||
|
||||
readonly nameShort: string;
|
||||
readonly nameLong: string;
|
||||
|
||||
readonly win32AppUserModelId?: string;
|
||||
readonly win32MutexName?: string;
|
||||
readonly applicationName: string;
|
||||
|
||||
readonly urlProtocol: string;
|
||||
readonly dataFolderName: string; // location for extensions (e.g. ~/.vscode-insiders)
|
||||
|
||||
readonly builtInExtensions?: IBuiltInExtension[];
|
||||
|
||||
readonly downloadUrl?: string;
|
||||
readonly updateUrl?: string;
|
||||
readonly webEndpointUrl?: string;
|
||||
readonly target?: string;
|
||||
|
||||
readonly settingsSearchBuildId?: number;
|
||||
readonly settingsSearchUrl?: string;
|
||||
|
||||
readonly tasConfig?: {
|
||||
endpoint: string;
|
||||
telemetryEventName: string;
|
||||
featuresTelemetryPropertyName: string;
|
||||
assignmentContextTelemetryPropertyName: string;
|
||||
};
|
||||
|
||||
readonly experimentsUrl?: string;
|
||||
|
||||
readonly extensionsGallery?: {
|
||||
readonly serviceUrl: string;
|
||||
readonly itemUrl: string;
|
||||
readonly controlUrl: string;
|
||||
readonly recommendationsUrl: string;
|
||||
};
|
||||
|
||||
readonly extensionTips?: { [id: string]: string; };
|
||||
readonly extensionImportantTips?: IStringDictionary<ImportantExtensionTip>;
|
||||
readonly configBasedExtensionTips?: { [id: string]: IConfigBasedExtensionTip; };
|
||||
readonly exeBasedExtensionTips?: { [id: string]: IExeBasedExtensionTip; };
|
||||
readonly remoteExtensionTips?: { [remoteName: string]: IRemoteExtensionTip; };
|
||||
readonly extensionKeywords?: { [extension: string]: readonly string[]; };
|
||||
readonly keymapExtensionTips?: readonly string[];
|
||||
readonly trustedExtensionUrlPublicKeys?: { [id: string]: string[]; };
|
||||
|
||||
readonly crashReporter?: {
|
||||
readonly companyName: string;
|
||||
readonly productName: string;
|
||||
};
|
||||
|
||||
readonly enableTelemetry?: boolean;
|
||||
readonly aiConfig?: {
|
||||
readonly asimovKey: string;
|
||||
};
|
||||
|
||||
readonly sendASmile?: {
|
||||
readonly reportIssueUrl: string,
|
||||
readonly requestFeatureUrl: string
|
||||
};
|
||||
|
||||
readonly documentationUrl?: string;
|
||||
readonly releaseNotesUrl?: string;
|
||||
readonly keyboardShortcutsUrlMac?: string;
|
||||
readonly keyboardShortcutsUrlLinux?: string;
|
||||
readonly keyboardShortcutsUrlWin?: string;
|
||||
readonly introductoryVideosUrl?: string;
|
||||
readonly tipsAndTricksUrl?: string;
|
||||
readonly newsletterSignupUrl?: string;
|
||||
readonly twitterUrl?: string;
|
||||
readonly requestFeatureUrl?: string;
|
||||
readonly reportIssueUrl?: string;
|
||||
readonly reportMarketplaceIssueUrl?: string;
|
||||
readonly licenseUrl?: string;
|
||||
readonly privacyStatementUrl?: string;
|
||||
readonly telemetryOptOutUrl?: string;
|
||||
|
||||
readonly npsSurveyUrl?: string;
|
||||
readonly cesSurveyUrl?: string;
|
||||
readonly surveys?: readonly ISurveyData[];
|
||||
|
||||
readonly checksums?: { [path: string]: string; };
|
||||
readonly checksumFailMoreInfoUrl?: string;
|
||||
|
||||
readonly appCenter?: IAppCenterConfiguration;
|
||||
|
||||
readonly portable?: string;
|
||||
|
||||
readonly extensionKind?: { readonly [extensionId: string]: ExtensionKind[]; };
|
||||
readonly extensionSyncedKeys?: { readonly [extensionId: string]: string[]; };
|
||||
readonly extensionAllowedProposedApi?: readonly string[];
|
||||
|
||||
readonly msftInternalDomains?: string[];
|
||||
readonly linkProtectionTrustedDomains?: readonly string[];
|
||||
|
||||
readonly 'configurationSync.store'?: ConfigurationSyncStore;
|
||||
|
||||
readonly darwinUniversalAssetId?: string;
|
||||
}
|
||||
|
||||
export type ImportantExtensionTip = { name: string; languages?: string[]; pattern?: string; isExtensionPack?: boolean };
|
||||
|
||||
export interface IAppCenterConfiguration {
|
||||
readonly 'win32-ia32': string;
|
||||
readonly 'win32-x64': string;
|
||||
readonly 'linux-x64': string;
|
||||
readonly 'darwin': string;
|
||||
}
|
||||
|
||||
export interface IConfigBasedExtensionTip {
|
||||
configPath: string;
|
||||
configName: string;
|
||||
recommendations: IStringDictionary<{ name: string, remotes?: string[], important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IExeBasedExtensionTip {
|
||||
friendlyName: string;
|
||||
windowsPath?: string;
|
||||
important?: boolean;
|
||||
recommendations: IStringDictionary<{ name: string, important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IRemoteExtensionTip {
|
||||
friendlyName: string;
|
||||
extensionId: string;
|
||||
}
|
||||
|
||||
export interface ISurveyData {
|
||||
surveyId: string;
|
||||
surveyUrl: string;
|
||||
languageId: string;
|
||||
editCount: number;
|
||||
userProbability: number;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,8 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
|||
}
|
||||
});
|
||||
|
||||
const config: ISharedProcessConfiguration = {
|
||||
// Store into config object URL
|
||||
configObjectUrl.update({
|
||||
machineId: this.machineId,
|
||||
windowId: this.window.id,
|
||||
appRoot: this.environmentMainService.appRoot,
|
||||
|
@ -190,10 +191,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
|||
userEnv: this.userEnv,
|
||||
args: this.environmentMainService.args,
|
||||
logLevel: this.logService.getLevel()
|
||||
};
|
||||
|
||||
// Store into config object URL
|
||||
configObjectUrl.update(config);
|
||||
});
|
||||
|
||||
// Load with config
|
||||
this.window.loadURL(FileAccess.asBrowserUri('vs/code/electron-browser/sharedProcess/sharedProcess.html', require).toString(true));
|
||||
|
|
|
@ -96,6 +96,7 @@ export interface IOffProcessTerminalService {
|
|||
listProcesses(reduceGraceTime?: boolean): Promise<IProcessDetails[]>;
|
||||
setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void>;
|
||||
getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined>;
|
||||
reduceConnectionGraceTime(): void;
|
||||
}
|
||||
|
||||
export const ILocalTerminalService = createDecorator<ILocalTerminalService>('localTerminalService');
|
||||
|
@ -111,8 +112,8 @@ export interface IPtyService {
|
|||
readonly onPtyHostStart?: Event<void>;
|
||||
readonly onPtyHostUnresponsive?: Event<void>;
|
||||
readonly onPtyHostResponsive?: Event<void>;
|
||||
|
||||
readonly onProcessData: Event<{ id: number, event: IProcessDataEvent | string }>;
|
||||
readonly onProcessBinary: Event<{ id: number, event: string }>;
|
||||
readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
|
||||
readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string } }>;
|
||||
readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
|
||||
|
@ -142,10 +143,8 @@ export interface IPtyService {
|
|||
|
||||
/**
|
||||
* Lists all orphaned processes, ie. those without a connected frontend.
|
||||
* @param reduceGraceTime Whether to reduce the reconnection grace time for all orphaned
|
||||
* terminals.
|
||||
*/
|
||||
listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]>;
|
||||
listProcesses(): Promise<IProcessDetails[]>;
|
||||
|
||||
start(id: number): Promise<ITerminalLaunchError | undefined>;
|
||||
shutdown(id: number, immediate: boolean): Promise<void>;
|
||||
|
@ -155,11 +154,13 @@ export interface IPtyService {
|
|||
getCwd(id: number): Promise<string>;
|
||||
getLatency(id: number): Promise<number>;
|
||||
acknowledgeDataEvent(id: number, charCount: number): Promise<void>;
|
||||
processBinary(id: number, data: string): void;
|
||||
/** Confirm the process is _not_ an orphan. */
|
||||
orphanQuestionReply(id: number): Promise<void>;
|
||||
|
||||
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void>;
|
||||
getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined>;
|
||||
reduceConnectionGraceTime(): void;
|
||||
}
|
||||
|
||||
export enum HeartbeatConstants {
|
||||
|
@ -346,6 +347,7 @@ export interface ITerminalChildProcess {
|
|||
*/
|
||||
shutdown(immediate: boolean): void;
|
||||
input(data: string): void;
|
||||
processBinary(data: string): void;
|
||||
resize(cols: number, rows: number): void;
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,9 +49,10 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
readonly onPtyHostUnresponsive = this._onPtyHostUnresponsive.event;
|
||||
private readonly _onPtyHostResponsive = this._register(new Emitter<void>());
|
||||
readonly onPtyHostResponsive = this._onPtyHostResponsive.event;
|
||||
|
||||
private readonly _onProcessData = this._register(new Emitter<{ id: number, event: IProcessDataEvent | string }>());
|
||||
readonly onProcessData = this._onProcessData.event;
|
||||
private readonly _onProcessBinary = this._register(new Emitter<{ id: number, event: string }>());
|
||||
readonly onProcessBinary = this._onProcessBinary.event;
|
||||
private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
|
||||
readonly onProcessExit = this._onProcessExit.event;
|
||||
private readonly _onProcessReady = this._register(new Emitter<{ id: number, event: { pid: number, cwd: string } }>());
|
||||
|
@ -123,6 +124,7 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
// Create proxy and forward events
|
||||
const proxy = ProxyChannel.toService<IPtyService>(client.getChannel(TerminalIpcChannels.PtyHost));
|
||||
this._register(proxy.onProcessData(e => this._onProcessData.fire(e)));
|
||||
this._register(proxy.onProcessBinary(e => this._onProcessBinary.fire(e)));
|
||||
this._register(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
|
||||
this._register(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
|
||||
this._register(proxy.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
|
||||
|
@ -153,10 +155,12 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
detachFromProcess(id: number): Promise<void> {
|
||||
return this._proxy.detachFromProcess(id);
|
||||
}
|
||||
listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> {
|
||||
return this._proxy.listProcesses(reduceGraceTime);
|
||||
listProcesses(): Promise<IProcessDetails[]> {
|
||||
return this._proxy.listProcesses();
|
||||
}
|
||||
reduceConnectionGraceTime(): void {
|
||||
return this._proxy.reduceConnectionGraceTime();
|
||||
}
|
||||
|
||||
start(id: number): Promise<ITerminalLaunchError | undefined> {
|
||||
return this._proxy.start(id);
|
||||
}
|
||||
|
@ -188,6 +192,9 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void> {
|
||||
return this._proxy.setTerminalLayoutInfo(args);
|
||||
}
|
||||
processBinary(id: number, data: string): void {
|
||||
this._proxy.processBinary(id, data);
|
||||
}
|
||||
async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined> {
|
||||
return await this._proxy.getTerminalLayoutInfo(args);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
|
||||
private readonly _onProcessData = this._register(new Emitter<{ id: number, event: IProcessDataEvent | string }>());
|
||||
readonly onProcessData = this._onProcessData.event;
|
||||
private readonly _onProcessBinary = this._register(new Emitter<{ id: number, event: string }>());
|
||||
readonly onProcessBinary = this._onProcessBinary.event;
|
||||
private readonly _onProcessReplay = this._register(new Emitter<{ id: number, event: IPtyHostProcessReplayEvent }>());
|
||||
readonly onProcessReplay = this._onProcessReplay.event;
|
||||
private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
|
||||
|
@ -114,13 +116,13 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
this._throwIfNoPty(id).detach();
|
||||
}
|
||||
|
||||
async listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> {
|
||||
if (reduceGraceTime) {
|
||||
for (const pty of this._ptys.values()) {
|
||||
pty.reduceGraceTime();
|
||||
}
|
||||
reduceConnectionGraceTime(): void {
|
||||
for (const pty of this._ptys.values()) {
|
||||
pty.reduceGraceTime();
|
||||
}
|
||||
}
|
||||
|
||||
async listProcesses(): Promise<IProcessDetails[]> {
|
||||
const persistentProcesses = Array.from(this._ptys.entries()).filter(([_, pty]) => pty.shouldPersistTerminal);
|
||||
|
||||
this._logService.info(`Listing ${persistentProcesses.length} persistent terminals, ${this._ptys.size} total terminals`);
|
||||
|
@ -157,6 +159,10 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
return this._throwIfNoPty(id).orphanQuestionReply();
|
||||
}
|
||||
|
||||
processBinary(id: number, data: string): void {
|
||||
return this._throwIfNoPty(id).writeBinary(data);
|
||||
}
|
||||
|
||||
async setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void> {
|
||||
this._workspaceLayoutInfos.set(args.workspaceId, args);
|
||||
}
|
||||
|
@ -337,6 +343,9 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
}
|
||||
return this._terminalProcess.input(data);
|
||||
}
|
||||
writeBinary(data: string): void {
|
||||
return this._terminalProcess.processBinary(data);
|
||||
}
|
||||
resize(cols: number, rows: number): void {
|
||||
if (this._inReplay) {
|
||||
return;
|
||||
|
|
|
@ -311,23 +311,27 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||
}
|
||||
}
|
||||
|
||||
public input(data: string): void {
|
||||
public input(data: string, isBinary?: boolean): void {
|
||||
if (this._isDisposed || !this._ptyProcess) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i <= Math.floor(data.length / WRITE_MAX_CHUNK_SIZE); i++) {
|
||||
this._writeQueue.push(data.substr(i * WRITE_MAX_CHUNK_SIZE, WRITE_MAX_CHUNK_SIZE));
|
||||
}
|
||||
this._startWrite();
|
||||
this._startWrite(isBinary);
|
||||
}
|
||||
|
||||
private _startWrite(): void {
|
||||
public processBinary(data: string): void {
|
||||
this.input(data, true);
|
||||
}
|
||||
|
||||
private _startWrite(isBinary?: boolean): void {
|
||||
// Don't write if it's already queued of is there is nothing to write
|
||||
if (this._writeTimeout !== undefined || this._writeQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._doWrite();
|
||||
this._doWrite(isBinary);
|
||||
|
||||
// Don't queue more writes if the queue is empty
|
||||
if (this._writeQueue.length === 0) {
|
||||
|
@ -342,10 +346,16 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||
}, WRITE_INTERVAL_MS);
|
||||
}
|
||||
|
||||
private _doWrite(): void {
|
||||
private _doWrite(isBinary?: boolean): void {
|
||||
console.info('writing binary', isBinary);
|
||||
const data = this._writeQueue.shift()!;
|
||||
this._logService.trace('IPty#write', `${data.length} characters`);
|
||||
this._ptyProcess!.write(data);
|
||||
if (isBinary) {
|
||||
this._logService.info('IPty#write (binary)', `${data.length} characters`);
|
||||
this._ptyProcess!.write(Buffer.from(data, 'binary') as any);
|
||||
} else {
|
||||
this._logService.info('IPty#write', `${data.length} characters`);
|
||||
this._ptyProcess!.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
public resize(cols: number, rows: number): void {
|
||||
|
|
|
@ -10,7 +10,8 @@ import { joinPath, relativePath } from 'vs/base/common/resources';
|
|||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IHeaders, IRequestOptions, IRequestContext } from 'vs/base/parts/request/common/request';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IProductService, ConfigurationSyncStore } from 'vs/platform/product/common/productService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ConfigurationSyncStore } from 'vs/base/common/product';
|
||||
import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/serviceMachineId';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
|
|
|
@ -7,7 +7,8 @@ import * as assert from 'assert';
|
|||
import { IUserDataSyncStoreService, SyncResource, UserDataSyncErrorCode, UserDataSyncStoreError, IUserDataSyncStoreManagementService, IUserDataSyncStore } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncClient, UserDataSyncTestServer } from 'vs/platform/userDataSync/test/common/userDataSyncClient';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IProductService, ConfigurationSyncStore } from 'vs/platform/product/common/productService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ConfigurationSyncStore } from 'vs/base/common/product';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { RequestsSession, UserDataSyncStoreService, UserDataSyncStoreManagementService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
|
|
@ -871,9 +871,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
release: release()
|
||||
};
|
||||
|
||||
// Force enable developer tools for extension development
|
||||
configuration.forceEnableDeveloperKeybindings = Array.isArray(configuration.extensionDevelopmentPath);
|
||||
|
||||
// Store into config object URL
|
||||
this.configObjectUrl.update(configuration);
|
||||
}
|
||||
|
|
|
@ -45,14 +45,14 @@ export interface IWorkspaceTrustModel {
|
|||
}
|
||||
|
||||
export interface WorkspaceTrustRequestButton {
|
||||
label: string;
|
||||
type: 'ContinueWithTrust' | 'ContinueWithoutTrust' | 'Manage' | 'Cancel'
|
||||
readonly label: string;
|
||||
readonly type: 'ContinueWithTrust' | 'ContinueWithoutTrust' | 'Manage' | 'Cancel'
|
||||
}
|
||||
|
||||
export interface WorkspaceTrustRequestOptions {
|
||||
buttons?: WorkspaceTrustRequestButton[];
|
||||
message?: string;
|
||||
modal: boolean;
|
||||
readonly buttons?: WorkspaceTrustRequestButton[];
|
||||
readonly message?: string;
|
||||
readonly modal: boolean;
|
||||
}
|
||||
|
||||
export interface IWorkspaceTrustRequestModel {
|
||||
|
@ -68,8 +68,8 @@ export interface IWorkspaceTrustRequestModel {
|
|||
}
|
||||
|
||||
export interface WorkspaceTrustStateChangeEvent {
|
||||
previousTrustState: WorkspaceTrustState;
|
||||
currentTrustState: WorkspaceTrustState;
|
||||
readonly previousTrustState: WorkspaceTrustState;
|
||||
readonly currentTrustState: WorkspaceTrustState;
|
||||
}
|
||||
|
||||
export type WorkspaceTrustChangeEvent = Event<WorkspaceTrustStateChangeEvent>;
|
||||
|
@ -84,7 +84,7 @@ export interface IWorkspaceTrustService {
|
|||
onDidChangeTrustState: WorkspaceTrustChangeEvent;
|
||||
getWorkspaceTrustState(): WorkspaceTrustState;
|
||||
isWorkspaceTrustEnabled(): boolean;
|
||||
requireWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState>;
|
||||
requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState | undefined>;
|
||||
}
|
||||
|
||||
export interface IWorkspaceTrustUriInfo {
|
||||
|
|
8
src/vs/vscode.proposed.d.ts
vendored
8
src/vs/vscode.proposed.d.ts
vendored
|
@ -2806,12 +2806,12 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Previous trust state of the workspace
|
||||
*/
|
||||
previousTrustState: WorkspaceTrustState;
|
||||
readonly previousTrustState: WorkspaceTrustState;
|
||||
|
||||
/**
|
||||
* Current trust state of the workspace
|
||||
*/
|
||||
currentTrustState: WorkspaceTrustState;
|
||||
readonly currentTrustState: WorkspaceTrustState;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2822,7 +2822,7 @@ declare module 'vscode' {
|
|||
* When true, a modal dialog will be used to request workspace trust.
|
||||
* When false, a badge will be displayed on the Setting activity bar item
|
||||
*/
|
||||
modal: boolean;
|
||||
readonly modal: boolean;
|
||||
}
|
||||
|
||||
export namespace workspace {
|
||||
|
@ -2836,7 +2836,7 @@ declare module 'vscode' {
|
|||
* @param options Optional object describing the properties of the
|
||||
* workspace trust request
|
||||
*/
|
||||
export function requireWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Thenable<WorkspaceTrustState>;
|
||||
export function requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Thenable<WorkspaceTrustState | undefined>;
|
||||
|
||||
/**
|
||||
* Event that fires when the trust state of the current workspace changes
|
||||
|
|
|
@ -422,7 +422,7 @@ export class MainThreadTask implements MainThreadTaskShape {
|
|||
if (execution.task?.execution && CustomExecutionDTO.is(execution.task.execution) && event.resolvedVariables) {
|
||||
const dictionary: IStringDictionary<string> = {};
|
||||
Array.from(event.resolvedVariables.entries()).forEach(entry => dictionary[entry[0]] = entry[1]);
|
||||
resolvedDefinition = await this._configurationResolverService.resolveAny(task.getWorkspaceFolder(),
|
||||
resolvedDefinition = await this._configurationResolverService.resolveAnyAsync(task.getWorkspaceFolder(),
|
||||
execution.task.definition, dictionary);
|
||||
}
|
||||
this._proxy.$onDidStartTask(execution, event.terminalId!, resolvedDefinition);
|
||||
|
|
|
@ -100,9 +100,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
|||
public dispose(): void {
|
||||
this._toDispose.dispose();
|
||||
this._linkProvider?.dispose();
|
||||
|
||||
// TODO@Daniel: Should all the previously created terminals be disposed
|
||||
// when the extension host process goes down ?
|
||||
}
|
||||
|
||||
private _getTerminalId(id: TerminalIdentifier): number | undefined {
|
||||
|
@ -157,17 +154,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
|||
}
|
||||
|
||||
public $dispose(id: TerminalIdentifier): void {
|
||||
const terminalInstance = this._getTerminalInstance(id);
|
||||
if (terminalInstance) {
|
||||
terminalInstance.dispose();
|
||||
}
|
||||
this._getTerminalInstance(id)?.dispose();
|
||||
}
|
||||
|
||||
public $sendText(id: TerminalIdentifier, text: string, addNewLine: boolean): void {
|
||||
const terminalInstance = this._getTerminalInstance(id);
|
||||
if (terminalInstance) {
|
||||
terminalInstance.sendText(text, addNewLine);
|
||||
}
|
||||
this._getTerminalInstance(id)?.sendText(text, addNewLine);
|
||||
}
|
||||
|
||||
public $startSendingDataEvents(): void {
|
||||
|
@ -183,10 +174,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
|||
}
|
||||
|
||||
public $stopSendingDataEvents(): void {
|
||||
if (this._dataEventTracker) {
|
||||
this._dataEventTracker.dispose();
|
||||
this._dataEventTracker = undefined;
|
||||
}
|
||||
this._dataEventTracker?.dispose();
|
||||
this._dataEventTracker = undefined;
|
||||
}
|
||||
|
||||
public $startLinkProvider(): void {
|
||||
|
@ -276,60 +265,35 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
|||
}
|
||||
|
||||
public $sendProcessTitle(terminalId: number, title: string): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitTitle(title);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitTitle(title);
|
||||
}
|
||||
|
||||
public $sendProcessData(terminalId: number, data: string): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitData(data);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitData(data);
|
||||
}
|
||||
|
||||
public $sendProcessReady(terminalId: number, pid: number, cwd: string): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitReady(pid, cwd);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitReady(pid, cwd);
|
||||
}
|
||||
|
||||
public $sendProcessExit(terminalId: number, exitCode: number | undefined): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitExit(exitCode);
|
||||
this._terminalProcessProxies.delete(terminalId);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitExit(exitCode);
|
||||
}
|
||||
|
||||
public $sendOverrideDimensions(terminalId: number, dimensions: ITerminalDimensions | undefined): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitOverrideDimensions(dimensions);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitOverrideDimensions(dimensions);
|
||||
}
|
||||
|
||||
public $sendProcessInitialCwd(terminalId: number, initialCwd: string): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitInitialCwd(initialCwd);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitInitialCwd(initialCwd);
|
||||
}
|
||||
|
||||
public $sendProcessCwd(terminalId: number, cwd: string): void {
|
||||
const terminalProcess = this._terminalProcessProxies.get(terminalId);
|
||||
if (terminalProcess) {
|
||||
terminalProcess.emitCwd(cwd);
|
||||
}
|
||||
this._terminalProcessProxies.get(terminalId)?.emitCwd(cwd);
|
||||
}
|
||||
|
||||
public $sendResolvedLaunchConfig(terminalId: number, shellLaunchConfig: IShellLaunchConfig): void {
|
||||
const instance = this._terminalService.getInstanceFromId(terminalId);
|
||||
if (instance) {
|
||||
this._getTerminalProcess(terminalId)?.emitResolvedShellLaunchConfig(shellLaunchConfig);
|
||||
}
|
||||
this._getTerminalProcess(terminalId)?.emitResolvedShellLaunchConfig(shellLaunchConfig);
|
||||
}
|
||||
|
||||
private async _onRequestLatency(terminalId: number): Promise<void> {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { MainThreadWebviews, reviveWebviewContentOptions, reviveWebviewExtension } from 'vs/workbench/api/browser/mainThreadWebviews';
|
||||
|
@ -81,7 +81,6 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
|
|||
private readonly _webviewInputs = new WebviewInputStore();
|
||||
|
||||
private readonly _editorProviders = new Map<string, IDisposable>();
|
||||
private readonly _webviewFromDiffEditorHandles = new Set<string>();
|
||||
|
||||
private readonly _revivers = new Map<string, IDisposable>();
|
||||
|
||||
|
@ -99,18 +98,17 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
|
|||
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewPanels);
|
||||
|
||||
this._register(_editorService.onDidActiveEditorChange(() => {
|
||||
const activeInput = this._editorService.activeEditor;
|
||||
if (activeInput instanceof DiffEditorInput && activeInput.primary instanceof WebviewInput && activeInput.secondary instanceof WebviewInput) {
|
||||
this.registerWebviewFromDiffEditorListeners(activeInput);
|
||||
}
|
||||
|
||||
this.updateWebviewViewStates(activeInput);
|
||||
this.updateWebviewViewStates(this._editorService.activeEditor);
|
||||
}));
|
||||
|
||||
this._register(_editorService.onDidVisibleEditorsChange(() => {
|
||||
this.updateWebviewViewStates(this._editorService.activeEditor);
|
||||
}));
|
||||
|
||||
this._register(_webviewWorkbenchService.onDidChangeActiveWebviewEditor(input => {
|
||||
this.updateWebviewViewStates(input);
|
||||
}));
|
||||
|
||||
// This reviver's only job is to activate extensions.
|
||||
// This should trigger the real reviver to be registered from the extension host side.
|
||||
this._register(_webviewWorkbenchService.registerResolver({
|
||||
|
@ -260,27 +258,6 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
|
|||
this._revivers.delete(viewType);
|
||||
}
|
||||
|
||||
private registerWebviewFromDiffEditorListeners(diffEditorInput: DiffEditorInput): void {
|
||||
const primary = diffEditorInput.primary as WebviewInput;
|
||||
const secondary = diffEditorInput.secondary as WebviewInput;
|
||||
|
||||
if (this._webviewFromDiffEditorHandles.has(primary.id) || this._webviewFromDiffEditorHandles.has(secondary.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webviewFromDiffEditorHandles.add(primary.id);
|
||||
this._webviewFromDiffEditorHandles.add(secondary.id);
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
disposables.add(primary.webview.onDidFocus(() => this.updateWebviewViewStates(primary)));
|
||||
disposables.add(secondary.webview.onDidFocus(() => this.updateWebviewViewStates(secondary)));
|
||||
disposables.add(diffEditorInput.onWillDispose(() => {
|
||||
this._webviewFromDiffEditorHandles.delete(primary.id);
|
||||
this._webviewFromDiffEditorHandles.delete(secondary.id);
|
||||
dispose(disposables);
|
||||
}));
|
||||
}
|
||||
|
||||
private updateWebviewViewStates(activeEditorInput: IEditorInput | undefined) {
|
||||
if (!this._webviewInputs.size) {
|
||||
return;
|
||||
|
|
|
@ -208,8 +208,8 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
|
|||
|
||||
// --- trust ---
|
||||
|
||||
$requireWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState> {
|
||||
return this._workspaceTrustService.requireWorkspaceTrust(options);
|
||||
$requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState | undefined> {
|
||||
return this._workspaceTrustService.requestWorkspaceTrust(options);
|
||||
}
|
||||
|
||||
private getWorkspaceTrustState(): WorkspaceTrustState {
|
||||
|
|
|
@ -912,9 +912,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
checkProposedApiEnabled(extension);
|
||||
return extHostWorkspace.trustState;
|
||||
},
|
||||
requireWorkspaceTrust: (options?: vscode.WorkspaceTrustRequestOptions) => {
|
||||
requestWorkspaceTrust: (options?: vscode.WorkspaceTrustRequestOptions) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostWorkspace.requireWorkspaceTrust(options);
|
||||
return extHostWorkspace.requestWorkspaceTrust(options);
|
||||
},
|
||||
onDidChangeWorkspaceTrustState: (listener, thisArgs?, disposables?) => {
|
||||
return extHostWorkspace.onDidChangeWorkspaceTrustState(listener, thisArgs, disposables);
|
||||
|
|
|
@ -927,7 +927,7 @@ export interface MainThreadWorkspaceShape extends IDisposable {
|
|||
$saveAll(includeUntitled?: boolean): Promise<boolean>;
|
||||
$updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string; }[]): Promise<void>;
|
||||
$resolveProxy(url: string): Promise<string | undefined>;
|
||||
$requireWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState>;
|
||||
$requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState | undefined>;
|
||||
}
|
||||
|
||||
export interface IFileChangeDto {
|
||||
|
|
|
@ -225,6 +225,10 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
|||
}
|
||||
}
|
||||
|
||||
processBinary(data: string) {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
acknowledgeDataEvent(charCount: number): void {
|
||||
// No-op, flow control is not supported in extension owned terminals. If this is ever
|
||||
// implemented it will need new pause and resume VS Code APIs.
|
||||
|
|
|
@ -563,8 +563,8 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
|
|||
return this._workspaceTrustState;
|
||||
}
|
||||
|
||||
requireWorkspaceTrust(options?: vscode.WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState> {
|
||||
return this._proxy.$requireWorkspaceTrust(options);
|
||||
requestWorkspaceTrust(options?: vscode.WorkspaceTrustRequestOptions): Promise<WorkspaceTrustState | undefined> {
|
||||
return this._proxy.$requestWorkspaceTrust(options);
|
||||
}
|
||||
|
||||
$onDidChangeWorkspaceTrustState(state: WorkspaceTrustStateChangeEvent): void {
|
||||
|
|
|
@ -153,19 +153,19 @@ export class ExtHostTask extends ExtHostTaskBase {
|
|||
}
|
||||
};
|
||||
for (let variable of toResolve.variables) {
|
||||
result.variables[variable] = resolver.resolve(ws, variable);
|
||||
result.variables[variable] = await resolver.resolveAsync(ws, variable);
|
||||
}
|
||||
if (toResolve.process !== undefined) {
|
||||
let paths: string[] | undefined = undefined;
|
||||
if (toResolve.process.path !== undefined) {
|
||||
paths = toResolve.process.path.split(path.delimiter);
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
paths[i] = resolver.resolve(ws, paths[i]);
|
||||
paths[i] = await resolver.resolveAsync(ws, paths[i]);
|
||||
}
|
||||
}
|
||||
result.process = await win32.findExecutable(
|
||||
resolver.resolve(ws, toResolve.process.name),
|
||||
toResolve.process.cwd !== undefined ? resolver.resolve(ws, toResolve.process.cwd) : undefined,
|
||||
await resolver.resolveAsync(ws, toResolve.process.name),
|
||||
toResolve.process.cwd !== undefined ? await resolver.resolveAsync(ws, toResolve.process.cwd) : undefined,
|
||||
paths
|
||||
);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
|
|||
|
||||
protected async _beforeAlmostReadyToRunExtensions(): Promise<void> {
|
||||
const mainThreadConsole = this._extHostContext.getProxy(MainContext.MainThreadConsole);
|
||||
wrapConsoleMethods(mainThreadConsole);
|
||||
wrapConsoleMethods(mainThreadConsole, this._initData.environment.isExtensionDevelopmentDebug);
|
||||
|
||||
// initialize API and register actors
|
||||
const apiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors);
|
||||
|
@ -173,15 +173,19 @@ function ensureSuffix(path: string, suffix: string): string {
|
|||
}
|
||||
|
||||
// copied from bootstrap-fork.js
|
||||
function wrapConsoleMethods(service: MainThreadConsoleShape) {
|
||||
function wrapConsoleMethods(service: MainThreadConsoleShape, callToNative: boolean) {
|
||||
wrap('info', 'log');
|
||||
wrap('log', 'log');
|
||||
wrap('warn', 'warn');
|
||||
wrap('error', 'error');
|
||||
|
||||
function wrap(method: 'error' | 'warn' | 'info' | 'log', severity: 'error' | 'warn' | 'log') {
|
||||
const original = console[method];
|
||||
console[method] = function () {
|
||||
service.$logExtensionHostMessage({ type: '__$console', severity, arguments: safeToArray(arguments) });
|
||||
if (callToNative) {
|
||||
original.apply(console, arguments as any);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ class ViewMenuActions extends CompositeMenuActions {
|
|||
const scopedContextKeyService = contextKeyService.createScoped(element);
|
||||
scopedContextKeyService.createKey('view', viewId);
|
||||
const viewLocationKey = scopedContextKeyService.createKey('viewLocation', ViewContainerLocationToString(viewDescriptorService.getViewLocationById(viewId)!));
|
||||
super(menuId, contextMenuId, undefined, scopedContextKeyService, menuService);
|
||||
super(menuId, contextMenuId, { shouldForwardArgs: true }, scopedContextKeyService, menuService);
|
||||
this._register(scopedContextKeyService);
|
||||
this._register(Event.filter(viewDescriptorService.onDidChangeLocation, e => e.views.some(view => view.id === viewId))(() => viewLocationKey.set(ViewContainerLocationToString(viewDescriptorService.getViewLocationById(viewId)!))));
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ class ViewContainerMenuActions extends CompositeMenuActions {
|
|||
const scopedContextKeyService = contextKeyService.createScoped(element);
|
||||
scopedContextKeyService.createKey('viewContainer', viewContainer.id);
|
||||
const viewContainerLocationKey = scopedContextKeyService.createKey('viewContainerLocation', ViewContainerLocationToString(viewDescriptorService.getViewContainerLocation(viewContainer)!));
|
||||
super(MenuId.ViewContainerTitle, MenuId.ViewContainerTitleContext, undefined, scopedContextKeyService, menuService);
|
||||
super(MenuId.ViewContainerTitle, MenuId.ViewContainerTitleContext, { shouldForwardArgs: true }, scopedContextKeyService, menuService);
|
||||
this._register(scopedContextKeyService);
|
||||
this._register(Event.filter(viewDescriptorService.onDidChangeContainerLocation, e => e.viewContainer === viewContainer)(() => viewContainerLocationKey.set(ViewContainerLocationToString(viewDescriptorService.getViewContainerLocation(viewContainer)!))));
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import { IExtensionsViewPaneContainer, IExtensionsWorkbenchService, IExtension }
|
|||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { localize } from 'vs/nls';
|
||||
import { StorageScope, IStorageService, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ImportantExtensionTip, IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ImportantExtensionTip } from 'vs/base/common/product';
|
||||
import { forEach, IStringDictionary } from 'vs/base/common/collections';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
|
|
@ -270,7 +270,8 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
updateItems.push({
|
||||
output: key,
|
||||
cellTop: cellTop,
|
||||
outputOffset: outputOffset
|
||||
outputOffset: outputOffset,
|
||||
forceDisplay: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +281,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
removedItems.forEach(output => activeWebview.removeInset(output));
|
||||
|
||||
if (updateItems.length) {
|
||||
activeWebview.updateViewScrollTop(-scrollTop, false, updateItems);
|
||||
activeWebview.updateScrollTops(updateItems, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -575,10 +576,9 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
await activeWebview.createOutput({ diffElement: cellDiffViewModel, cellHandle: cellViewModel.handle, cellId: cellViewModel.id, cellUri: cellViewModel.uri }, output, cellTop, getOffset());
|
||||
} else {
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cellDiffViewModel);
|
||||
const scrollTop = this._list.scrollTop;
|
||||
const outputIndex = cellViewModel.outputsViewModels.indexOf(output.source);
|
||||
const outputOffset = cellTop + cellDiffViewModel.getOutputOffsetInCell(diffSide, outputIndex);
|
||||
activeWebview.updateViewScrollTop(-scrollTop, true, [{ output: output.source, cellTop, outputOffset }]);
|
||||
activeWebview.updateScrollTops([{ output: output.source, cellTop, outputOffset, forceDisplay: true }], []);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -622,10 +622,9 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
}
|
||||
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cellDiffViewModel);
|
||||
const scrollTop = this._list.scrollTop;
|
||||
const outputIndex = cellViewModel.outputsViewModels.indexOf(displayOutput);
|
||||
const outputOffset = cellTop + cellDiffViewModel.getOutputOffsetInCell(diffSide, outputIndex);
|
||||
activeWebview.updateViewScrollTop(-scrollTop, true, [{ output: displayOutput, cellTop, outputOffset }]);
|
||||
activeWebview.updateScrollTops([{ output: displayOutput, cellTop, outputOffset, forceDisplay: true }], []);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ export interface IDisplayOutputLayoutUpdateRequest {
|
|||
output: IDisplayOutputViewModel;
|
||||
cellTop: number;
|
||||
outputOffset: number;
|
||||
forceDisplay: boolean;
|
||||
}
|
||||
|
||||
export interface ICommonCellInfo {
|
||||
|
@ -480,7 +481,6 @@ export interface INotebookEditor extends ICommonNotebookEditor {
|
|||
unhideMarkdownPreview(cell: ICellViewModel): Promise<void>;
|
||||
hideMarkdownPreview(cell: ICellViewModel): Promise<void>;
|
||||
removeMarkdownPreview(cell: ICellViewModel): Promise<void>;
|
||||
updateMarkdownPreviewSelectionState(cell: ICellViewModel, isSelected: boolean): Promise<void>;
|
||||
|
||||
/**
|
||||
* Render the output in webview layer
|
||||
|
|
|
@ -1119,87 +1119,80 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
|
||||
this._localStore.add(this.viewModel.onDidChangeSelection(() => {
|
||||
this._onDidChangeSelection.fire();
|
||||
this.updateSelectedMarkdownPreviews();
|
||||
}));
|
||||
|
||||
this._localStore.add(this._list.onWillScroll(e => {
|
||||
if (this._webview?.isResolved()) {
|
||||
this._webview.updateViewScrollTop(-e.scrollTop, true, []);
|
||||
this._webviewTransparentCover!.style.top = `${e.scrollTop}px`;
|
||||
}
|
||||
}));
|
||||
|
||||
let hasPendingChangeContentHeight = false;
|
||||
this._localStore.add(this._list.onDidChangeContentHeight(() => {
|
||||
if (hasPendingChangeContentHeight) {
|
||||
return;
|
||||
}
|
||||
hasPendingChangeContentHeight = true;
|
||||
|
||||
DOM.scheduleAtNextAnimationFrame(() => {
|
||||
if (this._isDisposed) {
|
||||
hasPendingChangeContentHeight = false;
|
||||
if (this._isDisposed || !this._webview?.isResolved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scrollTop = this._list.scrollTop;
|
||||
const scrollHeight = this._list.scrollHeight;
|
||||
|
||||
if (!this._webview?.isResolved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webview!.element.style.height = `${scrollHeight}px`;
|
||||
|
||||
if (this._webview?.insetMapping) {
|
||||
const updateItems: IDisplayOutputLayoutUpdateRequest[] = [];
|
||||
const removedItems: ICellOutputViewModel[] = [];
|
||||
this._webview?.insetMapping.forEach((value, key) => {
|
||||
const cell = this.viewModel?.getCellByHandle(value.cellInfo.cellHandle);
|
||||
if (!cell || !(cell instanceof CodeCellViewModel)) {
|
||||
return;
|
||||
}
|
||||
const updateItems: IDisplayOutputLayoutUpdateRequest[] = [];
|
||||
const removedItems: ICellOutputViewModel[] = [];
|
||||
this._webview?.insetMapping.forEach((value, key) => {
|
||||
const cell = this.viewModel?.getCellByHandle(value.cellInfo.cellHandle);
|
||||
if (!cell || !(cell instanceof CodeCellViewModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewIndex = this._list.getViewIndex(cell);
|
||||
this.viewModel?.viewCells.find(cell => cell.handle === value.cellInfo.cellHandle);
|
||||
const viewIndex = this._list.getViewIndex(cell);
|
||||
|
||||
if (viewIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
if (viewIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell.outputsViewModels.indexOf(key) < 0) {
|
||||
// output is already gone
|
||||
removedItems.push(key);
|
||||
}
|
||||
if (cell.outputsViewModels.indexOf(key) < 0) {
|
||||
// output is already gone
|
||||
removedItems.push(key);
|
||||
}
|
||||
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
if (this._webview!.shouldUpdateInset(cell, key, cellTop)) {
|
||||
const outputIndex = cell.outputsViewModels.indexOf(key);
|
||||
|
||||
const outputOffset = cellTop + cell.getOutputOffset(outputIndex);
|
||||
|
||||
updateItems.push({
|
||||
output: key,
|
||||
cellTop: cellTop,
|
||||
outputOffset,
|
||||
forceDisplay: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
removedItems.forEach(output => this._webview?.removeInset(output));
|
||||
|
||||
const markdownUpdateItems: { id: string, top: number }[] = [];
|
||||
for (const cellId of this._webview.markdownPreviewMapping.keys()) {
|
||||
const cell = this.viewModel?.viewCells.find(cell => cell.id === cellId);
|
||||
if (cell) {
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
if (this._webview!.shouldUpdateInset(cell, key, cellTop)) {
|
||||
const outputIndex = cell.outputsViewModels.indexOf(key);
|
||||
|
||||
const outputOffset = cellTop + cell.getOutputOffset(outputIndex);
|
||||
|
||||
updateItems.push({
|
||||
output: key,
|
||||
cellTop: cellTop,
|
||||
outputOffset
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
removedItems.forEach(output => this._webview?.removeInset(output));
|
||||
|
||||
if (updateItems.length) {
|
||||
this._debug('_list.onDidChangeContentHeight/outputs', updateItems);
|
||||
this._webview?.updateViewScrollTop(-scrollTop, false, updateItems);
|
||||
markdownUpdateItems.push({ id: cellId, top: cellTop });
|
||||
}
|
||||
}
|
||||
|
||||
if (this._webview?.markdownPreviewMapping) {
|
||||
const updateItems: { id: string, top: number }[] = [];
|
||||
this._webview.markdownPreviewMapping.forEach((_, cellId) => {
|
||||
const cell = this.viewModel?.viewCells.find(cell => cell.id === cellId);
|
||||
if (cell) {
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
updateItems.push({ id: cellId, top: cellTop });
|
||||
}
|
||||
});
|
||||
|
||||
if (updateItems.length) {
|
||||
this._debug('_list.onDidChangeContentHeight/markdown', updateItems);
|
||||
this._webview?.updateMarkdownScrollTop(updateItems);
|
||||
}
|
||||
|
||||
if (markdownUpdateItems.length || updateItems.length) {
|
||||
this._debug('_list.onDidChangeContentHeight/markdown', markdownUpdateItems);
|
||||
this._webview?.updateScrollTops(updateItems, markdownUpdateItems);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
@ -1308,10 +1301,9 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
// no cached view state so we are rendering the first viewport
|
||||
// after above async call, we already get init height for markdown cells, we can update their offset
|
||||
let offset = 0;
|
||||
let offsetUpdateRequests: { id: string, top: number }[] = [];
|
||||
const offsetUpdateRequests: { id: string, top: number }[] = [];
|
||||
const scrollBottom = Math.max(this._dimension?.height ?? 0, 1080);
|
||||
for (let i = 0; i < viewModel.length; i++) {
|
||||
const cell = viewModel.cellAt(i)!;
|
||||
for (const cell of viewModel.viewCells) {
|
||||
if (cell.cellKind === CellKind.Markdown) {
|
||||
offsetUpdateRequests.push({ id: cell.id, top: offset });
|
||||
}
|
||||
|
@ -1323,7 +1315,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
}
|
||||
}
|
||||
|
||||
this._webview?.updateMarkdownScrollTop(offsetUpdateRequests);
|
||||
this._webview?.updateScrollTops([], offsetUpdateRequests);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2196,13 +2188,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
await this._webview?.removeMarkdownPreview(cell.id);
|
||||
}
|
||||
|
||||
async updateMarkdownPreviewSelectionState(cell: ICellViewModel, isSelected: boolean): Promise<void> {
|
||||
if (!this.useRenderer) {
|
||||
// TODO: handle case where custom renderer is disabled?
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._webview) {
|
||||
private async updateSelectedMarkdownPreviews(): Promise<void> {
|
||||
if (!this.useRenderer || !this._webview) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2210,7 +2197,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
await this._resolveWebview();
|
||||
}
|
||||
|
||||
await this._webview?.updateMarkdownPreviewSelectionState(cell.id, isSelected);
|
||||
const selectedCells = this.getSelectionViewModels().map(cell => cell.id);
|
||||
|
||||
// Only show selection when there is more than 1 cell selected
|
||||
await this._webview?.updateMarkdownPreviewSelections(selectedCells.length > 1 ? selectedCells : []);
|
||||
}
|
||||
|
||||
async createOutput(cell: CodeCellViewModel, output: IInsetRenderOutput, offset: number): Promise<void> {
|
||||
|
@ -2223,16 +2213,14 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
await this._resolveWebview();
|
||||
}
|
||||
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
if (!this._webview!.insetMapping.has(output.source)) {
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
await this._webview!.createOutput({ cellId: cell.id, cellHandle: cell.handle, cellUri: cell.uri }, output, cellTop, offset);
|
||||
} else {
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
const scrollTop = this._list.scrollTop;
|
||||
const outputIndex = cell.outputsViewModels.indexOf(output.source);
|
||||
const outputOffset = cellTop + cell.getOutputOffset(outputIndex);
|
||||
|
||||
this._webview!.updateViewScrollTop(-scrollTop, true, [{ output: output.source, cellTop, outputOffset }]);
|
||||
this._webview!.updateScrollTops([{ output: output.source, cellTop, outputOffset, forceDisplay: true }], []);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import { IWebviewService, WebviewContentPurpose, WebviewElement } from 'vs/workb
|
|||
import { asWebviewUri } from 'vs/workbench/contrib/webview/common/webviewUri';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
interface BaseToWebviewMessage {
|
||||
readonly __vscode_notebook_message: true;
|
||||
|
@ -35,14 +36,18 @@ export interface WebviewIntialized extends BaseToWebviewMessage {
|
|||
type: 'initialized';
|
||||
}
|
||||
|
||||
export interface IDimensionMessage extends BaseToWebviewMessage {
|
||||
type: 'dimension';
|
||||
export interface DimensionUpdate {
|
||||
id: string;
|
||||
init?: boolean;
|
||||
data: { height: number };
|
||||
isOutput?: boolean;
|
||||
}
|
||||
|
||||
export interface IDimensionMessage extends BaseToWebviewMessage {
|
||||
type: 'dimension';
|
||||
updates: readonly DimensionUpdate[];
|
||||
}
|
||||
|
||||
export interface IMouseEnterMessage extends BaseToWebviewMessage {
|
||||
type: 'mouseenter';
|
||||
id: string;
|
||||
|
@ -183,20 +188,13 @@ export interface ICreationRequestMessage {
|
|||
export interface IContentWidgetTopRequest {
|
||||
id: string;
|
||||
top: number;
|
||||
left: number;
|
||||
forceDisplay: boolean;
|
||||
}
|
||||
|
||||
export interface IViewScrollTopRequestMessage {
|
||||
type: 'view-scroll';
|
||||
top?: number;
|
||||
forceDisplay: boolean;
|
||||
widgets: IContentWidgetTopRequest[];
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface IViewScrollMarkdownRequestMessage {
|
||||
type: 'view-scroll-markdown';
|
||||
cells: { id: string; top: number }[];
|
||||
markdownPreviews: { id: string; top: number }[];
|
||||
}
|
||||
|
||||
export interface IScrollRequestMessage {
|
||||
|
@ -287,10 +285,9 @@ export interface IShowMarkdownMessage {
|
|||
top: number;
|
||||
}
|
||||
|
||||
export interface IUpdateMarkdownPreviewSelectionState {
|
||||
readonly type: 'updateMarkdownPreviewSelectionState',
|
||||
readonly id: string;
|
||||
readonly isSelected: boolean;
|
||||
export interface IUpdateSelectedMarkdownPreviews {
|
||||
readonly type: 'updateSelectedMarkdownPreviews',
|
||||
readonly selectedCellIds: readonly string[]
|
||||
}
|
||||
|
||||
export interface IInitializeMarkdownMessage {
|
||||
|
@ -337,9 +334,8 @@ export type ToWebviewMessage =
|
|||
| IShowMarkdownMessage
|
||||
| IHideMarkdownMessage
|
||||
| IUnhideMarkdownMessage
|
||||
| IUpdateMarkdownPreviewSelectionState
|
||||
| IInitializeMarkdownMessage
|
||||
| IViewScrollMarkdownRequestMessage;
|
||||
| IUpdateSelectedMarkdownPreviews
|
||||
| IInitializeMarkdownMessage;
|
||||
|
||||
export type AnyMessage = FromWebviewMessage | ToWebviewMessage;
|
||||
|
||||
|
@ -367,12 +363,11 @@ export interface IResolvedBackLayerWebview {
|
|||
webview: WebviewElement;
|
||||
}
|
||||
|
||||
let version = 0;
|
||||
export class BackLayerWebView<T extends ICommonCellInfo> extends Disposable {
|
||||
element: HTMLElement;
|
||||
webview: WebviewElement | undefined = undefined;
|
||||
insetMapping: Map<IDisplayOutputViewModel, ICachedInset<T>> = new Map();
|
||||
markdownPreviewMapping = new Map<string, { version: number, visible: boolean }>();
|
||||
readonly markdownPreviewMapping = new Map<string, { version: number, visible: boolean }>();
|
||||
hiddenInsetMapping: Set<IDisplayOutputViewModel> = new Set();
|
||||
reversedInsetMapping: Map<string, IDisplayOutputViewModel> = new Map();
|
||||
localResourceRootsCache: URI[] | undefined = undefined;
|
||||
|
@ -838,18 +833,20 @@ var requirejs = (function() {
|
|||
switch (data.type) {
|
||||
case 'dimension':
|
||||
{
|
||||
if (data.isOutput) {
|
||||
const height = data.data.height;
|
||||
const outputHeight = height;
|
||||
for (const update of data.updates) {
|
||||
if (update.isOutput) {
|
||||
const height = update.data.height;
|
||||
const outputHeight = height;
|
||||
|
||||
const resolvedResult = this.resolveOutputId(data.id);
|
||||
if (resolvedResult) {
|
||||
const { cellInfo, output } = resolvedResult;
|
||||
this.notebookEditor.updateOutputHeight(cellInfo, output, outputHeight, !!data.init, 'webview#dimension');
|
||||
const resolvedResult = this.resolveOutputId(update.id);
|
||||
if (resolvedResult) {
|
||||
const { cellInfo, output } = resolvedResult;
|
||||
this.notebookEditor.updateOutputHeight(cellInfo, output, outputHeight, !!update.init, 'webview#dimension');
|
||||
}
|
||||
} else {
|
||||
const cellId = update.id.substr(0, update.id.length - '_preview'.length);
|
||||
this.notebookEditor.updateMarkdownCellHeight(cellId, update.data.height, !!update.init);
|
||||
}
|
||||
} else {
|
||||
const cellId = data.id.substr(0, data.id.length - '_preview'.length);
|
||||
this.notebookEditor.updateMarkdownCellHeight(cellId, data.data.height, !!data.init);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1109,20 +1106,16 @@ var requirejs = (function() {
|
|||
return true;
|
||||
}
|
||||
|
||||
updateMarkdownScrollTop(items: { id: string, top: number }[]) {
|
||||
this._sendMessageToWebview({
|
||||
type: 'view-scroll-markdown',
|
||||
cells: items
|
||||
});
|
||||
}
|
||||
|
||||
updateViewScrollTop(top: number, forceDisplay: boolean, items: IDisplayOutputLayoutUpdateRequest[]) {
|
||||
updateScrollTops(outputs: IDisplayOutputLayoutUpdateRequest[], markdownPreviews: { id: string, top: number }[]) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const widgets: IContentWidgetTopRequest[] = items.map(item => {
|
||||
const outputCache = this.insetMapping.get(item.output)!;
|
||||
const widgets = coalesce(outputs.map((item): IContentWidgetTopRequest | undefined => {
|
||||
const outputCache = this.insetMapping.get(item.output);
|
||||
if (!outputCache) {
|
||||
return;
|
||||
}
|
||||
const id = outputCache.outputId;
|
||||
const outputOffset = item.outputOffset;
|
||||
outputCache.cachedCreation.top = outputOffset;
|
||||
|
@ -1131,16 +1124,18 @@ var requirejs = (function() {
|
|||
return {
|
||||
id: id,
|
||||
top: outputOffset,
|
||||
left: 0
|
||||
forceDisplay: item.forceDisplay,
|
||||
};
|
||||
});
|
||||
}));
|
||||
|
||||
if (!widgets.length && !markdownPreviews.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToWebview({
|
||||
top,
|
||||
type: 'view-scroll',
|
||||
version: version++,
|
||||
forceDisplay,
|
||||
widgets: widgets
|
||||
widgets: widgets,
|
||||
markdownPreviews,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1256,21 +1251,14 @@ var requirejs = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
async updateMarkdownPreviewSelectionState(cellId: any, isSelected: boolean) {
|
||||
async updateMarkdownPreviewSelections(selectedCellsIds: string[]) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.markdownPreviewMapping.has(cellId)) {
|
||||
// TODO: this currently seems expected on first load
|
||||
// console.error(`Try to update selection state for preview that does not exist: ${cellId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendMessageToWebview({
|
||||
type: 'updateMarkdownPreviewSelectionState',
|
||||
id: cellId,
|
||||
isSelected
|
||||
type: 'updateSelectedMarkdownPreviews',
|
||||
selectedCellIds: selectedCellsIds.filter(id => this.markdownPreviewMapping.has(id)),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -198,15 +198,6 @@ export class StatefulMarkdownCell extends Disposable {
|
|||
if (this.viewCell.layoutInfo.totalHeight > 0) {
|
||||
this.relayoutCell();
|
||||
}
|
||||
|
||||
// Update for selection
|
||||
this._register(this.notebookEditor.onDidChangeSelection(() => {
|
||||
const selectedCells = this.notebookEditor.getSelectionViewModels();
|
||||
|
||||
// Only show selection if there are more than one cells selected
|
||||
const isSelected = selectedCells.length > 1 && selectedCells.some(selectedCell => selectedCell === viewCell);
|
||||
this.notebookEditor.updateMarkdownPreviewSelectionState(viewCell, isSelected);
|
||||
}));
|
||||
}
|
||||
|
||||
// apply decorations
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import type { Event } from 'vs/base/common/event';
|
||||
import type { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { FromWebviewMessage, IBlurOutputMessage, ICellDropMessage, ICellDragMessage, ICellDragStartMessage, IClickedDataUrlMessage, ICustomRendererMessage, IDimensionMessage, IClickMarkdownPreviewMessage, IMouseEnterMarkdownPreviewMessage, IMouseEnterMessage, IMouseLeaveMarkdownPreviewMessage, IMouseLeaveMessage, IToggleMarkdownPreviewMessage, IWheelMessage, ToWebviewMessage, ICellDragEndMessage, IOutputFocusMessage, IOutputBlurMessage } from 'vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView';
|
||||
import { FromWebviewMessage, IBlurOutputMessage, ICellDropMessage, ICellDragMessage, ICellDragStartMessage, IClickedDataUrlMessage, ICustomRendererMessage, IDimensionMessage, IClickMarkdownPreviewMessage, IMouseEnterMarkdownPreviewMessage, IMouseEnterMessage, IMouseLeaveMarkdownPreviewMessage, IMouseLeaveMessage, IToggleMarkdownPreviewMessage, IWheelMessage, ToWebviewMessage, ICellDragEndMessage, IOutputFocusMessage, IOutputBlurMessage, DimensionUpdate } from 'vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView';
|
||||
|
||||
// !! IMPORTANT !! everything must be in-line within the webviewPreloads
|
||||
// function. Imports are not allowed. This is stringifies and injected into
|
||||
|
@ -136,6 +136,26 @@ function webviewPreloads() {
|
|||
|
||||
const outputObservers = new Map<string, ResizeObserver>();
|
||||
|
||||
const dimensionUpdater = new class {
|
||||
private readonly pending = new Map<string, DimensionUpdate>();
|
||||
|
||||
update(id: string, update: DimensionUpdate) {
|
||||
if (!this.pending.size) {
|
||||
setTimeout(() => {
|
||||
if (!this.pending.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
updates: Array.from(this.pending.values())
|
||||
});
|
||||
this.pending.clear();
|
||||
}, 0);
|
||||
}
|
||||
this.pending.set(id, update);
|
||||
}
|
||||
};
|
||||
|
||||
const resizeObserve = (container: Element, id: string, output: boolean) => {
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
for (const entry of entries) {
|
||||
|
@ -145,27 +165,20 @@ function webviewPreloads() {
|
|||
|
||||
if (entry.target.id === id && entry.contentRect) {
|
||||
if (output) {
|
||||
let height = 0;
|
||||
if (entry.contentRect.height !== 0) {
|
||||
entry.target.style.padding = `${__outputNodePadding__}px ${__outputNodePadding__}px ${__outputNodePadding__}px ${output ? __outputNodeLeftPadding__ : __leftMargin__}px`;
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
id: id,
|
||||
data: {
|
||||
height: entry.contentRect.height + __outputNodePadding__ * 2
|
||||
},
|
||||
isOutput: true
|
||||
});
|
||||
height = entry.contentRect.height + __outputNodePadding__ * 2;
|
||||
} else {
|
||||
entry.target.style.padding = `0px`;
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
id: id,
|
||||
data: {
|
||||
height: entry.contentRect.height
|
||||
},
|
||||
isOutput: true
|
||||
});
|
||||
}
|
||||
dimensionUpdater.update(id, {
|
||||
id: id,
|
||||
data: { height },
|
||||
isOutput: true
|
||||
});
|
||||
} else {
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
dimensionUpdater.update(id, {
|
||||
id: id,
|
||||
data: {
|
||||
// entry.contentRect does not include padding
|
||||
|
@ -537,12 +550,22 @@ function webviewPreloads() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'updateMarkdownPreviewSelectionState':
|
||||
case 'updateSelectedMarkdownPreviews':
|
||||
{
|
||||
const data = event.data;
|
||||
const previewNode = document.getElementById(`${data.id}_preview`);
|
||||
if (previewNode) {
|
||||
previewNode.classList.toggle('selected', data.isSelected);
|
||||
const selectedCellIds = new Set<string>(event.data.selectedCellIds);
|
||||
|
||||
for (const oldSelected of document.querySelectorAll('.preview.selected')) {
|
||||
const id = oldSelected.id.replace('_preview', '');
|
||||
if (!selectedCellIds.has(id)) {
|
||||
oldSelected.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
|
||||
for (const newSelected of selectedCellIds) {
|
||||
const previewNode = document.getElementById(`${newSelected}_preview`);
|
||||
if (previewNode) {
|
||||
previewNode.classList.add('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -634,7 +657,7 @@ function webviewPreloads() {
|
|||
if (clientHeight !== 0 && cps.padding === '0px') {
|
||||
// we set padding to zero if the output height is zero (then we can have a zero-height output DOM node)
|
||||
// thus we need to ensure the padding is accounted when updating the init height of the output
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
dimensionUpdater.update(outputId, {
|
||||
id: outputId,
|
||||
isOutput: true,
|
||||
init: true,
|
||||
|
@ -645,7 +668,7 @@ function webviewPreloads() {
|
|||
|
||||
outputNode.style.padding = `${__outputNodePadding__}px ${__outputNodePadding__}px ${__outputNodePadding__}px ${__outputNodeLeftPadding__}px`;
|
||||
} else {
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
dimensionUpdater.update(outputId, {
|
||||
id: outputId,
|
||||
isOutput: true,
|
||||
init: true,
|
||||
|
@ -656,7 +679,7 @@ function webviewPreloads() {
|
|||
}
|
||||
|
||||
// don't hide until after this step so that the height is right
|
||||
cellOutputContainer.style.display = data.initiallyHidden ? 'none' : 'block';
|
||||
cellOutputContainer.style.visibility = data.initiallyHidden ? 'hidden' : 'visible';
|
||||
});
|
||||
break;
|
||||
case 'view-scroll':
|
||||
|
@ -664,34 +687,22 @@ function webviewPreloads() {
|
|||
// const date = new Date();
|
||||
// console.log('----- will scroll ---- ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
|
||||
for (let i = 0; i < event.data.widgets.length; i++) {
|
||||
const widget = document.getElementById(event.data.widgets[i].id)!;
|
||||
for (const request of event.data.widgets) {
|
||||
const widget = document.getElementById(request.id)!;
|
||||
if (widget) {
|
||||
widget.style.top = event.data.widgets[i].top + 'px';
|
||||
if (event.data.forceDisplay) {
|
||||
widget.parentElement!.style.display = 'block';
|
||||
widget.style.top = request.top + 'px';
|
||||
if (request.forceDisplay) {
|
||||
widget.parentElement!.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'view-scroll-markdown':
|
||||
{
|
||||
// const date = new Date();
|
||||
// console.log(`${date.getSeconds()}:${date.getMilliseconds().toString().padStart(3, '0')}`, '[iframe]: view-scroll-markdown', event.data.cells);
|
||||
event.data.cells.map(cell => {
|
||||
const widget = document.getElementById(`${cell.id}_preview`)!;
|
||||
|
||||
for (const cell of event.data.markdownPreviews) {
|
||||
const widget = document.getElementById(`${cell.id}_preview`)!;
|
||||
if (widget) {
|
||||
widget.style.top = `${cell.top}px`;
|
||||
}
|
||||
|
||||
const markdownPreview = document.getElementById(`${cell.id}`);
|
||||
|
||||
if (markdownPreview) {
|
||||
markdownPreview.style.display = 'block';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -721,7 +732,7 @@ function webviewPreloads() {
|
|||
enqueueOutputAction(event.data, ({ outputId }) => {
|
||||
const container = document.getElementById(outputId)?.parentElement;
|
||||
if (container) {
|
||||
container.style.display = 'none';
|
||||
container.style.visibility = 'hidden';
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -729,10 +740,10 @@ function webviewPreloads() {
|
|||
enqueueOutputAction(event.data, ({ outputId, top }) => {
|
||||
const output = document.getElementById(outputId);
|
||||
if (output) {
|
||||
output.parentElement!.style.display = 'block';
|
||||
output.parentElement!.style.visibility = 'visible';
|
||||
output.style.top = top + 'px';
|
||||
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
dimensionUpdater.update(outputId, {
|
||||
id: outputId,
|
||||
isOutput: true,
|
||||
data: {
|
||||
|
@ -767,13 +778,8 @@ function webviewPreloads() {
|
|||
case 'decorations':
|
||||
{
|
||||
const outputContainer = document.getElementById(event.data.cellId);
|
||||
event.data.addedClassNames.forEach(n => {
|
||||
outputContainer?.classList.add(n);
|
||||
});
|
||||
|
||||
event.data.removedClassNames.forEach(n => {
|
||||
outputContainer?.classList.remove(n);
|
||||
});
|
||||
outputContainer?.classList.add(...event.data.addedClassNames);
|
||||
outputContainer?.classList.remove(...event.data.removedClassNames);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -839,8 +845,7 @@ function webviewPreloads() {
|
|||
|
||||
cellContainer.appendChild(previewContainerNode);
|
||||
|
||||
previewContainerNode.attachShadow({ mode: 'open' });
|
||||
const previewRoot = previewContainerNode.shadowRoot! as any as HTMLElement;
|
||||
const previewRoot = previewContainerNode.attachShadow({ mode: 'open' });
|
||||
|
||||
// Add default webview style
|
||||
const defaultStyles = document.getElementById('_defaultStyles') as HTMLStyleElement;
|
||||
|
@ -894,7 +899,7 @@ function webviewPreloads() {
|
|||
}
|
||||
}
|
||||
|
||||
postNotebookMessage<IDimensionMessage>('dimension', {
|
||||
dimensionUpdater.update(`${cellId}_preview`, {
|
||||
id: `${cellId}_preview`,
|
||||
data: {
|
||||
height: previewContainerNode.clientHeight,
|
||||
|
|
|
@ -104,7 +104,6 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
|||
this._model.setMode(e);
|
||||
}
|
||||
}));
|
||||
this._modelDisposables.push(langId);
|
||||
this._modelDisposables.push(this._extensionService.onDidChangeExtensionsStatus(this._updateModel, this));
|
||||
|
||||
writeTransientState(this._model, { wordWrapOverride: 'off' }, this._editorService);
|
||||
|
|
|
@ -1025,24 +1025,21 @@ export class DefaultPreferencesEditor extends BaseTextEditor {
|
|||
return options;
|
||||
}
|
||||
|
||||
setInput(input: DefaultPreferencesEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
return super.setInput(input, options, context, token)
|
||||
.then(() => this.input!.resolve()
|
||||
.then<any>(editorModel => {
|
||||
if (token.isCancellationRequested) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return editorModel!.resolve();
|
||||
})
|
||||
.then(editorModel => {
|
||||
if (token.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
const editor = assertIsDefined(this.getControl());
|
||||
editor.setModel((<ResourceEditorModel>editorModel).textEditorModel);
|
||||
}));
|
||||
async setInput(input: DefaultPreferencesEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, context, token);
|
||||
const editorModel = await this.input!.resolve();
|
||||
if (!editorModel) {
|
||||
return;
|
||||
}
|
||||
if (token.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
await editorModel.resolve();
|
||||
if (token.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
const editor = assertIsDefined(this.getControl());
|
||||
editor.setModel((<ResourceEditorModel>editorModel).textEditorModel);
|
||||
}
|
||||
|
||||
clearInput(): void {
|
||||
|
|
|
@ -94,11 +94,11 @@ export class ForwardedPortsView extends Disposable implements IWorkbenchContribu
|
|||
private enableBadgeAndStatusBar() {
|
||||
const disposable = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).onViewsRegistered(e => {
|
||||
if (e.find(view => view.views.find(viewDescriptor => viewDescriptor.id === TUNNEL_VIEW_ID))) {
|
||||
this._register(this.remoteExplorerService.tunnelModel.onForwardPort(() => {
|
||||
this._register(Event.debounce(this.remoteExplorerService.tunnelModel.onForwardPort, (_last, e) => e, 50)(() => {
|
||||
this.updateActivityBadge();
|
||||
this.updateStatusBar();
|
||||
}));
|
||||
this._register(this.remoteExplorerService.tunnelModel.onClosePort(() => {
|
||||
this._register(Event.debounce(this.remoteExplorerService.tunnelModel.onClosePort, (_last, e) => e, 50)(() => {
|
||||
this.updateActivityBadge();
|
||||
this.updateStatusBar();
|
||||
}));
|
||||
|
|
|
@ -664,6 +664,10 @@ export class TunnelPanel extends ViewPane {
|
|||
}));
|
||||
}
|
||||
|
||||
get portCount(): number {
|
||||
return this.remoteExplorerService.tunnelModel.forwarded.size + this.remoteExplorerService.tunnelModel.detected.size;
|
||||
}
|
||||
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
super.renderBody(container);
|
||||
|
||||
|
@ -719,8 +723,12 @@ export class TunnelPanel extends ViewPane {
|
|||
const rerender = () => this.table.splice(0, Number.POSITIVE_INFINITY, this.viewModel.all);
|
||||
|
||||
rerender();
|
||||
this._register(this.viewModel.onForwardedPortsChanged(() => {
|
||||
this._onDidChangeViewWelcomeState.fire();
|
||||
let lastPortCount = this.portCount;
|
||||
this._register(Event.debounce(this.viewModel.onForwardedPortsChanged, (_last, e) => e, 50)(() => {
|
||||
const newPortCount = this.portCount;
|
||||
if (((lastPortCount === 0) || (newPortCount === 0)) && (lastPortCount !== newPortCount)) {
|
||||
this._onDidChangeViewWelcomeState.fire();
|
||||
}
|
||||
rerender();
|
||||
}));
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions as
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ISurveyData, IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ISurveyData } from 'vs/base/common/product';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { ITextFileService, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
|
|
@ -2058,6 +2058,15 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
|||
let workspaceFolder: IWorkspaceFolder = this.contextService.getWorkspace().folders[0];
|
||||
workspaceFolders.push(workspaceFolder);
|
||||
executionEngine = this.computeExecutionEngine(workspaceFolder);
|
||||
const telemetryData: { [key: string]: any; } = {
|
||||
executionEngineVersion: executionEngine
|
||||
};
|
||||
/* __GDPR__
|
||||
"taskService.engineVersion" : {
|
||||
"executionEngineVersion" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('taskService.engineVersion', telemetryData);
|
||||
schemaVersion = this.computeJsonSchemaVersion(workspaceFolder);
|
||||
} else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
|
||||
workspace = this.contextService.getWorkspace();
|
||||
|
|
|
@ -116,7 +116,7 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
|
|||
|
||||
public static async promptForPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustService: IWorkspaceTrustService,
|
||||
openerService: IOpenerService, workspaceTaskResult: Map<string, WorkspaceFolderTaskResult>) {
|
||||
const isWorkspaceTrusted = await workspaceTrustService.requireWorkspaceTrust({ modal: false }) === WorkspaceTrustState.Trusted;
|
||||
const isWorkspaceTrusted = await workspaceTrustService.requestWorkspaceTrust({ modal: false }) === WorkspaceTrustState.Trusted;
|
||||
if (!isWorkspaceTrusted) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -81,21 +81,30 @@ class InstanceManager {
|
|||
}
|
||||
|
||||
class VariableResolver {
|
||||
|
||||
private static regex = /\$\{(.*?)\}/g;
|
||||
constructor(public workspaceFolder: IWorkspaceFolder | undefined, public taskSystemInfo: TaskSystemInfo | undefined, public readonly values: Map<string, string>, private _service: IConfigurationResolverService | undefined) {
|
||||
}
|
||||
resolve(value: string): string {
|
||||
return value.replace(/\$\{(.*?)\}/g, (match: string, variable: string) => {
|
||||
// Strip out the ${} because the map contains them variables without those characters.
|
||||
let result = this.values.get(match.substring(2, match.length - 1));
|
||||
if ((result !== undefined) && (result !== null)) {
|
||||
return result;
|
||||
}
|
||||
if (this._service) {
|
||||
return this._service.resolve(this.workspaceFolder, match);
|
||||
}
|
||||
async resolve(value: string): Promise<string> {
|
||||
const replacers: Promise<string>[] = [];
|
||||
value.replace(VariableResolver.regex, (match, ...args) => {
|
||||
replacers.push(this.replacer(match, args));
|
||||
return match;
|
||||
});
|
||||
const resolvedReplacers = await Promise.all(replacers);
|
||||
return value.replace(VariableResolver.regex, () => resolvedReplacers.shift()!);
|
||||
|
||||
}
|
||||
|
||||
private async replacer(match: string, args: string[]): Promise<string> {
|
||||
// Strip out the ${} because the map contains them variables without those characters.
|
||||
let result = this.values.get(match.substring(2, match.length - 1));
|
||||
if ((result !== undefined) && (result !== null)) {
|
||||
return result;
|
||||
}
|
||||
if (this._service) {
|
||||
return this._service.resolveAsync(this.workspaceFolder, match);
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,9 +543,9 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
}
|
||||
|
||||
private async resolveAndFindExecutable(systemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, cwd: string | undefined, envPath: string | undefined): Promise<string> {
|
||||
const command = this.configurationResolverService.resolve(workspaceFolder, CommandString.value(task.command.name!));
|
||||
cwd = cwd ? this.configurationResolverService.resolve(workspaceFolder, cwd) : undefined;
|
||||
const paths = envPath ? envPath.split(path.delimiter).map(p => this.configurationResolverService.resolve(workspaceFolder, p)) : undefined;
|
||||
const command = await this.configurationResolverService.resolveAsync(workspaceFolder, CommandString.value(task.command.name!));
|
||||
cwd = cwd ? await this.configurationResolverService.resolveAsync(workspaceFolder, cwd) : undefined;
|
||||
const paths = envPath ? await Promise.all(envPath.split(path.delimiter).map(p => this.configurationResolverService.resolveAsync(workspaceFolder, p))) : undefined;
|
||||
let foundExecutable = await systemInfo?.findExecutable(command, cwd, paths);
|
||||
if (!foundExecutable) {
|
||||
foundExecutable = path.join(cwd ?? '', command);
|
||||
|
@ -633,7 +642,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
if (Platform.isWindows) {
|
||||
processVarValue = await this.resolveAndFindExecutable(taskSystemInfo, workspaceFolder, task, cwd, envPath);
|
||||
} else {
|
||||
processVarValue = this.configurationResolverService.resolve(workspaceFolder, CommandString.value(task.command.name!));
|
||||
processVarValue = await this.configurationResolverService.resolveAsync(workspaceFolder, CommandString.value(task.command.name!));
|
||||
}
|
||||
resolvedVariablesMap.set(TerminalTaskSystem.ProcessVarName, processVarValue);
|
||||
}
|
||||
|
@ -726,7 +735,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
let error: TaskError | undefined = undefined;
|
||||
let promise: Promise<ITaskSummary> | undefined = undefined;
|
||||
if (task.configurationProperties.isBackground) {
|
||||
const problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers);
|
||||
const problemMatchers = await this.resolveMatchers(resolver, task.configurationProperties.problemMatchers);
|
||||
let watchingProblemMatcher = new WatchingProblemCollector(problemMatchers, this.markerService, this.modelService, this.fileService);
|
||||
if ((problemMatchers.length > 0) && !watchingProblemMatcher.isWatching()) {
|
||||
this.appendOutput(nls.localize('TerminalTaskSystem.nonWatchingMatcher', 'Task {0} is a background task but uses a problem matcher without a background pattern', task._label));
|
||||
|
@ -871,7 +880,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
const mapKey = task.getMapKey();
|
||||
this.busyTasks[mapKey] = task;
|
||||
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task));
|
||||
let problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers);
|
||||
let problemMatchers = await this.resolveMatchers(resolver, task.configurationProperties.problemMatchers);
|
||||
let startStopProblemMatcher = new StartStopProblemCollector(problemMatchers, this.markerService, this.modelService, ProblemHandlingStrategy.Clean, this.fileService);
|
||||
let skipLine: boolean = (!!task.command.presentation && task.command.presentation.echo);
|
||||
const onData = terminal.onLineData((line) => {
|
||||
|
@ -1006,11 +1015,11 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell;
|
||||
if (shellOptions) {
|
||||
if (shellOptions.executable) {
|
||||
shellLaunchConfig.executable = this.resolveVariable(variableResolver, shellOptions.executable);
|
||||
shellLaunchConfig.executable = await this.resolveVariable(variableResolver, shellOptions.executable);
|
||||
shellSpecified = true;
|
||||
}
|
||||
if (shellOptions.args) {
|
||||
shellLaunchConfig.args = this.resolveVariables(variableResolver, shellOptions.args.slice());
|
||||
shellLaunchConfig.args = await this.resolveVariables(variableResolver, shellOptions.args.slice());
|
||||
} else {
|
||||
shellLaunchConfig.args = [];
|
||||
}
|
||||
|
@ -1082,7 +1091,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
} else {
|
||||
let commandExecutable = (task.command.runtime !== RuntimeType.CustomExecution) ? CommandString.value(command) : undefined;
|
||||
let executable = !isShellCommand
|
||||
? this.resolveVariable(variableResolver, this.resolveVariable(variableResolver, '${' + TerminalTaskSystem.ProcessVarName + '}'))
|
||||
? await this.resolveVariable(variableResolver, await this.resolveVariable(variableResolver, '${' + TerminalTaskSystem.ProcessVarName + '}'))
|
||||
: commandExecutable;
|
||||
|
||||
// When we have a process task there is no need to quote arguments. So we go ahead and take the string value.
|
||||
|
@ -1129,7 +1138,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
|
||||
private async createTerminal(task: CustomTask | ContributedTask, resolver: VariableResolver, workspaceFolder: IWorkspaceFolder | undefined): Promise<[ITerminalInstance | undefined, string | undefined, TaskError | undefined]> {
|
||||
let platform = resolver.taskSystemInfo ? resolver.taskSystemInfo.platform : Platform.platform;
|
||||
let options = this.resolveOptions(resolver, task.command.options);
|
||||
let options = await this.resolveOptions(resolver, task.command.options);
|
||||
|
||||
let waitOnExit: boolean | string = false;
|
||||
const presentationOptions = task.command.presentation;
|
||||
|
@ -1161,7 +1170,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
isFeatureTerminal: true
|
||||
};
|
||||
} else {
|
||||
let resolvedResult: { command: CommandString, args: CommandString[] } = this.resolveCommandAndArgs(resolver, task.command);
|
||||
let resolvedResult: { command: CommandString, args: CommandString[] } = await this.resolveCommandAndArgs(resolver, task.command);
|
||||
command = resolvedResult.command;
|
||||
args = resolvedResult.args;
|
||||
commandExecutable = CommandString.value(command);
|
||||
|
@ -1466,26 +1475,26 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
} while (matches);
|
||||
}
|
||||
|
||||
private resolveCommandAndArgs(resolver: VariableResolver, commandConfig: CommandConfiguration): { command: CommandString, args: CommandString[] } {
|
||||
private async resolveCommandAndArgs(resolver: VariableResolver, commandConfig: CommandConfiguration): Promise<{ command: CommandString, args: CommandString[] }> {
|
||||
// First we need to use the command args:
|
||||
let args: CommandString[] = commandConfig.args ? commandConfig.args.slice() : [];
|
||||
args = this.resolveVariables(resolver, args);
|
||||
let command: CommandString = this.resolveVariable(resolver, commandConfig.name);
|
||||
args = await this.resolveVariables(resolver, args);
|
||||
let command: CommandString = await this.resolveVariable(resolver, commandConfig.name);
|
||||
return { command, args };
|
||||
}
|
||||
|
||||
private resolveVariables(resolver: VariableResolver, value: string[]): string[];
|
||||
private resolveVariables(resolver: VariableResolver, value: CommandString[]): CommandString[];
|
||||
private resolveVariables(resolver: VariableResolver, value: CommandString[]): CommandString[] {
|
||||
return value.map(s => this.resolveVariable(resolver, s));
|
||||
private async resolveVariables(resolver: VariableResolver, value: string[]): Promise<string[]>;
|
||||
private async resolveVariables(resolver: VariableResolver, value: CommandString[]): Promise<CommandString[]>;
|
||||
private async resolveVariables(resolver: VariableResolver, value: CommandString[]): Promise<CommandString[]> {
|
||||
return Promise.all(value.map(s => this.resolveVariable(resolver, s)));
|
||||
}
|
||||
|
||||
private resolveMatchers(resolver: VariableResolver, values: Array<string | ProblemMatcher> | undefined): ProblemMatcher[] {
|
||||
private async resolveMatchers(resolver: VariableResolver, values: Array<string | ProblemMatcher> | undefined): Promise<ProblemMatcher[]> {
|
||||
if (values === undefined || values === null || values.length === 0) {
|
||||
return [];
|
||||
}
|
||||
let result: ProblemMatcher[] = [];
|
||||
values.forEach((value) => {
|
||||
for (const value of values) {
|
||||
let matcher: ProblemMatcher;
|
||||
if (Types.isString(value)) {
|
||||
if (value[0] === '$') {
|
||||
|
@ -1498,7 +1507,7 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
}
|
||||
if (!matcher) {
|
||||
this.appendOutput(nls.localize('unknownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored'));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
let taskSystemInfo: TaskSystemInfo | undefined = resolver.taskSystemInfo;
|
||||
let hasFilePrefix = matcher.filePrefix !== undefined;
|
||||
|
@ -1511,23 +1520,23 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
copy.uriProvider = taskSystemInfo.uriProvider;
|
||||
}
|
||||
if (hasFilePrefix) {
|
||||
copy.filePrefix = this.resolveVariable(resolver, copy.filePrefix);
|
||||
copy.filePrefix = await this.resolveVariable(resolver, copy.filePrefix);
|
||||
}
|
||||
result.push(copy);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private resolveVariable(resolver: VariableResolver, value: string | undefined): string;
|
||||
private resolveVariable(resolver: VariableResolver, value: CommandString | undefined): CommandString;
|
||||
private resolveVariable(resolver: VariableResolver, value: CommandString | undefined): CommandString {
|
||||
private async resolveVariable(resolver: VariableResolver, value: string | undefined): Promise<string>;
|
||||
private async resolveVariable(resolver: VariableResolver, value: CommandString | undefined): Promise<CommandString>;
|
||||
private async resolveVariable(resolver: VariableResolver, value: CommandString | undefined): Promise<CommandString> {
|
||||
// TODO@Dirk Task.getWorkspaceFolder should return a WorkspaceFolder that is defined in workspace.ts
|
||||
if (Types.isString(value)) {
|
||||
return resolver.resolve(value);
|
||||
} else if (value !== undefined) {
|
||||
return {
|
||||
value: resolver.resolve(value.value),
|
||||
value: await resolver.resolve(value.value),
|
||||
quoting: value.quoting
|
||||
};
|
||||
} else { // This should never happen
|
||||
|
@ -1535,29 +1544,29 @@ export class TerminalTaskSystem implements ITaskSystem {
|
|||
}
|
||||
}
|
||||
|
||||
private resolveOptions(resolver: VariableResolver, options: CommandOptions | undefined): CommandOptions {
|
||||
private async resolveOptions(resolver: VariableResolver, options: CommandOptions | undefined): Promise<CommandOptions> {
|
||||
if (options === undefined || options === null) {
|
||||
let cwd: string | undefined;
|
||||
try {
|
||||
cwd = this.resolveVariable(resolver, '${workspaceFolder}');
|
||||
cwd = await this.resolveVariable(resolver, '${workspaceFolder}');
|
||||
} catch (e) {
|
||||
// No workspace
|
||||
}
|
||||
return { cwd };
|
||||
}
|
||||
let result: CommandOptions = Types.isString(options.cwd)
|
||||
? { cwd: this.resolveVariable(resolver, options.cwd) }
|
||||
: { cwd: this.resolveVariable(resolver, '${workspaceFolder}') };
|
||||
? { cwd: await this.resolveVariable(resolver, options.cwd) }
|
||||
: { cwd: await this.resolveVariable(resolver, '${workspaceFolder}') };
|
||||
if (options.env) {
|
||||
result.env = Object.create(null);
|
||||
Object.keys(options.env).forEach((key) => {
|
||||
for (const key of Object.keys(options.env)) {
|
||||
let value: any = options.env![key];
|
||||
if (Types.isString(value)) {
|
||||
result.env![key] = this.resolveVariable(resolver, value);
|
||||
result.env![key] = await this.resolveVariable(resolver, value);
|
||||
} else {
|
||||
result.env![key] = value.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
|
|||
|
||||
public readonly _onProcessData = this._register(new Emitter<string | IProcessDataEvent>());
|
||||
public readonly onProcessData: Event<string | IProcessDataEvent> = this._onProcessData.event;
|
||||
public readonly _onProcessBinary = this._register(new Emitter<string>());
|
||||
public readonly onProcessBinary: Event<string> = this._onProcessBinary.event;
|
||||
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
|
||||
public readonly onProcessExit: Event<number | undefined> = this._onProcessExit.event;
|
||||
public readonly _onProcessReady = this._register(new Emitter<{ pid: number, cwd: string }>());
|
||||
|
@ -118,6 +120,9 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
|
|||
handleData(e: string | IProcessDataEvent) {
|
||||
this._onProcessData.fire(e);
|
||||
}
|
||||
processBinary(e: string) {
|
||||
this._onProcessBinary.fire(e);
|
||||
}
|
||||
handleExit(e: number | undefined) {
|
||||
this._onProcessExit.fire(e);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
|
|||
this._remoteTerminalChannel = channel;
|
||||
|
||||
channel.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event));
|
||||
channel.onProcessBinary(e => this._ptys.get(e.id)?.processBinary(e.event));
|
||||
channel.onProcessExit(e => {
|
||||
const pty = this._ptys.get(e.id);
|
||||
if (pty) {
|
||||
|
@ -168,8 +169,8 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
|
|||
return undefined;
|
||||
}
|
||||
|
||||
public async listProcesses(reduceGraceTime: boolean = false): Promise<IRemoteTerminalAttachTarget[]> {
|
||||
const terms = this._remoteTerminalChannel ? await this._remoteTerminalChannel.listProcesses(reduceGraceTime) : [];
|
||||
public async listProcesses(): Promise<IRemoteTerminalAttachTarget[]> {
|
||||
const terms = this._remoteTerminalChannel ? await this._remoteTerminalChannel.listProcesses() : [];
|
||||
return terms.map(termDto => {
|
||||
return <IRemoteTerminalAttachTarget>{
|
||||
id: termDto.id,
|
||||
|
@ -190,8 +191,14 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
|
|||
return this._remoteTerminalChannel.setTerminalLayoutInfo(layout);
|
||||
}
|
||||
|
||||
public reduceConnectionGraceTime(): void {
|
||||
if (!this._remoteTerminalChannel) {
|
||||
throw new Error('Cannot reduce grace time when there is no remote');
|
||||
}
|
||||
this._remoteTerminalChannel.reduceConnectionGraceTime();
|
||||
}
|
||||
|
||||
public async getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined> {
|
||||
await this._remoteTerminalChannel?.listProcesses(true);
|
||||
if (!this._remoteTerminalChannel) {
|
||||
throw new Error(`Cannot call getActiveInstanceId when there is no remote`);
|
||||
}
|
||||
|
|
|
@ -292,6 +292,11 @@ export interface ITerminalInstance {
|
|||
*/
|
||||
onData: Event<string>;
|
||||
|
||||
/**
|
||||
* Attach a listener to the binary data stream coming from xterm and going to pty
|
||||
*/
|
||||
onBinary: Event<string>;
|
||||
|
||||
/**
|
||||
* Attach a listener to listen for new lines added to this terminal instance.
|
||||
*
|
||||
|
|
|
@ -683,9 +683,13 @@ export function registerTerminalActions() {
|
|||
const labelService = accessor.get(ILabelService);
|
||||
const remoteAgentService = accessor.get(IRemoteAgentService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const offProcTerminalService = remoteAgentService.getConnection() ? accessor.get(IRemoteTerminalService) : accessor.get(ILocalTerminalService);
|
||||
const remoteTerms = await offProcTerminalService.listProcesses();
|
||||
const unattachedTerms = remoteTerms.filter(term => !terminalService.isAttachedToTerminal(term));
|
||||
let offProcTerminalService = remoteAgentService.getConnection() ? accessor.get(IRemoteTerminalService) : accessor.get(ILocalTerminalService);
|
||||
|
||||
const terms = await offProcTerminalService.listProcesses();
|
||||
|
||||
offProcTerminalService.reduceConnectionGraceTime();
|
||||
|
||||
const unattachedTerms = terms.filter(term => !terminalService.isAttachedToTerminal(term));
|
||||
const items = unattachedTerms.map(term => {
|
||||
const cwdLabel = labelService.getUriLabel(URI.file(term.cwd));
|
||||
return {
|
||||
|
|
|
@ -184,6 +184,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
public get onTitleChanged(): Event<ITerminalInstance> { return this._onTitleChanged.event; }
|
||||
private readonly _onData = new Emitter<string>();
|
||||
public get onData(): Event<string> { return this._onData.event; }
|
||||
private readonly _onBinary = new Emitter<string>();
|
||||
public get onBinary(): Event<string> { return this._onBinary.event; }
|
||||
private readonly _onLineData = new Emitter<string>();
|
||||
public get onLineData(): Event<string> { return this._onLineData.event; }
|
||||
private readonly _onRequestExtHostProcess = new Emitter<ITerminalInstance>();
|
||||
|
@ -468,6 +470,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
|
||||
this._processManager.onProcessData(e => this._onProcessData(e));
|
||||
this._xterm.onData(data => this._processManager.write(data));
|
||||
this._xterm.onBinary(data => this._processManager.processBinary(data));
|
||||
this.processReady.then(async () => {
|
||||
if (this._linkManager) {
|
||||
this._linkManager.processCwd = await this._processManager.getInitialCwd();
|
||||
|
|
|
@ -102,6 +102,10 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
|
|||
}
|
||||
}
|
||||
|
||||
processBinary(data: string): void {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
public async start(): Promise<ITerminalLaunchError | undefined> {
|
||||
if (!this._shellLaunchConfig.isExtensionCustomPtyTerminal) {
|
||||
throw new Error('Attempt to start an ext host process that is not an extension terminal');
|
||||
|
|
|
@ -499,6 +499,10 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
}
|
||||
}
|
||||
|
||||
public processBinary(data: string): void {
|
||||
this._process?.processBinary(data);
|
||||
}
|
||||
|
||||
public getInitialCwd(): Promise<string> {
|
||||
return Promise.resolve(this._initialCwd ? this._initialCwd : '');
|
||||
}
|
||||
|
|
|
@ -189,6 +189,7 @@ export class TerminalService implements ITerminalService {
|
|||
private async _reconnectToRemoteTerminals(): Promise<void> {
|
||||
// Reattach to all remote terminals
|
||||
const layoutInfo = await this._remoteTerminalService.getTerminalLayoutInfo();
|
||||
this._remoteTerminalService.reduceConnectionGraceTime();
|
||||
const reconnectCounter = this._recreateTerminalTabs(layoutInfo);
|
||||
/* __GDPR__
|
||||
"terminalReconnection" : {
|
||||
|
@ -210,6 +211,7 @@ export class TerminalService implements ITerminalService {
|
|||
}
|
||||
// Reattach to all local terminals
|
||||
const layoutInfo = await this._localTerminalService.getTerminalLayoutInfo();
|
||||
this._localTerminalService.reduceConnectionGraceTime();
|
||||
if (layoutInfo && layoutInfo.tabs.length > 0) {
|
||||
this._recreateTerminalTabs(layoutInfo);
|
||||
}
|
||||
|
|
|
@ -95,6 +95,9 @@ export class RemoteTerminalChannelClient {
|
|||
public get onProcessData(): Event<{ id: number, event: IProcessDataEvent | string }> {
|
||||
return this._channel.listen<{ id: number, event: IProcessDataEvent | string }>('$onProcessDataEvent');
|
||||
}
|
||||
public get onProcessBinary(): Event<{ id: number, event: string }> {
|
||||
return this._channel.listen<{ id: number, event: string }>('$onProcessBinaryEvent');
|
||||
}
|
||||
public get onProcessExit(): Event<{ id: number, event: number | undefined }> {
|
||||
return this._channel.listen<{ id: number, event: number | undefined }>('$onProcessExitEvent');
|
||||
}
|
||||
|
@ -232,11 +235,12 @@ export class RemoteTerminalChannelClient {
|
|||
public attachToProcess(id: number): Promise<void> {
|
||||
return this._channel.call('$attachToProcess', [id]);
|
||||
}
|
||||
|
||||
public listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> {
|
||||
return this._channel.call('$listProcesses', [reduceGraceTime]);
|
||||
public listProcesses(): Promise<IProcessDetails[]> {
|
||||
return this._channel.call('$listProcesses');
|
||||
}
|
||||
public reduceConnectionGraceTime(): Promise<void> {
|
||||
return this._channel.call('$reduceConnectionGraceTime');
|
||||
}
|
||||
|
||||
public start(id: number): Promise<ITerminalLaunchError | void> {
|
||||
return this._channel.call('$start', [id]);
|
||||
}
|
||||
|
@ -261,7 +265,6 @@ export class RemoteTerminalChannelClient {
|
|||
public orphanQuestionReply(id: number): Promise<void> {
|
||||
return this._channel.call('$orphanQuestionReply', [id]);
|
||||
}
|
||||
|
||||
public sendCommandResult(reqId: number, isError: boolean, payload: any): Promise<void> {
|
||||
return this._channel.call<void>('$sendCommandResult', [reqId, isError, payload]);
|
||||
}
|
||||
|
|
|
@ -306,6 +306,7 @@ export interface ITerminalProcessManager extends IDisposable {
|
|||
setDimensions(cols: number, rows: number, sync: false): Promise<void>;
|
||||
setDimensions(cols: number, rows: number, sync: true): void;
|
||||
acknowledgeDataEvent(charCount: number): void;
|
||||
processBinary(data: string): void;
|
||||
|
||||
getInitialCwd(): Promise<string>;
|
||||
getCwd(): Promise<string>;
|
||||
|
|
|
@ -50,6 +50,12 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
|
|||
shutdown(immediate: boolean): void {
|
||||
this._localPtyService.shutdown(this.id, immediate);
|
||||
}
|
||||
processBinary(data: string): void {
|
||||
if (this._inReplay) {
|
||||
return;
|
||||
}
|
||||
this._localPtyService.processBinary(this.id, data);
|
||||
}
|
||||
input(data: string): void {
|
||||
if (this._inReplay) {
|
||||
return;
|
||||
|
|
|
@ -116,8 +116,12 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe
|
|||
return undefined;
|
||||
}
|
||||
|
||||
public async listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> {
|
||||
return this._localPtyService.listProcesses(reduceGraceTime);
|
||||
public async listProcesses(): Promise<IProcessDetails[]> {
|
||||
return this._localPtyService.listProcesses();
|
||||
}
|
||||
|
||||
public reduceConnectionGraceTime(): void {
|
||||
this._localPtyService.reduceConnectionGraceTime();
|
||||
}
|
||||
|
||||
public async setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void> {
|
||||
|
@ -136,6 +140,10 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe
|
|||
return result;
|
||||
}
|
||||
|
||||
public processBinary(id: number, data: string): void {
|
||||
this._localPtyService.processBinary(id, data);
|
||||
}
|
||||
|
||||
private _getWorkspaceId(): string {
|
||||
return this._workspaceContextService.getWorkspace().id;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,11 @@ export interface IWebviewService {
|
|||
*/
|
||||
readonly activeWebview: Webview | undefined;
|
||||
|
||||
/**
|
||||
* Fired when the currently focused webview changes.
|
||||
*/
|
||||
readonly onDidChangeActiveWebview: Event<Webview | undefined>;
|
||||
|
||||
/**
|
||||
* Create a basic webview dom element.
|
||||
*/
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing';
|
||||
import { IWebviewService, Webview, WebviewContentOptions, WebviewElement, WebviewExtensionDescription, WebviewOptions, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement';
|
||||
import { DynamicWebviewEditorOverlay } from './dynamicWebviewEditorOverlay';
|
||||
|
||||
export class WebviewService implements IWebviewService {
|
||||
export class WebviewService extends Disposable implements IWebviewService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
protected readonly _webviewThemeDataProvider: WebviewThemeDataProvider;
|
||||
|
@ -17,12 +19,24 @@ export class WebviewService implements IWebviewService {
|
|||
constructor(
|
||||
@IInstantiationService protected readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
this._webviewThemeDataProvider = this._instantiationService.createInstance(WebviewThemeDataProvider);
|
||||
}
|
||||
|
||||
private _activeWebview?: Webview;
|
||||
|
||||
public get activeWebview() { return this._activeWebview; }
|
||||
|
||||
private updateActiveWebview(value: Webview | undefined) {
|
||||
if (value !== this._activeWebview) {
|
||||
this._activeWebview = value;
|
||||
this._onDidChangeActiveWebview.fire(value);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly _onDidChangeActiveWebview = this._register(new Emitter<Webview | undefined>());
|
||||
public readonly onDidChangeActiveWebview = this._onDidChangeActiveWebview.event;
|
||||
|
||||
createWebviewElement(
|
||||
id: string,
|
||||
options: WebviewOptions,
|
||||
|
@ -47,12 +61,12 @@ export class WebviewService implements IWebviewService {
|
|||
|
||||
protected addWebviewListeners(webview: Webview) {
|
||||
webview.onDidFocus(() => {
|
||||
this._activeWebview = webview;
|
||||
this.updateActiveWebview(webview);
|
||||
});
|
||||
|
||||
const onBlur = () => {
|
||||
if (this._activeWebview === webview) {
|
||||
this._activeWebview = undefined;
|
||||
this.updateActiveWebview(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -7,11 +7,13 @@ import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async
|
|||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
||||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { IWebviewService, WebviewContentOptions, WebviewExtensionDescription, WebviewOptions, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { WebviewIconManager, WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager';
|
||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
|
@ -69,6 +71,8 @@ export interface IWebviewWorkbenchService {
|
|||
resolveWebview(
|
||||
webview: WebviewInput,
|
||||
): CancelablePromise<void>;
|
||||
|
||||
readonly onDidChangeActiveWebviewEditor: Event<WebviewInput | undefined>;
|
||||
}
|
||||
|
||||
export interface WebviewResolver {
|
||||
|
@ -171,12 +175,48 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc
|
|||
super();
|
||||
|
||||
this._iconManager = this._register(this._instantiationService.createInstance(WebviewIconManager));
|
||||
|
||||
this._register(_editorService.onDidActiveEditorChange(() => {
|
||||
this.updateActiveWebview();
|
||||
}));
|
||||
|
||||
// The user may have switched focus between two sides of a diff editor
|
||||
this._register(_webviewService.onDidChangeActiveWebview(() => {
|
||||
this.updateActiveWebview();
|
||||
}));
|
||||
|
||||
this.updateActiveWebview();
|
||||
}
|
||||
|
||||
get iconManager() {
|
||||
return this._iconManager;
|
||||
}
|
||||
|
||||
private _activeWebview: WebviewInput | undefined;
|
||||
|
||||
private readonly _onDidChangeActiveWebviewEditor = this._register(new Emitter<WebviewInput | undefined>());
|
||||
public readonly onDidChangeActiveWebviewEditor = this._onDidChangeActiveWebviewEditor.event;
|
||||
|
||||
private updateActiveWebview() {
|
||||
const activeInput = this._editorService.activeEditor;
|
||||
|
||||
let newActiveWebview: WebviewInput | undefined;
|
||||
if (activeInput instanceof WebviewInput) {
|
||||
newActiveWebview = activeInput;
|
||||
} else if (activeInput instanceof DiffEditorInput) {
|
||||
if (activeInput.primary instanceof WebviewInput && activeInput.primary.webview === this._webviewService.activeWebview) {
|
||||
newActiveWebview = activeInput.primary;
|
||||
} else if (activeInput.secondary instanceof WebviewInput && activeInput.secondary.webview === this._webviewService.activeWebview) {
|
||||
newActiveWebview = activeInput.secondary;
|
||||
}
|
||||
}
|
||||
|
||||
if (newActiveWebview !== this._activeWebview) {
|
||||
this._activeWebview = newActiveWebview;
|
||||
this._onDidChangeActiveWebviewEditor.fire(newActiveWebview);
|
||||
}
|
||||
}
|
||||
|
||||
public createWebview(
|
||||
id: string,
|
||||
viewType: string,
|
||||
|
|
|
@ -279,6 +279,7 @@ class SimpleWebviewService implements IWebviewService {
|
|||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
readonly activeWebview = undefined;
|
||||
readonly onDidChangeActiveWebview = Event.None;
|
||||
|
||||
createWebviewElement(id: string, options: WebviewOptions, contentOptions: WebviewContentOptions, extension: WebviewExtensionDescription | undefined): WebviewElement { throw new Error('Method not implemented.'); }
|
||||
createWebviewOverlay(id: string, options: WebviewOptions, contentOptions: WebviewContentOptions, extension: WebviewExtensionDescription | undefined): WebviewOverlay { throw new Error('Method not implemented.'); }
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const FOLDER_CONFIG_FOLDER_NAME = '.vscode';
|
||||
export const FOLDER_SETTINGS_NAME = 'settings';
|
||||
|
@ -45,7 +45,7 @@ export interface IConfigurationCache {
|
|||
|
||||
}
|
||||
|
||||
export const IWorkbenchConfigurationService = createDecorator<IWorkbenchConfigurationService>('configurationService');
|
||||
export const IWorkbenchConfigurationService = refineServiceDecorator<IConfigurationService, IWorkbenchConfigurationService>(IConfigurationService);
|
||||
export interface IWorkbenchConfigurationService extends IConfigurationService {
|
||||
/**
|
||||
* A promise that resolves when the remote configuration is loaded in a remote window.
|
||||
|
|
|
@ -31,6 +31,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
|
|||
getExecPath: () => string | undefined
|
||||
},
|
||||
envVariables: IProcessEnvironment,
|
||||
envVariablesPromise: Promise<IProcessEnvironment>,
|
||||
editorService: IEditorService,
|
||||
private readonly configurationService: IConfigurationService,
|
||||
private readonly commandService: ICommandService,
|
||||
|
@ -101,7 +102,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
|
|||
}
|
||||
return undefined;
|
||||
}
|
||||
}, labelService, envVariables);
|
||||
}, labelService, envVariables, envVariablesPromise);
|
||||
}
|
||||
|
||||
public async resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary<string>, target?: ConfigurationTarget): Promise<any> {
|
||||
|
@ -367,8 +368,10 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi
|
|||
@ICommandService commandService: ICommandService,
|
||||
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@ILabelService labelService: ILabelService
|
||||
@ILabelService labelService: ILabelService,
|
||||
) {
|
||||
super({ getAppRoot: () => undefined, getExecPath: () => undefined }, Object.create(null), editorService, configurationService, commandService, workspaceContextService, quickInputService, labelService);
|
||||
super({ getAppRoot: () => undefined, getExecPath: () => undefined }, Object.create(null),
|
||||
Promise.resolve(Object.create(null)), editorService, configurationService,
|
||||
commandService, workspaceContextService, quickInputService, labelService);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
|
|||
private _envVariables?: IProcessEnvironment;
|
||||
protected _contributedVariables: Map<string, () => Promise<string | undefined>> = new Map();
|
||||
|
||||
|
||||
constructor(_context: IVariableResolveContext, _labelService?: ILabelService, _envVariables?: IProcessEnvironment) {
|
||||
constructor(_context: IVariableResolveContext, _labelService?: ILabelService, _envVariables?: IProcessEnvironment, _envVariablesPromise?: Promise<IProcessEnvironment>) {
|
||||
this._context = _context;
|
||||
this._labelService = _labelService;
|
||||
// TODO: delete _envVariables in favor of _envVariablesPromise https://github.com/microsoft/vscode/issues/108804
|
||||
if (_envVariables) {
|
||||
if (isWindows) {
|
||||
// windows env variables are case insensitive
|
||||
|
@ -65,6 +65,9 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
|
|||
return this.recursiveResolve(root ? root.uri : undefined, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use the async version of `resolve` instead.
|
||||
*/
|
||||
public resolve(root: IWorkspaceFolder | undefined, value: string): string;
|
||||
public resolve(root: IWorkspaceFolder | undefined, value: string[]): string[];
|
||||
public resolve(root: IWorkspaceFolder | undefined, value: IStringDictionary<string>): IStringDictionary<string>;
|
||||
|
@ -72,6 +75,9 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
|
|||
return this.recursiveResolve(root ? root.uri : undefined, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use the async version of `resolve` instead.
|
||||
*/
|
||||
public resolveAnyBase(workspaceFolder: IWorkspaceFolder | undefined, config: any, commandValueMapping?: IStringDictionary<string>, resolvedVariables?: Map<string, string>): any {
|
||||
|
||||
const result = objects.deepClone(config) as any;
|
||||
|
|
|
@ -14,6 +14,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
|||
import { BaseConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService';
|
||||
import { env } from 'vs/base/common/process';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IShellEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/shellEnvironmentService';
|
||||
|
||||
export class ConfigurationResolverService extends BaseConfigurationResolverService {
|
||||
|
||||
|
@ -24,7 +25,8 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi
|
|||
@ICommandService commandService: ICommandService,
|
||||
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@ILabelService labelService: ILabelService
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IShellEnvironmentService shellEnvironmentService: IShellEnvironmentService
|
||||
) {
|
||||
super({
|
||||
getAppRoot: (): string | undefined => {
|
||||
|
@ -33,7 +35,7 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi
|
|||
getExecPath: (): string | undefined => {
|
||||
return environmentService.execPath;
|
||||
}
|
||||
}, env, editorService, configurationService, commandService, workspaceContextService, quickInputService, labelService);
|
||||
}, env, shellEnvironmentService.getShellEnv(), editorService, configurationService, commandService, workspaceContextService, quickInputService, labelService);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ suite('Configuration Resolver Service', () => {
|
|||
labelService = new MockLabelService();
|
||||
containingWorkspace = testWorkspace(uri.parse('file:///VSCode/workspaceLocation'));
|
||||
workspace = containingWorkspace.folders[0];
|
||||
configurationResolverService = new TestConfigurationResolverService(nullContext, environmentService.userEnv, editorService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(containingWorkspace), quickInputService, labelService);
|
||||
configurationResolverService = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), editorService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(containingWorkspace), quickInputService, labelService);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
|
@ -214,7 +214,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} xyz'), 'abc foo xyz');
|
||||
});
|
||||
|
||||
|
@ -225,7 +225,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
assert.strictEqual(service.resolve(undefined, 'abc ${config:editor.fontFamily} xyz'), 'abc foo xyz');
|
||||
});
|
||||
|
||||
|
@ -242,7 +242,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz');
|
||||
});
|
||||
|
||||
|
@ -259,7 +259,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${workspaceFolder} ${env:key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for key1 xyz');
|
||||
} else {
|
||||
|
@ -280,7 +280,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve(workspace, '${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} ${workspaceFolder} - ${workspaceFolder} ${env:key1} - ${env:key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for key1 - Value for key2');
|
||||
} else {
|
||||
|
@ -314,7 +314,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:editor.lineNumbers} ${config:editor.insertSpaces} xyz'), 'abc foo 123 false xyz');
|
||||
});
|
||||
|
||||
|
@ -324,7 +324,7 @@ suite('Configuration Resolver Service', () => {
|
|||
editor: {}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${unknownVariable} xyz'), 'abc ${unknownVariable} xyz');
|
||||
assert.strictEqual(service.resolve(workspace, 'abc ${env:unknownVariable} xyz'), 'abc xyz');
|
||||
});
|
||||
|
@ -337,7 +337,7 @@ suite('Configuration Resolver Service', () => {
|
|||
}
|
||||
});
|
||||
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
let service = new TestConfigurationResolverService(nullContext, environmentService.userEnv, Promise.resolve(environmentService.userEnv), new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService, labelService);
|
||||
|
||||
assert.throws(() => service.resolve(workspace, 'abc ${env} xyz'));
|
||||
assert.throws(() => service.resolve(workspace, 'abc ${env:} xyz'));
|
||||
|
|
|
@ -25,7 +25,7 @@ import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecyc
|
|||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IExtensionBisectService } from 'vs/workbench/services/extensionManagement/browser/extensionBisect';
|
||||
import { IWorkspaceTrustService, WorkspaceTrustState } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { IWorkspaceTrustService, WorkspaceTrustState, WorkspaceTrustStateChangeEvent } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { Promises } from 'vs/base/common/async';
|
||||
|
||||
const SOURCE = 'IWorkbenchExtensionEnablementService';
|
||||
|
@ -64,18 +64,13 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
|||
this._register(this.globalExtensionEnablementService.onDidChangeEnablement(({ extensions, source }) => this.onDidChangeExtensions(extensions, source)));
|
||||
this._register(extensionManagementService.onDidInstallExtension(this._onDidInstallExtension, this));
|
||||
this._register(extensionManagementService.onDidUninstallExtension(this._onDidUninstallExtension, this));
|
||||
this._register(this.workspaceTrustService.onDidChangeTrustState(this._onDidChangeTrustState, this));
|
||||
|
||||
// Trusted extensions notification
|
||||
// TODO: Confirm that this is the right lifecycle phase
|
||||
this.lifecycleService.when(LifecyclePhase.Eventually).then(() => {
|
||||
if (this.extensionsDisabledByTrustRequirement.length > 0) {
|
||||
this.workspaceTrustService.requireWorkspaceTrust({ modal: false })
|
||||
.then(trustState => {
|
||||
if (trustState === WorkspaceTrustState.Trusted) {
|
||||
this._onEnablementChanged.fire(this.extensionsDisabledByTrustRequirement);
|
||||
this.extensionsDisabledByTrustRequirement = [];
|
||||
}
|
||||
});
|
||||
this.workspaceTrustService.requestWorkspaceTrust({ modal: false });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -174,7 +169,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
|||
|
||||
const result = await Promises.settled(extensions.map(e => {
|
||||
if (this._isDisabledByTrustRequirement(e)) {
|
||||
return this.workspaceTrustService.requireWorkspaceTrust()
|
||||
return this.workspaceTrustService.requestWorkspaceTrust()
|
||||
.then(trustState => {
|
||||
if (trustState === WorkspaceTrustState.Trusted) {
|
||||
return this._setEnablement(e, newState);
|
||||
|
@ -447,7 +442,8 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
|||
|
||||
private _onDidInstallExtension({ local, error }: DidInstallExtensionEvent): void {
|
||||
if (local && !error && this._isDisabledByTrustRequirement(local)) {
|
||||
this.workspaceTrustService.requireWorkspaceTrust();
|
||||
this.workspaceTrustService.requestWorkspaceTrust({ modal: false });
|
||||
this._onEnablementChanged.fire([local]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,6 +453,13 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
|||
}
|
||||
}
|
||||
|
||||
private _onDidChangeTrustState({ currentTrustState }: WorkspaceTrustStateChangeEvent): void {
|
||||
if (currentTrustState === WorkspaceTrustState.Trusted && this.extensionsDisabledByTrustRequirement.length > 0) {
|
||||
this._onEnablementChanged.fire(this.extensionsDisabledByTrustRequirement);
|
||||
this.extensionsDisabledByTrustRequirement = [];
|
||||
}
|
||||
}
|
||||
|
||||
private _reset(extension: IExtensionIdentifier) {
|
||||
this._removeFromWorkspaceDisabledExtensions(extension);
|
||||
this._removeFromWorkspaceEnabledExtensions(extension);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { createDecorator, refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtension, IScannedExtension, ExtensionType, ITranslatedScannedExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier, ILocalExtension, InstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -24,7 +24,7 @@ export interface IExtensionManagementServerService {
|
|||
getExtensionManagementServer(extension: IExtension): IExtensionManagementServer | null;
|
||||
}
|
||||
|
||||
export const IWorkbenchExtensionManagementService = createDecorator<IWorkbenchExtensionManagementService>('extensionManagementService');
|
||||
export const IWorkbenchExtensionManagementService = refineServiceDecorator<IExtensionManagementService, IWorkbenchExtensionManagementService>(IExtensionManagementService);
|
||||
export interface IWorkbenchExtensionManagementService extends IExtensionManagementService {
|
||||
readonly _serviceBrand: undefined;
|
||||
installExtensions(extensions: IGalleryExtension[], installOptions?: InstallOptions): Promise<ILocalExtension[]>;
|
||||
|
|
|
@ -25,7 +25,7 @@ import Severity from 'vs/base/common/severity';
|
|||
import { canceled } from 'vs/base/common/errors';
|
||||
import { IUserDataAutoSyncEnablementService, IUserDataSyncResourceEnablementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Promises } from 'vs/base/common/async';
|
||||
import { IWorkspaceTrustService, WorkspaceTrustState } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { IWorkspaceTrustService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
|
||||
export class ExtensionManagementService extends Disposable implements IWorkbenchExtensionManagementService {
|
||||
|
||||
|
@ -362,9 +362,21 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
|||
|
||||
protected async checkForWorkspaceTrust(manifest: IExtensionManifest): Promise<void> {
|
||||
if (getExtensionWorkspaceTrustRequirement(manifest) === 'onStart') {
|
||||
const trustState = await this.workspaceTrustService.requireWorkspaceTrust();
|
||||
return trustState === WorkspaceTrustState.Trusted ? Promise.resolve() : Promise.reject(canceled());
|
||||
const trustState = await this.workspaceTrustService.requestWorkspaceTrust({
|
||||
modal: true,
|
||||
message: localize('extensionInstallWorkspaceTrustMessage', "Enabling this extension requires a trusted workspace."),
|
||||
buttons: [
|
||||
{ label: localize('extensionInstallWorkspaceTrustButton', "Trust Workspace & Install"), type: 'ContinueWithTrust' },
|
||||
{ label: localize('extensionInstallWorkspaceTrustContinueButton', "Install"), type: 'ContinueWithoutTrust' },
|
||||
{ label: localize('extensionInstallWorkspaceTrustManageButton', "Learn More"), type: 'Manage' }
|
||||
]
|
||||
});
|
||||
|
||||
if (!trustState) {
|
||||
Promise.reject(canceled());
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue