mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Merge branch 'main' into electron-19.x.y
This commit is contained in:
commit
afdf486c1e
|
@ -259,6 +259,7 @@
|
|||
"windows-process-tree",
|
||||
"worker_threads",
|
||||
"xterm",
|
||||
"xterm-addon-canvas",
|
||||
"xterm-addon-search",
|
||||
"xterm-addon-serialize",
|
||||
"xterm-addon-unicode11",
|
||||
|
|
2
.vscode/notebooks/api.github-issues
vendored
2
.vscode/notebooks/api.github-issues
vendored
|
@ -7,7 +7,7 @@
|
|||
{
|
||||
"kind": 2,
|
||||
"language": "github-issues",
|
||||
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2022\""
|
||||
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"August 2022\""
|
||||
},
|
||||
{
|
||||
"kind": 1,
|
||||
|
|
|
@ -20,6 +20,9 @@ vscode-textmate/webpack.config.js
|
|||
|
||||
xterm/src/**
|
||||
|
||||
xterm-addon-canvas/src/**
|
||||
xterm-addon-canvas/out/**
|
||||
|
||||
xterm-addon-search/src/**
|
||||
xterm-addon-search/out/**
|
||||
xterm-addon-search/fixtures/**
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"emmet.showAbbreviationSuggestions": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"scope": "language-overridable",
|
||||
"scope": "resource",
|
||||
"markdownDescription": "%emmetShowAbbreviationSuggestions%"
|
||||
},
|
||||
"emmet.includeLanguages": {
|
||||
|
|
|
@ -264,47 +264,47 @@ export async function wrapWithAbbreviation(args: any): Promise<boolean> {
|
|||
}
|
||||
|
||||
export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined> {
|
||||
if (!validate() || !vscode.window.activeTextEditor) {
|
||||
return fallbackTab();
|
||||
if (!validate()) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
const editor = vscode.window.activeTextEditor!;
|
||||
|
||||
args = args || {};
|
||||
if (!args['language']) {
|
||||
args['language'] = editor.document.languageId;
|
||||
} else {
|
||||
const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ?? [];
|
||||
if (excludedLanguages.includes(args['language'])) {
|
||||
return fallbackTab(args['language']);
|
||||
}
|
||||
}
|
||||
const languageId: string = args['language'];
|
||||
|
||||
/**
|
||||
* Short circuit the parsing. If previous character is space, do not expand.
|
||||
*/
|
||||
if (vscode.window.activeTextEditor.selections.length === 1 &&
|
||||
vscode.window.activeTextEditor.selection.isEmpty
|
||||
if (editor.selections.length === 1 && editor.selection.isEmpty
|
||||
) {
|
||||
const anchor = vscode.window.activeTextEditor.selection.anchor;
|
||||
const anchor = editor.selection.anchor;
|
||||
if (anchor.character === 0) {
|
||||
return fallbackTab();
|
||||
return fallbackTab(languageId);
|
||||
}
|
||||
|
||||
const prevPositionAnchor = anchor.translate(0, -1);
|
||||
const prevText = vscode.window.activeTextEditor.document.getText(new vscode.Range(prevPositionAnchor, anchor));
|
||||
const prevText = editor.document.getText(new vscode.Range(prevPositionAnchor, anchor));
|
||||
if (prevText === ' ' || prevText === '\t') {
|
||||
return fallbackTab();
|
||||
return fallbackTab(languageId);
|
||||
}
|
||||
}
|
||||
|
||||
args = args || {};
|
||||
if (!args['language']) {
|
||||
args['language'] = vscode.window.activeTextEditor.document.languageId;
|
||||
} else {
|
||||
const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ? vscode.workspace.getConfiguration('emmet')['excludeLanguages'] : [];
|
||||
if (excludedLanguages.indexOf(vscode.window.activeTextEditor.document.languageId) > -1) {
|
||||
return fallbackTab();
|
||||
}
|
||||
}
|
||||
const syntax = getSyntaxFromArgs(args);
|
||||
if (!syntax) {
|
||||
return fallbackTab();
|
||||
return fallbackTab(languageId);
|
||||
}
|
||||
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
|
||||
// When tabbed on a non empty selection, do not treat it as an emmet abbreviation, and fallback to tab instead
|
||||
if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) {
|
||||
return fallbackTab();
|
||||
if (vscode.workspace.getConfiguration('emmet', { languageId })['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) {
|
||||
return fallbackTab(languageId);
|
||||
}
|
||||
|
||||
const abbreviationList: ExpandAbbreviationInput[] = [];
|
||||
|
@ -325,7 +325,7 @@ export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined
|
|||
}
|
||||
|
||||
const currentLine = editor.document.lineAt(position.line).text;
|
||||
const textTillPosition = currentLine.substr(0, position.character);
|
||||
const textTillPosition = currentLine.substring(0, position.character);
|
||||
|
||||
// Expand cases like <div to <div></div> explicitly
|
||||
// else we will end up with <<div></div>
|
||||
|
@ -415,12 +415,12 @@ export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined
|
|||
});
|
||||
|
||||
return expandAbbreviationInRange(editor, abbreviationList, allAbbreviationsSame).then(success => {
|
||||
return success ? Promise.resolve(undefined) : fallbackTab();
|
||||
return success ? Promise.resolve(undefined) : fallbackTab(languageId);
|
||||
});
|
||||
}
|
||||
|
||||
function fallbackTab(): Thenable<boolean | undefined> {
|
||||
if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true) {
|
||||
function fallbackTab(languageId: string): Thenable<boolean | undefined> {
|
||||
if (vscode.workspace.getConfiguration('emmet', { languageId })['triggerExpansionOnTab'] === true) {
|
||||
return vscode.commands.executeCommand('tab');
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
|
@ -470,13 +470,13 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
|
|||
&& propertyNode.separator
|
||||
&& offset >= propertyNode.separatorToken.end
|
||||
&& offset <= propertyNode.terminatorToken.start
|
||||
&& abbreviation.indexOf(':') === -1) {
|
||||
&& !abbreviation.includes(':')) {
|
||||
return hexColorRegex.test(abbreviation) || abbreviation === '!';
|
||||
}
|
||||
if (!propertyNode.terminatorToken
|
||||
&& propertyNode.separator
|
||||
&& offset >= propertyNode.separatorToken.end
|
||||
&& abbreviation.indexOf(':') === -1) {
|
||||
&& !abbreviation.includes(':')) {
|
||||
return hexColorRegex.test(abbreviation) || abbreviation === '!';
|
||||
}
|
||||
if (hexColorRegex.test(abbreviation) || abbreviation === '!') {
|
||||
|
@ -529,7 +529,7 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
|
|||
const typeAttribute = (currentHtmlNode.attributes || []).filter(x => x.name.toString() === 'type')[0];
|
||||
const typeValue = typeAttribute ? typeAttribute.value.toString() : '';
|
||||
|
||||
if (allowedMimeTypesInScriptTag.indexOf(typeValue) > -1) {
|
||||
if (allowedMimeTypesInScriptTag.includes(typeValue)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
|
|||
|
||||
if (expandedText.startsWith('<')) {
|
||||
this.lastCompletionType = 'html';
|
||||
} else if (expandedText.indexOf(':') > 0 && expandedText.endsWith(';')) {
|
||||
} else if (expandedText.includes(':') && expandedText.endsWith(';')) {
|
||||
this.lastCompletionType = 'css';
|
||||
} else {
|
||||
this.lastCompletionType = undefined;
|
||||
|
@ -43,7 +43,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
|
|||
private provideCompletionItemsInternal(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext): Thenable<vscode.CompletionList | undefined> | undefined {
|
||||
const emmetConfig = vscode.workspace.getConfiguration('emmet');
|
||||
const excludedLanguages = emmetConfig['excludeLanguages'] ? emmetConfig['excludeLanguages'] : [];
|
||||
if (excludedLanguages.indexOf(document.languageId) > -1) {
|
||||
if (excludedLanguages.includes(document.languageId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ function getNextAttribute(document: vscode.TextDocument, selectionStart: number,
|
|||
}
|
||||
|
||||
// Fetch the next word in the attr value
|
||||
if (attr.value.toString().indexOf(' ') === -1) {
|
||||
if (!attr.value.toString().includes(' ')) {
|
||||
// attr value does not have space, so no next word to find
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ export async function activate(ctx: RendererContext<void>) {
|
|||
md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => {
|
||||
const token = tokens[idx];
|
||||
const src = token.attrGet('src');
|
||||
const attachments: Record<string, Record<string, string>> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell
|
||||
const attachments: Record<string, Record<string, string>> = env.outputItem.metadata().custom?.attachments;
|
||||
if (attachments && src) {
|
||||
const imageAttachment = attachments[src.replace('attachment:', '')];
|
||||
if (imageAttachment) {
|
||||
|
|
|
@ -44,7 +44,7 @@ export interface CellOutputMetadata {
|
|||
|
||||
/**
|
||||
* Metadata we store in VS Code cells.
|
||||
* This contains the original metadata from the Jupyuter cells.
|
||||
* This contains the original metadata from the Jupyter cells.
|
||||
*/
|
||||
export interface CellMetadata {
|
||||
/**
|
||||
|
|
|
@ -164,17 +164,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
await saveAllFilesAndCloseAll();
|
||||
});
|
||||
|
||||
test('edit API batch edits', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } });
|
||||
edit.set(notebook.uri, [metdataEdit]);
|
||||
const success = await vscode.workspace.applyEdit(edit);
|
||||
assert.equal(success, true);
|
||||
assert.ok(notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`);
|
||||
});
|
||||
|
||||
test('notebook open', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
|
@ -298,7 +287,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider));
|
||||
});
|
||||
|
||||
test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@roblourens https://github.com/microsoft/vscode/issues/139324
|
||||
test('provideCellStatusBarItems called on metadata change', async function () {
|
||||
const provideCalled = asPromise(onDidCallProvide);
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
|
@ -306,7 +295,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true });
|
||||
vscode.workspace.applyEdit(edit);
|
||||
await vscode.workspace.applyEdit(edit);
|
||||
await provideCalled;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -315,6 +315,18 @@ suite('Notebook Document', function () {
|
|||
assert.strictEqual(data.cellChanges[0].cell.index, 0);
|
||||
});
|
||||
|
||||
test('workspace edit API (notebookMetadata)', async function () {
|
||||
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
const document = await vscode.workspace.openNotebookDocument(uri);
|
||||
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...document.metadata, custom: { ...(document.metadata.custom || {}), extraNotebookMetadata: true } });
|
||||
edit.set(document.uri, [metdataEdit]);
|
||||
const success = await vscode.workspace.applyEdit(edit);
|
||||
assert.equal(success, true);
|
||||
assert.ok(document.metadata.custom.extraNotebookMetadata, `Test metadata not found`);
|
||||
});
|
||||
|
||||
test('document save API', async function () {
|
||||
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
const notebook = await vscode.workspace.openNotebookDocument(uri);
|
||||
|
|
|
@ -65,39 +65,6 @@ import * as utils from '../utils';
|
|||
testDisposables.length = 0;
|
||||
});
|
||||
|
||||
test.skip('showNotebookDocument', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/139078
|
||||
|
||||
const notebookDocumentsFromOnDidOpen = new Set<vscode.NotebookDocument>();
|
||||
const sub = vscode.workspace.onDidOpenNotebookDocument(e => {
|
||||
notebookDocumentsFromOnDidOpen.add(e);
|
||||
});
|
||||
|
||||
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
|
||||
const editor = await vscode.window.showNotebookDocument(uri);
|
||||
assert.strictEqual(uri.toString(), editor.notebook.uri.toString());
|
||||
|
||||
assert.strictEqual(notebookDocumentsFromOnDidOpen.has(editor.notebook), true);
|
||||
|
||||
const includes = vscode.workspace.notebookDocuments.includes(editor.notebook);
|
||||
assert.strictEqual(true, includes);
|
||||
|
||||
sub.dispose();
|
||||
});
|
||||
|
||||
// TODO@rebornix deal with getting started
|
||||
test.skip('notebook editor has viewColumn', async function () {
|
||||
|
||||
const uri1 = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
const editor1 = await vscode.window.showNotebookDocument(uri1);
|
||||
|
||||
assert.strictEqual(editor1.viewColumn, vscode.ViewColumn.One);
|
||||
|
||||
const uri2 = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
const editor2 = await vscode.window.showNotebookDocument(uri2, { viewColumn: vscode.ViewColumn.Beside });
|
||||
assert.strictEqual(editor2.viewColumn, vscode.ViewColumn.Two);
|
||||
});
|
||||
|
||||
// #138683
|
||||
test('Opening a notebook should fire activeNotebook event changed only once', async function () {
|
||||
const openedEditor = onDidOpenNotebookEditor();
|
||||
|
|
|
@ -174,19 +174,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
await saveAllFilesAndCloseAll();
|
||||
});
|
||||
|
||||
// TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied
|
||||
test.skip('cell execute command takes arguments', async () => {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
|
||||
const editor = vscode.window.activeNotebookEditor!;
|
||||
const cell = editor.notebook.cellAt(0);
|
||||
|
||||
await vscode.commands.executeCommand('notebook.execute');
|
||||
assert.strictEqual(cell.outputs.length, 0, 'should not execute'); // not runnable, didn't work
|
||||
});
|
||||
|
||||
test('cell execute command takes arguments 2', async () => {
|
||||
test('cell execute command takes arguments', async () => {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
|
||||
|
@ -217,11 +205,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
});
|
||||
|
||||
// #126371
|
||||
test.skip('cell execute command takes arguments ICellRange[]', async () => {
|
||||
test('cell execute command takes arguments', async () => {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
|
||||
vscode.commands.executeCommand('notebook.cell.execute', { ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] });
|
||||
let firstCellExecuted = false;
|
||||
let secondCellExecuted = false;
|
||||
let resolve: () => void;
|
||||
|
@ -242,6 +229,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
}
|
||||
});
|
||||
|
||||
vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] });
|
||||
|
||||
await p;
|
||||
listener.dispose();
|
||||
await saveAllFilesAndCloseAll();
|
||||
|
@ -306,12 +295,11 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
});
|
||||
});
|
||||
|
||||
test.skip('onDidChangeCellExecutionState is fired', async () => { // TODO@rebornix https://github.com/microsoft/vscode/issues/139350
|
||||
test('onDidChangeCellExecutionState is fired', async () => {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
const cell = editor.notebook.cellAt(0);
|
||||
|
||||
vscode.commands.executeCommand('notebook.cell.execute');
|
||||
let eventCount = 0;
|
||||
let resolve: () => void;
|
||||
const p = new Promise<void>(r => resolve = r);
|
||||
|
@ -330,6 +318,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
|
|||
eventCount++;
|
||||
});
|
||||
|
||||
vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }] });
|
||||
|
||||
await p;
|
||||
listener.dispose();
|
||||
});
|
||||
|
|
|
@ -86,12 +86,13 @@
|
|||
"vscode-proxy-agent": "^0.12.0",
|
||||
"vscode-regexpp": "^3.1.0",
|
||||
"vscode-textmate": "7.0.1",
|
||||
"xterm": "4.20.0-beta.20",
|
||||
"xterm": "5.0.0-beta.32",
|
||||
"xterm-addon-canvas": "0.2.0-beta.15",
|
||||
"xterm-addon-search": "0.10.0-beta.3",
|
||||
"xterm-addon-serialize": "0.8.0-beta.3",
|
||||
"xterm-addon-unicode11": "0.4.0-beta.3",
|
||||
"xterm-addon-webgl": "0.13.0-beta.9",
|
||||
"xterm-headless": "4.20.0-beta.20",
|
||||
"xterm-addon-webgl": "0.13.0-beta.32",
|
||||
"xterm-headless": "5.0.0-beta.5",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3"
|
||||
},
|
||||
|
@ -124,7 +125,7 @@
|
|||
"@types/yazl": "^2.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"@vscode/telemetry-extractor": "^1.9.6",
|
||||
"@vscode/telemetry-extractor": "^1.9.8",
|
||||
"@vscode/test-web": "^0.0.29",
|
||||
"ansi-colors": "^3.2.3",
|
||||
"asar": "^3.0.3",
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
"vscode-proxy-agent": "^0.12.0",
|
||||
"vscode-regexpp": "^3.1.0",
|
||||
"vscode-textmate": "7.0.1",
|
||||
"xterm": "4.20.0-beta.20",
|
||||
"xterm": "5.0.0-beta.32",
|
||||
"xterm-addon-canvas": "0.2.0-beta.15",
|
||||
"xterm-addon-search": "0.10.0-beta.3",
|
||||
"xterm-addon-serialize": "0.8.0-beta.3",
|
||||
"xterm-addon-unicode11": "0.4.0-beta.3",
|
||||
"xterm-addon-webgl": "0.13.0-beta.9",
|
||||
"xterm-headless": "4.20.0-beta.20",
|
||||
"xterm-addon-webgl": "0.13.0-beta.32",
|
||||
"xterm-headless": "5.0.0-beta.5",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3"
|
||||
},
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
"tas-client-umd": "0.1.6",
|
||||
"vscode-oniguruma": "1.6.1",
|
||||
"vscode-textmate": "7.0.1",
|
||||
"xterm": "4.20.0-beta.20",
|
||||
"xterm": "5.0.0-beta.32",
|
||||
"xterm-addon-canvas": "0.2.0-beta.15",
|
||||
"xterm-addon-search": "0.10.0-beta.3",
|
||||
"xterm-addon-unicode11": "0.4.0-beta.3",
|
||||
"xterm-addon-webgl": "0.13.0-beta.9"
|
||||
"xterm-addon-webgl": "0.13.0-beta.32"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,11 @@ vscode-textmate@7.0.1:
|
|||
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-7.0.1.tgz#8118a32b02735dccd14f893b495fa5389ad7de79"
|
||||
integrity sha512-zQ5U/nuXAAMsh691FtV0wPz89nSkHbs+IQV8FDk+wew9BlSDhf4UmWGlWJfTR2Ti6xZv87Tj5fENzKf6Qk7aLw==
|
||||
|
||||
xterm-addon-canvas@0.2.0-beta.15:
|
||||
version "0.2.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4"
|
||||
integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw==
|
||||
|
||||
xterm-addon-search@0.10.0-beta.3:
|
||||
version "0.10.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a"
|
||||
|
@ -78,12 +83,12 @@ xterm-addon-unicode11@0.4.0-beta.3:
|
|||
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa"
|
||||
integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q==
|
||||
|
||||
xterm-addon-webgl@0.13.0-beta.9:
|
||||
version "0.13.0-beta.9"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb"
|
||||
integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g==
|
||||
xterm-addon-webgl@0.13.0-beta.32:
|
||||
version "0.13.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212"
|
||||
integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw==
|
||||
|
||||
xterm@4.20.0-beta.20:
|
||||
version "4.20.0-beta.20"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed"
|
||||
integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ==
|
||||
xterm@5.0.0-beta.32:
|
||||
version "5.0.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c"
|
||||
integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA==
|
||||
|
|
|
@ -788,6 +788,11 @@ wrappy@1:
|
|||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xterm-addon-canvas@0.2.0-beta.15:
|
||||
version "0.2.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4"
|
||||
integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw==
|
||||
|
||||
xterm-addon-search@0.10.0-beta.3:
|
||||
version "0.10.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a"
|
||||
|
@ -803,20 +808,20 @@ xterm-addon-unicode11@0.4.0-beta.3:
|
|||
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa"
|
||||
integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q==
|
||||
|
||||
xterm-addon-webgl@0.13.0-beta.9:
|
||||
version "0.13.0-beta.9"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb"
|
||||
integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g==
|
||||
xterm-addon-webgl@0.13.0-beta.32:
|
||||
version "0.13.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212"
|
||||
integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw==
|
||||
|
||||
xterm-headless@4.20.0-beta.20:
|
||||
version "4.20.0-beta.20"
|
||||
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.20.0-beta.20.tgz#da2d8131b02d6f1e37f47cc17e578f2c2980fbb6"
|
||||
integrity sha512-JK4jUIiUH7TdzvMrpfDnbGxTuC4s7byjqnMHR8+gIpY8qCFjz0xcMFSbp+ZshxGwVyziI4jtJqTHZjFToT2/kw==
|
||||
xterm-headless@5.0.0-beta.5:
|
||||
version "5.0.0-beta.5"
|
||||
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.0.0-beta.5.tgz#e29b6c5081f31f887122b7263ba996b0c46b3c22"
|
||||
integrity sha512-CMQ1+prBNF92oBMeZzc2rfTcmOaCGfwwSaoPYNTjyziZT6mZsEg7amajYkb0YAnqJ29MFm4kPGZbU78/dX4k2A==
|
||||
|
||||
xterm@4.20.0-beta.20:
|
||||
version "4.20.0-beta.20"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed"
|
||||
integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ==
|
||||
xterm@5.0.0-beta.32:
|
||||
version "5.0.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c"
|
||||
integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
|
|
@ -11,7 +11,7 @@ Icon: @@NAME@@.xpm
|
|||
Requires: @@DEPENDENCIES@@
|
||||
AutoReq: 0
|
||||
|
||||
%global __provides_exclude_from ^%{_datadir}/@@NAME@@/.*\\.so.*$
|
||||
%global __provides_exclude_from ^%{_datadir}/%{name}/.*\\.so.*$
|
||||
|
||||
%description
|
||||
Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ.
|
||||
|
@ -21,25 +21,29 @@ Visual Studio Code is a new choice of tool that combines the simplicity of a cod
|
|||
%define _build_id_links none
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}/usr/bin
|
||||
mkdir -p %{buildroot}/usr/share/@@NAME@@
|
||||
mkdir -p %{buildroot}/usr/share/applications
|
||||
mkdir -p %{buildroot}/usr/share/pixmaps
|
||||
mkdir -p %{buildroot}/usr/share/bash-completion/completions
|
||||
mkdir -p %{buildroot}/usr/share/zsh/site-functions
|
||||
mkdir -p %{buildroot}/usr/share/mime/packages
|
||||
cp -r usr/share/@@NAME@@/* %{buildroot}/usr/share/@@NAME@@
|
||||
cp -r usr/share/applications/@@NAME@@.desktop %{buildroot}/usr/share/applications
|
||||
cp -r usr/share/applications/@@NAME@@-url-handler.desktop %{buildroot}/usr/share/applications
|
||||
cp -r usr/share/mime/packages/@@NAME@@-workspace.xml %{buildroot}/usr/share/mime/packages/@@NAME@@-workspace.xml
|
||||
cp -r usr/share/pixmaps/@@ICON@@.png %{buildroot}/usr/share/pixmaps
|
||||
cp usr/share/bash-completion/completions/@@NAME@@ %{buildroot}/usr/share/bash-completion/completions/@@NAME@@
|
||||
cp usr/share/zsh/site-functions/_@@NAME@@ %{buildroot}/usr/share/zsh/site-functions/_@@NAME@@
|
||||
ln -s ../share/@@NAME@@/bin/@@NAME@@ %{buildroot}/usr/bin/@@NAME@@
|
||||
# Destination directories
|
||||
mkdir -p %{buildroot}%{_bindir}
|
||||
mkdir -p %{buildroot}%{_datadir}/%{name}
|
||||
mkdir -p %{buildroot}%{_datadir}/applications
|
||||
mkdir -p %{buildroot}%{_datadir}/mime/packages
|
||||
mkdir -p %{buildroot}%{_datadir}/pixmaps
|
||||
mkdir -p %{buildroot}%{_datadir}/bash-completion/completions
|
||||
mkdir -p %{buildroot}%{_datadir}/zsh/site-functions
|
||||
# Application
|
||||
cp -r usr/share/%{name}/* %{buildroot}%{_datadir}/%{name}
|
||||
ln -s %{_datadir}/%{name}/bin/%{name} %{buildroot}%{_bindir}/%{name}
|
||||
# Support files
|
||||
cp -r usr/share/applications/%{name}.desktop %{buildroot}%{_datadir}/applications
|
||||
cp -r usr/share/applications/%{name}-url-handler.desktop %{buildroot}%{_datadir}/applications
|
||||
cp -r usr/share/mime/packages/%{name}-workspace.xml %{buildroot}%{_datadir}/mime/packages/%{name}-workspace.xml
|
||||
cp -r usr/share/pixmaps/@@ICON@@.png %{buildroot}%{_datadir}/pixmaps
|
||||
# Shell completions
|
||||
cp usr/share/bash-completion/completions/%{name} %{buildroot}%{_datadir}/bash-completion/completions/%{name}
|
||||
cp usr/share/zsh/site-functions/_%{name} %{buildroot}%{_datadir}/zsh/site-functions/_%{name}
|
||||
|
||||
%post
|
||||
# Remove the legacy bin command if this is the stable build
|
||||
if [ "@@NAME@@" = "code" ]; then
|
||||
if [ "%{name}" = "code" ]; then
|
||||
rm -f /usr/local/bin/code
|
||||
fi
|
||||
|
||||
|
@ -54,21 +58,21 @@ fi
|
|||
#fi
|
||||
|
||||
# Update mimetype database to pickup workspace mimetype
|
||||
update-mime-database /usr/share/mime &> /dev/null || :
|
||||
update-mime-database %{_datadir}/mime &> /dev/null || :
|
||||
|
||||
%postun
|
||||
# Update mimetype database for removed workspace mimetype
|
||||
update-mime-database /usr/share/mime &> /dev/null || :
|
||||
update-mime-database %{_datadir}/mime &> /dev/null || :
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%attr(4755, root, root) /usr/share/@@NAME@@/chrome-sandbox
|
||||
%attr(4755, root, root) %{_datadir}/%{name}/chrome-sandbox
|
||||
|
||||
/usr/bin/@@NAME@@
|
||||
/usr/share/@@NAME@@/
|
||||
/usr/share/applications/@@NAME@@.desktop
|
||||
/usr/share/applications/@@NAME@@-url-handler.desktop
|
||||
/usr/share/mime/packages/@@NAME@@-workspace.xml
|
||||
/usr/share/pixmaps/@@ICON@@.png
|
||||
/usr/share/bash-completion/completions/@@NAME@@
|
||||
/usr/share/zsh/site-functions/_@@NAME@@
|
||||
%{_bindir}/%{name}
|
||||
%{_datadir}/%{name}/
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_datadir}/applications/%{name}-url-handler.desktop
|
||||
%{_datadir}/mime/packages/%{name}-workspace.xml
|
||||
%{_datadir}/pixmaps/@@ICON@@.png
|
||||
%{_datadir}/bash-completion/completions/%{name}
|
||||
%{_datadir}/zsh/site-functions/_%{name}
|
||||
|
|
|
@ -8,6 +8,7 @@ const path = require('path');
|
|||
|
||||
const moduleNames = [
|
||||
'xterm',
|
||||
'xterm-addon-canvas',
|
||||
'xterm-addon-search',
|
||||
'xterm-addon-unicode11',
|
||||
'xterm-addon-webgl'
|
||||
|
@ -30,7 +31,17 @@ function getLatestModuleVersion(moduleName) {
|
|||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
const versions = JSON.parse(stdout);
|
||||
let versions = JSON.parse(stdout);
|
||||
// HACK: Some bad versions were published as v5 which cannot be unpublished, ignore these
|
||||
if (moduleName === 'xterm-addon-canvas') {
|
||||
versions = versions.filter(e => ![
|
||||
'0.12.0',
|
||||
'5.0.0-beta.1',
|
||||
'5.0.0-beta.2',
|
||||
'5.0.0-beta.3',
|
||||
'5.0.0-beta.4',
|
||||
].includes(e));
|
||||
}
|
||||
resolve(versions[versions.length - 1]);
|
||||
});
|
||||
});
|
||||
|
|
3
src/bootstrap-window.js
vendored
3
src/bootstrap-window.js
vendored
|
@ -136,6 +136,7 @@
|
|||
'vscode-textmate': `${baseNodeModulesPath}/vscode-textmate/release/main.js`,
|
||||
'vscode-oniguruma': `${baseNodeModulesPath}/vscode-oniguruma/release/main.js`,
|
||||
'xterm': `${baseNodeModulesPath}/xterm/lib/xterm.js`,
|
||||
'xterm-addon-canvas': `${baseNodeModulesPath}/xterm-addon-canvas/lib/xterm-addon-canvas.js`,
|
||||
'xterm-addon-search': `${baseNodeModulesPath}/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-unicode11': `${baseNodeModulesPath}/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`,
|
||||
'xterm-addon-webgl': `${baseNodeModulesPath}/xterm-addon-webgl/lib/xterm-addon-webgl.js`,
|
||||
|
@ -150,7 +151,7 @@
|
|||
// which has a fallback to using node.js `require`
|
||||
// (node.js enabled renderers only)
|
||||
if (!safeProcess.sandboxed) {
|
||||
loaderConfig.amdModulesPattern = /(^vs\/)|(^vscode-textmate$)|(^vscode-oniguruma$)|(^xterm$)|(^xterm-addon-search$)|(^xterm-addon-unicode11$)|(^xterm-addon-webgl$)|(^@vscode\/iconv-lite-umd$)|(^jschardet$)|(^@vscode\/vscode-languagedetection$)|(^vscode-regexp-languagedetection$)|(^tas-client-umd$)/;
|
||||
loaderConfig.amdModulesPattern = /(^vs\/)|(^vscode-textmate$)|(^vscode-oniguruma$)|(^xterm$)|(^xterm-addon-canvas$)|(^xterm-addon-search$)|(^xterm-addon-unicode11$)|(^xterm-addon-webgl$)|(^@vscode\/iconv-lite-umd$)|(^jschardet$)|(^@vscode\/vscode-languagedetection$)|(^vscode-regexp-languagedetection$)|(^tas-client-umd$)/;
|
||||
}
|
||||
|
||||
// Signal before require.config()
|
||||
|
|
Binary file not shown.
|
@ -96,10 +96,10 @@ export class HighlightedLabel {
|
|||
if (pos < highlight.start) {
|
||||
const substring = this.text.substring(pos, highlight.start);
|
||||
children.push(dom.$('span', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]));
|
||||
pos = highlight.end;
|
||||
pos = highlight.start;
|
||||
}
|
||||
|
||||
const substring = this.text.substring(highlight.start, highlight.end);
|
||||
const substring = this.text.substring(pos, highlight.end);
|
||||
const element = dom.$('span.highlight', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]);
|
||||
|
||||
if (highlight.extraClasses) {
|
||||
|
|
|
@ -829,3 +829,79 @@ export class ArrayQueue<T> {
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is faster than an iterator and array for lazy computed data.
|
||||
*/
|
||||
export class CallbackIterable<T> {
|
||||
public static readonly empty = new CallbackIterable<never>(_callback => { });
|
||||
|
||||
constructor(
|
||||
/**
|
||||
* Calls the callback for every item.
|
||||
* Stops when the callback returns false.
|
||||
*/
|
||||
public readonly iterate: (callback: (item: T) => boolean) => void
|
||||
) {
|
||||
}
|
||||
|
||||
forEach(handler: (item: T) => void) {
|
||||
this.iterate(item => { handler(item); return true; });
|
||||
}
|
||||
|
||||
toArray(): T[] {
|
||||
const result: T[] = [];
|
||||
this.iterate(item => { result.push(item); return true; });
|
||||
return result;
|
||||
}
|
||||
|
||||
filter(predicate: (item: T) => boolean): CallbackIterable<T> {
|
||||
return new CallbackIterable(cb => this.iterate(item => predicate(item) ? cb(item) : true));
|
||||
}
|
||||
|
||||
map<TResult>(mapFn: (item: T) => TResult): CallbackIterable<TResult> {
|
||||
return new CallbackIterable<TResult>(cb => this.iterate(item => cb(mapFn(item))));
|
||||
}
|
||||
|
||||
some(predicate: (item: T) => boolean): boolean {
|
||||
let result = false;
|
||||
this.iterate(item => { result = predicate(item); return !result; });
|
||||
return result;
|
||||
}
|
||||
|
||||
findFirst(predicate: (item: T) => boolean): T | undefined {
|
||||
let result: T | undefined;
|
||||
this.iterate(item => {
|
||||
if (predicate(item)) {
|
||||
result = item;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
findLast(predicate: (item: T) => boolean): T | undefined {
|
||||
let result: T | undefined;
|
||||
this.iterate(item => {
|
||||
if (predicate(item)) {
|
||||
result = item;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
findLastMaxBy(comparator: Comparator<T>): T | undefined {
|
||||
let result: T | undefined;
|
||||
let first = true;
|
||||
this.iterate(item => {
|
||||
if (first || CompareResult.isGreaterThan(comparator(item, result!))) {
|
||||
first = false;
|
||||
result = item;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,11 +94,12 @@ export class Codicon implements CSSIcon {
|
|||
public static readonly eyeUnwatch = new Codicon('eye-unwatch', { fontCharacter: '\\ea70' });
|
||||
public static readonly eyeWatch = new Codicon('eye-watch', { fontCharacter: '\\ea70' });
|
||||
public static readonly circleFilled = new Codicon('circle-filled', { fontCharacter: '\\ea71' });
|
||||
public static readonly primitiveDot = new Codicon('primitive-dot', { fontCharacter: '\\ea71' });
|
||||
public static readonly closeDirty = new Codicon('close-dirty', { fontCharacter: '\\ea71' });
|
||||
public static readonly debugBreakpoint = new Codicon('debug-breakpoint', { fontCharacter: '\\ea71' });
|
||||
public static readonly debugBreakpointDisabled = new Codicon('debug-breakpoint-disabled', { fontCharacter: '\\ea71' });
|
||||
public static readonly debugHint = new Codicon('debug-hint', { fontCharacter: '\\ea71' });
|
||||
public static readonly primitiveDot = new Codicon('primitive-dot', Codicon.circleFilled.definition);
|
||||
public static readonly closeDirty = new Codicon('close-dirty', Codicon.circleFilled.definition);
|
||||
public static readonly terminalDecorationSuccess = new Codicon('terminal-decoration-success', Codicon.circleFilled.definition);
|
||||
public static readonly debugBreakpoint = new Codicon('debug-breakpoint', Codicon.circleFilled.definition);
|
||||
public static readonly debugBreakpointDisabled = new Codicon('debug-breakpoint-disabled', Codicon.circleFilled.definition);
|
||||
public static readonly debugHint = new Codicon('debug-hint', Codicon.circleFilled.definition);
|
||||
public static readonly primitiveSquare = new Codicon('primitive-square', { fontCharacter: '\\ea72' });
|
||||
public static readonly edit = new Codicon('edit', { fontCharacter: '\\ea73' });
|
||||
public static readonly pencil = new Codicon('pencil', { fontCharacter: '\\ea73' });
|
||||
|
@ -218,8 +219,10 @@ export class Codicon implements CSSIcon {
|
|||
public static readonly chromeMaximize = new Codicon('chrome-maximize', { fontCharacter: '\\eab9' });
|
||||
public static readonly chromeMinimize = new Codicon('chrome-minimize', { fontCharacter: '\\eaba' });
|
||||
public static readonly chromeRestore = new Codicon('chrome-restore', { fontCharacter: '\\eabb' });
|
||||
public static readonly circleOutline = new Codicon('circle-outline', { fontCharacter: '\\eabc' });
|
||||
public static readonly debugBreakpointUnverified = new Codicon('debug-breakpoint-unverified', { fontCharacter: '\\eabc' });
|
||||
public static readonly circle = new Codicon('circle', { fontCharacter: '\\eabc' });
|
||||
public static readonly circleOutline = new Codicon('circle-outline', Codicon.circle.definition);
|
||||
public static readonly terminalDecorationIncomplete = new Codicon('terminal-decoration-incomplete', Codicon.circle.definition);
|
||||
public static readonly debugBreakpointUnverified = new Codicon('debug-breakpoint-unverified', Codicon.circle.definition);
|
||||
public static readonly circleSlash = new Codicon('circle-slash', { fontCharacter: '\\eabd' });
|
||||
public static readonly circuitBoard = new Codicon('circuit-board', { fontCharacter: '\\eabe' });
|
||||
public static readonly clearAll = new Codicon('clear-all', { fontCharacter: '\\eabf' });
|
||||
|
@ -430,6 +433,7 @@ export class Codicon implements CSSIcon {
|
|||
public static readonly debugStackframeActive = new Codicon('debug-stackframe-active', { fontCharacter: '\\eb89' });
|
||||
public static readonly circleSmallFilled = new Codicon('circle-small-filled', { fontCharacter: '\\eb8a' });
|
||||
public static readonly debugStackframeDot = new Codicon('debug-stackframe-dot', Codicon.circleSmallFilled.definition);
|
||||
public static readonly terminalDecorationMark = new Codicon('terminal-decoration-mark', Codicon.circleSmallFilled.definition);
|
||||
public static readonly debugStackframe = new Codicon('debug-stackframe', { fontCharacter: '\\eb8b' });
|
||||
public static readonly debugStackframeFocused = new Codicon('debug-stackframe-focused', { fontCharacter: '\\eb8b' });
|
||||
public static readonly debugBreakpointUnsupported = new Codicon('debug-breakpoint-unsupported', { fontCharacter: '\\eb8c' });
|
||||
|
@ -473,7 +477,8 @@ export class Codicon implements CSSIcon {
|
|||
public static readonly pinnedDirty = new Codicon('pinned-dirty', { fontCharacter: '\\ebb2' });
|
||||
public static readonly passFilled = new Codicon('pass-filled', { fontCharacter: '\\ebb3' });
|
||||
public static readonly circleLargeFilled = new Codicon('circle-large-filled', { fontCharacter: '\\ebb4' });
|
||||
public static readonly circleLargeOutline = new Codicon('circle-large-outline', { fontCharacter: '\\ebb5' });
|
||||
public static readonly circleLarge = new Codicon('circle-large', { fontCharacter: '\\ebb5' });
|
||||
public static readonly circleLargeOutline = new Codicon('circle-large-outline', Codicon.circleLarge.definition);
|
||||
public static readonly combine = new Codicon('combine', { fontCharacter: '\\ebb6' });
|
||||
public static readonly gather = new Codicon('gather', { fontCharacter: '\\ebb6' });
|
||||
public static readonly table = new Codicon('table', { fontCharacter: '\\ebb7' });
|
||||
|
@ -549,6 +554,7 @@ export class Codicon implements CSSIcon {
|
|||
public static readonly indent = new Codicon('indent', { fontCharacter: '\\ebf9' });
|
||||
public static readonly recordSmall = new Codicon('record-small', { fontCharacter: '\\ebfa' });
|
||||
public static readonly errorSmall = new Codicon('error-small', { fontCharacter: '\\ebfb' });
|
||||
public static readonly terminalDecorationError = new Codicon('terminal-decoration-error', Codicon.errorSmall.definition);
|
||||
public static readonly arrowCircleDown = new Codicon('arrow-circle-down', { fontCharacter: '\\ebfc' });
|
||||
public static readonly arrowCircleLeft = new Codicon('arrow-circle-left', { fontCharacter: '\\ebfd' });
|
||||
public static readonly arrowCircleRight = new Codicon('arrow-circle-right', { fontCharacter: '\\ebfe' });
|
||||
|
|
|
@ -136,6 +136,12 @@ export interface WebSocketCloseEvent {
|
|||
|
||||
export type SocketCloseEvent = NodeSocketCloseEvent | WebSocketCloseEvent | undefined;
|
||||
|
||||
export interface SocketTimeoutEvent {
|
||||
readonly unacknowledgedMsgCount: number;
|
||||
readonly timeSinceOldestUnacknowledgedMsg: number;
|
||||
readonly timeSinceLastReceivedSomeData: number;
|
||||
}
|
||||
|
||||
export interface ISocket extends IDisposable {
|
||||
onData(listener: (e: VSBuffer) => void): IDisposable;
|
||||
onClose(listener: (e: SocketCloseEvent) => void): IDisposable;
|
||||
|
@ -667,6 +673,16 @@ class Queue<T> {
|
|||
this._last = null;
|
||||
}
|
||||
|
||||
public length(): number {
|
||||
let result = 0;
|
||||
let current = this._first;
|
||||
while (current) {
|
||||
current = current.next;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public peek(): T | null {
|
||||
if (!this._first) {
|
||||
return null;
|
||||
|
@ -800,8 +816,8 @@ export class PersistentProtocol implements IMessagePassingProtocol {
|
|||
private readonly _onSocketClose = new BufferedEmitter<SocketCloseEvent>();
|
||||
readonly onSocketClose: Event<SocketCloseEvent> = this._onSocketClose.event;
|
||||
|
||||
private readonly _onSocketTimeout = new BufferedEmitter<void>();
|
||||
readonly onSocketTimeout: Event<void> = this._onSocketTimeout.event;
|
||||
private readonly _onSocketTimeout = new BufferedEmitter<SocketTimeoutEvent>();
|
||||
readonly onSocketTimeout: Event<SocketTimeoutEvent> = this._onSocketTimeout.event;
|
||||
|
||||
public get unacknowledgedCount(): number {
|
||||
return this._outgoingMsgId - this._outgoingAckId;
|
||||
|
@ -1081,7 +1097,11 @@ export class PersistentProtocol implements IMessagePassingProtocol {
|
|||
if (!this._loadEstimator.hasHighLoad()) {
|
||||
// Trash the socket
|
||||
this._lastSocketTimeoutTime = Date.now();
|
||||
this._onSocketTimeout.fire(undefined);
|
||||
this._onSocketTimeout.fire({
|
||||
unacknowledgedMsgCount: this._outgoingUnackMsg.length(),
|
||||
timeSinceOldestUnacknowledgedMsg,
|
||||
timeSinceLastReceivedSomeData
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1021,7 +1021,7 @@ export class Minimap extends ViewPart implements IMinimapModel {
|
|||
} else {
|
||||
visibleRange = new Range(startLineNumber, 1, endLineNumber, this._context.viewModel.getLineMaxColumn(endLineNumber));
|
||||
}
|
||||
const decorations = this._context.viewModel.getDecorationsInViewport(visibleRange);
|
||||
const decorations = this._context.viewModel.getDecorationsInViewport(visibleRange, true);
|
||||
|
||||
if (this._samplingState) {
|
||||
const result: ViewModelDecoration[] = [];
|
||||
|
|
|
@ -945,7 +945,7 @@ export interface ITextModel {
|
|||
* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).
|
||||
* @return An array with the decorations
|
||||
*/
|
||||
getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[];
|
||||
getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[];
|
||||
|
||||
/**
|
||||
* Gets all the decorations as an array.
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CallbackIterable, compareBy } from 'vs/base/common/arrays';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, IDisposable, IReference, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { LineTokens } from 'vs/editor/common/tokens/lineTokens';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { BracketPairsTree } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree';
|
||||
import { BracketInfo, BracketPairInfo, BracketPairWithMinIndentationInfo, IBracketPairsTextModelPart, IFoundBracket } from 'vs/editor/common/textModelBracketPairs';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents';
|
||||
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
|
||||
import { ignoreBracketsInToken } from 'vs/editor/common/languages/supports';
|
||||
import { RichEditBrackets, BracketsUtils, RichEditBracket } from 'vs/editor/common/languages/supports/richEditBrackets';
|
||||
import { compareBy, findLast, findLastMaxBy } from 'vs/base/common/arrays';
|
||||
import { LanguageBracketsConfiguration } from 'vs/editor/common/languages/supports/languageBracketsConfiguration';
|
||||
import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/common/languages/supports/richEditBrackets';
|
||||
import { BracketPairsTree } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { BracketInfo, BracketPairInfo, BracketPairWithMinIndentationInfo, IBracketPairsTextModelPart, IFoundBracket } from 'vs/editor/common/textModelBracketPairs';
|
||||
import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents';
|
||||
import { LineTokens } from 'vs/editor/common/tokens/lineTokens';
|
||||
|
||||
export class BracketPairsTextModelPart extends Disposable implements IBracketPairsTextModelPart {
|
||||
private readonly bracketPairsTree = this._register(new MutableDisposable<IReference<BracketPairsTree>>());
|
||||
|
@ -102,22 +102,22 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai
|
|||
* Returns all bracket pairs that intersect the given range.
|
||||
* The result is sorted by the start position.
|
||||
*/
|
||||
public getBracketPairsInRange(range: Range): BracketPairInfo[] {
|
||||
public getBracketPairsInRange(range: Range): CallbackIterable<BracketPairInfo> {
|
||||
this.bracketsRequested = true;
|
||||
this.updateBracketPairsTree();
|
||||
return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, false) || [];
|
||||
return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, false) || CallbackIterable.empty;
|
||||
}
|
||||
|
||||
public getBracketPairsInRangeWithMinIndentation(range: Range): BracketPairWithMinIndentationInfo[] {
|
||||
public getBracketPairsInRangeWithMinIndentation(range: Range): CallbackIterable<BracketPairWithMinIndentationInfo> {
|
||||
this.bracketsRequested = true;
|
||||
this.updateBracketPairsTree();
|
||||
return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, true) || [];
|
||||
return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, true) || CallbackIterable.empty;
|
||||
}
|
||||
|
||||
public getBracketsInRange(range: Range): BracketInfo[] {
|
||||
public getBracketsInRange(range: Range): CallbackIterable<BracketInfo> {
|
||||
this.bracketsRequested = true;
|
||||
this.updateBracketPairsTree();
|
||||
return this.bracketPairsTree.value?.object.getBracketsInRange(range) || [];
|
||||
return this.bracketPairsTree.value?.object.getBracketsInRange(range) || CallbackIterable.empty;
|
||||
}
|
||||
|
||||
public findMatchingBracketUp(_bracket: string, _position: IPosition, maxDuration?: number): Range | null {
|
||||
|
@ -133,7 +133,7 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai
|
|||
return null;
|
||||
}
|
||||
|
||||
const bracketPair = findLast(this.getBracketPairsInRange(Range.fromPositions(_position, _position)) || [], (b) =>
|
||||
const bracketPair = this.getBracketPairsInRange(Range.fromPositions(_position, _position)).findLast((b) =>
|
||||
closingBracketInfo.closes(b.openingBracketInfo)
|
||||
);
|
||||
|
||||
|
@ -163,7 +163,7 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai
|
|||
|
||||
public matchBracket(position: IPosition, maxDuration?: number): [Range, Range] | null {
|
||||
if (this.canBuildAST) {
|
||||
const bracketPair = findLastMaxBy(
|
||||
const bracketPair =
|
||||
this.getBracketPairsInRange(
|
||||
Range.fromPositions(position, position)
|
||||
).filter(
|
||||
|
@ -171,15 +171,15 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai
|
|||
item.closingBracketRange !== undefined &&
|
||||
(item.openingBracketRange.containsPosition(position) ||
|
||||
item.closingBracketRange.containsPosition(position))
|
||||
),
|
||||
compareBy(
|
||||
(item) =>
|
||||
item.openingBracketRange.containsPosition(position)
|
||||
? item.openingBracketRange
|
||||
: item.closingBracketRange,
|
||||
Range.compareRangesUsingStarts
|
||||
)
|
||||
);
|
||||
).findLastMaxBy(
|
||||
compareBy(
|
||||
(item) =>
|
||||
item.openingBracketRange.containsPosition(position)
|
||||
? item.openingBracketRange
|
||||
: item.closingBracketRange,
|
||||
Range.compareRangesUsingStarts
|
||||
)
|
||||
);
|
||||
if (bracketPair) {
|
||||
return [bracketPair.openingBracketRange, bracketPair.closingBracketRange!];
|
||||
}
|
||||
|
@ -674,10 +674,10 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai
|
|||
|
||||
if (this.canBuildAST) {
|
||||
const range = Range.fromPositions(position);
|
||||
const bracketPair = findLast(
|
||||
this.getBracketPairsInRange(Range.fromPositions(position, position)),
|
||||
(item) => item.closingBracketRange !== undefined && item.range.strictContainsRange(range)
|
||||
);
|
||||
const bracketPair =
|
||||
this.getBracketPairsInRange(Range.fromPositions(position, position)).findLast(
|
||||
(item) => item.closingBracketRange !== undefined && item.range.strictContainsRange(range)
|
||||
);
|
||||
if (bracketPair) {
|
||||
return [bracketPair.openingBracketRange, bracketPair.closingBracketRange!];
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import { DenseKeyProvider } from './smallImmutableSet';
|
|||
import { FastTokenizer, TextBufferTokenizer } from './tokenizer';
|
||||
import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { CallbackIterable } from 'vs/base/common/arrays';
|
||||
|
||||
export class BracketPairsTree extends Disposable {
|
||||
private readonly didChangeEmitter = new Emitter<void>();
|
||||
|
@ -125,26 +126,24 @@ export class BracketPairsTree extends Disposable {
|
|||
return result;
|
||||
}
|
||||
|
||||
public getBracketsInRange(range: Range): BracketInfo[] {
|
||||
public getBracketsInRange(range: Range): CallbackIterable<BracketInfo> {
|
||||
const startOffset = toLength(range.startLineNumber - 1, range.startColumn - 1);
|
||||
const endOffset = toLength(range.endLineNumber - 1, range.endColumn - 1);
|
||||
const result = new Array<BracketInfo>();
|
||||
const node = this.initialAstWithoutTokens || this.astWithTokens!;
|
||||
collectBrackets(node, lengthZero, node.length, startOffset, endOffset, result, 0, new Map());
|
||||
return result;
|
||||
return new CallbackIterable(cb => {
|
||||
const node = this.initialAstWithoutTokens || this.astWithTokens!;
|
||||
collectBrackets(node, lengthZero, node.length, startOffset, endOffset, cb, 0, new Map());
|
||||
});
|
||||
}
|
||||
|
||||
public getBracketPairsInRange(range: Range, includeMinIndentation: boolean): BracketPairWithMinIndentationInfo[] {
|
||||
const result = new Array<BracketPairWithMinIndentationInfo>();
|
||||
|
||||
public getBracketPairsInRange(range: Range, includeMinIndentation: boolean): CallbackIterable<BracketPairWithMinIndentationInfo> {
|
||||
const startLength = positionToLength(range.getStartPosition());
|
||||
const endLength = positionToLength(range.getEndPosition());
|
||||
|
||||
const node = this.initialAstWithoutTokens || this.astWithTokens!;
|
||||
const context = new CollectBracketPairsContext(result, includeMinIndentation, this.textModel);
|
||||
collectBracketPairs(node, lengthZero, node.length, startLength, endLength, context, 0, new Map());
|
||||
|
||||
return result;
|
||||
return new CallbackIterable(cb => {
|
||||
const node = this.initialAstWithoutTokens || this.astWithTokens!;
|
||||
const context = new CollectBracketPairsContext(cb, includeMinIndentation, this.textModel);
|
||||
collectBracketPairs(node, lengthZero, node.length, startLength, endLength, context, 0, new Map());
|
||||
});
|
||||
}
|
||||
|
||||
public getFirstBracketAfter(position: Position): IFoundBracket | null {
|
||||
|
@ -219,108 +218,105 @@ function collectBrackets(
|
|||
nodeOffsetEnd: Length,
|
||||
startOffset: Length,
|
||||
endOffset: Length,
|
||||
result: BracketInfo[],
|
||||
push: (item: BracketInfo) => boolean,
|
||||
level: number,
|
||||
levelPerBracketType: Map<string, number>
|
||||
): void {
|
||||
): boolean {
|
||||
if (level > 200) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node.kind === AstNodeKind.List) {
|
||||
for (const child of node.children) {
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
collectBrackets(
|
||||
child,
|
||||
nodeOffsetStart,
|
||||
nodeOffsetEnd,
|
||||
startOffset,
|
||||
endOffset,
|
||||
result,
|
||||
level,
|
||||
levelPerBracketType
|
||||
);
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
}
|
||||
} else if (node.kind === AstNodeKind.Pair) {
|
||||
let levelPerBracket = 0;
|
||||
if (levelPerBracketType) {
|
||||
let existing = levelPerBracketType.get(node.openingBracket.text);
|
||||
if (existing === undefined) {
|
||||
existing = 0;
|
||||
}
|
||||
levelPerBracket = existing;
|
||||
existing++;
|
||||
levelPerBracketType.set(node.openingBracket.text, existing);
|
||||
}
|
||||
whileLoop:
|
||||
while (true) {
|
||||
switch (node.kind) {
|
||||
case AstNodeKind.List: {
|
||||
const childCount = node.childrenLength;
|
||||
for (let i = 0; i < childCount; i++) {
|
||||
const child = node.getChild(i);
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);
|
||||
if (childEndsAfterEnd) {
|
||||
// No child after this child in the requested window, don't recurse
|
||||
node = child;
|
||||
continue whileLoop;
|
||||
}
|
||||
|
||||
// Don't use node.children here to improve performance
|
||||
{
|
||||
const child = node.openingBracket;
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
const shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level, levelPerBracketType);
|
||||
if (!shouldContinue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case AstNodeKind.Pair: {
|
||||
let levelPerBracket = 0;
|
||||
if (levelPerBracketType) {
|
||||
let existing = levelPerBracketType.get(node.openingBracket.text);
|
||||
if (existing === undefined) {
|
||||
existing = 0;
|
||||
}
|
||||
levelPerBracket = existing;
|
||||
existing++;
|
||||
levelPerBracketType.set(node.openingBracket.text, existing);
|
||||
}
|
||||
|
||||
const childCount = node.childrenLength;
|
||||
for (let i = 0; i < childCount; i++) {
|
||||
const child = node.getChild(i);
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);
|
||||
if (childEndsAfterEnd) {
|
||||
// No child after this child in the requested window, don't recurse
|
||||
node = child;
|
||||
level++;
|
||||
continue whileLoop;
|
||||
}
|
||||
|
||||
const shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracketType);
|
||||
if (!shouldContinue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
}
|
||||
|
||||
levelPerBracketType?.set(node.openingBracket.text, levelPerBracket);
|
||||
|
||||
return true;
|
||||
}
|
||||
case AstNodeKind.UnexpectedClosingBracket: {
|
||||
const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd);
|
||||
result.push(
|
||||
new BracketInfo(range, level, levelPerBracket, !node.closingBracket)
|
||||
);
|
||||
return push(new BracketInfo(range, level - 1, 0, true));
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
}
|
||||
|
||||
if (node.child) {
|
||||
const child = node.child;
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
collectBrackets(
|
||||
child,
|
||||
nodeOffsetStart,
|
||||
nodeOffsetEnd,
|
||||
startOffset,
|
||||
endOffset,
|
||||
result,
|
||||
level + 1,
|
||||
levelPerBracketType
|
||||
);
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
}
|
||||
if (node.closingBracket) {
|
||||
const child = node.closingBracket;
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
case AstNodeKind.Bracket: {
|
||||
const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd);
|
||||
result.push(new BracketInfo(range, level, levelPerBracket, false));
|
||||
return push(new BracketInfo(range, level - 1, 0, false));
|
||||
}
|
||||
nodeOffsetStart = nodeOffsetEnd;
|
||||
case AstNodeKind.Text:
|
||||
return true;
|
||||
}
|
||||
|
||||
levelPerBracketType?.set(node.openingBracket.text, levelPerBracket);
|
||||
} else if (node.kind === AstNodeKind.UnexpectedClosingBracket) {
|
||||
const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd);
|
||||
result.push(new BracketInfo(range, level - 1, 0, true));
|
||||
} else if (node.kind === AstNodeKind.Bracket) {
|
||||
const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd);
|
||||
result.push(new BracketInfo(range, level - 1, 0, false));
|
||||
}
|
||||
}
|
||||
|
||||
class CollectBracketPairsContext {
|
||||
constructor(
|
||||
public readonly result: BracketPairWithMinIndentationInfo[],
|
||||
public readonly push: (item: BracketPairWithMinIndentationInfo) => boolean,
|
||||
public readonly includeMinIndentation: boolean,
|
||||
public readonly textModel: ITextModel,
|
||||
) {
|
||||
|
@ -336,11 +332,13 @@ function collectBracketPairs(
|
|||
context: CollectBracketPairsContext,
|
||||
level: number,
|
||||
levelPerBracketType: Map<string, number>
|
||||
) {
|
||||
): boolean {
|
||||
if (level > 200) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
let shouldContinue = true;
|
||||
|
||||
if (node.kind === AstNodeKind.Pair) {
|
||||
let levelPerBracket = 0;
|
||||
if (levelPerBracketType) {
|
||||
|
@ -362,7 +360,7 @@ function collectBracketPairs(
|
|||
);
|
||||
}
|
||||
|
||||
context.result.push(
|
||||
shouldContinue = context.push(
|
||||
new BracketPairWithMinIndentationInfo(
|
||||
lengthsToRange(nodeOffsetStart, nodeOffsetEnd),
|
||||
lengthsToRange(nodeOffsetStart, openingBracketEnd),
|
||||
|
@ -380,14 +378,14 @@ function collectBracketPairs(
|
|||
);
|
||||
|
||||
nodeOffsetStart = openingBracketEnd;
|
||||
if (node.child) {
|
||||
if (shouldContinue && node.child) {
|
||||
const child = node.child;
|
||||
nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length);
|
||||
if (
|
||||
lengthLessThanEqual(nodeOffsetStart, endOffset) &&
|
||||
lengthGreaterThanEqual(nodeOffsetEnd, startOffset)
|
||||
) {
|
||||
collectBracketPairs(
|
||||
shouldContinue = collectBracketPairs(
|
||||
child,
|
||||
nodeOffsetStart,
|
||||
nodeOffsetEnd,
|
||||
|
@ -397,6 +395,9 @@ function collectBracketPairs(
|
|||
level + 1,
|
||||
levelPerBracketType
|
||||
);
|
||||
if (!shouldContinue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,7 +412,7 @@ function collectBracketPairs(
|
|||
lengthLessThanEqual(childOffset, endOffset) &&
|
||||
lengthLessThanEqual(startOffset, curOffset)
|
||||
) {
|
||||
collectBracketPairs(
|
||||
shouldContinue = collectBracketPairs(
|
||||
child,
|
||||
childOffset,
|
||||
curOffset,
|
||||
|
@ -421,8 +422,12 @@ function collectBracketPairs(
|
|||
level,
|
||||
levelPerBracketType
|
||||
);
|
||||
if (!shouldContinue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldContinue;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,11 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen
|
|||
|
||||
//#endregion
|
||||
|
||||
getDecorationsInRange(range: Range, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[] {
|
||||
getDecorationsInRange(range: Range, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[] {
|
||||
if (onlyMinimapDecorations) {
|
||||
// Bracket pair colorization decorations are not rendered in the minimap
|
||||
return [];
|
||||
}
|
||||
if (ownerId === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
@ -50,22 +54,20 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen
|
|||
return [];
|
||||
}
|
||||
|
||||
const result = new Array<IModelDecoration>();
|
||||
const bracketsInRange = this.textModel.bracketPairs.getBracketsInRange(range);
|
||||
for (const bracket of bracketsInRange) {
|
||||
result.push({
|
||||
id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`,
|
||||
options: {
|
||||
description: 'BracketPairColorization',
|
||||
inlineClassName: this.colorProvider.getInlineClassName(
|
||||
bracket,
|
||||
this.colorizationOptions.independentColorPoolPerBracketType
|
||||
),
|
||||
},
|
||||
ownerId: 0,
|
||||
range: bracket.range,
|
||||
});
|
||||
}
|
||||
const result = this.textModel.bracketPairs.getBracketsInRange(range).map<IModelDecoration>(bracket =>
|
||||
({
|
||||
id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`,
|
||||
options: {
|
||||
description: 'BracketPairColorization',
|
||||
inlineClassName: this.colorProvider.getInlineClassName(
|
||||
bracket,
|
||||
this.colorizationOptions.independentColorPoolPerBracketType
|
||||
),
|
||||
},
|
||||
ownerId: 0,
|
||||
range: bracket.range,
|
||||
})).toArray();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ export interface DecorationProvider {
|
|||
* @param ownerId If set, it will ignore decorations belonging to other owners.
|
||||
* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).
|
||||
*/
|
||||
getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[];
|
||||
getAllDecorations(ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[];
|
||||
|
||||
onDidChange: Event<void>;
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ export class GuidesTextModelPart extends TextModelPart implements IGuidesTextMod
|
|||
endLineNumber,
|
||||
this.textModel.getLineMaxColumn(endLineNumber)
|
||||
)
|
||||
);
|
||||
).toArray();
|
||||
|
||||
let activeBracketPairRange: Range | undefined = undefined;
|
||||
if (activePosition && bracketPairs.length > 0) {
|
||||
|
@ -303,7 +303,7 @@ export class GuidesTextModelPart extends TextModelPart implements IGuidesTextMod
|
|||
? bracketPairs
|
||||
: this.textModel.bracketPairs.getBracketPairsInRange(
|
||||
Range.fromPositions(activePosition)
|
||||
)
|
||||
).toArray()
|
||||
).filter((bp) => Range.strictContainsPosition(bp.range, activePosition));
|
||||
|
||||
activeBracketPairRange = findLast(
|
||||
|
|
|
@ -1714,11 +1714,11 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
|
|||
return decorations;
|
||||
}
|
||||
|
||||
public getDecorationsInRange(range: IRange, ownerId: number = 0, filterOutValidation: boolean = false): model.IModelDecoration[] {
|
||||
public getDecorationsInRange(range: IRange, ownerId: number = 0, filterOutValidation: boolean = false, onlyMinimapDecorations: boolean = false): model.IModelDecoration[] {
|
||||
const validatedRange = this.validateRange(range);
|
||||
|
||||
const decorations = this._getDecorationsInRange(validatedRange, ownerId, filterOutValidation);
|
||||
pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation));
|
||||
pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation, onlyMinimapDecorations));
|
||||
return decorations;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CallbackIterable } from 'vs/base/common/arrays';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
|
@ -19,15 +20,15 @@ export interface IBracketPairsTextModelPart {
|
|||
* Gets all bracket pairs that intersect the given position.
|
||||
* The result is sorted by the start position.
|
||||
*/
|
||||
getBracketPairsInRange(range: IRange): BracketPairInfo[];
|
||||
getBracketPairsInRange(range: IRange): CallbackIterable<BracketPairInfo>;
|
||||
|
||||
/**
|
||||
* Gets all bracket pairs that intersect the given position.
|
||||
* The result is sorted by the start position.
|
||||
*/
|
||||
getBracketPairsInRangeWithMinIndentation(range: IRange): BracketPairWithMinIndentationInfo[];
|
||||
getBracketPairsInRangeWithMinIndentation(range: IRange): CallbackIterable<BracketPairWithMinIndentationInfo>;
|
||||
|
||||
getBracketsInRange(range: IRange): BracketInfo[];
|
||||
getBracketsInRange(range: IRange): CallbackIterable<BracketInfo>;
|
||||
|
||||
/**
|
||||
* Find the matching bracket of `request` up, counting brackets.
|
||||
|
|
|
@ -40,7 +40,7 @@ export interface IViewModel extends ICursorSimpleModel {
|
|||
onCompositionStart(): void;
|
||||
onCompositionEnd(): void;
|
||||
|
||||
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
|
||||
getDecorationsInViewport(visibleRange: Range, onlyMinimapDecorations?: boolean): ViewModelDecoration[];
|
||||
getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;
|
||||
getViewLineRenderingData(lineNumber: number): ViewLineRenderingData;
|
||||
getViewLineData(lineNumber: number): ViewLineData;
|
||||
|
|
|
@ -36,6 +36,7 @@ export class ViewModelDecorations implements IDisposable {
|
|||
|
||||
private _cachedModelDecorationsResolver: IDecorationsViewportData | null;
|
||||
private _cachedModelDecorationsResolverViewRange: Range | null;
|
||||
private _cachedOnlyMinimapDecorations: boolean | null = null;
|
||||
|
||||
constructor(editorId: number, model: ITextModel, configuration: IEditorConfiguration, linesCollection: IViewModelLines, coordinatesConverter: ICoordinatesConverter) {
|
||||
this.editorId = editorId;
|
||||
|
@ -96,23 +97,25 @@ export class ViewModelDecorations implements IDisposable {
|
|||
return r;
|
||||
}
|
||||
|
||||
public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {
|
||||
public getDecorationsViewportData(viewRange: Range, onlyMinimapDecorations: boolean = false): IDecorationsViewportData {
|
||||
let cacheIsValid = (this._cachedModelDecorationsResolver !== null);
|
||||
cacheIsValid = cacheIsValid && (viewRange.equalsRange(this._cachedModelDecorationsResolverViewRange));
|
||||
cacheIsValid = cacheIsValid && (this._cachedOnlyMinimapDecorations === onlyMinimapDecorations);
|
||||
if (!cacheIsValid) {
|
||||
this._cachedModelDecorationsResolver = this._getDecorationsInRange(viewRange);
|
||||
this._cachedModelDecorationsResolver = this._getDecorationsInRange(viewRange, onlyMinimapDecorations);
|
||||
this._cachedModelDecorationsResolverViewRange = viewRange;
|
||||
this._cachedOnlyMinimapDecorations = onlyMinimapDecorations;
|
||||
}
|
||||
return this._cachedModelDecorationsResolver!;
|
||||
}
|
||||
|
||||
public getInlineDecorationsOnLine(lineNumber: number): InlineDecoration[] {
|
||||
public getInlineDecorationsOnLine(lineNumber: number, onlyMinimapDecorations: boolean = false): InlineDecoration[] {
|
||||
const range = new Range(lineNumber, this._linesCollection.getViewLineMinColumn(lineNumber), lineNumber, this._linesCollection.getViewLineMaxColumn(lineNumber));
|
||||
return this._getDecorationsInRange(range).inlineDecorations[0];
|
||||
return this._getDecorationsInRange(range, onlyMinimapDecorations).inlineDecorations[0];
|
||||
}
|
||||
|
||||
private _getDecorationsInRange(viewRange: Range): IDecorationsViewportData {
|
||||
const modelDecorations = this._linesCollection.getDecorationsInRange(viewRange, this.editorId, filterValidationDecorations(this.configuration.options));
|
||||
private _getDecorationsInRange(viewRange: Range, onlyMinimapDecorations: boolean): IDecorationsViewportData {
|
||||
const modelDecorations = this._linesCollection.getDecorationsInRange(viewRange, this.editorId, filterValidationDecorations(this.configuration.options), onlyMinimapDecorations);
|
||||
const startLineNumber = viewRange.startLineNumber;
|
||||
const endLineNumber = viewRange.endLineNumber;
|
||||
|
||||
|
|
|
@ -675,8 +675,8 @@ export class ViewModel extends Disposable implements IViewModel {
|
|||
return result + 2;
|
||||
}
|
||||
|
||||
public getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[] {
|
||||
return this._decorations.getDecorationsViewportData(visibleRange).decorations;
|
||||
public getDecorationsInViewport(visibleRange: Range, onlyMinimapDecorations: boolean = false): ViewModelDecoration[] {
|
||||
return this._decorations.getDecorationsViewportData(visibleRange, onlyMinimapDecorations).decorations;
|
||||
}
|
||||
|
||||
public getInjectedTextAt(viewPosition: Position): InjectedText | null {
|
||||
|
|
|
@ -45,7 +45,7 @@ export interface IViewModelLines extends IDisposable {
|
|||
getViewLineData(viewLineNumber: number): ViewLineData;
|
||||
getViewLinesData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): Array<ViewLineData | null>;
|
||||
|
||||
getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[];
|
||||
getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[];
|
||||
|
||||
getInjectedTextAt(viewPosition: Position): InjectedText | null;
|
||||
|
||||
|
@ -888,14 +888,14 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines {
|
|||
return this.modelLineProjections[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1));
|
||||
}
|
||||
|
||||
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] {
|
||||
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[] {
|
||||
const modelStart = this.convertViewPositionToModelPosition(range.startLineNumber, range.startColumn);
|
||||
const modelEnd = this.convertViewPositionToModelPosition(range.endLineNumber, range.endColumn);
|
||||
|
||||
if (modelEnd.lineNumber - modelStart.lineNumber <= range.endLineNumber - range.startLineNumber) {
|
||||
// most likely there are no hidden lines => fast path
|
||||
// fetch decorations from column 1 to cover the case of wrapped lines that have whole line decorations at column 1
|
||||
return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, 1, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation);
|
||||
return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, 1, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation, onlyMinimapDecorations);
|
||||
}
|
||||
|
||||
let result: IModelDecoration[] = [];
|
||||
|
@ -914,14 +914,14 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines {
|
|||
// hit invisible line => flush request
|
||||
if (reqStart !== null) {
|
||||
const maxLineColumn = this.model.getLineMaxColumn(modelLineIndex);
|
||||
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelLineIndex, maxLineColumn), ownerId, filterOutValidation));
|
||||
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelLineIndex, maxLineColumn), ownerId, filterOutValidation, onlyMinimapDecorations));
|
||||
reqStart = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reqStart !== null) {
|
||||
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation));
|
||||
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation, onlyMinimapDecorations));
|
||||
reqStart = null;
|
||||
}
|
||||
|
||||
|
@ -1221,8 +1221,8 @@ export class ViewModelLinesFromModelAsIs implements IViewModelLines {
|
|||
return result;
|
||||
}
|
||||
|
||||
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] {
|
||||
return this.model.getDecorationsInRange(range, ownerId, filterOutValidation);
|
||||
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[] {
|
||||
return this.model.getDecorationsInRange(range, ownerId, filterOutValidation, onlyMinimapDecorations);
|
||||
}
|
||||
|
||||
normalizePosition(position: Position, affinity: PositionAffinity): Position {
|
||||
|
|
|
@ -117,7 +117,6 @@ class CodeMenuRenderer implements IListRenderer<ICodeActionMenuItem, ICodeAction
|
|||
|
||||
element.isEnabled = element.action.enabled;
|
||||
|
||||
|
||||
if (element.action instanceof CodeActionAction) {
|
||||
|
||||
// Check documentation type
|
||||
|
@ -239,6 +238,15 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
|
|||
}
|
||||
}
|
||||
|
||||
private _onListClick(e: IListMouseEvent<ICodeActionMenuItem>): void {
|
||||
if (e.element) {
|
||||
if (!e.element.isEnabled) {
|
||||
this.currSelectedItem = undefined;
|
||||
this.codeActionList.value?.setFocus([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private renderCodeActionMenuList(element: HTMLElement, inputArray: IAction[]): IDisposable {
|
||||
const renderDisposables = new DisposableStore();
|
||||
const renderMenu = document.createElement('div');
|
||||
|
@ -275,12 +283,12 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
|
|||
}, [this.listRenderer], { keyboardSupport: false }
|
||||
);
|
||||
|
||||
renderDisposables.add(this.codeActionList.value.onMouseClick(e => this._onListClick(e)));
|
||||
renderDisposables.add(this.codeActionList.value.onMouseOver(e => this._onListHover(e)));
|
||||
renderDisposables.add(this.codeActionList.value.onDidChangeFocus(e => this.codeActionList.value?.domFocus()));
|
||||
renderDisposables.add(this.codeActionList.value.onDidChangeSelection(e => this._onListSelection(e)));
|
||||
renderDisposables.add(this._editor.onDidLayoutChange(e => this.hideCodeActionWidget()));
|
||||
|
||||
|
||||
// Populating the list widget and tracking enabled options.
|
||||
inputArray.forEach((item, index) => {
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeat
|
|||
import { OutlineModel, OutlineElement } from 'vs/editor/contrib/documentSymbols/browser/outlineModel';
|
||||
import { CancellationToken, CancellationTokenSource, } from 'vs/base/common/cancellation';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditorLayoutInfo, EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { createStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { SymbolKind } from 'vs/editor/common/languages';
|
||||
|
@ -68,6 +68,10 @@ class StickyScrollController extends Disposable implements IEditorContribution {
|
|||
this._sessionStore.add(this._editor.onDidLayoutChange(() => this._onDidResize()));
|
||||
this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule()));
|
||||
this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this._update(true)));
|
||||
const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers);
|
||||
if (lineNumberOption.renderType === RenderLineNumbersType.Relative) {
|
||||
this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this._update(false)));
|
||||
}
|
||||
this._update(true);
|
||||
}
|
||||
}
|
||||
|
@ -178,8 +182,7 @@ class StickyScrollController extends Disposable implements IEditorContribution {
|
|||
});
|
||||
let previous: number[] = [];
|
||||
for (const [index, arr] of this._ranges.entries()) {
|
||||
const [start, end, _depth] = arr;
|
||||
if (previous[0] === start && previous[1] === end) {
|
||||
if (previous[0] === arr[0]) {
|
||||
this._ranges.splice(index, 1);
|
||||
} else {
|
||||
previous = arr;
|
||||
|
@ -202,9 +205,8 @@ class StickyScrollController extends Disposable implements IEditorContribution {
|
|||
const scrollTop = this._editor.getScrollTop();
|
||||
|
||||
this.stickyScrollWidget.emptyRootNode();
|
||||
const beginningLinesConsidered: Set<number> = new Set<number>();
|
||||
|
||||
for (const [index, arr] of this._ranges.entries()) {
|
||||
for (const arr of this._ranges) {
|
||||
const [start, end, depth] = arr;
|
||||
if (end - start > 0) {
|
||||
const topOfElementAtDepth = (depth - 1) * lineHeight;
|
||||
|
@ -214,18 +216,12 @@ class StickyScrollController extends Disposable implements IEditorContribution {
|
|||
const topOfEndLine = this._editor.getTopForLineNumber(end) - scrollTop;
|
||||
const bottomOfEndLine = this._editor.getBottomForLineNumber(end) - scrollTop;
|
||||
|
||||
if (!beginningLinesConsidered.has(start)) {
|
||||
if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) {
|
||||
beginningLinesConsidered.add(start);
|
||||
this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth));
|
||||
break;
|
||||
}
|
||||
else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < bottomOfEndLine - 1) {
|
||||
beginningLinesConsidered.add(start);
|
||||
this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, 0, 0));
|
||||
}
|
||||
} else {
|
||||
this._ranges.splice(index, 1);
|
||||
if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) {
|
||||
this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth));
|
||||
break;
|
||||
}
|
||||
else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < bottomOfEndLine - 1) {
|
||||
this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +306,12 @@ class StickyScrollCodeLine extends Disposable {
|
|||
}
|
||||
|
||||
const innerLineNumberHTML = document.createElement('span');
|
||||
innerLineNumberHTML.innerText = this._lineNumber.toString();
|
||||
const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers);
|
||||
if (lineNumberOption.renderType === RenderLineNumbersType.On || lineNumberOption.renderType === RenderLineNumbersType.Interval && this._lineNumber % 10 === 0) {
|
||||
innerLineNumberHTML.innerText = this._lineNumber.toString();
|
||||
} else if (lineNumberOption.renderType === RenderLineNumbersType.Relative) {
|
||||
innerLineNumberHTML.innerText = Math.abs(this._lineNumber - this._editor.getPosition().lineNumber).toString();
|
||||
}
|
||||
innerLineNumberHTML.className = 'sticky-line-number';
|
||||
innerLineNumberHTML.style.lineHeight = `${lineHeight}px`;
|
||||
innerLineNumberHTML.style.width = `${layoutInfo.lineNumbersWidth}px`;
|
||||
|
|
|
@ -36,7 +36,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => {
|
|||
assert.deepStrictEqual(
|
||||
model.bracketPairs
|
||||
.getBracketPairsInRange(doc.range(1, 2))
|
||||
.map(bracketPairToJSON),
|
||||
.map(bracketPairToJSON)
|
||||
.toArray(),
|
||||
[
|
||||
{
|
||||
level: 0,
|
||||
|
@ -68,7 +69,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => {
|
|||
assert.deepStrictEqual(
|
||||
model.bracketPairs
|
||||
.getBracketPairsInRange(doc.range(1, 2))
|
||||
.map(bracketPairToJSON),
|
||||
.map(bracketPairToJSON)
|
||||
.toArray(),
|
||||
[
|
||||
{
|
||||
level: 0,
|
||||
|
@ -94,7 +96,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => {
|
|||
assert.deepStrictEqual(
|
||||
model.bracketPairs
|
||||
.getBracketPairsInRange(doc.range(1, 2))
|
||||
.map(bracketPairToJSON),
|
||||
.map(bracketPairToJSON)
|
||||
.toArray(),
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
@ -107,7 +110,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => {
|
|||
assert.deepStrictEqual(
|
||||
model.bracketPairs
|
||||
.getBracketPairsInRange(doc.range(1, 2))
|
||||
.map(bracketPairToJSON),
|
||||
.map(bracketPairToJSON)
|
||||
.toArray(),
|
||||
[
|
||||
{
|
||||
level: 0,
|
||||
|
|
2
src/vs/monaco.d.ts
vendored
2
src/vs/monaco.d.ts
vendored
|
@ -2010,7 +2010,7 @@ declare namespace monaco.editor {
|
|||
* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).
|
||||
* @return An array with the decorations
|
||||
*/
|
||||
getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[];
|
||||
getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[];
|
||||
/**
|
||||
* Gets all the decorations as an array.
|
||||
* @param ownerId If set, it will ignore decorations belonging to other owners.
|
||||
|
|
|
@ -64,6 +64,7 @@ export interface IProgressNotificationOptions extends IProgressOptions {
|
|||
readonly secondaryActions?: readonly IAction[];
|
||||
readonly delay?: number;
|
||||
readonly silent?: boolean;
|
||||
readonly type?: 'syncing' | 'loading';
|
||||
}
|
||||
|
||||
export interface IProgressDialogOptions extends IProgressOptions {
|
||||
|
|
|
@ -595,9 +595,9 @@ export abstract class PersistentConnection extends Disposable {
|
|||
}
|
||||
this._beginReconnecting();
|
||||
}));
|
||||
this._register(protocol.onSocketTimeout(() => {
|
||||
this._register(protocol.onSocketTimeout((e) => {
|
||||
const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
|
||||
this._options.logService.info(`${logPrefix} received socket timeout event.`);
|
||||
this._options.logService.info(`${logPrefix} received socket timeout event (unacknowledgedMsgCount: ${e.unacknowledgedMsgCount}, timeSinceOldestUnacknowledgedMsg: ${e.timeSinceOldestUnacknowledgedMsg}, timeSinceLastReceivedSomeData: ${e.timeSinceLastReceivedSomeData}).`);
|
||||
this._beginReconnecting();
|
||||
}));
|
||||
|
||||
|
|
|
@ -112,7 +112,8 @@ export const enum TerminalSettingId {
|
|||
ShellIntegrationDecorationIcon = 'terminal.integrated.shellIntegration.decorationIcon',
|
||||
ShellIntegrationDecorationIconError = 'terminal.integrated.shellIntegration.decorationIconError',
|
||||
ShellIntegrationDecorationIconSuccess = 'terminal.integrated.shellIntegration.decorationIconSuccess',
|
||||
ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history'
|
||||
ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history',
|
||||
SmoothScrolling = 'terminal.integrated.smoothScrolling'
|
||||
}
|
||||
|
||||
export const enum TerminalLogConstants {
|
||||
|
@ -167,14 +168,20 @@ export interface IPtyHostAttachTarget {
|
|||
icon: TerminalIcon | undefined;
|
||||
fixedDimensions: IFixedTerminalDimensions | undefined;
|
||||
environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined;
|
||||
reconnectionOwner?: string;
|
||||
task?: { label: string; id: string; lastTask: string; group?: string };
|
||||
reconnectionProperties?: IReconnectionProperties;
|
||||
waitOnExit?: WaitOnExitValue;
|
||||
hideFromUser?: boolean;
|
||||
isFeatureTerminal?: boolean;
|
||||
type?: TerminalType;
|
||||
}
|
||||
|
||||
export interface IReconnectionProperties {
|
||||
ownerId: string;
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
export interface IReconnectionTaskData { label: string; id: string; lastTask: string; group?: string }
|
||||
|
||||
export type TerminalType = 'Task' | 'Local' | undefined;
|
||||
|
||||
export enum TitleEventSource {
|
||||
|
@ -447,9 +454,9 @@ export interface IShellLaunchConfig {
|
|||
ignoreConfigurationCwd?: boolean;
|
||||
|
||||
/**
|
||||
* The owner of this terminal for reconnection.
|
||||
* The reconnection properties for this terminal
|
||||
*/
|
||||
reconnectionOwner?: string;
|
||||
reconnectionProperties?: IReconnectionProperties;
|
||||
|
||||
/** Whether to wait for a key press before closing the terminal. */
|
||||
waitOnExit?: WaitOnExitValue;
|
||||
|
@ -476,7 +483,7 @@ export interface IShellLaunchConfig {
|
|||
* This is a terminal that attaches to an already running terminal.
|
||||
*/
|
||||
attachPersistentProcess?: {
|
||||
id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections; reconnectionOwner?: string; task?: { label: string; id: string; lastTask: string; group?: string }; type?: TerminalType; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean;
|
||||
id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections; reconnectionProperties?: IReconnectionProperties; type?: TerminalType; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -548,11 +555,6 @@ export interface IShellLaunchConfig {
|
|||
* Create a terminal without shell integration even when it's enabled
|
||||
*/
|
||||
ignoreShellIntegration?: boolean;
|
||||
|
||||
/**
|
||||
* The task associated with this terminal
|
||||
*/
|
||||
task?: { label: string; id: string; lastTask: string; group?: string };
|
||||
}
|
||||
|
||||
export type WaitOnExitValue = boolean | string | ((exitCode: number) => string);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { UriComponents } from 'vs/base/common/uri';
|
||||
import { ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable';
|
||||
import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, IReconnectionProperties, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
|
||||
export interface ISingleTerminalConfiguration<T> {
|
||||
userValue: T | undefined;
|
||||
|
@ -60,8 +60,7 @@ export interface IProcessDetails {
|
|||
color: string | undefined;
|
||||
fixedDimensions: IFixedTerminalDimensions | undefined;
|
||||
environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined;
|
||||
reconnectionOwner?: string;
|
||||
task?: { label: string; id: string; lastTask: string; group?: string };
|
||||
reconnectionProperties?: IReconnectionProperties;
|
||||
waitOnExit?: WaitOnExitValue;
|
||||
hideFromUser?: boolean;
|
||||
isFeatureTerminal?: boolean;
|
||||
|
|
|
@ -410,8 +410,7 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
color: persistentProcess.color,
|
||||
fixedDimensions: persistentProcess.fixedDimensions,
|
||||
environmentVariableCollections: persistentProcess.processLaunchOptions.options.environmentVariableCollections,
|
||||
reconnectionOwner: persistentProcess.shellLaunchConfig.reconnectionOwner,
|
||||
task: persistentProcess.shellLaunchConfig.task,
|
||||
reconnectionProperties: persistentProcess.shellLaunchConfig.reconnectionProperties,
|
||||
waitOnExit: persistentProcess.shellLaunchConfig.waitOnExit,
|
||||
hideFromUser: persistentProcess.shellLaunchConfig.hideFromUser,
|
||||
isFeatureTerminal: persistentProcess.shellLaunchConfig.isFeatureTerminal,
|
||||
|
@ -789,7 +788,12 @@ class XtermSerializer implements ITerminalSerializer {
|
|||
private _rawReviveBuffer: string | undefined,
|
||||
logService: ILogService
|
||||
) {
|
||||
this._xterm = new XtermTerminal({ cols, rows, scrollback });
|
||||
this._xterm = new XtermTerminal({
|
||||
cols,
|
||||
rows,
|
||||
scrollback,
|
||||
allowProposedApi: true
|
||||
});
|
||||
if (reviveBufferWithRestoreMessage) {
|
||||
this._xterm.writeln(reviveBufferWithRestoreMessage);
|
||||
}
|
||||
|
@ -815,7 +819,7 @@ class XtermSerializer implements ITerminalSerializer {
|
|||
const serialize = new (await this._getSerializeConstructor());
|
||||
this._xterm.loadAddon(serialize);
|
||||
const options: ISerializeOptions = {
|
||||
scrollback: this._xterm.getOption('scrollback')
|
||||
scrollback: this._xterm.options.scrollback
|
||||
};
|
||||
if (normalBufferOnly) {
|
||||
options.excludeAltBuffer = true;
|
||||
|
|
|
@ -1417,12 +1417,15 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
|||
const currentWindowConfig = window.config;
|
||||
if (!configuration.extensionDevelopmentPath && currentWindowConfig && !!currentWindowConfig.extensionDevelopmentPath) {
|
||||
configuration.extensionDevelopmentPath = currentWindowConfig.extensionDevelopmentPath;
|
||||
configuration.extensionDevelopmentKind = currentWindowConfig.extensionDevelopmentKind;
|
||||
configuration['enable-proposed-api'] = currentWindowConfig['enable-proposed-api'];
|
||||
configuration.verbose = currentWindowConfig.verbose;
|
||||
configuration['inspect-extensions'] = currentWindowConfig['inspect-extensions'];
|
||||
configuration['inspect-brk-extensions'] = currentWindowConfig['inspect-brk-extensions'];
|
||||
configuration.debugId = currentWindowConfig.debugId;
|
||||
configuration.extensionEnvironment = currentWindowConfig.extensionEnvironment;
|
||||
configuration['inspect-extensions'] = currentWindowConfig['inspect-extensions'];
|
||||
configuration['extensions-dir'] = currentWindowConfig['extensions-dir'];
|
||||
configuration['disable-extensions'] = currentWindowConfig['disable-extensions'];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -951,8 +951,14 @@ function registerCloseEditorCommands() {
|
|||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
const untypedEditor = editor.toUntyped();
|
||||
|
||||
const resolvedEditor = await editorResolverService.resolveEditor({ editor, options: { ...editorService.activeEditorPane?.options, override: EditorResolution.PICK } }, group);
|
||||
// Resolver can only resolve untyped editors
|
||||
if (!untypedEditor) {
|
||||
return;
|
||||
}
|
||||
untypedEditor.options = { ...editorService.activeEditorPane?.options, override: EditorResolution.PICK };
|
||||
const resolvedEditor = await editorResolverService.resolveEditor(untypedEditor, group);
|
||||
if (!isEditorInputWithOptionsAndGroup(resolvedEditor)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ class StatusBarCodiconLabel extends SimpleIconLabel {
|
|||
private progressCodicon = renderIcon(syncing);
|
||||
|
||||
private currentText = '';
|
||||
private currentShowProgress = false;
|
||||
private currentShowProgress: boolean | 'syncing' | 'loading' = false;
|
||||
|
||||
constructor(
|
||||
private readonly container: HTMLElement
|
||||
|
@ -258,7 +258,7 @@ class StatusBarCodiconLabel extends SimpleIconLabel {
|
|||
|
||||
set showProgress(showProgress: boolean | 'syncing' | 'loading') {
|
||||
if (this.currentShowProgress !== showProgress) {
|
||||
this.currentShowProgress = !!showProgress;
|
||||
this.currentShowProgress = showProgress;
|
||||
this.progressCodicon = renderIcon(showProgress === 'loading' ? spinningLoading : syncing);
|
||||
this.text = this.currentText;
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ export class ConfigurationManager implements IConfigurationManager {
|
|||
disposables.add(input.onDidTriggerItemButton(async (context) => {
|
||||
resolve(undefined);
|
||||
const { launch, config } = context.item;
|
||||
await launch.openConfigFile({ preserveFocus: false, type: config.type });
|
||||
await launch.openConfigFile({ preserveFocus: false, type: config.type, suppressInitialConfigs: true });
|
||||
// Only Launch have a pin trigger button
|
||||
await (launch as Launch).writeConfiguration(config);
|
||||
await this.selectConfiguration(launch, config.name);
|
||||
|
@ -564,7 +564,7 @@ class Launch extends AbstractLaunch implements ILaunch {
|
|||
return this.configurationService.inspect<IGlobalConfig>('launch', { resource: this.workspace.uri }).workspaceFolderValue;
|
||||
}
|
||||
|
||||
async openConfigFile({ preserveFocus, type, useInitialConfigs }: { preserveFocus: boolean; type?: string; useInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }> {
|
||||
async openConfigFile({ preserveFocus, type, suppressInitialConfigs }: { preserveFocus: boolean; type?: string; suppressInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }> {
|
||||
const resource = this.uri;
|
||||
let created = false;
|
||||
let content = '';
|
||||
|
@ -573,7 +573,7 @@ class Launch extends AbstractLaunch implements ILaunch {
|
|||
content = fileContent.value.toString();
|
||||
} catch {
|
||||
// launch.json not found: create one by collecting launch configs from debugConfigProviders
|
||||
content = await this.getInitialConfigurationContent(this.workspace.uri, type, useInitialConfigs, token);
|
||||
content = await this.getInitialConfigurationContent(this.workspace.uri, type, !suppressInitialConfigs, token);
|
||||
if (!content) {
|
||||
// Cancelled
|
||||
return { editor: null, created: false };
|
||||
|
|
|
@ -63,7 +63,7 @@ export class StartDebugQuickAccessProvider extends PickerQuickAccessProvider<IPi
|
|||
tooltip: localize('customizeLaunchConfig', "Configure Launch Configuration")
|
||||
}],
|
||||
trigger: () => {
|
||||
config.launch.openConfigFile({ preserveFocus: false, useInitialConfigs: false });
|
||||
config.launch.openConfigFile({ preserveFocus: false });
|
||||
|
||||
return TriggerAction.CLOSE_PICKER;
|
||||
},
|
||||
|
|
|
@ -840,17 +840,19 @@ export class DebugService implements IDebugService {
|
|||
try {
|
||||
return await dbg.substituteVariables(folder, config);
|
||||
} catch (err) {
|
||||
this.showError(err.message);
|
||||
this.showError(err.message, undefined, !!launch?.getConfiguration(config.name));
|
||||
return undefined; // bail out
|
||||
}
|
||||
}
|
||||
return Promise.resolve(config);
|
||||
}
|
||||
|
||||
private async showError(message: string, errorActions: ReadonlyArray<IAction> = []): Promise<void> {
|
||||
private async showError(message: string, errorActions: ReadonlyArray<IAction> = [], promptLaunchJson = true): Promise<void> {
|
||||
const configureAction = new Action(DEBUG_CONFIGURE_COMMAND_ID, DEBUG_CONFIGURE_LABEL, undefined, true, () => this.commandService.executeCommand(DEBUG_CONFIGURE_COMMAND_ID));
|
||||
// Don't append the standard command if id of any provided action indicates it is a command
|
||||
const actions = errorActions.filter((action) => action.id.endsWith('.command')).length > 0 ? errorActions : [...errorActions, configureAction];
|
||||
const actions = errorActions.filter((action) => action.id.endsWith('.command')).length > 0 ?
|
||||
errorActions :
|
||||
[...errorActions, ...(promptLaunchJson ? [configureAction] : [])];
|
||||
const { choice } = await this.dialogService.show(severity.Error, message, actions.map(a => a.label).concat(nls.localize('cancel', "Cancel")), { cancelId: actions.length });
|
||||
if (choice < actions.length) {
|
||||
await actions[choice].run();
|
||||
|
|
|
@ -927,7 +927,7 @@ export interface ILaunch {
|
|||
/**
|
||||
* Opens the launch.json file. Creates if it does not exist.
|
||||
*/
|
||||
openConfigFile(options: { preserveFocus: boolean; type?: string; useInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }>;
|
||||
openConfigFile(options: { preserveFocus: boolean; type?: string; suppressInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }>;
|
||||
}
|
||||
|
||||
// Debug service interfaces
|
||||
|
|
|
@ -158,11 +158,11 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
|||
title: EDIT_SESSIONS_TITLE,
|
||||
ctorDescriptor: new SyncDescriptor(
|
||||
ViewPaneContainer,
|
||||
[EDIT_SESSIONS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }]
|
||||
[EDIT_SESSIONS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]
|
||||
),
|
||||
icon: EDIT_SESSIONS_VIEW_ICON,
|
||||
hideIfEmpty: true
|
||||
}, ViewContainerLocation.Sidebar
|
||||
}, ViewContainerLocation.Sidebar, { donotRegisterOpenCommand: true }
|
||||
);
|
||||
this._register(this.instantiationService.createInstance(EditSessionsDataViews, container));
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
|
|||
'workbench.experimental.editSessions.enabled': {
|
||||
'type': 'boolean',
|
||||
'tags': ['experimental', 'usesOnlineServices'],
|
||||
'default': false,
|
||||
'default': true,
|
||||
'markdownDescription': localize('editSessionsEnabled', "Controls whether to display cloud-enabled actions to store and resume uncommitted changes when switching between web, desktop, or devices."),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -10,16 +10,19 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { TreeView, TreeViewPane } from 'vs/workbench/browser/parts/views/treeView';
|
||||
import { Extensions, ITreeItem, ITreeViewDataProvider, ITreeViewDescriptor, IViewsRegistry, TreeItemCollapsibleState, TreeViewItemHandleArg, ViewContainer } from 'vs/workbench/common/views';
|
||||
import { EDIT_SESSIONS_DATA_VIEW_ID, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions';
|
||||
import { EDIT_SESSIONS_DATA_VIEW_ID, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_SIGNED_IN_KEY, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ContextKeyExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
||||
const EDIT_SESSIONS_COUNT_KEY = 'editSessionsCount';
|
||||
const EDIT_SESSIONS_COUNT_CONTEXT_KEY = new RawContextKey<number>(EDIT_SESSIONS_COUNT_KEY, 0);
|
||||
|
||||
export class EditSessionsDataViews extends Disposable {
|
||||
constructor(
|
||||
container: ViewContainer,
|
||||
|
@ -31,7 +34,7 @@ export class EditSessionsDataViews extends Disposable {
|
|||
|
||||
private registerViews(container: ViewContainer): void {
|
||||
const viewId = EDIT_SESSIONS_DATA_VIEW_ID;
|
||||
const name = localize('edit sessions data', 'All Sessions');
|
||||
const name = EDIT_SESSIONS_TITLE;
|
||||
const treeView = this.instantiationService.createInstance(TreeView, viewId, name);
|
||||
treeView.showCollapseAllAction = true;
|
||||
treeView.showRefreshAction = true;
|
||||
|
@ -41,7 +44,9 @@ export class EditSessionsDataViews extends Disposable {
|
|||
treeView.dataProvider = this.instantiationService.createInstance(EditSessionDataViewDataProvider);
|
||||
}
|
||||
});
|
||||
Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).registerViews([<ITreeViewDescriptor>{
|
||||
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([<ITreeViewDescriptor>{
|
||||
id: viewId,
|
||||
name,
|
||||
ctorDescriptor: new SyncDescriptor(TreeViewPane),
|
||||
|
@ -54,12 +59,26 @@ export class EditSessionsDataViews extends Disposable {
|
|||
hideByDefault: true,
|
||||
}], container);
|
||||
|
||||
viewsRegistry.registerViewWelcomeContent(viewId, {
|
||||
content: localize(
|
||||
'noEditSessions',
|
||||
'You have no stored edit sessions to display.\n{0}',
|
||||
localize(
|
||||
{ key: 'storeEditSessionCommand', comment: ['Please do not translate the word "command", it is part of our internal syntax which must not change'] },
|
||||
'[{0}](command:workbench.editSessions.actions.store)',
|
||||
localize('storeEditSessionTitle', 'Store Edit Session')
|
||||
)
|
||||
),
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), ContextKeyExpr.equals(EDIT_SESSIONS_COUNT_KEY, 0)),
|
||||
order: 1
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.editSessions.actions.resume',
|
||||
title: localize('workbench.editSessions.actions.resume', "Resume Edit Session"),
|
||||
icon: Codicon.repoPull,
|
||||
icon: Codicon.desktopDownload,
|
||||
menu: {
|
||||
id: MenuId.ViewItemContext,
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', viewId), ContextKeyExpr.regex('viewItem', /edit-session/i)),
|
||||
|
@ -76,6 +95,22 @@ export class EditSessionsDataViews extends Disposable {
|
|||
}
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.editSessions.actions.store',
|
||||
title: localize('workbench.editSessions.actions.store', "Store Edit Session"),
|
||||
icon: Codicon.cloudUpload,
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise<void> {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
await commandService.executeCommand('workbench.experimental.editSessions.actions.storeCurrent');
|
||||
await treeView.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -105,13 +140,47 @@ export class EditSessionsDataViews extends Disposable {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.editSessions.actions.deleteAll',
|
||||
title: localize('workbench.editSessions.actions.deleteAll', "Delete All Edit Sessions"),
|
||||
icon: Codicon.trash,
|
||||
menu: {
|
||||
id: MenuId.ViewTitle,
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', viewId), ContextKeyExpr.greater(EDIT_SESSIONS_COUNT_KEY, 0)),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor): Promise<void> {
|
||||
const dialogService = accessor.get(IDialogService);
|
||||
const editSessionWorkbenchService = accessor.get(IEditSessionsWorkbenchService);
|
||||
const result = await dialogService.confirm({
|
||||
message: localize('confirm delete all', 'Are you sure you want to permanently delete all edit sessions? You cannot undo this action.'),
|
||||
type: 'warning',
|
||||
title: EDIT_SESSIONS_TITLE
|
||||
});
|
||||
if (result.confirmed) {
|
||||
await editSessionWorkbenchService.delete(null);
|
||||
await treeView.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class EditSessionDataViewDataProvider implements ITreeViewDataProvider {
|
||||
|
||||
private editSessionsCount;
|
||||
|
||||
constructor(
|
||||
@IEditSessionsWorkbenchService private readonly editSessionsWorkbenchService: IEditSessionsWorkbenchService
|
||||
) { }
|
||||
@IEditSessionsWorkbenchService private readonly editSessionsWorkbenchService: IEditSessionsWorkbenchService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService
|
||||
) {
|
||||
this.editSessionsCount = EDIT_SESSIONS_COUNT_CONTEXT_KEY.bindTo(this.contextKeyService);
|
||||
}
|
||||
|
||||
async getChildren(element?: ITreeItem): Promise<ITreeItem[]> {
|
||||
if (!element) {
|
||||
|
@ -131,13 +200,14 @@ class EditSessionDataViewDataProvider implements ITreeViewDataProvider {
|
|||
|
||||
private async getAllEditSessions(): Promise<ITreeItem[]> {
|
||||
const allEditSessions = await this.editSessionsWorkbenchService.list();
|
||||
this.editSessionsCount.set(allEditSessions.length);
|
||||
return allEditSessions.map((session) => {
|
||||
const resource = URI.from({ scheme: EDIT_SESSIONS_SCHEME, authority: 'remote-session-content', path: `/${session.ref}` });
|
||||
return {
|
||||
handle: resource.toString(),
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||
label: { label: session.ref },
|
||||
description: fromNow(session.created, true),
|
||||
label: { label: fromNow(session.created, true) },
|
||||
description: session.ref,
|
||||
themeIcon: Codicon.repo,
|
||||
contextValue: `edit-session`
|
||||
};
|
||||
|
|
|
@ -59,6 +59,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
// If another window changes the preferred session storage, reset our cached auth state in memory
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e)));
|
||||
|
||||
this.registerSignInAction();
|
||||
this.registerResetAuthenticationAction();
|
||||
|
||||
this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService);
|
||||
|
@ -109,7 +110,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined;
|
||||
}
|
||||
|
||||
async delete(ref: string) {
|
||||
async delete(ref: string | null) {
|
||||
await this.initialize();
|
||||
if (!this.initialized) {
|
||||
throw new Error(`Unable to delete edit session with ref ${ref}.`);
|
||||
|
@ -349,6 +350,27 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
}
|
||||
}
|
||||
|
||||
private registerSignInAction() {
|
||||
const that = this;
|
||||
this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.editSessions.actions.signIn',
|
||||
title: localize('sign in', 'Sign In'),
|
||||
category: EDIT_SESSION_SYNC_CATEGORY,
|
||||
precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, false),
|
||||
menu: [{
|
||||
id: MenuId.CommandPalette,
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
async run() {
|
||||
await that.initialize();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private registerResetAuthenticationAction() {
|
||||
const that = this;
|
||||
this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 {
|
||||
|
|
|
@ -23,7 +23,7 @@ export interface IEditSessionsWorkbenchService {
|
|||
|
||||
read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>;
|
||||
write(editSession: EditSession): Promise<string>;
|
||||
delete(ref: string): Promise<void>;
|
||||
delete(ref: string | null): Promise<void>;
|
||||
list(): Promise<IResourceRefHandle[]>;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/workbench/services
|
|||
import { IExtensionService, ExtensionPointContribution } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
interface ModeScopeMap {
|
||||
[key: string]: string;
|
||||
|
@ -70,13 +71,18 @@ export abstract class EmmetEditorAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
|
||||
const extensionService = accessor.get(IExtensionService);
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
const extensionService = accessor.get(IExtensionService);
|
||||
|
||||
return this._withGrammarContributions(extensionService).then((grammarContributions) => {
|
||||
|
||||
if (this.id === 'editor.emmet.action.expandAbbreviation' && grammarContributions) {
|
||||
return commandService.executeCommand<void>('emmet.expandAbbreviation', EmmetEditorAction.getLanguage(editor, grammarContributions));
|
||||
const languageInfo = EmmetEditorAction.getLanguage(editor, grammarContributions);
|
||||
const languageId = languageInfo?.language;
|
||||
if (configurationService.getValue('emmet.triggerExpansionOnTab', { overrideIdentifier: languageId }) === true) {
|
||||
return commandService.executeCommand<void>('emmet.expandAbbreviation', languageInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
|
|
@ -95,7 +95,6 @@ export class CellDragAndDropController extends Disposable {
|
|||
return;
|
||||
}
|
||||
event.browserEvent.preventDefault();
|
||||
event.browserEvent.stopImmediatePropagation();
|
||||
this.onCellDragover(event);
|
||||
}, true);
|
||||
addCellDragListener(DOM.EventType.DROP, event => {
|
||||
|
|
|
@ -1025,31 +1025,33 @@ var requirejs = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
async showMarkupPreview(initialization: IMarkupCellInitialization) {
|
||||
async showMarkupPreview(newContent: IMarkupCellInitialization) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry = this.markupPreviewMapping.get(initialization.cellId);
|
||||
const entry = this.markupPreviewMapping.get(newContent.cellId);
|
||||
if (!entry) {
|
||||
return this.createMarkupPreview(initialization);
|
||||
return this.createMarkupPreview(newContent);
|
||||
}
|
||||
|
||||
const sameContent = initialization.content === entry.content;
|
||||
if (!sameContent || !entry.visible) {
|
||||
const sameContent = newContent.content === entry.content;
|
||||
const sameMetadata = newContent.metadata === entry.metadata;
|
||||
if (!sameContent || !sameMetadata || !entry.visible) {
|
||||
this._sendMessageToWebview({
|
||||
type: 'showMarkupCell',
|
||||
id: initialization.cellId,
|
||||
handle: initialization.cellHandle,
|
||||
id: newContent.cellId,
|
||||
handle: newContent.cellHandle,
|
||||
// If the content has not changed, we still want to make sure the
|
||||
// preview is visible but don't need to send anything over
|
||||
content: sameContent ? undefined : initialization.content,
|
||||
top: initialization.offset
|
||||
content: sameContent ? undefined : newContent.content,
|
||||
top: newContent.offset,
|
||||
metadata: sameMetadata ? undefined : newContent.metadata
|
||||
});
|
||||
}
|
||||
|
||||
entry.content = initialization.content;
|
||||
entry.offset = initialization.offset;
|
||||
entry.metadata = newContent.metadata;
|
||||
entry.content = newContent.content;
|
||||
entry.offset = newContent.offset;
|
||||
entry.visible = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,7 @@ export interface IShowMarkupCellMessage {
|
|||
readonly handle: number;
|
||||
readonly content: string | undefined;
|
||||
readonly top: number;
|
||||
readonly metadata: NotebookCellMetadata | undefined;
|
||||
}
|
||||
|
||||
export interface IUpdateSelectedMarkupCellsMessage {
|
||||
|
|
|
@ -1035,7 +1035,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
break;
|
||||
|
||||
case 'showMarkupCell':
|
||||
viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content);
|
||||
viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content, event.data.metadata);
|
||||
break;
|
||||
|
||||
case 'hideMarkupCells':
|
||||
|
@ -1448,7 +1448,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
let cell = this._markupCells.get(info.cellId);
|
||||
if (cell) {
|
||||
cell.element.style.visibility = info.visible ? 'visible' : 'hidden';
|
||||
await cell.updateContentAndRender(info.content);
|
||||
await cell.updateContentAndRender(info.content, info.metadata);
|
||||
} else {
|
||||
cell = await this.createMarkupCell(info, info.offset, info.visible);
|
||||
}
|
||||
|
@ -1462,14 +1462,14 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
}
|
||||
}
|
||||
|
||||
public async updateMarkupContent(id: string, newContent: string): Promise<void> {
|
||||
public async updateMarkupContent(id: string, newContent: string, metadata: NotebookCellMetadata): Promise<void> {
|
||||
const cell = this.getExpectedMarkupCell(id);
|
||||
await cell?.updateContentAndRender(newContent);
|
||||
await cell?.updateContentAndRender(newContent, metadata);
|
||||
}
|
||||
|
||||
public showMarkupCell(id: string, top: number, newContent: string | undefined): void {
|
||||
public showMarkupCell(id: string, top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void {
|
||||
const cell = this.getExpectedMarkupCell(id);
|
||||
cell?.show(top, newContent);
|
||||
cell?.show(top, newContent, metadata);
|
||||
}
|
||||
|
||||
public hideMarkupCell(id: string): void {
|
||||
|
@ -1633,11 +1633,11 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
private readonly outputItem: rendererApi.OutputItem;
|
||||
|
||||
/// Internal field that holds text content
|
||||
private _content: { readonly value: string; readonly version: number };
|
||||
private _content: { readonly value: string; readonly version: number; readonly metadata: NotebookCellMetadata };
|
||||
|
||||
constructor(id: string, mime: string, content: string, top: number, metadata: NotebookCellMetadata) {
|
||||
this.id = id;
|
||||
this._content = { value: content, version: 0 };
|
||||
this._content = { value: content, version: 0, metadata: metadata };
|
||||
|
||||
let resolveReady: () => void;
|
||||
this.ready = new Promise<void>(r => resolveReady = r);
|
||||
|
@ -1646,7 +1646,10 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
this.outputItem = Object.freeze(<rendererApi.OutputItem>{
|
||||
id,
|
||||
mime,
|
||||
metadata,
|
||||
|
||||
metadata: (): NotebookCellMetadata => {
|
||||
return this._content.metadata;
|
||||
},
|
||||
|
||||
text: (): string => {
|
||||
return this._content.value;
|
||||
|
@ -1688,7 +1691,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
|
||||
this.addEventListeners();
|
||||
|
||||
this.updateContentAndRender(this._content.value).then(() => {
|
||||
this.updateContentAndRender(this._content.value, this._content.metadata).then(() => {
|
||||
resizeObserver.observe(this.element, this.id, false, this.id);
|
||||
resolveReady();
|
||||
});
|
||||
|
@ -1738,8 +1741,8 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
});
|
||||
}
|
||||
|
||||
public async updateContentAndRender(newContent: string): Promise<void> {
|
||||
this._content = { value: newContent, version: this._content.version + 1 };
|
||||
public async updateContentAndRender(newContent: string, metadata: NotebookCellMetadata): Promise<void> {
|
||||
this._content = { value: newContent, version: this._content.version + 1, metadata };
|
||||
|
||||
await renderers.render(this.outputItem, this.element);
|
||||
|
||||
|
@ -1772,11 +1775,11 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
});
|
||||
}
|
||||
|
||||
public show(top: number, newContent: string | undefined): void {
|
||||
public show(top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void {
|
||||
this.element.style.visibility = 'visible';
|
||||
this.element.style.top = `${top}px`;
|
||||
if (typeof newContent === 'string') {
|
||||
this.updateContentAndRender(newContent);
|
||||
if (typeof newContent === 'string' || metadata) {
|
||||
this.updateContentAndRender(newContent ?? this._content.value, metadata ?? this._content.metadata);
|
||||
} else {
|
||||
this.updateMarkupDimensions();
|
||||
}
|
||||
|
@ -1792,7 +1795,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
}
|
||||
|
||||
public rerender() {
|
||||
this.updateContentAndRender(this._content.value);
|
||||
this.updateContentAndRender(this._content.value, this._content.metadata);
|
||||
}
|
||||
|
||||
public remove() {
|
||||
|
|
|
@ -29,8 +29,10 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
|||
|
||||
public get renderedHtml(): string | undefined { return this._renderedHtml; }
|
||||
public set renderedHtml(value: string | undefined) {
|
||||
this._renderedHtml = value;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
if (this._renderedHtml !== value) {
|
||||
this._renderedHtml = value;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}
|
||||
}
|
||||
|
||||
get layoutInfo() {
|
||||
|
|
|
@ -642,6 +642,7 @@ export class SettingsEditor2 extends EditorPane {
|
|||
|
||||
private onDidClickSetting(evt: ISettingLinkClickEvent, recursed?: boolean): void {
|
||||
const targetElement = this.currentSettingsModel.getElementsByName(evt.targetKey)?.[0];
|
||||
let revealFailed = false;
|
||||
if (targetElement) {
|
||||
let sourceTop = 0.5;
|
||||
try {
|
||||
|
@ -661,23 +662,34 @@ export class SettingsEditor2 extends EditorPane {
|
|||
if (this.viewState.filterToCategory && evt.source.displayCategory !== targetElement.displayCategory) {
|
||||
this.tocTree.setFocus([]);
|
||||
}
|
||||
this.settingsTree.reveal(targetElement, sourceTop);
|
||||
try {
|
||||
this.settingsTree.reveal(targetElement, sourceTop);
|
||||
} catch (_) {
|
||||
// The listwidget couldn't find the setting to reveal,
|
||||
// even though it's in the model, meaning there might be a filter
|
||||
// preventing it from showing up.
|
||||
revealFailed = true;
|
||||
}
|
||||
|
||||
// We need to shift focus from the setting that contains the link to the setting that's
|
||||
// linked. Clicking on the link sets focus on the setting that contains the link,
|
||||
// which is why we need the setTimeout.
|
||||
setTimeout(() => {
|
||||
this.settingsTree.setFocus([targetElement]);
|
||||
}, 50);
|
||||
if (!revealFailed) {
|
||||
// We need to shift focus from the setting that contains the link to the setting that's
|
||||
// linked. Clicking on the link sets focus on the setting that contains the link,
|
||||
// which is why we need the setTimeout.
|
||||
setTimeout(() => {
|
||||
this.settingsTree.setFocus([targetElement]);
|
||||
}, 50);
|
||||
|
||||
const domElements = this.settingRenderers.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), evt.targetKey);
|
||||
if (domElements && domElements[0]) {
|
||||
const control = domElements[0].querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
|
||||
if (control) {
|
||||
(<HTMLElement>control).focus();
|
||||
const domElements = this.settingRenderers.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), evt.targetKey);
|
||||
if (domElements && domElements[0]) {
|
||||
const control = domElements[0].querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
|
||||
if (control) {
|
||||
(<HTMLElement>control).focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!recursed) {
|
||||
}
|
||||
|
||||
if (!recursed && revealFailed) {
|
||||
// We'll call this event handler again after clearing the search query,
|
||||
// so that more settings show up in the list.
|
||||
const p = this.triggerSearch('');
|
||||
|
|
|
@ -510,7 +510,7 @@ configurationRegistry.registerConfiguration({
|
|||
},
|
||||
[TaskSettingId.ShowDecorations]: {
|
||||
type: 'boolean',
|
||||
description: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks."),
|
||||
markdownDescription: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks. {0} will take precedence over this setting", '`#terminal.integrated.shellIntegration.decorationsEnabled#`'),
|
||||
default: true
|
||||
},
|
||||
[TaskSettingId.Reconnection]: {
|
||||
|
|
|
@ -209,7 +209,8 @@ export class TaskQuickPick extends Disposable {
|
|||
const changeSettingResult = await this._dialogService.show(Severity.Warning,
|
||||
nls.localize('TaskQuickPick.changeSettingDetails',
|
||||
"Task detection for {0} tasks causes files in any workspace you open to be run as code. Enabling {0} task detection is a user setting and will apply to any workspace you open. \n\n Do you want to enable {0} task detection for all workspaces?", selectedType),
|
||||
[noButton, yesButton]
|
||||
[noButton, yesButton],
|
||||
{ cancelId: 1 }
|
||||
);
|
||||
if (changeSettingResult.choice === 1) {
|
||||
await this._configurationService.updateValue(`${selectedType}.autoDetect`, 'on');
|
||||
|
|
|
@ -30,7 +30,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
import { IReconnectionTaskData, IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
@ -1271,7 +1271,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
|
|||
private async _reconnectToTerminal(task: Task): Promise<ITerminalInstance | undefined> {
|
||||
for (let i = 0; i < this._reconnectTerminals.length; i++) {
|
||||
const terminal = this._reconnectTerminals[i];
|
||||
const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.task;
|
||||
const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties?.data as IReconnectionTaskData;
|
||||
if (taskForTerminal?.id && task.getRecentlyUsedKey() === taskForTerminal.lastTask) {
|
||||
this._reconnectTerminals.splice(i, 1);
|
||||
return terminal;
|
||||
|
@ -1318,7 +1318,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
|
|||
return;
|
||||
}
|
||||
for (const terminal of terminals) {
|
||||
const task = terminal.shellLaunchConfig.attachPersistentProcess?.task;
|
||||
const task = terminal.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties?.data as IReconnectionTaskData;
|
||||
if (!task) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1428,8 +1428,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
|
|||
|
||||
this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(task, group, launchConfigs!));
|
||||
const terminal: ITerminalInstance = (await this._terminalCreationQueue)!;
|
||||
terminal.shellLaunchConfig.task = { lastTask: task.getRecentlyUsedKey()!, group, label: task._label, id: task._id };
|
||||
terminal.shellLaunchConfig.reconnectionOwner = ReconnectionType;
|
||||
terminal.shellLaunchConfig.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: taskKey, group, label: task._label, id: task._id } };
|
||||
const terminalKey = terminal.instanceId.toString();
|
||||
const terminalData = { terminal: terminal, lastTask: taskKey, group };
|
||||
terminal.onDisposed(() => this._deleteTaskAndTerminal(terminal, terminalData));
|
||||
|
|
|
@ -11,7 +11,7 @@ import { FindReplaceState } from 'vs/editor/contrib/find/browser/findState';
|
|||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||
import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
import { IExtensionTerminalProfile, IProcessPropertyMap, IReconnectionProperties, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||
import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
|
@ -257,11 +257,10 @@ interface ITerminalEditorInputObject {
|
|||
readonly icon: TerminalIcon | undefined;
|
||||
readonly color: string | undefined;
|
||||
readonly hasChildProcesses?: boolean;
|
||||
readonly task?: { label: string; id: string; lastTask: string; group?: string; waitOnExit?: WaitOnExitValue };
|
||||
readonly type?: TerminalType;
|
||||
readonly isFeatureTerminal?: boolean;
|
||||
readonly hideFromUser?: boolean;
|
||||
readonly reconnectionOwner?: string;
|
||||
readonly reconnectionProperties?: IReconnectionProperties;
|
||||
}
|
||||
|
||||
export interface ISerializedTerminalEditorInput extends ITerminalEditorInputObject {
|
||||
|
@ -450,7 +449,7 @@ export interface ITerminalInstance {
|
|||
readonly fixedRows?: number;
|
||||
readonly icon?: TerminalIcon;
|
||||
readonly color?: string;
|
||||
readonly reconnectionOwner?: string;
|
||||
readonly reconnectionProperties?: IReconnectionProperties;
|
||||
readonly processName: string;
|
||||
readonly sequence?: string;
|
||||
readonly staticTitle?: string;
|
||||
|
|
|
@ -44,10 +44,9 @@ export class TerminalInputSerializer implements IEditorSerializer {
|
|||
color: instance.color,
|
||||
resource: instance.resource.toString(),
|
||||
hasChildProcesses: instance.hasChildProcesses,
|
||||
task: instance.shellLaunchConfig.task,
|
||||
type: instance.shellLaunchConfig.type,
|
||||
isFeatureTerminal: instance.shellLaunchConfig.isFeatureTerminal,
|
||||
hideFromUser: instance.shellLaunchConfig.hideFromUser,
|
||||
reconnectionProperties: instance.shellLaunchConfig.reconnectionProperties
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||
import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
|
||||
import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal';
|
||||
import { IProcessDataEvent, IProcessPropertyMap, IReconnectionProperties, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal';
|
||||
import { escapeNonWindowsPath, collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment';
|
||||
import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
@ -282,7 +282,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
// TODO: Should this be an event as it can fire twice?
|
||||
get processReady(): Promise<void> { return this._processManager.ptyProcessReady; }
|
||||
get hasChildProcesses(): boolean { return this.shellLaunchConfig.attachPersistentProcess?.hasChildProcesses || this._processManager.hasChildProcesses; }
|
||||
get reconnectionOwner(): string | undefined { return this.shellLaunchConfig.attachPersistentProcess?.reconnectionOwner || this.shellLaunchConfig.reconnectionOwner; }
|
||||
get reconnectionProperties(): IReconnectionProperties | undefined { return this.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties || this.shellLaunchConfig.reconnectionProperties; }
|
||||
get areLinksReady(): boolean { return this._areLinksReady; }
|
||||
get initialDataEvents(): string[] | undefined { return this._initialDataEvents; }
|
||||
get exitCode(): number | undefined { return this._exitCode; }
|
||||
|
@ -696,7 +696,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
this._shutdownPersistentProcessId = shutdownPersistentProcessId;
|
||||
}
|
||||
get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId ?? this._shutdownPersistentProcessId; }
|
||||
get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient && (!this.reconnectionOwner || this._configurationService.getValue(TaskSettingId.Reconnection) === true); }
|
||||
get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient && (!this.reconnectionProperties || this._configurationService.getValue(TaskSettingId.Reconnection) === true); }
|
||||
|
||||
/**
|
||||
* Create xterm.js instance and attach data listeners.
|
||||
|
@ -1249,7 +1249,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
|
||||
// If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal
|
||||
// panel was initialized.
|
||||
if (xterm.raw.getOption('disableStdin')) {
|
||||
if (xterm.raw.options.disableStdin) {
|
||||
this._attachPressAnyKeyToCloseListener(xterm.raw);
|
||||
}
|
||||
}
|
||||
|
@ -2392,7 +2392,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
info.requiresAction &&
|
||||
this._configHelper.config.environmentChangesRelaunch &&
|
||||
!this._processManager.hasWrittenData &&
|
||||
(!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionOwner && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) &&
|
||||
(!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) &&
|
||||
!this._shellLaunchConfig.customPtyImplementation
|
||||
&& !this._shellLaunchConfig.isExtensionOwnedTerminal &&
|
||||
!this._shellLaunchConfig.attachPersistentProcess
|
||||
|
|
|
@ -20,7 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|||
import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||
import { NaiveCwdDetectionCapability } from 'vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability';
|
||||
import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
|
||||
import { FlowControlConstants, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalEnvironment, ITerminalLaunchError, ITerminalProcessOptions, ProcessPropertyType, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
||||
import { FlowControlConstants, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IReconnectionProperties, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalEnvironment, ITerminalLaunchError, ITerminalProcessOptions, ProcessPropertyType, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
||||
import { ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess';
|
||||
import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
|
@ -114,10 +114,10 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
readonly onRestoreCommands = this._onRestoreCommands.event;
|
||||
|
||||
get persistentProcessId(): number | undefined { return this._process?.id; }
|
||||
get shouldPersist(): boolean { return !!this.reconnectionOwner || (this._process ? this._process.shouldPersist : false); }
|
||||
get shouldPersist(): boolean { return !!this.reconnectionProperties || (this._process ? this._process.shouldPersist : false); }
|
||||
get hasWrittenData(): boolean { return this._hasWrittenData; }
|
||||
get hasChildProcesses(): boolean { return this._hasChildProcesses; }
|
||||
get reconnectionOwner(): string | undefined { return this._shellLaunchConfig?.attachPersistentProcess?.reconnectionOwner || this._shellLaunchConfig?.reconnectionOwner || undefined; }
|
||||
get reconnectionProperties(): IReconnectionProperties | undefined { return this._shellLaunchConfig?.attachPersistentProcess?.reconnectionProperties || this._shellLaunchConfig?.reconnectionProperties || undefined; }
|
||||
|
||||
constructor(
|
||||
private readonly _instanceId: number,
|
||||
|
@ -246,7 +246,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
|
||||
// this is a copy of what the merged environment collection is on the remote side
|
||||
const env = await this._resolveEnvironment(backend, variableResolver, shellLaunchConfig);
|
||||
const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionOwner) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient;
|
||||
const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionProperties) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient;
|
||||
if (shellLaunchConfig.attachPersistentProcess) {
|
||||
const result = await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id);
|
||||
if (result) {
|
||||
|
@ -460,7 +460,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
windowsEnableConpty: this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled,
|
||||
environmentVariableCollections: this._extEnvironmentVariableCollection ? serializeEnvironmentVariableCollections(this._extEnvironmentVariableCollection.collections) : undefined
|
||||
};
|
||||
const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionOwner) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient;
|
||||
const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionProperties) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient;
|
||||
return await backend.createProcess(shellLaunchConfig, initialCwd, cols, rows, this._configHelper.config.unicodeVersion, env, options, shouldPersist);
|
||||
}
|
||||
|
||||
|
@ -493,7 +493,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
this._ptyResponsiveListener?.dispose();
|
||||
this._ptyResponsiveListener = undefined;
|
||||
if (this._shellLaunchConfig) {
|
||||
if (this._shellLaunchConfig.isFeatureTerminal && !this.reconnectionOwner) {
|
||||
if (this._shellLaunchConfig.isFeatureTerminal && !this.reconnectionProperties) {
|
||||
// Indicate the process is exited (and gone forever) only for feature terminals
|
||||
// so they can react to the exit, this is particularly important for tasks so
|
||||
// that it knows that the process is not still active. Note that this is not
|
||||
|
|
|
@ -1049,12 +1049,12 @@ export class TerminalService implements ITerminalService {
|
|||
}
|
||||
|
||||
private _addToReconnected(instance: ITerminalInstance): void {
|
||||
if (instance.reconnectionOwner) {
|
||||
const reconnectedTerminals = this._reconnectedTerminals.get(instance.reconnectionOwner);
|
||||
if (instance.reconnectionProperties) {
|
||||
const reconnectedTerminals = this._reconnectedTerminals.get(instance.reconnectionProperties.ownerId);
|
||||
if (reconnectedTerminals) {
|
||||
reconnectedTerminals.push(instance);
|
||||
} else {
|
||||
this._reconnectedTerminals.set(instance.reconnectionOwner, [instance]);
|
||||
this._reconnectedTerminals.set(instance.reconnectionProperties.ownerId, [instance]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import type { IBuffer, IMarker, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm';
|
||||
import type { IBuffer, IMarker, ITheme, Terminal as RawXtermTerminal } from 'xterm';
|
||||
import type { CanvasAddon as CanvasAddonType } from 'xterm-addon-canvas';
|
||||
import type { ISearchOptions, SearchAddon as SearchAddonType } from 'xterm-addon-search';
|
||||
import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11';
|
||||
import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl';
|
||||
import { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize';
|
||||
import type { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize';
|
||||
import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||
|
@ -27,7 +28,7 @@ import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeServic
|
|||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { TERMINAL_FOREGROUND_COLOR, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, ansiColorIdentifiers, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_FIND_MATCH_FOREGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
import { TERMINAL_FOREGROUND_COLOR, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, ansiColorIdentifiers, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_FIND_MATCH_FOREGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR, TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ShellIntegrationAddon } from 'vs/platform/terminal/common/xterm/shellIntegrationAddon';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -41,11 +42,13 @@ import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProc
|
|||
// which suggests the fallback DOM-based renderer
|
||||
const SLOW_CANVAS_RENDER_THRESHOLD = 50;
|
||||
const NUMBER_OF_FRAMES_TO_MEASURE = 20;
|
||||
const SMOOTH_SCROLL_DURATION = 125;
|
||||
|
||||
let CanvasAddon: typeof CanvasAddonType;
|
||||
let SearchAddon: typeof SearchAddonType;
|
||||
let SerializeAddon: typeof SerializeAddonType;
|
||||
let Unicode11Addon: typeof Unicode11AddonType;
|
||||
let WebglAddon: typeof WebglAddonType;
|
||||
let SerializeAddon: typeof SerializeAddonType;
|
||||
|
||||
/**
|
||||
* Wraps the xterm object with additional functionality. Interaction with the backing process is out
|
||||
|
@ -78,6 +81,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
private _decorationAddon: DecorationAddon;
|
||||
|
||||
// Optional addons
|
||||
private _canvasAddon?: CanvasAddonType;
|
||||
private _searchAddon?: SearchAddonType;
|
||||
private _unicode11Addon?: Unicode11AddonType;
|
||||
private _webglAddon?: WebglAddonType;
|
||||
|
@ -130,6 +134,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
const editorOptions = this._configurationService.getValue<IEditorOptions>('editor');
|
||||
|
||||
this.raw = this.add(new xtermCtor({
|
||||
allowProposedApi: true,
|
||||
cols,
|
||||
rows,
|
||||
altClickMovesCursor: config.altClickMovesCursor && editorOptions.multiCursorModifier === 'alt',
|
||||
|
@ -146,16 +151,15 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
cursorBlink: config.cursorBlinking,
|
||||
cursorStyle: config.cursorStyle === 'line' ? 'bar' : config.cursorStyle,
|
||||
cursorWidth: config.cursorWidth,
|
||||
bellStyle: 'none',
|
||||
macOptionIsMeta: config.macOptionIsMeta,
|
||||
macOptionClickForcesSelection: config.macOptionClickForcesSelection,
|
||||
rightClickSelectsWord: config.rightClickBehavior === 'selectWord',
|
||||
fastScrollModifier: 'alt',
|
||||
fastScrollSensitivity: config.fastScrollSensitivity,
|
||||
scrollSensitivity: config.mouseWheelScrollSensitivity,
|
||||
rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType),
|
||||
wordSeparator: config.wordSeparators,
|
||||
overviewRulerWidth: 10
|
||||
overviewRulerWidth: 10,
|
||||
smoothScrollDuration: config.smoothScrolling ? SMOOTH_SCROLL_DURATION : 0
|
||||
}));
|
||||
this._core = (this.raw as any)._core as IXtermCore;
|
||||
|
||||
|
@ -227,6 +231,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
this._container = container;
|
||||
if (this._shouldLoadWebgl()) {
|
||||
this._enableWebglRenderer();
|
||||
} else if (this._shouldLoadCanvas()) {
|
||||
this._enableCanvasRenderer();
|
||||
}
|
||||
// Screen must be created at this point as xterm.open is called
|
||||
return this._container.querySelector('.xterm-screen')!;
|
||||
|
@ -250,11 +256,16 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
this.raw.options.rightClickSelectsWord = config.rightClickBehavior === 'selectWord';
|
||||
this.raw.options.wordSeparator = config.wordSeparators;
|
||||
this.raw.options.customGlyphs = config.customGlyphs;
|
||||
this.raw.options.smoothScrollDuration = config.smoothScrolling ? SMOOTH_SCROLL_DURATION : 0;
|
||||
if (this._shouldLoadWebgl()) {
|
||||
this._enableWebglRenderer();
|
||||
} else {
|
||||
this._disposeOfWebglRenderer();
|
||||
this.raw.options.rendererType = this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType);
|
||||
if (this._shouldLoadCanvas()) {
|
||||
this._enableCanvasRenderer();
|
||||
} else {
|
||||
this._disposeOfCanvasRenderer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,6 +273,10 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
return !isSafari && (this._configHelper.config.gpuAcceleration === 'auto' && XtermTerminal._suggestedRendererType === undefined) || this._configHelper.config.gpuAcceleration === 'on';
|
||||
}
|
||||
|
||||
private _shouldLoadCanvas(): boolean {
|
||||
return (this._configHelper.config.gpuAcceleration === 'auto' && (XtermTerminal._suggestedRendererType === undefined || XtermTerminal._suggestedRendererType === 'canvas')) || this._configHelper.config.gpuAcceleration === 'canvas';
|
||||
}
|
||||
|
||||
forceRedraw() {
|
||||
this._webglAddon?.clearTextureAtlas();
|
||||
this.raw.clearTextureAtlas();
|
||||
|
@ -280,7 +295,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
// This is to fix an issue where dragging the windpow to the top of the screen to
|
||||
// maximize on Windows/Linux would fire an event saying that the terminal was not
|
||||
// visible.
|
||||
if (this.raw.getOption('rendererType') === 'canvas') {
|
||||
if (!!this._canvasAddon) {
|
||||
this._core._renderService?._onIntersectionChange({ intersectionRatio: 1 });
|
||||
// HACK: Force a refresh of the screen to ensure links are refresh corrected.
|
||||
// This can probably be removed when the above hack is fixed in Chromium.
|
||||
|
@ -432,27 +447,19 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
}
|
||||
}
|
||||
|
||||
private _getBuiltInXtermRenderer(gpuAcceleration: string, suggestedRendererType?: string): RendererType {
|
||||
let rendererType: RendererType = 'canvas';
|
||||
if (gpuAcceleration === 'off' || (gpuAcceleration === 'auto' && suggestedRendererType === 'dom')) {
|
||||
rendererType = 'dom';
|
||||
}
|
||||
return rendererType;
|
||||
}
|
||||
|
||||
private async _enableWebglRenderer(): Promise<void> {
|
||||
if (!this.raw.element || this._webglAddon) {
|
||||
return;
|
||||
}
|
||||
const Addon = await this._getWebglAddonConstructor();
|
||||
this._webglAddon = new Addon();
|
||||
this._disposeOfCanvasRenderer();
|
||||
try {
|
||||
this.raw.loadAddon(this._webglAddon);
|
||||
this._logService.trace('Webgl was loaded');
|
||||
this._webglAddon.onContextLoss(() => {
|
||||
this._logService.info(`Webgl lost context, disposing of webgl renderer`);
|
||||
this._disposeOfWebglRenderer();
|
||||
this.raw.options.rendererType = 'dom';
|
||||
});
|
||||
// Uncomment to add the texture atlas to the DOM
|
||||
// setTimeout(() => {
|
||||
|
@ -467,12 +474,41 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') {
|
||||
this._measureRenderTime();
|
||||
}
|
||||
this.raw.options.rendererType = 'canvas';
|
||||
XtermTerminal._suggestedRendererType = 'canvas';
|
||||
this._disposeOfWebglRenderer();
|
||||
this._enableCanvasRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
private async _enableCanvasRenderer(): Promise<void> {
|
||||
if (!this.raw.element || this._canvasAddon) {
|
||||
return;
|
||||
}
|
||||
const Addon = await this._getCanvasAddonConstructor();
|
||||
this._canvasAddon = new Addon();
|
||||
this._disposeOfWebglRenderer();
|
||||
try {
|
||||
this.raw.loadAddon(this._canvasAddon);
|
||||
this._logService.trace('Canvas was loaded');
|
||||
} catch (e) {
|
||||
this._logService.warn(`Canvas could not be loaded. Falling back to the dom renderer type.`, e);
|
||||
const neverMeasureRenderTime = this._storageService.getBoolean(TerminalStorageKeys.NeverMeasureRenderTime, StorageScope.APPLICATION, false);
|
||||
// if it's already set to dom, no need to measure render time
|
||||
if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') {
|
||||
this._measureRenderTime();
|
||||
}
|
||||
XtermTerminal._suggestedRendererType = 'dom';
|
||||
this._disposeOfCanvasRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
protected async _getCanvasAddonConstructor(): Promise<typeof CanvasAddonType> {
|
||||
if (!CanvasAddon) {
|
||||
CanvasAddon = (await import('xterm-addon-canvas')).CanvasAddon;
|
||||
}
|
||||
return CanvasAddon;
|
||||
}
|
||||
|
||||
protected async _getSearchAddonConstructor(): Promise<typeof SearchAddonType> {
|
||||
if (!SearchAddon) {
|
||||
SearchAddon = (await import('xterm-addon-search')).SearchAddon;
|
||||
|
@ -501,6 +537,15 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
return SerializeAddon;
|
||||
}
|
||||
|
||||
private _disposeOfCanvasRenderer(): void {
|
||||
try {
|
||||
this._canvasAddon?.dispose();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
this._canvasAddon = undefined;
|
||||
}
|
||||
|
||||
private _disposeOfWebglRenderer(): void {
|
||||
try {
|
||||
this._webglAddon?.dispose();
|
||||
|
@ -579,6 +624,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
const cursorColor = theme.getColor(TERMINAL_CURSOR_FOREGROUND_COLOR) || foregroundColor;
|
||||
const cursorAccentColor = theme.getColor(TERMINAL_CURSOR_BACKGROUND_COLOR) || backgroundColor;
|
||||
const selectionBackgroundColor = theme.getColor(TERMINAL_SELECTION_BACKGROUND_COLOR);
|
||||
const selectionInactiveBackgroundColor = theme.getColor(TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR);
|
||||
const selectionForegroundColor = theme.getColor(TERMINAL_SELECTION_FOREGROUND_COLOR) || undefined;
|
||||
|
||||
return {
|
||||
|
@ -586,7 +632,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
foreground: foregroundColor?.toString(),
|
||||
cursor: cursorColor?.toString(),
|
||||
cursorAccent: cursorAccentColor?.toString(),
|
||||
selection: selectionBackgroundColor?.toString(),
|
||||
selectionBackground: selectionBackgroundColor?.toString(),
|
||||
selectionInactiveBackground: selectionInactiveBackgroundColor?.toString(),
|
||||
selectionForeground: selectionForegroundColor?.toString(),
|
||||
black: theme.getColor(ansiColorIdentifiers[0])?.toString(),
|
||||
red: theme.getColor(ansiColorIdentifiers[1])?.toString(),
|
||||
|
@ -608,7 +655,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
|
|||
}
|
||||
|
||||
private _updateTheme(theme?: IColorTheme): void {
|
||||
this.raw.setOption('theme', this._getXtermTheme(theme));
|
||||
this.raw.options.theme = this._getXtermTheme(theme);
|
||||
}
|
||||
|
||||
private async _updateUnicodeVersion(): Promise<void> {
|
||||
|
|
|
@ -302,6 +302,7 @@ export interface ITerminalConfiguration {
|
|||
enabled: boolean;
|
||||
decorationsEnabled: boolean;
|
||||
};
|
||||
smoothScrolling: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_LOCAL_ECHO_EXCLUDE: ReadonlyArray<string> = ['vim', 'vi', 'nano', 'tmux'];
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
import { registerColor, ColorIdentifier, ColorDefaults, editorFindMatch, editorFindMatchHighlight, overviewRulerFindMatchForeground, editorSelectionBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerColor, ColorIdentifier, ColorDefaults, editorFindMatch, editorFindMatchHighlight, overviewRulerFindMatchForeground, editorSelectionBackground, transparent } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { EDITOR_DRAG_AND_DROP_BACKGROUND, PANEL_BORDER, TAB_ACTIVE_BORDER } from 'vs/workbench/common/theme';
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,12 @@ export const TERMINAL_SELECTION_BACKGROUND_COLOR = registerColor('terminal.selec
|
|||
hcDark: editorSelectionBackground,
|
||||
hcLight: editorSelectionBackground
|
||||
}, nls.localize('terminal.selectionBackground', 'The selection background color of the terminal.'));
|
||||
export const TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR = registerColor('terminal.inactiveSelectionBackground', {
|
||||
light: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5),
|
||||
dark: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5),
|
||||
hcDark: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.7),
|
||||
hcLight: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5)
|
||||
}, nls.localize('terminal.inactiveSelectionBackground', 'The selection background color of the terminal when it does not have focus.'));
|
||||
export const TERMINAL_SELECTION_FOREGROUND_COLOR = registerColor('terminal.selectionForeground', {
|
||||
light: null,
|
||||
dark: null,
|
||||
|
|
|
@ -571,6 +571,11 @@ const terminalConfiguration: IConfigurationNode = {
|
|||
type: 'number',
|
||||
default: 100
|
||||
},
|
||||
[TerminalSettingId.SmoothScrolling]: {
|
||||
markdownDescription: localize('terminal.integrated.smoothScrolling', "Controls whether the terminal will scroll using an animation."),
|
||||
type: 'boolean',
|
||||
default: false
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ suite('CommandDetectionCapability', () => {
|
|||
}
|
||||
|
||||
setup(() => {
|
||||
xterm = new Terminal({ cols: 80 });
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80 });
|
||||
capability = new TestCommandDetectionCapability(xterm, new NullLogService());
|
||||
addEvents = [];
|
||||
capability.onCommandFinished(e => addEvents.push(e));
|
||||
|
|
|
@ -35,7 +35,7 @@ suite('PartialCommandDetectionCapability', () => {
|
|||
}
|
||||
|
||||
setup(() => {
|
||||
xterm = new Terminal({ cols: 80 }) as TestTerminal;
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80 }) as TestTerminal;
|
||||
capability = new PartialCommandDetectionCapability(xterm);
|
||||
addEvents = [];
|
||||
capability.onCommandFinished(e => addEvents.push(e));
|
||||
|
|
|
@ -80,7 +80,7 @@ suite('TerminalLinkManager', () => {
|
|||
instantiationService.stub(IThemeService, themeService);
|
||||
instantiationService.stub(IViewDescriptorService, viewDescriptorService);
|
||||
|
||||
xterm = new Terminal({ cols: 80, rows: 30 });
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 });
|
||||
linkManager = instantiationService.createInstance(TestLinkManager, xterm, upcastPartial<ITerminalProcessManager>({
|
||||
async getInitialCwd() {
|
||||
return '';
|
||||
|
|
|
@ -87,7 +87,7 @@ suite('Workbench - TerminalLinkOpeners', () => {
|
|||
}
|
||||
} as Partial<IEditorService>);
|
||||
// /*editorServiceSpy = */instantiationService.spy(IEditorService, 'openEditor');
|
||||
xterm = new Terminal();
|
||||
xterm = new Terminal({ allowProposedApi: true });
|
||||
});
|
||||
|
||||
suite('TerminalSearchLinkOpener', () => {
|
||||
|
|
|
@ -98,7 +98,7 @@ suite('Workbench - TerminalLocalLinkDetector', () => {
|
|||
configurationService = new TestConfigurationService();
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
|
||||
xterm = new Terminal({ cols: 80, rows: 30 });
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 });
|
||||
});
|
||||
|
||||
suite('platform independent', () => {
|
||||
|
|
|
@ -22,7 +22,7 @@ suite('Workbench - TerminalUriLinkDetector', () => {
|
|||
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
|
||||
xterm = new Terminal({ cols: 80, rows: 30 });
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 });
|
||||
detector = instantiationService.createInstance(TerminalUriLinkDetector, xterm, resolveLinkForTest);
|
||||
});
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ suite('Workbench - TerminalWordLinkDetector', () => {
|
|||
|
||||
instantiationService.stub(IConfigurationService, configurationService);
|
||||
|
||||
xterm = new Terminal({ cols: 80, rows: 30 });
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 });
|
||||
detector = instantiationService.createInstance(TerminalWordLinkDetector, xterm);
|
||||
});
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ suite('DecorationAddon', () => {
|
|||
});
|
||||
instantiationService.stub(IThemeService, new TestThemeService());
|
||||
xterm = new TestTerminal({
|
||||
allowProposedApi: true,
|
||||
cols: 80,
|
||||
rows: 30
|
||||
});
|
||||
|
|
|
@ -28,9 +28,7 @@ suite('LineDataEventAddon', () => {
|
|||
let events: string[];
|
||||
|
||||
setup(() => {
|
||||
xterm = new Terminal({
|
||||
cols: 4
|
||||
});
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 4 });
|
||||
lineDataEventAddon = new LineDataEventAddon();
|
||||
xterm.loadAddon(lineDataEventAddon);
|
||||
|
||||
|
|
|
@ -42,10 +42,7 @@ suite('ShellIntegrationAddon', () => {
|
|||
let capabilities: ITerminalCapabilityStore;
|
||||
|
||||
setup(() => {
|
||||
xterm = new Terminal({
|
||||
cols: 80,
|
||||
rows: 30
|
||||
});
|
||||
xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 });
|
||||
const instantiationService = new TestInstantiationService();
|
||||
instantiationService.stub(ILogService, NullLogService);
|
||||
shellIntegrationAddon = instantiationService.createInstance(TestShellIntegrationAddon, undefined, undefined);
|
||||
|
|
|
@ -16,7 +16,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||
import { IViewDescriptor, IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
import { TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR, TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { WebglAddon } from 'xterm-addon-webgl';
|
||||
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
|
||||
|
@ -33,6 +33,7 @@ import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecy
|
|||
class TestWebglAddon {
|
||||
static shouldThrow = false;
|
||||
static isEnabled = false;
|
||||
readonly onChangeTextureAtlas = new Emitter().event as IEvent<HTMLCanvasElement>;
|
||||
readonly onContextLoss = new Emitter().event as IEvent<void>;
|
||||
activate() {
|
||||
TestWebglAddon.isEnabled = !TestWebglAddon.shouldThrow;
|
||||
|
@ -48,8 +49,8 @@ class TestWebglAddon {
|
|||
|
||||
class TestXtermTerminal extends XtermTerminal {
|
||||
webglAddonPromise: Promise<typeof WebglAddon> = Promise.resolve(TestWebglAddon);
|
||||
// Force synchronous to avoid async when activating the addon
|
||||
protected override _getWebglAddonConstructor() {
|
||||
// Force synchronous to avoid async when activating the addon
|
||||
return this.webglAddonPromise;
|
||||
}
|
||||
}
|
||||
|
@ -123,8 +124,8 @@ suite('XtermTerminal', () => {
|
|||
});
|
||||
|
||||
test('should use fallback dimensions of 80x30', () => {
|
||||
strictEqual(xterm.raw.options.cols, 80);
|
||||
strictEqual(xterm.raw.options.rows, 30);
|
||||
strictEqual(xterm.raw.cols, 80);
|
||||
strictEqual(xterm.raw.rows, 30);
|
||||
});
|
||||
|
||||
suite('theme', () => {
|
||||
|
@ -149,6 +150,7 @@ suite('XtermTerminal', () => {
|
|||
[TERMINAL_CURSOR_FOREGROUND_COLOR]: '#000300',
|
||||
[TERMINAL_CURSOR_BACKGROUND_COLOR]: '#000400',
|
||||
[TERMINAL_SELECTION_BACKGROUND_COLOR]: '#000500',
|
||||
[TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR]: '#000600',
|
||||
[TERMINAL_SELECTION_FOREGROUND_COLOR]: undefined,
|
||||
'terminal.ansiBlack': '#010000',
|
||||
'terminal.ansiRed': '#020000',
|
||||
|
@ -173,7 +175,8 @@ suite('XtermTerminal', () => {
|
|||
foreground: '#000200',
|
||||
cursor: '#000300',
|
||||
cursorAccent: '#000400',
|
||||
selection: '#000500',
|
||||
selectionBackground: '#000500',
|
||||
selectionInactiveBackground: '#000600',
|
||||
selectionForeground: undefined,
|
||||
black: '#010000',
|
||||
green: '#030000',
|
||||
|
@ -198,7 +201,8 @@ suite('XtermTerminal', () => {
|
|||
[TERMINAL_CURSOR_FOREGROUND_COLOR]: '#00030f',
|
||||
[TERMINAL_CURSOR_BACKGROUND_COLOR]: '#00040f',
|
||||
[TERMINAL_SELECTION_BACKGROUND_COLOR]: '#00050f',
|
||||
[TERMINAL_SELECTION_FOREGROUND_COLOR]: '#00060f',
|
||||
[TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR]: '#00060f',
|
||||
[TERMINAL_SELECTION_FOREGROUND_COLOR]: '#00070f',
|
||||
'terminal.ansiBlack': '#01000f',
|
||||
'terminal.ansiRed': '#02000f',
|
||||
'terminal.ansiGreen': '#03000f',
|
||||
|
@ -221,8 +225,9 @@ suite('XtermTerminal', () => {
|
|||
foreground: '#00020f',
|
||||
cursor: '#00030f',
|
||||
cursorAccent: '#00040f',
|
||||
selection: '#00050f',
|
||||
selectionForeground: '#00060f',
|
||||
selectionBackground: '#00050f',
|
||||
selectionInactiveBackground: '#00060f',
|
||||
selectionForeground: '#00070f',
|
||||
black: '#01000f',
|
||||
green: '#03000f',
|
||||
red: '#02000f',
|
||||
|
@ -246,7 +251,6 @@ suite('XtermTerminal', () => {
|
|||
suite('renderers', () => {
|
||||
test('should re-evaluate gpu acceleration auto when the setting is changed', async () => {
|
||||
// Check initial state
|
||||
strictEqual(xterm.raw.options.rendererType, 'dom');
|
||||
strictEqual(TestWebglAddon.isEnabled, false);
|
||||
|
||||
// Open xterm as otherwise the webgl addon won't activate
|
||||
|
@ -267,7 +271,6 @@ suite('XtermTerminal', () => {
|
|||
await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } });
|
||||
configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any);
|
||||
await xterm.webglAddonPromise; // await addon activate
|
||||
strictEqual(xterm.raw.options.rendererType, 'dom');
|
||||
strictEqual(TestWebglAddon.isEnabled, false);
|
||||
|
||||
// Set to auto again but throw when activating the webgl addon
|
||||
|
@ -275,7 +278,6 @@ suite('XtermTerminal', () => {
|
|||
await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } });
|
||||
configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any);
|
||||
await xterm.webglAddonPromise; // await addon activate
|
||||
strictEqual(xterm.raw.options.rendererType, 'canvas');
|
||||
strictEqual(TestWebglAddon.isEnabled, false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -83,37 +83,16 @@ export class EditorResolverService extends Disposable implements IEditorResolver
|
|||
});
|
||||
}
|
||||
|
||||
private resolveUntypedInputAndGroup(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IUntypedEditorInput, IEditorGroup, EditorActivation | undefined] | undefined {
|
||||
let untypedEditor: IUntypedEditorInput | undefined = undefined;
|
||||
private resolveUntypedInputAndGroup(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IUntypedEditorInput, IEditorGroup, EditorActivation | undefined] | undefined {
|
||||
const untypedEditor = editor;
|
||||
|
||||
// Typed: convert to untyped to be able to resolve the editor as the service only uses untyped
|
||||
if (isEditorInputWithOptions(editor)) {
|
||||
untypedEditor = editor.editor.toUntyped();
|
||||
|
||||
if (untypedEditor) {
|
||||
// Preserve original options: specifically it is
|
||||
// possible that a `override` was defined from
|
||||
// the outside and we do not want to lose it.
|
||||
untypedEditor.options = { ...untypedEditor.options, ...editor.options };
|
||||
}
|
||||
}
|
||||
|
||||
// Untyped: take as is
|
||||
else {
|
||||
untypedEditor = editor;
|
||||
}
|
||||
|
||||
// Typed editors that cannot convert to untyped will be returned as undefined
|
||||
if (!untypedEditor) {
|
||||
return undefined;
|
||||
}
|
||||
// Use the untyped editor to find a group
|
||||
const [group, activation] = this.instantiationService.invokeFunction(findGroup, untypedEditor, preferredGroup);
|
||||
|
||||
return [untypedEditor, group, activation];
|
||||
}
|
||||
|
||||
async resolveEditor(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ResolvedEditor> {
|
||||
async resolveEditor(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ResolvedEditor> {
|
||||
// Update the flattened editors
|
||||
this._flattenedEditors = this._flattenEditorsMap();
|
||||
|
||||
|
|
|
@ -501,8 +501,8 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
}
|
||||
|
||||
// Resolve override unless disabled
|
||||
if (options?.override !== EditorResolution.DISABLED) {
|
||||
const resolvedEditor = await this.editorResolverService.resolveEditor(isEditorInput(editor) ? { editor, options } : editor, preferredGroup);
|
||||
if (options?.override !== EditorResolution.DISABLED && !isEditorInput(editor)) {
|
||||
const resolvedEditor = await this.editorResolverService.resolveEditor(editor, preferredGroup);
|
||||
|
||||
if (resolvedEditor === ResolvedStatus.ABORT) {
|
||||
return; // skip editor if override is aborted
|
||||
|
@ -561,7 +561,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
let group: IEditorGroup | undefined = undefined;
|
||||
|
||||
// Resolve override unless disabled
|
||||
if (editor.options?.override !== EditorResolution.DISABLED) {
|
||||
if (editor.options?.override !== EditorResolution.DISABLED && !isEditorInputWithOptions(editor)) {
|
||||
const resolvedEditor = await this.editorResolverService.resolveEditor(editor, preferredGroup);
|
||||
|
||||
if (resolvedEditor === ResolvedStatus.ABORT) {
|
||||
|
@ -860,9 +860,9 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
}
|
||||
|
||||
// Resolve override unless disabled
|
||||
if (override !== EditorResolution.DISABLED) {
|
||||
if (override !== EditorResolution.DISABLED && !isEditorInput(replacement.replacement)) {
|
||||
const resolvedEditor = await this.editorResolverService.resolveEditor(
|
||||
isEditorReplacement(replacement) ? { editor: replacement.replacement, options: replacement.options } : replacement.replacement,
|
||||
replacement.replacement,
|
||||
targetGroup
|
||||
);
|
||||
|
||||
|
|
|
@ -156,12 +156,12 @@ export interface IEditorResolverService {
|
|||
): IDisposable;
|
||||
|
||||
/**
|
||||
* Given an editor resolves it to the suitable EditorInputWithOptionsAndGroup based on user extensions, settings, and built-in editors
|
||||
* Given an editor resolves it to the suitable ResolvedEitor based on user extensions, settings, and built-in editors
|
||||
* @param editor The editor to resolve
|
||||
* @param preferredGroup The group you want to open the editor in
|
||||
* @returns An EditorInputWithOptionsAndGroup if there is an available editor or a status of how to proceed
|
||||
*/
|
||||
resolveEditor(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ResolvedEditor>;
|
||||
resolveEditor(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ResolvedEditor>;
|
||||
|
||||
/**
|
||||
* Given a resource returns all the editor ids that match that resource. If there is exclusive editor we return an empty array
|
||||
|
|
|
@ -851,11 +851,12 @@ suite('EditorService', () => {
|
|||
assert.ok(typedInput instanceof TestFileEditorInput);
|
||||
assert.strictEqual(typedInput.resource.toString(), typedEditor.resource.toString());
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 1);
|
||||
// It's a typed editor input so the resolver should not have been called
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString());
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -876,11 +877,11 @@ suite('EditorService', () => {
|
|||
assert.ok(typedInput instanceof TestFileEditorInput);
|
||||
assert.strictEqual(typedInput.resource.toString(), typedEditorReplacement.resource.toString());
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 2);
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedInput.resource.toString());
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -941,7 +942,8 @@ suite('EditorService', () => {
|
|||
const pane = await openEditor({ editor: typedEditor, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } });
|
||||
|
||||
assert.strictEqual(pane?.group, rootGroup);
|
||||
assert.ok(pane.input instanceof FileEditorInput);
|
||||
// We shouldn't have resolved because it is a typed editor, even though we have an override specified
|
||||
assert.ok(pane.input instanceof TestFileEditorInput);
|
||||
assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString());
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
|
@ -964,11 +966,11 @@ suite('EditorService', () => {
|
|||
assert.ok(pane.input instanceof TestFileEditorInput);
|
||||
assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString());
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 1);
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString());
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -985,12 +987,11 @@ suite('EditorService', () => {
|
|||
assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString());
|
||||
assert.strictEqual(pane.group.isSticky(pane.input), true);
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 1);
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString());
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).options?.preserveFocus, true);
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -1008,12 +1009,11 @@ suite('EditorService', () => {
|
|||
assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString());
|
||||
assert.strictEqual(pane.group.isSticky(pane.input), true);
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 1);
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString());
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).options?.preserveFocus, true);
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -1031,11 +1031,11 @@ suite('EditorService', () => {
|
|||
assert.ok(pane?.input instanceof TestFileEditorInput);
|
||||
assert.strictEqual(pane?.input.resource.toString(), typedEditor.resource.toString());
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 1);
|
||||
assert.strictEqual(editorFactoryCalled, 0);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString());
|
||||
assert.ok(!lastEditorFactoryEditor);
|
||||
assert.ok(!lastUntitledEditorFactoryEditor);
|
||||
assert.ok(!lastDiffEditorFactoryEditor);
|
||||
|
||||
|
@ -1342,7 +1342,8 @@ suite('EditorService', () => {
|
|||
assert.strictEqual(pane?.group, rootGroup);
|
||||
assert.strictEqual(pane?.group.count, 5);
|
||||
|
||||
assert.strictEqual(editorFactoryCalled, 3);
|
||||
// Only the untyped editors should have had factories called (and 1 is disabled so 3 untyped - 1 disabled = 2)
|
||||
assert.strictEqual(editorFactoryCalled, 2);
|
||||
assert.strictEqual(untitledEditorFactoryCalled, 0);
|
||||
assert.strictEqual(diffEditorFactoryCalled, 0);
|
||||
|
||||
|
@ -2334,13 +2335,19 @@ suite('EditorService', () => {
|
|||
);
|
||||
assert.strictEqual(editorCount, 0);
|
||||
|
||||
const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource1.txt'), TEST_EDITOR_INPUT_ID);
|
||||
const input2 = new TestFileEditorInput(URI.parse('file://test/path/resource2.txt'), TEST_EDITOR_INPUT_ID);
|
||||
const input3 = new TestFileEditorInput(URI.parse('file://test/path/resource3.md'), TEST_EDITOR_INPUT_ID);
|
||||
const input4 = new TestFileEditorInput(URI.parse('file://test/path/resource4.md'), TEST_EDITOR_INPUT_ID);
|
||||
const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource1.txt'), TEST_EDITOR_INPUT_ID).toUntyped();
|
||||
const input2 = new TestFileEditorInput(URI.parse('file://test/path/resource2.txt'), TEST_EDITOR_INPUT_ID).toUntyped();
|
||||
const input3 = new TestFileEditorInput(URI.parse('file://test/path/resource3.md'), TEST_EDITOR_INPUT_ID).toUntyped();
|
||||
const input4 = new TestFileEditorInput(URI.parse('file://test/path/resource4.md'), TEST_EDITOR_INPUT_ID).toUntyped();
|
||||
|
||||
// Open editor input 1 and it shouln't trigger override as the glob doesn't match
|
||||
await service.openEditors([{ editor: input1 }, { editor: input2 }, { editor: input3 }, { editor: input4 }]);
|
||||
assert.ok(input1);
|
||||
assert.ok(input2);
|
||||
assert.ok(input3);
|
||||
assert.ok(input4);
|
||||
|
||||
// Open editor inputs
|
||||
await service.openEditors([input1, input2, input3, input4]);
|
||||
// Only two matched the factory glob
|
||||
assert.strictEqual(editorCount, 2);
|
||||
|
||||
registrationDisposable.dispose();
|
||||
|
@ -2374,6 +2381,8 @@ suite('EditorService', () => {
|
|||
assert.strictEqual(editorCount, 0);
|
||||
|
||||
const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource2.md'), TEST_EDITOR_INPUT_ID);
|
||||
const untypedInput1 = input1.toUntyped();
|
||||
assert.ok(untypedInput1);
|
||||
|
||||
// Open editor input 1 and it shouldn't trigger because I've disabled the override logic
|
||||
await service.openEditor(input1, { override: EditorResolution.DISABLED });
|
||||
|
@ -2381,7 +2390,7 @@ suite('EditorService', () => {
|
|||
|
||||
await service.replaceEditors([{
|
||||
editor: input1,
|
||||
replacement: input1,
|
||||
replacement: untypedInput1,
|
||||
}], part.activeGroup);
|
||||
assert.strictEqual(editorCount, 1);
|
||||
|
||||
|
|
|
@ -71,15 +71,17 @@ export class ProgressService extends Disposable implements IProgressService {
|
|||
switch (location) {
|
||||
case ProgressLocation.Notification:
|
||||
return this.withNotificationProgress({ ...options, location, silent: this.notificationService.doNotDisturbMode }, task, onDidCancel);
|
||||
case ProgressLocation.Window:
|
||||
case ProgressLocation.Window: {
|
||||
const type = (options as IProgressWindowOptions).type;
|
||||
if ((options as IProgressWindowOptions).command) {
|
||||
// Window progress with command get's shown in the status bar
|
||||
return this.withWindowProgress({ ...options, location }, task);
|
||||
return this.withWindowProgress({ ...options, location, type }, task);
|
||||
}
|
||||
// Window progress without command can be shown as silent notification
|
||||
// which will first appear in the status bar and can then be brought to
|
||||
// the front when clicking.
|
||||
return this.withNotificationProgress({ delay: 150 /* default for ProgressLocation.Window */, ...options, silent: true, location: ProgressLocation.Notification }, task, onDidCancel);
|
||||
return this.withNotificationProgress({ delay: 150 /* default for ProgressLocation.Window */, ...options, silent: true, location: ProgressLocation.Notification, type }, task, onDidCancel);
|
||||
}
|
||||
case ProgressLocation.Explorer:
|
||||
return this.withPaneCompositeProgress('workbench.view.explorer', ViewContainerLocation.Sidebar, task, { ...options, location });
|
||||
case ProgressLocation.Scm:
|
||||
|
@ -235,7 +237,8 @@ export class ProgressService extends Disposable implements IProgressService {
|
|||
this.withWindowProgress({
|
||||
location: ProgressLocation.Window,
|
||||
title: options.title ? parseLinkedText(options.title).toString() : undefined, // convert markdown links => string
|
||||
command: 'notifications.showList'
|
||||
command: 'notifications.showList',
|
||||
type: options.type
|
||||
}, progress => {
|
||||
|
||||
function reportProgress(step: IProgressStep) {
|
||||
|
|
|
@ -87,23 +87,23 @@ export class TextEditorService extends Disposable implements ITextEditorService
|
|||
createTextEditor(input: IUntypedFileEditorInput): IFileEditorInput;
|
||||
createTextEditor(input: IUntypedEditorInput | IUntypedFileEditorInput): EditorInput | IFileEditorInput {
|
||||
|
||||
// Merge Editor is Unsupported from here
|
||||
// Merge Editor Not Supported (we fallback to showing the result only)
|
||||
if (isResourceMergeEditorInput(input)) {
|
||||
throw new Error('Unsupported input');
|
||||
return this.createTextEditor(input.result);
|
||||
}
|
||||
|
||||
// Diff Editor Support
|
||||
if (isResourceDiffEditorInput(input)) {
|
||||
const original = this.createTextEditor({ ...input.original });
|
||||
const modified = this.createTextEditor({ ...input.modified });
|
||||
const original = this.createTextEditor(input.original);
|
||||
const modified = this.createTextEditor(input.modified);
|
||||
|
||||
return this.instantiationService.createInstance(DiffEditorInput, input.label, input.description, original, modified, undefined);
|
||||
}
|
||||
|
||||
// Side by Side Editor Support
|
||||
if (isResourceSideBySideEditorInput(input)) {
|
||||
const primary = this.createTextEditor({ ...input.primary });
|
||||
const secondary = this.createTextEditor({ ...input.secondary });
|
||||
const primary = this.createTextEditor(input.primary);
|
||||
const secondary = this.createTextEditor(input.secondary);
|
||||
|
||||
return this.instantiationService.createInstance(SideBySideEditorInput, input.label, input.description, secondary, primary);
|
||||
}
|
||||
|
|
88
yarn.lock
88
yarn.lock
|
@ -575,13 +575,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
||||
|
||||
"@ts-morph/common@~0.12.3":
|
||||
version "0.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.12.3.tgz#a96e250217cd30e480ab22ec6a0ebbe65fd784ff"
|
||||
integrity sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==
|
||||
"@ts-morph/common@~0.16.0":
|
||||
version "0.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.16.0.tgz#57e27d4b3fd65a4cd72cb36679ed08acb40fa3ba"
|
||||
integrity sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==
|
||||
dependencies:
|
||||
fast-glob "^3.2.7"
|
||||
minimatch "^3.0.4"
|
||||
fast-glob "^3.2.11"
|
||||
minimatch "^5.1.0"
|
||||
mkdirp "^1.0.4"
|
||||
path-browserify "^1.0.1"
|
||||
|
||||
|
@ -1005,14 +1005,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@vscode/sudo-prompt/-/sudo-prompt-9.3.1.tgz#c562334bc6647733649fd42afc96c0eea8de3b65"
|
||||
integrity sha512-9ORTwwS74VaTn38tNbQhsA5U44zkJfcb0BdTSyyG6frP4e8KMtHuTXYmwefe5dpL8XB1aGSIVTaLjD3BbWb5iA==
|
||||
|
||||
"@vscode/telemetry-extractor@^1.9.6":
|
||||
version "1.9.6"
|
||||
resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.6.tgz#1b8d31c2ea841b33e5aa4e9c69a01f011cfc3add"
|
||||
integrity sha512-G5m3NRNXW5ePsm4dft64EiOOopYin/3vQ6mBwWKkgnRkD8LivVvtDBjDMwZGsN5lF0w4t+ugb+IE4bXfMhZMcg==
|
||||
"@vscode/telemetry-extractor@^1.9.8":
|
||||
version "1.9.8"
|
||||
resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.8.tgz#ffc000720ea2b9cd3421ba8a7bd172972c398b06"
|
||||
integrity sha512-L27/fgC/gM7AY6AXriFGrznnX1M4Nc7VmHabYinDPoJDQYLjbSEDDVjjlSS6BiVkzc3OrFQStqXpHBhImis2eQ==
|
||||
dependencies:
|
||||
"@vscode/ripgrep" "^1.14.2"
|
||||
command-line-args "^5.2.1"
|
||||
ts-morph "^13.0.3"
|
||||
ts-morph "^15.1.0"
|
||||
|
||||
"@vscode/test-web@^0.0.29":
|
||||
version "0.0.29"
|
||||
|
@ -1963,6 +1963,13 @@ brace-expansion@^1.1.7:
|
|||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
braces@^2.3.1, braces@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
|
||||
|
@ -4232,18 +4239,7 @@ fast-glob@^3.1.1, fast-glob@^3.2.4:
|
|||
micromatch "^4.0.2"
|
||||
picomatch "^2.2.1"
|
||||
|
||||
fast-glob@^3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
|
||||
integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "^2.0.2"
|
||||
"@nodelib/fs.walk" "^1.2.3"
|
||||
glob-parent "^5.1.2"
|
||||
merge2 "^1.3.0"
|
||||
micromatch "^4.0.4"
|
||||
|
||||
fast-glob@^3.2.9:
|
||||
fast-glob@^3.2.11, fast-glob@^3.2.9:
|
||||
version "3.2.11"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
|
||||
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
|
||||
|
@ -7002,6 +6998,13 @@ minimatch@4.2.1:
|
|||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
|
||||
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
|
@ -10297,12 +10300,12 @@ ts-loader@^9.2.7:
|
|||
micromatch "^4.0.0"
|
||||
semver "^7.3.4"
|
||||
|
||||
ts-morph@^13.0.3:
|
||||
version "13.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.3.tgz#c0c51d1273ae2edb46d76f65161eb9d763444c1d"
|
||||
integrity sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==
|
||||
ts-morph@^15.1.0:
|
||||
version "15.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-15.1.0.tgz#53deea5296d967ff6eba8f15f99d378aa7074a4e"
|
||||
integrity sha512-RBsGE2sDzUXFTnv8Ba22QfeuKbgvAGJFuTN7HfmIRUkgT/NaVLfDM/8OFm2NlFkGlWEXdpW5OaFIp1jvqdDuOg==
|
||||
dependencies:
|
||||
"@ts-morph/common" "~0.12.3"
|
||||
"@ts-morph/common" "~0.16.0"
|
||||
code-block-writer "^11.0.0"
|
||||
|
||||
tsec@0.1.4:
|
||||
|
@ -11225,6 +11228,11 @@ xtend@~2.1.1:
|
|||
dependencies:
|
||||
object-keys "~0.4.0"
|
||||
|
||||
xterm-addon-canvas@0.2.0-beta.15:
|
||||
version "0.2.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4"
|
||||
integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw==
|
||||
|
||||
xterm-addon-search@0.10.0-beta.3:
|
||||
version "0.10.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a"
|
||||
|
@ -11240,20 +11248,20 @@ xterm-addon-unicode11@0.4.0-beta.3:
|
|||
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa"
|
||||
integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q==
|
||||
|
||||
xterm-addon-webgl@0.13.0-beta.9:
|
||||
version "0.13.0-beta.9"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb"
|
||||
integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g==
|
||||
xterm-addon-webgl@0.13.0-beta.32:
|
||||
version "0.13.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212"
|
||||
integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw==
|
||||
|
||||
xterm-headless@4.20.0-beta.20:
|
||||
version "4.20.0-beta.20"
|
||||
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.20.0-beta.20.tgz#da2d8131b02d6f1e37f47cc17e578f2c2980fbb6"
|
||||
integrity sha512-JK4jUIiUH7TdzvMrpfDnbGxTuC4s7byjqnMHR8+gIpY8qCFjz0xcMFSbp+ZshxGwVyziI4jtJqTHZjFToT2/kw==
|
||||
xterm-headless@5.0.0-beta.5:
|
||||
version "5.0.0-beta.5"
|
||||
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.0.0-beta.5.tgz#e29b6c5081f31f887122b7263ba996b0c46b3c22"
|
||||
integrity sha512-CMQ1+prBNF92oBMeZzc2rfTcmOaCGfwwSaoPYNTjyziZT6mZsEg7amajYkb0YAnqJ29MFm4kPGZbU78/dX4k2A==
|
||||
|
||||
xterm@4.20.0-beta.20:
|
||||
version "4.20.0-beta.20"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed"
|
||||
integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ==
|
||||
xterm@5.0.0-beta.32:
|
||||
version "5.0.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c"
|
||||
integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA==
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.2"
|
||||
|
|
Loading…
Reference in a new issue