Merge branch 'master' into scm-api

This commit is contained in:
Joao Moreno
2016-11-24 18:05:13 +01:00
179 changed files with 9449 additions and 68984 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.8.1' },
{ name: 'ms-vscode.node-debug', version: '1.8.3' },
{ name: 'ms-vscode.node-debug2', version: '1.8.1' }
];
+14 -10
View File
@@ -6,6 +6,19 @@
const cp = require('child_process');
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
function npmInstall(location) {
const result = cp.spawnSync(npm, ['install'], {
cwd: location ,
stdio: 'inherit'
});
if (result.error || result.status !== 0) {
process.exit(1);
}
}
npmInstall('extensions'); // node modules shared by all extensions
const extensions = [
'vscode-api-tests',
'vscode-colorize-tests',
@@ -21,13 +34,4 @@ const extensions = [
'git'
];
extensions.forEach(extension => {
const result = cp.spawnSync(npm, ['install'], {
cwd: `extensions/${extension}`,
stdio: 'inherit'
});
if (result.error || result.status !== 0) {
process.exit(1);
}
});
extensions.forEach(extension => npmInstall(`extensions/${extension}`));
@@ -44,16 +44,29 @@ function registerKeybindingsCompletions(): vscode.Disposable {
});
}
function updateLaunchJsonDecorations(editor: vscode.TextEditor) {
function newCompletionItem(text: string, range: vscode.Range) {
const item = new vscode.CompletionItem(JSON.stringify(text));
item.kind = vscode.CompletionItemKind.Value;
item.textEdit = {
range,
newText: item.label
};
return item;
}
function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined) {
if (!editor || path.basename(editor.document.fileName) !== 'launch.json') {
return;
}
const ranges = [];
const ranges: vscode.Range[] = [];
let addPropertyAndValue = false;
let depthInArray = 0;
visit(editor.document.getText(), {
onObjectProperty: (property, offset, length) => {
addPropertyAndValue = property === 'version' || property === 'type' || property === 'request' || property === 'configurations';
// Decorate attributes which are unlikely to be edited by the user.
// Only decorate "configurations" if it is not inside an array (compounds have a configurations property which should not be decorated).
addPropertyAndValue = property === 'version' || property === 'type' || property === 'request' || property === 'compounds' || (property === 'configurations' && depthInArray === 0);
if (addPropertyAndValue) {
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
}
@@ -62,19 +75,15 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor) {
if (addPropertyAndValue) {
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
}
},
onArrayBegin: (offset: number, length: number) => {
depthInArray++;
},
onArrayEnd: (offset: number, length: number) => {
depthInArray--;
}
});
editor.setDecorations(decoration, ranges);
}
function newCompletionItem(text: string, range: vscode.Range, documentation?: string) {
const item = new vscode.CompletionItem(JSON.stringify(text));
item.kind = vscode.CompletionItemKind.Value;
item.documentation = documentation;
item.textEdit = {
range,
newText: item.label
};
return item;
}
@@ -3,9 +3,10 @@
"noLib": true,
"target": "es5",
"module": "commonjs",
"outDir": "./out"
"outDir": "./out",
"strictNullChecks": true
},
"exclude": [
"node_modules"
]
}
}
+18 -18
View File
@@ -7,14 +7,14 @@
import * as path from 'path';
import { languages, window, commands, ExtensionContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit, Protocol2Code } from 'vscode-languageclient';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit } from 'vscode-languageclient';
import { activateColorDecorations } from './colorDecorators';
import * as nls from 'vscode-nls';
let localize = nls.loadMessageBundle();
namespace ColorSymbolRequest {
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
export const type: RequestType<string, Range[], any, any> = { get method() { return 'css/colorSymbols'; }, _: null };
}
// this method is called when vs code is activated
@@ -51,7 +51,7 @@ export function activate(context: ExtensionContext) {
context.subscriptions.push(disposable);
let colorRequestor = (uri: string) => {
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(Protocol2Code.asRange));
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(client.protocol2CodeConverter.asRange));
};
disposable = activateColorDecorations(colorRequestor, { css: true, scss: true, less: true });
context.subscriptions.push(disposable);
@@ -69,23 +69,23 @@ export function activate(context: ExtensionContext) {
});
commands.registerCommand('_css.applyCodeAction', applyCodeAction);
}
function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) {
let textEditor = window.activeTextEditor;
if (textEditor && textEditor.document.uri.toString() === uri) {
if (textEditor.document.version !== documentVersion) {
window.showInformationMessage(`CSS fix is outdated and can't be applied to the document.`);
function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) {
let textEditor = window.activeTextEditor;
if (textEditor && textEditor.document.uri.toString() === uri) {
if (textEditor.document.version !== documentVersion) {
window.showInformationMessage(`CSS fix is outdated and can't be applied to the document.`);
}
textEditor.edit(mutator => {
for (let edit of edits) {
mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText);
}
}).then(success => {
if (!success) {
window.showErrorMessage('Failed to apply CSS fix to the document. Please consider opening an issue with steps to reproduce.');
}
});
}
textEditor.edit(mutator => {
for (let edit of edits) {
mutator.replace(Protocol2Code.asRange(edit.range), edit.newText);
}
}).then(success => {
if (!success) {
window.showErrorMessage('Failed to apply CSS fix to the document. Please consider opening an issue with steps to reproduce.');
}
});
}
}
+1 -6
View File
@@ -3,9 +3,4 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../../src/typings/mocha.d.ts'/>
/// <reference path='../../../../../extensions/node.d.ts'/>
/// <reference path='../../../../../extensions/lib.core.d.ts'/>
/// <reference path='../../../../../extensions/declares.d.ts'/>
/// <reference path='../../../node_modules/vscode-languageclient/lib/main.d.ts'/>
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
+4 -2
View File
@@ -1,9 +1,11 @@
{
"compilerOptions": {
"noLib": true,
"target": "es5",
"module": "commonjs",
"outDir": "./out"
"outDir": "./out",
"lib": [
"es5", "es2015.promise"
]
},
"exclude": [
"node_modules"
+8 -8
View File
@@ -3,19 +3,19 @@
"version": "0.1.0",
"dependencies": {
"vscode-jsonrpc": {
"version": "2.3.2-next.5",
"from": "vscode-jsonrpc@>=2.3.2-next.2 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.3.2-next.5.tgz"
"version": "3.0.1-alpha.2",
"from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz"
},
"vscode-languageclient": {
"version": "2.4.2-next.22",
"version": "3.0.1-alpha.2",
"from": "vscode-languageclient@next",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-2.4.2-next.22.tgz"
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.0.1-alpha.2.tgz"
},
"vscode-languageserver-types": {
"version": "1.0.3",
"from": "vscode-languageserver-types@>=1.0.3 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz"
"version": "3.0.1-alpha.2",
"from": "vscode-languageserver-types@>=3.0.1-alpha.2 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz"
},
"vscode-nls": {
"version": "1.0.7",
+4 -1
View File
@@ -646,7 +646,10 @@
}
},
"dependencies": {
"vscode-languageclient": "^2.4.2-next.22",
"vscode-languageclient": "^3.0.1-alpha.2",
"vscode-nls": "^1.0.7"
},
"devDependencies": {
"@types/node": "^6.0.51"
}
}
+10 -22
View File
@@ -3,41 +3,29 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
"version": "1.1.0",
"version": "2.0.0-next.5",
"from": "vscode-css-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-1.1.0.tgz"
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0-next.5.tgz"
},
"vscode-jsonrpc": {
"version": "2.3.2-next.5",
"from": "vscode-jsonrpc@>=2.3.2-next.2 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.3.2-next.5.tgz"
"version": "3.0.1-alpha.2",
"from": "vscode-jsonrpc@>=3.0.1-alpha.2 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.0.1-alpha.2.tgz"
},
"vscode-languageserver": {
"version": "2.4.0-next.12",
"version": "3.0.1-alpha.2",
"from": "vscode-languageserver@next",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-2.4.0-next.12.tgz",
"dependencies": {
"vscode-languageserver-types": {
"version": "1.0.3",
"from": "vscode-languageserver-types@>=1.0.3 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz"
}
}
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.0.1-alpha.2.tgz"
},
"vscode-languageserver-types": {
"version": "1.0.3",
"from": "vscode-languageserver-types@>=1.0.3 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz"
"version": "3.0.1-alpha.2",
"from": "vscode-languageserver-types@>=3.0.1-alpha.2 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.1-alpha.2.tgz"
},
"vscode-nls": {
"version": "1.0.7",
"from": "vscode-nls@>=1.0.4 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-1.0.7.tgz"
},
"vscode-uri": {
"version": "1.0.0",
"from": "vscode-uri@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.0.tgz"
}
}
}
+5 -2
View File
@@ -8,8 +8,11 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^1.1.0",
"vscode-languageserver": "^2.4.0-next.12"
"vscode-css-languageservice": "^2.0.0-next.5",
"vscode-languageserver": "^3.0.1-alpha.2"
},
"devDependencies": {
"@types/node": "^6.0.51"
},
"scripts": {
"compile": "gulp compile-extension:css-server",
+1 -1
View File
@@ -13,7 +13,7 @@ import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService,
import { getLanguageModelCache } from './languageModelCache';
namespace ColorSymbolRequest {
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
export const type: RequestType<string, Range[], any, any> = { get method() { return 'css/colorSymbols'; }, _: null };
}
export interface Settings {
-112
View File
@@ -1,112 +0,0 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/**
* The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's
* lib.core.es6.d.ts file. See above Copyright notice.
*/
/**
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
* and others. This API makes no assumption about what promise libary is being used which
* enables reusing existing code without migrating to a specific promise implementation. Still,
* we recommand the use of native promises which are available in VS Code.
*/
interface Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> extends Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Promise<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch(onrejected?: (reason: any) => T | Thenable<T>): Promise<T>;
}
interface PromiseConstructor {
/**
* Creates a new Promise.
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
* a resolve callback used resolve the promise with a value or the result of another promise,
* and a reject callback used to reject the promise with a provided reason or error.
*/
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any Promise is rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
all<T>(values: Array<T | Thenable<T>>): Promise<T[]>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T>(values: Array<T | Thenable<T>>): Promise<T>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject(reason: any): Promise<void>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject<T>(reason: any): Promise<T>;
/**
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
resolve<T>(value: T | Thenable<T>): Promise<T>;
/**
* Creates a new resolved promise .
* @returns A resolved promise.
*/
resolve(): Promise<void>;
}
declare var Promise: PromiseConstructor;
-8
View File
@@ -1,8 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../../src/typings/mocha.d.ts'/>
/// <reference path='../../../../../extensions/node.d.ts'/>
/// <reference path='../../../../../extensions/lib.core.d.ts'/>
/// <reference path='../../../../../extensions/declares.d.ts'/>
+4 -2
View File
@@ -1,9 +1,11 @@
{
"compilerOptions": {
"noLib": true,
"target": "es5",
"module": "commonjs",
"outDir": "./out"
"outDir": "./out",
"lib": [
"es5"
]
},
"exclude": [
"node_modules"
-5
View File
@@ -2,10 +2,5 @@
"name": "extension-editing",
"version": "0.0.1",
"dependencies": {
"typescript": {
"version": "1.8.10",
"from": "typescript@>=1.8.10 <2.0.0",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz"
}
}
}
@@ -13,13 +13,9 @@
],
"main": "./out/extension",
"scripts": {
"postinstall": "node ./postinstall",
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"typescript": "^1.8.10"
},
"contributes": {
"jsonValidation": [
{
@@ -1,23 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const fs = require('fs');
const path = require('path');
// delete unused typescript stuff
const root = path.dirname(require.resolve('typescript'));
for (let name of fs.readdirSync(root)) {
if (name !== 'typescript.d.ts' && name !== 'typescript.js') {
try {
fs.unlinkSync(path.join(root, name));
console.log(`removed '${path.join(root, name)}'`);
} catch (e) {
console.warn(e);
}
}
}
@@ -83,7 +83,7 @@ namespace ast {
let end = Number.MAX_VALUE;
for (let name of dottedName.split('.')) {
let idx: number;
let idx: number = -1;
while ((idx = identifiers.indexOf(name, idx + 1)) >= 0) {
let myStart = spans[2 * idx];
let myEnd = spans[2 * idx + 1];
@@ -0,0 +1,6 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "definitelytyped",
"repositoryURL": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"license": "MIT"
}]
File diff suppressed because it is too large Load Diff
+17 -4
View File
@@ -5,7 +5,8 @@
'use strict';
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType } from 'vscode-languageserver';
import { DocumentContext, TextDocument, Diagnostic, DocumentLink, Range, TextEdit } from 'vscode-html-languageservice';
import { DocumentContext } from 'vscode-html-languageservice';
import { TextDocument, Diagnostic, DocumentLink, Range, TextEdit, SymbolInformation } from 'vscode-languageserver-types';
import { getLanguageModes, LanguageModes } from './modes/languageModes';
import * as url from 'url';
@@ -44,10 +45,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true });
documents.onDidClose(e => {
languageModes.getAllModes().forEach(m => m.onDocumentRemoved(e.document));
languageModes.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
languageModes.getAllModes().forEach(m => m.dispose());
languageModes.dispose();
});
return {
@@ -59,6 +60,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
documentHighlightProvider: true,
documentRangeFormattingProvider: initializationOptions && initializationOptions['format.enable'],
documentLinkProvider: true,
documentSymbolProvider: true,
definitionProvider: true,
signatureHelpProvider: { triggerCharacters: ['('] },
referencesProvider: true
@@ -198,7 +200,7 @@ connection.onDocumentRangeFormatting(formatParams => {
let result: TextEdit[] = [];
ranges.forEach(r => {
let mode = r.mode;
if (mode && mode.format) {
if (mode && mode.format && !r.attributeValue) {
let edits = mode.format(document, r, formatParams.options);
pushAll(result, edits);
}
@@ -225,6 +227,17 @@ connection.onDocumentLinks(documentLinkParam => {
return links;
});
connection.onDocumentSymbol(documentSymbolParms => {
let document = documents.get(documentSymbolParms.textDocument.uri);
let symbols: SymbolInformation[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentSymbols) {
pushAll(symbols, m.findDocumentSymbols(document));
}
});
return symbols;
});
connection.onRequest(ColorSymbolRequest.type, uri => {
let ranges: Range[] = [];
let document = documents.get(uri);
+16 -11
View File
@@ -5,16 +5,15 @@
'use strict';
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { LanguageService as HTMLLanguageService, HTMLDocument } from 'vscode-html-languageservice';
import { TextDocument, Position } from 'vscode-languageserver-types';
import { getCSSLanguageService, Stylesheet } from 'vscode-css-languageservice';
import { getEmbeddedDocument } from './embeddedSupport';
import { LanguageMode } from './languageModes';
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
export function getCSSMode(htmlLanguageService: HTMLLanguageService, htmlDocuments: LanguageModelCache<HTMLDocument>): LanguageMode {
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
let cssLanguageService = getCSSLanguageService();
let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css'));
let cssStylesheets = getLanguageModelCache<Stylesheet>(10, 60, document => cssLanguageService.parseStylesheet(document));
let getEmbeddedCSSDocument = (document: TextDocument) => getEmbeddedDocument(htmlLanguageService, document, htmlDocuments.get(document), 'css');
return {
getId() {
@@ -24,37 +23,43 @@ export function getCSSMode(htmlLanguageService: HTMLLanguageService, htmlDocumen
cssLanguageService.configure(options && options.css);
},
doValidation(document: TextDocument) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doValidation(embedded, cssStylesheets.get(embedded));
},
doComplete(document: TextDocument, position: Position) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doComplete(embedded, position, cssStylesheets.get(embedded));
},
doHover(document: TextDocument, position: Position) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doHover(embedded, position, cssStylesheets.get(embedded));
},
findDocumentHighlight(document: TextDocument, position: Position) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDocumentHighlights(embedded, position, cssStylesheets.get(embedded));
},
findDocumentSymbols(document: TextDocument) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDocumentSymbols(embedded, cssStylesheets.get(embedded)).filter(s => s.name !== CSS_STYLE_RULE);
},
findDefinition(document: TextDocument, position: Position) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDefinition(embedded, position, cssStylesheets.get(embedded));
},
findReferences(document: TextDocument, position: Position) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findReferences(embedded, position, cssStylesheets.get(embedded));
},
findColorSymbols(document: TextDocument) {
let embedded = getEmbeddedCSSDocument(document);
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findColorSymbols(embedded, cssStylesheets.get(embedded));
},
onDocumentRemoved(document: TextDocument) {
embeddedCSSDocuments.onDocumentRemoved(document);
cssStylesheets.onDocumentRemoved(document);
},
dispose() {
embeddedCSSDocuments.dispose();
cssStylesheets.dispose();
}
};
@@ -5,143 +5,187 @@
'use strict';
import { TextDocument, Position, HTMLDocument, Node, LanguageService, TokenType, Range, Scanner } from 'vscode-html-languageservice';
import { TextDocument, Position, LanguageService, TokenType, Range } from 'vscode-html-languageservice';
export interface LanguageRange extends Range {
languageId: string;
attributeValue?: boolean;
}
interface EmbeddedContent { languageId: string; start: number; end: number; attributeValue?: boolean; };
export interface HTMLDocumentRegions {
getEmbeddedDocument(languageId: string): TextDocument;
getLanguageRanges(range: Range): LanguageRange[];
getLanguageAtPosition(position: Position): string;
getLanguagesInDocument(): string[];
getImportedScripts(): string[];
}
export function getLanguageAtPosition(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, position: Position): string {
let offset = document.offsetAt(position);
let node = htmlDocument.findNodeAt(offset);
if (node) {
let embeddedContent = getEmbeddedContentForNode(languageService, document, node);
if (embeddedContent) {
for (let c of embeddedContent) {
if (c.start <= offset && offset <= c.end) {
return c.languageId;
export var CSS_STYLE_RULE = '__';
interface EmbeddedRegion { languageId: string; start: number; end: number; attributeValue?: boolean; };
export function getDocumentRegions(languageService: LanguageService, document: TextDocument): HTMLDocumentRegions {
let regions: EmbeddedRegion[] = [];
let scanner = languageService.createScanner(document.getText());
let lastTagName: string;
let lastAttributeName: string;
let languageIdFromType: string;
let importedScripts = [];
let token = scanner.scan();
while (token !== TokenType.EOS) {
switch (token) {
case TokenType.StartTag:
lastTagName = scanner.getTokenText();
lastAttributeName = null;
languageIdFromType = 'javascript';
break;
case TokenType.Styles:
regions.push({ languageId: 'css', start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
break;
case TokenType.Script:
regions.push({ languageId: languageIdFromType, start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
break;
case TokenType.AttributeName:
lastAttributeName = scanner.getTokenText();
break;
case TokenType.AttributeValue:
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
let value = scanner.getTokenText();
if (value[0] === '\'' || value[0] === '"') {
value = value.substr(1, value.length - 1);
}
importedScripts.push(value);
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
if (/["'](text|application)\/(java|ecma)script["']/.test(scanner.getTokenText())) {
languageIdFromType = 'javascript';
} else {
languageIdFromType = void 0;
}
} else {
let attributelLanguageId = getAttributeLanguage(lastAttributeName);
if (attributelLanguageId) {
let start = scanner.getTokenOffset();
let end = scanner.getTokenEnd();
let firstChar = document.getText()[start];
if (firstChar === '\'' || firstChar === '"') {
start++;
end--;
}
regions.push({ languageId: attributelLanguageId, start, end, attributeValue: true });
}
}
lastAttributeName = null;
break;
}
token = scanner.scan();
}
return {
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
getEmbeddedDocument: (languageId: string) => getEmbeddedDocument(document, regions, languageId),
getLanguageAtPosition: (position: Position) => getLanguageAtPosition(document, regions, position),
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
getImportedScripts: () => importedScripts
};
}
function getLanguageRanges(document: TextDocument, regions: EmbeddedRegion[], range: Range): LanguageRange[] {
let result: LanguageRange[] = [];
let currentPos = range ? range.start : Position.create(0, 0);
let currentOffset = range ? document.offsetAt(range.start) : 0;
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
for (let region of regions) {
if (region.end > currentOffset && region.start < endOffset) {
let start = Math.max(region.start, currentOffset);
let startPos = document.positionAt(start);
if (currentOffset < region.start) {
result.push({
start: currentPos,
end: startPos,
languageId: 'html'
});
}
let end = Math.min(region.end, endOffset);
let endPos = document.positionAt(end);
if (end > region.start) {
result.push({
start: startPos,
end: endPos,
languageId: region.languageId,
attributeValue: region.attributeValue
});
}
currentOffset = end;
currentPos = endPos;
}
}
if (currentOffset < endOffset) {
let endPos = range ? range.end : document.positionAt(endOffset);
result.push({
start: currentPos,
end: endPos,
languageId: 'html'
});
}
return result;
}
function getLanguagesInDocument(document: TextDocument, regions: EmbeddedRegion[]): string[] {
let result = [];
for (let region of regions) {
if (result.indexOf(region.languageId) === -1) {
result.push(region.languageId);
if (result.length === 3) {
return result;
}
}
}
result.push('html');
return result;
}
function getLanguageAtPosition(document: TextDocument, regions: EmbeddedRegion[], position: Position): string {
let offset = document.offsetAt(position);
for (let region of regions) {
if (region.start <= offset) {
if (offset <= region.end) {
return region.languageId;
}
} else {
break;
}
}
return 'html';
}
export function getLanguagesInContent(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument): string[] {
let embeddedLanguageIds = ['html'];
const maxEmbbeddedLanguages = 3;
function collectEmbeddedLanguages(node: Node): void {
if (embeddedLanguageIds.length < maxEmbbeddedLanguages) {
let embeddedContent = getEmbeddedContentForNode(languageService, document, node);
if (embeddedContent) {
for (let c of embeddedContent) {
if (!isWhitespace(document.getText(), c.start, c.end)) {
if (embeddedLanguageIds.lastIndexOf(c.languageId) === -1) {
embeddedLanguageIds.push(c.languageId);
if (embeddedLanguageIds.length === maxEmbbeddedLanguages) {
return;
}
}
}
}
}
node.children.forEach(collectEmbeddedLanguages);
}
}
htmlDocument.roots.forEach(collectEmbeddedLanguages);
return embeddedLanguageIds;
}
export function getLanguagesInRange(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, range: Range): LanguageRange[] {
let ranges: LanguageRange[] = [];
let currentPos = range.start;
let currentOffset = document.offsetAt(currentPos);
let rangeEndOffset = document.offsetAt(range.end);
function collectEmbeddedNodes(node: Node): void {
if (node.start < rangeEndOffset && node.end > currentOffset) {
let embeddedContent = getEmbeddedContentForNode(languageService, document, node);
if (embeddedContent) {
for (let c of embeddedContent) {
if (c.start < rangeEndOffset) {
let startPos = document.positionAt(c.start);
if (currentOffset < c.start) {
ranges.push({
start: currentPos,
end: startPos,
languageId: 'html'
});
}
let end = Math.min(c.end, rangeEndOffset);
let endPos = document.positionAt(end);
if (end > c.start) {
ranges.push({
start: startPos,
end: endPos,
languageId: c.languageId
});
}
currentOffset = end;
currentPos = endPos;
}
}
}
}
node.children.forEach(collectEmbeddedNodes);
}
htmlDocument.roots.forEach(collectEmbeddedNodes);
if (currentOffset < rangeEndOffset) {
ranges.push({
start: currentPos,
end: range.end,
languageId: 'html'
});
}
return ranges;
}
export function getEmbeddedDocument(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, languageId: string): TextDocument {
let contents: EmbeddedContent[] = [];
function collectEmbeddedNodes(node: Node): void {
let embeddedContent = getEmbeddedContentForNode(languageService, document, node);
if (embeddedContent) {
for (let c of embeddedContent) {
if (c.languageId === languageId) {
contents.push(c);
}
}
}
node.children.forEach(collectEmbeddedNodes);
}
htmlDocument.roots.forEach(collectEmbeddedNodes);
function getEmbeddedDocument(document: TextDocument, contents: EmbeddedRegion[], languageId: string): TextDocument {
let currentPos = 0;
let oldContent = document.getText();
let result = '';
let lastSuffix = '';
for (let c of contents) {
result = substituteWithWhitespace(result, currentPos, c.start, oldContent, lastSuffix, getPrefix(c));
result += oldContent.substring(c.start, c.end);
currentPos = c.end;
lastSuffix = getSuffix(c);
if (c.languageId === languageId) {
result = substituteWithWhitespace(result, currentPos, c.start, oldContent, lastSuffix, getPrefix(c));
result += oldContent.substring(c.start, c.end);
currentPos = c.end;
lastSuffix = getSuffix(c);
}
}
result = substituteWithWhitespace(result, currentPos, oldContent.length, oldContent, lastSuffix, '');
return TextDocument.create(document.uri, languageId, document.version, result);
}
function getPrefix(c: EmbeddedContent) {
function getPrefix(c: EmbeddedRegion) {
if (c.attributeValue) {
switch (c.languageId) {
case 'css': return 'x{';
case 'css': return CSS_STYLE_RULE + '{';
}
}
return '';
}
function getSuffix(c: EmbeddedContent) {
function getSuffix(c: EmbeddedRegion) {
if (c.attributeValue) {
switch (c.languageId) {
case 'css': return '}';
@@ -151,7 +195,6 @@ function getSuffix(c: EmbeddedContent) {
return '';
}
function substituteWithWhitespace(result: string, start: number, end: number, oldContent: string, before: string, after: string) {
let accumulatedWS = 0;
result += before;
@@ -181,87 +224,10 @@ function append(result: string, str: string, n: number): string {
return result;
}
function getEmbeddedContentForNode(languageService: LanguageService, document: TextDocument, node: Node): EmbeddedContent[] {
if (node.tag === 'style') {
let scanner = languageService.createScanner(document.getText().substring(node.start, node.end));
let token = scanner.scan();
while (token !== TokenType.EOS) {
if (token === TokenType.Styles) {
return [{ languageId: 'css', start: node.start + scanner.getTokenOffset(), end: node.start + scanner.getTokenEnd() }];
}
token = scanner.scan();
}
} else if (node.tag === 'script') {
let scanner = languageService.createScanner(document.getText().substring(node.start, node.end));
let token = scanner.scan();
let isTypeAttribute = false;
let languageId = 'javascript';
while (token !== TokenType.EOS) {
if (token === TokenType.AttributeName) {
isTypeAttribute = scanner.getTokenText() === 'type';
} else if (token === TokenType.AttributeValue) {
if (isTypeAttribute) {
if (/["'](text|application)\/(java|ecma)script["']/.test(scanner.getTokenText())) {
languageId = 'javascript';
} else {
languageId = void 0;
}
}
isTypeAttribute = false;
} else if (token === TokenType.Script) {
return [{ languageId, start: node.start + scanner.getTokenOffset(), end: node.start + scanner.getTokenEnd() }];
}
token = scanner.scan();
}
} else if (node.attributeNames) {
let scanner: Scanner;
let result;
for (let name of node.attributeNames) {
let languageId = getAttributeLanguage(name);
if (languageId) {
if (!scanner) {
scanner = languageService.createScanner(document.getText().substring(node.start, node.end));
}
let token = scanner.scan();
let lastAttribute;
while (token !== TokenType.EOS) {
if (token === TokenType.AttributeName) {
lastAttribute = scanner.getTokenText();
} else if (token === TokenType.AttributeValue && lastAttribute === name) {
let start = scanner.getTokenOffset() + node.start;
let end = scanner.getTokenEnd() + node.start;
let firstChar = document.getText()[start];
if (firstChar === '\'' || firstChar === '"') {
start++;
end--;
}
if (!result) {
result = [];
}
result.push({ languageId, start, end, attributeValue: true });
lastAttribute = null;
break;
}
token = scanner.scan();
}
}
}
return result;
}
return void 0;
}
function getAttributeLanguage(attributeName: string): string {
let match = attributeName.match(/^(style)|(on\w+)$/i);
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
if (!match) {
return null;
}
return match[1] ? 'css' : 'javascript';
}
function isWhitespace(str: string, start: number, end: number): boolean {
if (start === end) {
return true;
}
return !!str.substring(start, end).match(/^\s*$/);
}
+3 -3
View File
@@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { LanguageModelCache } from '../languageModelCache';
import { getLanguageModelCache } from '../languageModelCache';
import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions } from 'vscode-html-languageservice';
import { TextDocument, Position, Range } from 'vscode-languageserver-types';
import { LanguageMode } from './languageModes';
export function getHTMLMode(htmlLanguageService: HTMLLanguageService, htmlDocuments: LanguageModelCache<HTMLDocument>): LanguageMode {
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
let settings: any = {};
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => htmlLanguageService.parseHTMLDocument(document));
return {
getId() {
return 'html';
@@ -5,37 +5,35 @@
'use strict';
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { LanguageService as HTMLLanguageService, HTMLDocument } from 'vscode-html-languageservice';
import { getEmbeddedDocument } from './embeddedSupport';
import { CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types';
import { SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types';
import { LanguageMode } from './languageModes';
import { getWordAtText } from '../utils/words';
import { HTMLDocumentRegions } from './embeddedSupport';
import ts = require('./typescript/typescriptServices');
import { contents as libdts } from './typescript/lib-ts';
import * as ts from 'typescript';
import { join } from 'path';
const DEFAULT_LIB = {
NAME: 'defaultLib:lib.d.ts',
CONTENTS: libdts
};
const FILE_NAME = 'typescript://singlefile/1'; // the same 'file' is used for all contents
const FILE_NAME = 'vscode://javascript/1'; // the same 'file' is used for all contents
const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts');
const JS_WORD_REGEX = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
export function getJavascriptMode(htmlLanguageService: HTMLLanguageService, htmlDocuments: LanguageModelCache<HTMLDocument>): LanguageMode {
export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
let jsDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('javascript'));
let compilerOptions = { allowNonTsExtensions: true, allowJs: true, target: ts.ScriptTarget.Latest };
let currentTextDocument: TextDocument;
let host = {
getCompilationSettings: () => compilerOptions,
getScriptFileNames: () => [FILE_NAME],
getScriptFileNames: () => [FILE_NAME, JQUERY_D_TS],
getScriptVersion: (fileName: string) => {
if (fileName === FILE_NAME) {
return String(currentTextDocument.version);
}
return '1'; // default lib is static
return '1'; // default lib an jquery.d.ts are static
},
getScriptSnapshot: (fileName: string) => {
let text = fileName === FILE_NAME ? currentTextDocument.getText() : DEFAULT_LIB.CONTENTS;
let text = fileName === FILE_NAME ? currentTextDocument.getText() : ts.sys.readFile(fileName);
return {
getText: (start, end) => text.substring(start, end),
getLength: () => text.length,
@@ -43,13 +41,10 @@ export function getJavascriptMode(htmlLanguageService: HTMLLanguageService, html
};
},
getCurrentDirectory: () => '',
getDefaultLibFileName: options => DEFAULT_LIB.NAME
getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options)
};
let jsLanguageService = ts.createLanguageService(host);
let jsDocuments = getLanguageModelCache<TextDocument>(10, 60, document => {
return getEmbeddedDocument(htmlLanguageService, document, htmlDocuments.get(document), 'javascript');
});
let settings: any = {};
return {
@@ -169,6 +164,42 @@ export function getJavascriptMode(htmlLanguageService: HTMLLanguageService, html
};
return null;
},
findDocumentSymbols(document: TextDocument): SymbolInformation[] {
currentTextDocument = jsDocuments.get(document);
let items = jsLanguageService.getNavigationBarItems(FILE_NAME);
if (items) {
let result: SymbolInformation[] = [];
let existing = {};
let collectSymbols = (item: ts.NavigationBarItem, containerLabel?: string) => {
let sig = item.text + item.kind + item.spans[0].start;
if (item.kind !== 'script' && !existing[sig]) {
let symbol: SymbolInformation = {
name: item.text,
kind: convertSymbolKind(item.kind),
location: {
uri: document.uri,
range: convertRange(currentTextDocument, item.spans[0])
},
containerName: containerLabel
};
existing[sig] = true;
result.push(symbol);
containerLabel = item.text;
}
if (item.childItems && item.childItems.length > 0) {
for (let child of item.childItems) {
collectSymbols(child, containerLabel);
}
}
};
items.forEach(item => collectSymbols(item));
return result;
}
return null;
},
findDefinition(document: TextDocument, position: Position): Definition {
currentTextDocument = jsDocuments.get(document);
let definition = jsLanguageService.getDefinitionAtPosition(FILE_NAME, currentTextDocument.offsetAt(position));
@@ -220,8 +251,8 @@ export function getJavascriptMode(htmlLanguageService: HTMLLanguageService, html
jsDocuments.onDocumentRemoved(document);
},
dispose() {
jsDocuments.dispose();
jsLanguageService.dispose();
jsDocuments.dispose();
}
};
};
@@ -265,6 +296,33 @@ function convertKind(kind: string): CompletionItemKind {
return CompletionItemKind.Property;
}
function convertSymbolKind(kind: string): SymbolKind {
switch (kind) {
case 'var':
case 'local var':
case 'const':
return SymbolKind.Variable;
case 'function':
case 'local function':
return SymbolKind.Function;
case 'enum':
return SymbolKind.Enum;
case 'module':
return SymbolKind.Module;
case 'class':
return SymbolKind.Class;
case 'interface':
return SymbolKind.Interface;
case 'method':
return SymbolKind.Method;
case 'property':
case 'getter':
case 'setter':
return SymbolKind.Property;
}
return SymbolKind.Variable;
}
function convertOptions(options: FormattingOptions, formatSettings: any, initialIndentLevel: number): ts.FormatCodeOptions {
return {
ConvertTabsToSpaces: options.insertSpaces,
@@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { HTMLDocument, getLanguageService as getHTMLLanguageService, DocumentContext } from 'vscode-html-languageservice';
import { getLanguageService as getHTMLLanguageService, DocumentContext } from 'vscode-html-languageservice';
import {
CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range,
Hover, DocumentHighlight, CompletionList, Position, FormattingOptions
Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation
} from 'vscode-languageserver-types';
import { getLanguageModelCache } from '../languageModelCache';
import { getLanguageAtPosition, getLanguagesInContent, getLanguagesInRange } from './embeddedSupport';
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
import { getCSSMode } from './cssMode';
import { getJavascriptMode } from './javascriptMode';
import { getHTMLMode } from './htmlMode';
@@ -25,6 +25,7 @@ export interface LanguageMode {
doHover?: (document: TextDocument, position: Position) => Hover;
doSignatureHelp?: (document: TextDocument, position: Position) => SignatureHelp;
findDocumentHighlight?: (document: TextDocument, position: Position) => DocumentHighlight[];
findDocumentSymbols?: (document: TextDocument) => SymbolInformation[];
findDocumentLinks?: (document: TextDocument, documentContext: DocumentContext) => DocumentLink[];
findDefinition?: (document: TextDocument, position: Position) => Definition;
findReferences?: (document: TextDocument, position: Position) => Location[];
@@ -37,53 +38,55 @@ export interface LanguageMode {
export interface LanguageModes {
getModeAtPosition(document: TextDocument, position: Position): LanguageMode;
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[];
getAllModesInDocument(document: TextDocument): LanguageMode[];
getAllModes(): LanguageMode[];
getAllModesInDocument(document: TextDocument): LanguageMode[];
getMode(languageId: string): LanguageMode;
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}
export interface LanguageModeRange extends Range {
mode: LanguageMode;
attributeValue?: boolean;
}
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }): LanguageModes {
var htmlLanguageService = getHTMLLanguageService();
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => htmlLanguageService.parseHTMLDocument(document));
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document => getDocumentRegions(htmlLanguageService, document));
let modes = {
'html': getHTMLMode(htmlLanguageService, htmlDocuments),
'css': supportedLanguages['css'] && getCSSMode(htmlLanguageService, htmlDocuments),
'javascript': supportedLanguages['javascript'] && getJavascriptMode(htmlLanguageService, htmlDocuments)
};
let modelCaches: LanguageModelCache<any>[] = [];
modelCaches.push(documentRegions);
let modes = {};
modes['html'] = getHTMLMode(htmlLanguageService);
if (supportedLanguages['css']) {
modes['css'] = getCSSMode(documentRegions);
}
if (supportedLanguages['javascript']) {
modes['javascript'] = getJavascriptMode(documentRegions);
}
return {
getModeAtPosition(document: TextDocument, position: Position): LanguageMode {
let languageId = getLanguageAtPosition(htmlLanguageService, document, htmlDocuments.get(document), position);
let languageId = documentRegions.get(document).getLanguageAtPosition(position);;
if (languageId) {
return modes[languageId];
}
return null;
},
getAllModesInDocument(document: TextDocument): LanguageMode[] {
let result = [];
let languageIds = getLanguagesInContent(htmlLanguageService, document, htmlDocuments.get(document));
for (let languageId of languageIds) {
let mode = modes[languageId];
if (mode) {
result.push(mode);
}
}
return result;
},
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[] {
return getLanguagesInRange(htmlLanguageService, document, htmlDocuments.get(document), range).map(r => {
return documentRegions.get(document).getLanguageRanges(range).map(r => {
return {
start: r.start,
end: r.end,
mode: modes[r.languageId]
mode: modes[r.languageId],
attributeValue: r.attributeValue
};
});
},
getAllModesInDocument(document: TextDocument): LanguageMode[] {
return documentRegions.get(document).getLanguagesInDocument().map(languageId => modes[languageId]);
},
getAllModes(): LanguageMode[] {
let result = [];
for (let languageId in modes) {
@@ -96,6 +99,20 @@ export function getLanguageModes(supportedLanguages: { [languageId: string]: boo
},
getMode(languageId: string): LanguageMode {
return modes[languageId];
},
onDocumentRemoved(document: TextDocument) {
modelCaches.forEach(mc => mc.onDocumentRemoved(document));
for (let mode in modes) {
modes[mode].onDocumentRemoved(document);
}
},
dispose(): void {
modelCaches.forEach(mc => mc.dispose());
modelCaches = [];
for (let mode in modes) {
modes[mode].dispose();
}
modes = {};
}
};
}
@@ -1,6 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export declare var contents: string;
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -20,21 +20,18 @@ suite('HTML Embedded Support', () => {
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let position = document.positionAt(offset);
let ls = getLanguageService();
let htmlDoc = ls.parseHTMLDocument(document);
let languageId = embeddedSupport.getLanguageAtPosition(htmlLanguageService, document, htmlDoc, position);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let languageId = docRegions.getLanguageAtPosition(position);
assert.equal(languageId, expectedLanguageId);
}
function assertEmbeddedLanguageContent(value: string, languageId: string, expectedContent: string): void {
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let ls = getLanguageService();
let htmlDoc = ls.parseHTMLDocument(document);
let content = embeddedSupport.getEmbeddedDocument(ls, document, htmlDoc, languageId);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let content = docRegions.getEmbeddedDocument(languageId);
assert.equal(content.getText(), expectedContent);
}
@@ -70,8 +67,8 @@ suite('HTML Embedded Support', () => {
assertEmbeddedLanguageContent('<html><style>foo { }</style>Hello<style>foo { }</style></html>', 'css', ' foo { } foo { } ');
assertEmbeddedLanguageContent('<html>\n <style>\n foo { } \n </style>\n</html>\n', 'css', '\n \n foo { } \n \n\n');
assertEmbeddedLanguageContent('<div style="color: red"></div>', 'css', ' x{color: red} ');
assertEmbeddedLanguageContent('<div style=color:red></div>', 'css', ' x{color:red} ');
assertEmbeddedLanguageContent('<div style="color: red"></div>', 'css', ' __{color: red} ');
assertEmbeddedLanguageContent('<div style=color:red></div>', 'css', ' __{color:red} ');
});
test('Scripts', function (): any {
@@ -109,6 +106,9 @@ suite('HTML Embedded Support', () => {
assertLanguageId('<DIV ONKEYUP=foo(|)</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=foo()|</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=foo()<|/DIV>', 'html');
assertLanguageId('<label data-content="|Checkbox"/>', 'html');
assertLanguageId('<label on="|Checkbox"/>', 'html');
});
test('Script content', function (): any {
@@ -58,7 +58,7 @@ suite('HTML Embedded Formatting', () => {
assertFormat('<html><head>\n <script>\nvar x=1;\nconsole.log("Hi");\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n console.log("Hi");\n</script>\n</head>\n\n</html>');
assertFormat('<html><head>\n |<script>\nvar x=1;\n</script>|</head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
assertFormat('<html><head>\n <script>\n|var x=1;|\n</script></head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
assertFormat('<html><head>\n <script>\n|var x=1;|\n</script></head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
});
test('HTML & Multiple Scripts', function (): any {
@@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { getJavascriptMode } from '../modes/javascriptMode';
import { TextDocument, Range, TextEdit, FormattingOptions } from 'vscode-languageserver-types';
import { getLanguageModelCache } from '../languageModelCache';
import { getLanguageService } from 'vscode-html-languageservice';
import * as embeddedSupport from '../modes/embeddedSupport';
suite('HTML Javascript Support', () => {
var htmlLanguageService = getLanguageService();
function assertCompletions(value: string, expectedProposals: string[]): void {
let offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1);
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let documentRegions = getLanguageModelCache<embeddedSupport.HTMLDocumentRegions>(10, 60, document => embeddedSupport.getDocumentRegions(htmlLanguageService, document));
var mode = getJavascriptMode(documentRegions);
let position = document.positionAt(offset);
let list = mode.doComplete(document, position);
assert.ok(list);
let actualLabels = list.items.map(c => c.label).sort();
for (let expected of expectedProposals) {
assert.ok(actualLabels.indexOf(expected) !== -1, 'Not found:' + expected + ' is ' + actualLabels.join(', '));
}
}
test('Completions', function (): any {
assertCompletions('<html><script>window.|</script></html>', ['location']);
assertCompletions('<html><script>$.|</script></html>', ['getJSON']);
});
});
+20
View File
@@ -19,4 +19,24 @@
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
},{
"name": "textmate/javadoc.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/javadoc.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-javadoc.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
}]
+5 -2
View File
@@ -4,7 +4,7 @@
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/java.tmbundle Syntaxes/Java.plist ./syntaxes/java.json"
"update-grammar": "node ../../build/npm/update-grammar.js textmate/java.tmbundle Syntaxes/Java.plist ./syntaxes/java.tmLanguage.json && node ../../build/npm/update-grammar.js textmate/javadoc.tmbundle Syntaxes/JavaDoc.tmLanguage ./syntaxes/javadoc.tmLanguage.json"
},
"contributes": {
"languages": [{
@@ -16,7 +16,10 @@
"grammars": [{
"language": "java",
"scopeName": "source.java",
"path": "./syntaxes/java.json"
"path": "./syntaxes/java.tmLanguage.json"
},{
"scopeName": "text.html.javadoc",
"path": "./syntaxes/javadoc.tmLanguage.json"
}]
}
}
@@ -0,0 +1,432 @@
{
"fileTypes": [],
"name": "JavaDoc",
"patterns": [
{
"begin": "(/\\*\\*)\\s*$",
"beginCaptures": {
"1": {
"name": "punctuation.definition.comment.begin.javadoc"
}
},
"contentName": "text.html",
"end": "\\*/",
"endCaptures": {
"0": {
"name": "punctuation.definition.comment.end.javadoc"
}
},
"name": "comment.block.documentation.javadoc",
"patterns": [
{
"include": "#inline"
},
{
"begin": "((\\@)param)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.param.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.param.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)return)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.return.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.return.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)throws)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.throws.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.throws.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)exception)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.exception.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.exception.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)author)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.author.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.author.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)version)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.version.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.version.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)see)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.see.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.see.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)since)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.since.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.since.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serial)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serial.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serial.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serialField)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serialField.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serialField.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serialData)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serialData.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serialData.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)deprecated)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.deprecated.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.deprecated.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"captures": {
"1": {
"name": "keyword.other.documentation.custom.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"match": "((\\@)\\S+)\\s"
}
]
}
],
"repository": {
"inline": {
"patterns": [
{
"include": "#inline-formatting"
},
{
"comment": "This prevents < characters in commented source from starting\n\t\t\t\t\t\t\t\ta tag that will not end. List of allowed tags taken from\n\t\t\t\t\t\t\t\tjava checkstyle.",
"match": "<(?!(a|abbr|acronym|address|area|b|bdo|big|blockquote|br|caption|cite|code|colgroup|dd|del|div|dfn|dl|dt|em|fieldset|font|h1toh6|hr|i|img|ins|kbd|li|ol|p|pre|q|samp|small|span|strong|sub|sup|table|tbody|td|tfoot|th|thread|tr|tt|u|ul)\\b[^>]*>)"
},
{
"include": "text.html.basic"
},
{
"match": "((https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt)://|mailto:)[-:@a-zA-Z0-9_.,~%+/?=&#;]+(?<![-.,?:#;])",
"name": "markup.underline.link"
}
]
},
"inline-formatting": {
"patterns": [
{
"begin": "(\\{)((\\@)code)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.code.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"contentName": "markup.raw.code.javadoc",
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"name": "meta.tag.template.code.javadoc",
"patterns": []
},
{
"begin": "(\\{)((\\@)literal)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.literal.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"contentName": "markup.raw.literal.javadoc",
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"name": "meta.tag.template.literal.javadoc",
"patterns": []
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.docRoot.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)docRoot)(\\})",
"name": "meta.tag.template.docRoot.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.inheritDoc.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)inheritDoc)(\\})",
"name": "meta.tag.template.inheritDoc.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.link.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "markup.underline.link.javadoc"
},
"5": {
"name": "string.other.link.title.javadoc"
},
"6": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)link)(?:\\s+(\\S+?))?(?:\\s+(.+?))?\\s*(\\})",
"name": "meta.tag.template.link.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.linkplain.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "markup.underline.linkplain.javadoc"
},
"5": {
"name": "string.other.link.title.javadoc"
},
"6": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)linkplain)(?:\\s+(\\S+?))?(?:\\s+(.+?))?\\s*(\\})",
"name": "meta.tag.template.linkplain.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.value.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "variable.other.javadoc"
},
"5": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)value)\\s*(\\S+?)?\\s*(\\})",
"name": "meta.tag.template.value.javadoc"
}
]
}
},
"scopeName": "text.html.javadoc",
"uuid": "64BB98A4-59D4-474E-9091-C1E1D04BDD03",
"version": "https://github.com/textmate/javadoc.tmbundle/commit/5276d7a93f0cf53b7d425c39c6968b09ea9f2d40"
}
@@ -440,8 +440,8 @@
}
},
{
"c": "/*",
"t": "block.body.class.comment.definition.java.meta.punctuation",
"c": "/**",
"t": "begin.block.body.class.comment.definition.documentation.java.javadoc.meta.punctuation",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@@ -451,8 +451,8 @@
}
},
{
"c": "*",
"t": "block.body.class.comment.java.meta",
"c": "\t * ",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@@ -462,8 +462,30 @@
}
},
{
"c": "\t * @param args",
"t": "block.body.class.comment.java.meta",
"c": "@",
"t": "block.body.class.comment.definition.documentation.html.java.javadoc.keyword.meta.other.param.punctuation.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.definition.tag rgb(128, 128, 128)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.definition.tag rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.definition.tag rgb(128, 128, 128)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.definition.tag rgb(128, 0, 0)",
"hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.punctuation.definition.tag rgb(128, 128, 128)"
}
},
{
"c": "param",
"t": "block.body.class.comment.documentation.html.java.javadoc.keyword.meta.other.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.keyword rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.keyword rgb(0, 0, 255)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.keyword rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.keyword rgb(0, 0, 255)",
"hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.keyword rgb(86, 156, 214)"
}
},
{
"c": " args",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@@ -474,7 +496,7 @@
},
{
"c": "\t ",
"t": "block.body.class.comment.java.meta",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@@ -485,7 +507,7 @@
},
{
"c": "*/",
"t": "block.body.class.comment.definition.java.meta.punctuation",
"t": "block.body.class.comment.definition.documentation.end.java.javadoc.meta.punctuation",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
+3 -2
View File
@@ -97,12 +97,13 @@
"command": "markdown.showPreview",
"key": "shift+ctrl+v",
"mac": "shift+cmd+v",
"when": "!terminalFocus"
"when": "editorFocus"
},
{
"command": "markdown.showPreviewToSide",
"key": "ctrl+k v",
"mac": "cmd+k v"
"mac": "cmd+k v",
"when": "editorFocus"
}
],
"snippets": [
@@ -31,7 +31,7 @@
{
"name": "debug",
"repositoryURL": "https://github.com/visionmedia/debug",
"version": "2.2.0",
"version": "2.3.3",
"license": "MIT",
"isProd": true
},
@@ -52,7 +52,7 @@
{
"name": "glob",
"repositoryURL": "https://github.com/isaacs/node-glob",
"version": "7.0.6",
"version": "7.1.1",
"license": "ISC",
"isProd": true
},
@@ -73,7 +73,7 @@
{
"name": "inflight",
"repositoryURL": "https://github.com/npm/inflight",
"version": "1.0.5",
"version": "1.0.6",
"license": "ISC",
"isProd": true
},
@@ -94,7 +94,7 @@
{
"name": "ms",
"repositoryURL": "https://github.com/rauchg/ms.js",
"version": "0.7.1",
"version": "0.7.2",
"license": "MIT",
"isProd": true
},
@@ -108,7 +108,7 @@
{
"name": "path-is-absolute",
"repositoryURL": "https://github.com/sindresorhus/path-is-absolute",
"version": "1.0.0",
"version": "1.0.1",
"license": "MIT",
"isProd": true
},
+11
View File
@@ -0,0 +1,11 @@
{
"name": "vscode-extensions",
"version": "0.0.1",
"dependencies": {
"typescript": {
"version": "2.0.10",
"from": "typescript@>=2.0.10 <3.0.0",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.0.10.tgz"
}
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"name": "vscode-extensions",
"version": "0.0.1",
"private": true,
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "^2.0.10"
},
"scripts": {
"postinstall": "node ./postinstall"
}
}
+2 -23
View File
@@ -1,29 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "language-php",
"version": "0.29.0",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/atom/language-php",
"description": "The file snippets/php.json was derived from the Atom package https://atom.io/packages/language-php which was originally converted from the PHP TextMate bundle https://github.com/textmate/php.tmbundle."
},
{
"name": "textmate/php.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/php.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-php.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
"description": "The files snippets/php.json & syntaxes/php.tmLanguage.json were derived from the Atom package https://atom.io/packages/language-php which was originally converted from the PHP TextMate bundle https://github.com/textmate/php.tmbundle."
}]
+3 -2
View File
@@ -19,7 +19,7 @@
"grammars": [{
"language": "php",
"scopeName": "text.html.php",
"path": "./syntaxes/php.json",
"path": "./syntaxes/php.tmLanguage.json",
"embeddedLanguages": {
"text.html": "html",
"source.php": "php",
@@ -66,6 +66,7 @@
},
"scripts": {
"compile": "gulp compile-extension:php",
"watch": "gulp watch-extension:php"
"watch": "gulp watch-extension:php",
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-php grammars/php.cson ./syntaxes/php.tmLanguage.json"
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -223,10 +223,10 @@
"c": "<?php",
"t": "begin.block.embedded.meta.metatag.php.punctuation.section",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.begin.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.begin.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.begin.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.begin.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},
@@ -3237,10 +3237,10 @@
"c": "?",
"t": "block.embedded.end.meta.metatag.php.punctuation.section.source",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},
@@ -3248,10 +3248,10 @@
"c": ">",
"t": "block.embedded.end.meta.metatag.php.punctuation.section",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},
+34
View File
@@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const fs = require('fs');
const path = require('path');
function removeFile(filePath) {
try {
fs.unlinkSync(filePath);
console.log(`removed '${filePath}'`);
} catch (e) {
console.warn(e);
}
}
// delete unused typescript stuff in lib folder
const libPath = path.dirname(require.resolve('typescript'));
for (let name of fs.readdirSync(libPath)) {
if (name !== 'typescript.d.ts' && name !== 'typescript.js' && name !== 'lib.es6.d.ts') {
removeFile(path.join(libPath, name));
}
}
// delete unused typescript stuff in bin folder
const binPath = path.join(path.dirname(libPath), 'bin');
for (let name of fs.readdirSync(binPath)) {
removeFile(path.join(binPath, name));
}
removeFile(path.join(path.dirname(libPath), 'Gulpfile.ts'));
@@ -271,7 +271,8 @@
}
},
{
"scope": "metatag.php",
"name": "coloring of the PHP start and end tag (<?php and ?>)",
"scope": ["punctuation.section.embedded.begin.metatag.php", "punctuation.section.embedded.end.metatag.php"],
"settings": {
"foreground": "#569cd6"
}
@@ -268,7 +268,8 @@
}
},
{
"scope": "metatag.php",
"name": "coloring of the PHP start and end tag (<?php and ?>)",
"scope": ["punctuation.section.embedded.begin.metatag.php", "punctuation.section.embedded.end.metatag.php"],
"settings": {
"foreground": "#800000"
}
+5
View File
@@ -2,6 +2,11 @@
"name": "typescript",
"version": "0.10.1",
"dependencies": {
"@types/semver": {
"version": "5.3.30",
"from": "@types/semver@>=5.3.30 <6.0.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.3.30.tgz"
},
"applicationinsights": {
"version": "0.15.6",
"from": "applicationinsights@0.15.6",
+1
View File
@@ -11,6 +11,7 @@
"vscode": "*"
},
"dependencies": {
"@types/semver": "^5.3.30",
"semver": "4.3.6",
"vscode-extension-telemetry": "^0.0.5",
"vscode-nls": "^2.0.1",
-11
View File
@@ -1,11 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
declare function clearTimeout(timeoutId: NodeJS.Timer): void;
declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
declare function clearInterval(intervalId: NodeJS.Timer): void;
declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
declare function clearImmediate(immediateId: any): void;
-125
View File
@@ -1,125 +0,0 @@
// Type definitions for semver v2.2.1
// Project: https://github.com/isaacs/node-semver
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module SemVerModule {
/**
* Return the parsed version, or null if it's not valid.
*/
function valid(v: string, loose?: boolean): string;
/**
* Return the version incremented by the release type (major, minor, patch, or prerelease), or null if it's not valid.
*/
function inc(v: string, release: string, loose?: boolean): string;
// Comparison
/**
* v1 > v2
*/
function gt(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 >= v2
*/
function gte(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 < v2
*/
function lt(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 <= v2
*/
function lte(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 == v2 This is true if they're logically equivalent, even if they're not the exact same string. You already know how to compare strings.
*/
function eq(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 != v2 The opposite of eq.
*/
function neq(v1: string, v2: string, loose?: boolean): boolean;
/**
* Pass in a comparison string, and it'll call the corresponding semver comparison function. "===" and "!==" do simple string comparison, but are included for completeness. Throws if an invalid comparison string is provided.
*/
function cmp(v1: string, comparator: any, v2: string, loose?: boolean): boolean;
/**
* Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if v2 is greater. Sorts in ascending order if passed to Array.sort().
*/
function compare(v1: string, v2: string, loose?: boolean): number;
/**
* The reverse of compare. Sorts an array of versions in descending order when passed to Array.sort().
*/
function rcompare(v1: string, v2: string, loose?: boolean): number;
// Ranges
/**
* Return the valid range or null if it's not valid
*/
function validRange(range: string, loose?: boolean): string;
/**
* Return true if the version satisfies the range.
*/
function satisfies(version: string, range: string, loose?: boolean): boolean;
/**
* Return the highest version in the list that satisfies the range, or null if none of them do.
*/
function maxSatisfying(versions: string[], range: string, loose?: boolean): string;
/**
* Return true if version is greater than all the versions possible in the range.
*/
function gtr(version: string, range: string, loose?: boolean): boolean;
/**
* Return true if version is less than all the versions possible in the range.
*/
function ltr(version: string, range: string, loose?: boolean): boolean;
/**
* Return true if the version is outside the bounds of the range in either the high or low direction. The hilo argument must be either the string '>' or '<'. (This is the function called by gtr and ltr.)
*/
function outside(version: string, range: string, hilo: string, loose?: boolean): boolean;
class SemVerBase {
raw: string;
loose: boolean;
format(): string;
inspect(): string;
toString(): string;
}
class SemVer extends SemVerBase {
constructor(version: string, loose?: boolean);
major: number;
minor: number;
patch: number;
version: string;
build: string[];
prerelease: string[];
compare(other: SemVer): number;
compareMain(other: SemVer): number;
comparePre(other: SemVer): number;
inc(release: string): SemVer;
}
class Comparator extends SemVerBase {
constructor(comp: string, loose?: boolean);
semver: SemVer;
operator: string;
value: boolean;
parse(comp: string): void;
test(version: SemVer): boolean;
}
class Range extends SemVerBase {
constructor(range: string, loose?: boolean);
set: Comparator[][];
parseRange(range: string): Comparator[];
test(version: SemVer): boolean;
}
}
declare module "semver" {
export = SemVerModule;
}
@@ -8,7 +8,7 @@
import * as vscode from 'vscode';
import { ITypescriptServiceClient } from '../typescriptService';
import { loadMessageBundle } from 'vscode-nls';
import { dirname } from 'path';
import { dirname, join } from 'path';
const localize = loadMessageBundle();
const selector = ['javascript', 'javascriptreact'];
@@ -77,7 +77,6 @@ export function create(client: ITypescriptServiceClient, isOpen: (path: string)
}
if (fileNames.length > fileLimit) {
let largeRoots = computeLargeRoots(configFileName, fileNames).map(f => `'/${f}/'`).join(', ');
currentHint = {
@@ -91,7 +90,14 @@ export function create(client: ITypescriptServiceClient, isOpen: (path: string)
projectHinted[configFileName] = true;
item.hide();
return vscode.workspace.openTextDocument(configFileName)
let configFileUri: vscode.Uri;
if (dirname(configFileName).indexOf(vscode.workspace.rootPath) === 0) {
configFileUri = vscode.Uri.file(configFileName);
} else {
configFileUri = vscode.Uri.parse('untitled://' + join(vscode.workspace.rootPath, 'jsconfig.json'));
}
return vscode.workspace.openTextDocument(configFileUri)
.then(vscode.window.showTextDocument);
}
}]
+2 -2
View File
@@ -62,7 +62,7 @@ export function cleanUp(): Thenable<any> {
}
});
vscode.commands.executeCommand('workbench.action.closeAllEditors').then(null, reject);
vscode.commands.executeCommand('workbench.action.closeAllEditors').then(undefined, reject);
}).then(() => {
assert.equal(vscode.window.visibleTextEditors.length, 0);
@@ -76,4 +76,4 @@ export function cleanUp(): Thenable<any> {
// assert.equal(vscode.workspace.textDocuments.length, 0);
});
}
}
@@ -19,7 +19,7 @@ suite('window namespace tests', () => {
return window.showTextDocument(doc).then((editor) => {
const active = window.activeTextEditor;
assert.ok(active);
assert.ok(pathEquals(active.document.uri.fsPath, doc.uri.fsPath));
assert.ok(pathEquals(active!.document.uri.fsPath, doc.uri.fsPath));
});
});
});
@@ -6,7 +6,7 @@
'use strict';
import * as assert from 'assert';
import { workspace, TextDocument, window, Position, Uri, EventEmitter, WorkspaceEdit } from 'vscode';
import { workspace, TextDocument, window, Position, Uri, EventEmitter, WorkspaceEdit, Disposable } from 'vscode';
import { createRandomFile, deleteFile, cleanUp, pathEquals } from './utils';
import { join, basename } from 'path';
import * as fs from 'fs';
@@ -48,11 +48,13 @@ suite('workspace-namespace', () => {
test('textDocuments', () => {
assert.ok(Array.isArray(workspace.textDocuments));
assert.throws(() => workspace.textDocuments = null);
assert.throws(() => (<any>workspace).textDocuments = null);
});
test('rootPath', () => {
assert.ok(pathEquals(workspace.rootPath, join(__dirname, '../testWorkspace')));
if (workspace.rootPath) {
assert.ok(pathEquals(workspace.rootPath, join(__dirname, '../testWorkspace')));
}
assert.throws(() => workspace.rootPath = 'farboo');
});
@@ -64,23 +66,22 @@ suite('workspace-namespace', () => {
});
});
test('openTextDocument, illegal path', done => {
workspace.openTextDocument('funkydonky.txt').then(doc => {
done(new Error('missing error'));
test('openTextDocument, illegal path', () => {
return workspace.openTextDocument('funkydonky.txt').then(doc => {
throw new Error('missing error');
}, err => {
done();
// good!
});
});
test('openTextDocument, untitled is dirty', function (done) {
test('openTextDocument, untitled is dirty', function () {
if (process.platform === 'win32') {
return done(); // TODO@Joh this test fails on windows
return; // TODO@Joh this test fails on windows
}
workspace.openTextDocument(Uri.parse('untitled:' + join(workspace.rootPath, './newfile.txt'))).then(doc => {
return workspace.openTextDocument(Uri.parse('untitled:' + join(workspace.rootPath, './newfile.txt'))).then(doc => {
assert.equal(doc.uri.scheme, 'untitled');
assert.ok(doc.isDirty);
done();
});
});
@@ -137,7 +138,7 @@ suite('workspace-namespace', () => {
test('events: onDidOpenTextDocument, onDidChangeTextDocument, onDidSaveTextDocument', () => {
return createRandomFile().then(file => {
let disposables = [];
let disposables: Disposable[] = [];
let onDidOpenTextDocument = false;
disposables.push(workspace.onDidOpenTextDocument(e => {
@@ -370,7 +371,7 @@ suite('workspace-namespace', () => {
});
test('findFiles', () => {
return workspace.findFiles('*.js', null).then((res) => {
return workspace.findFiles('*.js').then((res) => {
assert.equal(res.length, 1);
assert.equal(basename(workspace.asRelativePath(res[0])), 'far.js');
});
+3 -2
View File
@@ -4,9 +4,10 @@
"target": "ES5",
"outDir": "out",
"noLib": true,
"sourceMap": true
"sourceMap": true,
"strictNullChecks": true
},
"exclude": [
"node_modules"
]
}
}
+2 -1
View File
@@ -6,7 +6,8 @@
declare function run(): void;
declare function suite(name: string, fn: (err?) => void);
declare function test(name: string, fn: (done?: (err?) => void) => void);
declare function test(name: string, fn: () => void);
declare function test(name: string, fn: (done: (err?) => void) => void);
declare function suiteSetup(fn: (done?: (err?) => void) => void);
declare function suiteTeardown(fn: (done?: (err?) => void) => void);
declare function setup(fn: (done?: (err?) => void) => void);
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "code-oss-dev",
"version": "1.8.0",
"electronVersion": "1.4.6",
"distro": "cc6a2710b81e898b8cde2b51ba29e178980009e8",
"distro": "d063cb1099fdf21be5c61e0b54e6b703b06a7e0f",
"author": {
"name": "Microsoft Corporation"
},
+1 -1
View File
@@ -16,7 +16,7 @@ set CODE=".build\electron\%NAMESHORT%"
for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"electronVersion\":.*" package.json') do set DESIREDVERSION=%%~a
set DESIREDVERSION=%DESIREDVERSION: "=%
set DESIREDVERSION=v%DESIREDVERSION:"=%
if exist .\.build\electron\version (set /p INSTALLEDVERSION=<.\.build\electron\version) else (INSTALLEDVERSION="")
if exist .\.build\electron\version (set /p INSTALLEDVERSION=<.\.build\electron\version) else (set INSTALLEDVERSION="")
:: Get electron
if not exist %CODE% node .\node_modules\gulp\bin\gulp.js electron
+2 -1
View File
@@ -6,7 +6,8 @@
declare function run(): void;
declare function suite(name: string, fn: (err?) => void);
declare function test(name: string, fn: (done?: (err?) => void) => void);
declare function test(name: string, fn: () => void);
declare function test(name: string, fn: (done: (err?) => void) => void);
declare function suiteSetup(fn: (done?: (err?) => void) => void);
declare function suiteTeardown(fn: (done?: (err?) => void) => void);
declare function setup(fn: (done?: (err?) => void) => void);
+18
View File
@@ -245,6 +245,24 @@ function rmRecursive(path: string, callback: (error: Error) => void): void {
});
}
export function delSync(path: string): void {
try {
const stat = fs.lstatSync(path);
if (stat.isDirectory() && !stat.isSymbolicLink()) {
readdirSync(path).forEach(child => delSync(paths.join(path, child)));
fs.rmdirSync(path);
} else {
fs.unlinkSync(path);
}
} catch (err) {
if (err.code === 'ENOENT') {
return; // not found
}
throw err;
}
}
export function mv(source: string, target: string, callback: (error: Error) => void): void {
if (source === target) {
return callback(null);
+53
View File
@@ -34,6 +34,59 @@ suite('Extfs', () => {
}); // 493 = 0755
});
test('delSync - swallows file not found error', function () {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
});
test('delSync - simple', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
done();
}); // 493 = 0755
});
test('delSync - recursive folder structure', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(path.join(newDir, 'somefolder'));
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
done();
}); // 493 = 0755
});
test('copy, move and delete', function (done: () => void) {
const id = uuid.generateUuid();
const id2 = uuid.generateUuid();
+43
View File
@@ -101,4 +101,47 @@ suite('PFS', () => {
}, error => onError(error, done));
});
});
test('rimraf - simple', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
pfs.rimraf(newDir).then(() => {
assert.ok(!fs.existsSync(newDir));
done();
}, error => onError(error, done));
}); // 493 = 0755
});
test('rimraf - recursive folder structure', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(path.join(newDir, 'somefolder'));
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
pfs.rimraf(newDir).then(() => {
assert.ok(!fs.existsSync(newDir));
done();
}, error => onError(error, done));
}); // 493 = 0755
});
});
+12 -28
View File
@@ -92,7 +92,7 @@ export class VSCodeMenu {
});
// Listen to some events from window service
this.windowsService.onPathOpen(path => this.updateMenu());
this.windowsService.onPathsOpen(paths => this.updateMenu());
this.windowsService.onRecentPathsChange(paths => this.updateMenu());
this.windowsService.onWindowClose(_ => this.onClose(this.windowsService.getWindowCount()));
@@ -298,7 +298,7 @@ export class VSCodeMenu {
const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' });
const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' });
const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' });
const quit = new MenuItem({ label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => this.quit(), accelerator: 'Command+Q' });
const quit = new MenuItem({ label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => this.windowsService.quit(), accelerator: this.getAccelerator('workbench.action.quit', 'Command+Q') });
const actions = [about];
actions.push(...checkForUpdates);
@@ -356,7 +356,7 @@ export class VSCodeMenu {
const closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder');
const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "Close &&Editor"), 'workbench.action.closeActiveEditor');
const exit = this.createMenuItem(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit"), () => this.quit());
const exit = new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")), accelerator: this.getAccelerator('workbench.action.quit'), click: () => this.windowsService.quit() });
arrays.coalesce([
newFile,
@@ -388,6 +388,7 @@ export class VSCodeMenu {
const userSettings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&User Settings"), 'workbench.action.openGlobalSettings');
const workspaceSettings = this.createMenuItem(nls.localize({ key: 'miOpenWorkspaceSettings', comment: ['&& denotes a mnemonic'] }, "&&Workspace Settings"), 'workbench.action.openWorkspaceSettings');
const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings');
const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymaps"), 'workbench.extensions.action.showRecommendedKeymapExtensions');
const snippetsSettings = this.createMenuItem(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), 'workbench.action.openSnippets');
const colorThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectColorTheme', comment: ['&& denotes a mnemonic'] }, "&&Color Theme"), 'workbench.action.selectTheme');
const iconThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectIconTheme', comment: ['&& denotes a mnemonic'] }, "File &&Icon Theme"), 'workbench.action.selectIconTheme');
@@ -397,6 +398,7 @@ export class VSCodeMenu {
preferencesMenu.append(workspaceSettings);
preferencesMenu.append(__separator__());
preferencesMenu.append(kebindingSettings);
preferencesMenu.append(keymapExtensions);
preferencesMenu.append(__separator__());
preferencesMenu.append(snippetsSettings);
preferencesMenu.append(__separator__());
@@ -406,25 +408,6 @@ export class VSCodeMenu {
return new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu });
}
private quit(): void {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const vscodeWindow = this.windowsService.getFocusedWindow();
if (vscodeWindow && vscodeWindow.isPluginDevelopmentHost && this.windowsService.getWindowCount() > 1) {
vscodeWindow.win.close();
}
// Otherwise: normal quit
else {
setTimeout(() => {
this.isQuitting = true;
app.quit();
}, 10 /* delay this because there is an issue with quitting while the menu is open */);
}
}
private setOpenRecentMenu(openRecentMenu: Electron.Menu): void {
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor'));
@@ -537,7 +520,7 @@ export class VSCodeMenu {
const commands = this.createMenuItem(nls.localize({ key: 'miCommandPalette', comment: ['&& denotes a mnemonic'] }, "&&Command Palette..."), 'workbench.action.showCommands');
const fullscreen = new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "Toggle &&Full Screen")), accelerator: this.getAccelerator('workbench.action.toggleFullScreen'), click: () => this.windowsService.getLastActiveWindow().toggleFullScreen(), enabled: this.windowsService.getWindowCount() > 0 });
const toggleFocusMode = this.createMenuItem(nls.localize('miToggleFocusMode', "Toggle Focus Mode"), 'workbench.action.toggleFocusMode', this.windowsService.getWindowCount() > 0);
const toggleZenMode = this.createMenuItem(nls.localize('miToggleZenMode', "Toggle Zen Mode"), 'workbench.action.toggleZenMode', this.windowsService.getWindowCount() > 0);
const toggleMenuBar = this.createMenuItem(nls.localize({ key: 'miToggleMenuBar', comment: ['&& denotes a mnemonic'] }, "Toggle Menu &&Bar"), 'workbench.action.toggleMenuBar');
const splitEditor = this.createMenuItem(nls.localize({ key: 'miSplitEditor', comment: ['&& denotes a mnemonic'] }, "Split &&Editor"), 'workbench.action.splitEditor');
const toggleEditorLayout = this.createMenuItem(nls.localize({ key: 'miToggleEditorLayout', comment: ['&& denotes a mnemonic'] }, "Toggle Editor Group &&Layout"), 'workbench.action.toggleEditorGroupLayout');
@@ -593,7 +576,7 @@ export class VSCodeMenu {
integratedTerminal,
__separator__(),
fullscreen,
toggleFocusMode,
toggleZenMode,
platform.isWindows || platform.isLinux ? toggleMenuBar : void 0,
__separator__(),
splitEditor,
@@ -867,7 +850,7 @@ export class VSCodeMenu {
});
}
private getAccelerator(actionId: string): string {
private getAccelerator(actionId: string, fallback?: string): string {
if (actionId) {
const resolvedKeybinding = this.mapResolvedKeybindingToActionId[actionId];
if (resolvedKeybinding) {
@@ -879,11 +862,12 @@ export class VSCodeMenu {
}
const lastKnownKeybinding = this.mapLastKnownKeybindingToActionId[actionId];
return lastKnownKeybinding; // return the last known keybining (chance of mismatch is very low unless it changed)
if (lastKnownKeybinding) {
return lastKnownKeybinding; // return the last known keybining (chance of mismatch is very low unless it changed)
}
}
return void (0);
return fallback;
}
private openAboutDialog(): void {
+1 -3
View File
@@ -17,7 +17,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { parseArgs } from 'vs/platform/environment/node/argv';
import product from 'vs/platform/product';
import { getCommonHTTPHeaders } from 'vs/platform/environment/node/http';
import { IBackupMainService } from 'vs/platform/backup/common/backup';
import { IWindowSettings } from 'vs/platform/windows/common/windows';
import { ReadyState, IVSCodeWindow } from 'vs/code/common/window';
@@ -121,8 +120,7 @@ export class VSCodeWindow implements IVSCodeWindow {
@ILogService private logService: ILogService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IConfigurationService private configurationService: IConfigurationService,
@IStorageService private storageService: IStorageService,
@IBackupMainService private backupService: IBackupMainService
@IStorageService private storageService: IStorageService
) {
this.options = config;
this._lastFocusTime = -1;
+22 -4
View File
@@ -91,7 +91,7 @@ export interface IWindowsMainService {
// events
onWindowReady: CommonEvent<VSCodeWindow>;
onWindowClose: CommonEvent<number>;
onPathOpen: CommonEvent<IPath>;
onPathsOpen: CommonEvent<IPath[]>;
onRecentPathsChange: CommonEvent<void>;
// methods
@@ -119,6 +119,7 @@ export interface IWindowsMainService {
removeFromRecentPathsList(paths: string[]): void;
clearRecentPathsList(): void;
toggleMenuBar(windowId: number): void;
quit(): void;
}
export class WindowsManager implements IWindowsMainService {
@@ -145,8 +146,8 @@ export class WindowsManager implements IWindowsMainService {
private _onWindowClose = new Emitter<number>();
onWindowClose: CommonEvent<number> = this._onWindowClose.event;
private _onPathOpen = new Emitter<IPath>();
onPathOpen: CommonEvent<IPath> = this._onPathOpen.event;
private _onPathsOpen = new Emitter<IPath[]>();
onPathsOpen: CommonEvent<IPath> = this._onPathsOpen.event;
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@@ -483,7 +484,7 @@ export class WindowsManager implements IWindowsMainService {
}
// Emit events
iPathsToOpen.forEach(iPath => this._onPathOpen.fire(iPath));
this._onPathsOpen.fire(iPathsToOpen);
return arrays.distinct(usedWindows);
}
@@ -1219,4 +1220,21 @@ export class WindowsManager implements IWindowsMainService {
this.logService.log('#setJumpList', error); // since setJumpList is relatively new API, make sure to guard for errors
}
}
public quit(): void {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const vscodeWindow = this.getFocusedWindow();
if (vscodeWindow && vscodeWindow.isPluginDevelopmentHost && this.getWindowCount() > 1) {
vscodeWindow.win.close();
}
// Otherwise: normal quit
else {
setTimeout(() => {
app.quit();
}, 10 /* delay to unwind callback stack (IPC) */);
}
}
}
-10
View File
@@ -603,16 +603,6 @@ registerCommand(new CoreCommand({
mac: { primary: KeyCode.Delete, secondary: [KeyMod.WinCtrl | KeyCode.KEY_D, KeyMod.WinCtrl | KeyCode.Delete] }
}
}));
registerCommand(new CoreCommand({
id: H.DeleteAllLeft,
precondition: EditorContextKeys.Writable,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.TextFocus,
primary: null,
mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace }
}
}));
registerCommand(new CoreCommand({
id: H.DeleteAllRight,
precondition: EditorContextKeys.Writable,
@@ -1009,7 +1009,6 @@ export class Cursor extends EventEmitter {
this._handlers[H.DeleteWordStartRight] = (ctx) => this._deleteWordRight(false, WordNavigationType.WordStart, ctx);
this._handlers[H.DeleteWordEndRight] = (ctx) => this._deleteWordRight(false, WordNavigationType.WordEnd, ctx);
this._handlers[H.DeleteAllLeft] = (ctx) => this._deleteAllLeft(ctx);
this._handlers[H.DeleteAllRight] = (ctx) => this._deleteAllRight(ctx);
this._handlers[H.Cut] = (ctx) => this._cut(ctx);
@@ -1518,10 +1517,6 @@ export class Cursor extends EventEmitter {
return this._applyEditForAll(ctx, (cursor) => WordOperations.deleteWordRight(cursor.config, cursor.model, cursor.modelState, whitespaceHeuristics, wordNavigationType));
}
private _deleteAllLeft(ctx: IMultipleCursorOperationContext): boolean {
return this._applyEditForAll(ctx, (cursor) => DeleteOperations.deleteAllLeft(cursor.config, cursor.model, cursor.modelState));
}
private _deleteAllRight(ctx: IMultipleCursorOperationContext): boolean {
return this._applyEditForAll(ctx, (cursor) => DeleteOperations.deleteAllRight(cursor.config, cursor.model, cursor.modelState));
}
@@ -164,37 +164,6 @@ export class DeleteOperations {
});
}
public static deleteAllLeft(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState): EditOperationResult {
let r = this.autoClosingPairDelete(config, model, cursor);
if (r) {
// This was a case for an auto-closing pair delete
return r;
}
let selection = cursor.selection;
if (selection.isEmpty()) {
let position = cursor.position;
let lineNumber = position.lineNumber;
let column = position.column;
if (column === 1) {
// Ignore deleting at beginning of line
return null;
}
let deleteSelection = new Range(lineNumber, 1, lineNumber, column);
if (!deleteSelection.isEmpty()) {
return new EditOperationResult(new ReplaceCommand(deleteSelection, ''), {
shouldPushStackElementBefore: false,
shouldPushStackElementAfter: false
});
}
}
return this.deleteLeft(config, model, cursor);
}
public static cut(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, enableEmptySelectionClipboard: boolean): EditOperationResult {
let selection = cursor.selection;
-1
View File
@@ -4583,7 +4583,6 @@ export var Handler = {
DeleteWordStartRight: 'deleteWordStartRight',
DeleteWordEndRight: 'deleteWordEndRight',
DeleteAllLeft: 'deleteAllLeft',
DeleteAllRight: 'deleteAllRight',
RemoveSecondaryCursors: 'removeSecondaryCursors',
+2 -2
View File
@@ -248,7 +248,7 @@ export interface ParameterInformation {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
}
/**
* Represents the signature of something callable. A signature
@@ -265,7 +265,7 @@ export interface SignatureInformation {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
/**
* The parameters of this signature.
*/
@@ -6,7 +6,7 @@
import { localize } from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import { IReadOnlyModel, IPosition } from 'vs/editor/common/editorCommon';
import { ITokenizedModel, IPosition } from 'vs/editor/common/editorCommon';
import { ISuggestion } from 'vs/editor/common/modes';
import { Registry } from 'vs/platform/platform';
@@ -29,7 +29,7 @@ export interface ISnippetsRegistry {
/**
* Get all snippet completions for the given position
*/
getSnippetCompletions(model: IReadOnlyModel, position: IPosition): ISuggestion[];
getSnippetCompletions(model: ITokenizedModel, position: IPosition): ISuggestion[];
}
@@ -69,8 +69,8 @@ class SnippetsRegistry implements ISnippetsRegistry {
}
}
public getSnippetCompletions(model: IReadOnlyModel, position: IPosition): ISuggestion[] {
const modeId = model.getModeId();
public getSnippetCompletions(model: ITokenizedModel, position: IPosition): ISuggestion[] {
const modeId = model.getModeIdAtPosition(position.lineNumber, position.column);
if (!this._snippets[modeId]) {
return;
}
@@ -212,19 +212,19 @@ class MirrorModel extends MirrorModel2 implements ICommonModel {
lineNumber = 1;
column = 1;
hasChanged = true;
}
else if (lineNumber >= this._lines.length) {
} else if (lineNumber > this._lines.length) {
lineNumber = this._lines.length;
column = this._lines[lineNumber - 1].length + 1;
hasChanged = true;
}
else {
} else {
let maxCharacter = this._lines[lineNumber - 1].length + 1;
if (column < 1) {
column = 1;
hasChanged = true;
}
else if (column >= maxCharacter) {
else if (column > maxCharacter) {
column = maxCharacter;
hasChanged = true;
}
@@ -7,8 +7,11 @@
import * as nls from 'vs/nls';
import { KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { SortLinesCommand } from 'vs/editor/contrib/linesOperations/common/sortLinesCommand';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { TrimTrailingWhitespaceCommand } from 'vs/editor/common/commands/trimTrailingWhitespaceCommand';
import { EditorContextKeys, Handler, ICommand, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { EditorContextKeys, Handler, ICommand, ICommonCodeEditor, IIdentifiedSingleEditOperation } from 'vs/editor/common/editorCommon';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { editorAction, ServicesAccessor, IActionOptions, EditorAction, HandlerEditorAction } from 'vs/editor/common/editorCommonExtensions';
import { CopyLinesCommand } from './copyLinesCommand';
import { DeleteLinesCommand } from './deleteLinesCommand';
@@ -346,3 +349,55 @@ class InsertLineAfterAction extends HandlerEditorAction {
});
}
}
@editorAction
export class DeleteAllLeftAction extends EditorAction {
constructor() {
super({
id: 'deleteAllLeft',
label: nls.localize('lines.deleteAllLeft', "Delete All Left"),
alias: 'Delete All Left',
precondition: EditorContextKeys.Writable,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: null,
mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace }
}
});
}
public run(accessor: ServicesAccessor, editor: ICommonCodeEditor): void {
let selections: Range[] = editor.getSelections();
selections.sort(Range.compareRangesUsingStarts);
selections = selections.map(selection => {
if (selection.isEmpty()) {
return new Selection(selection.startLineNumber, 1, selection.startLineNumber, selection.startColumn);
} else {
return selection;
}
});
// merge overlapping selections
let effectiveRanges: Range[] = [];
for (let i = 0, count = selections.length - 1; i < count; i++) {
let range = selections[i];
let nextRange = selections[i + 1];
if (Range.intersectRanges(range, nextRange) === null) {
effectiveRanges.push(range);
} else {
selections[i + 1] = Range.plusRange(range, nextRange);
}
}
effectiveRanges.push(selections[selections.length - 1]);
let edits: IIdentifiedSingleEditOperation[] = effectiveRanges.map(range => {
return EditOperation.replace(range, '');
});
editor.executeEdits(this.id, edits);
}
}
@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Selection } from 'vs/editor/common/core/selection';
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
import { DeleteAllLeftAction } from 'vs/editor/contrib/linesOperations/common/linesOperations';
suite('Editor Contrib - Line Operations', () => {
test('delete all left', function () {
withMockCodeEditor(
[
'one',
'two',
'three'
], {}, (editor, cursor) => {
let model = editor.getModel();
let deleteAllLeftAction = new DeleteAllLeftAction();
editor.setSelection(new Selection(1, 2, 1, 2));
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(1), 'ne', '001');
editor.setSelections([new Selection(2, 2, 2, 2), new Selection(3, 2, 3, 2)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(2), 'wo', '002');
assert.equal(model.getLineContent(3), 'hree', '003');
});
});
test('delete all left in multi cursor mode', function () {
withMockCodeEditor(
[
'hello',
'world',
'hello world',
'hello',
'bonjour',
'hola',
'world',
'hello world',
], {}, (editor, cursor) => {
let model = editor.getModel();
let deleteAllLeftAction = new DeleteAllLeftAction();
editor.setSelections([new Selection(1, 2, 1, 2), new Selection(1, 4, 1, 4)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(1), 'lo', '001');
editor.setSelections([new Selection(2, 2, 2, 2), new Selection(2, 4, 2, 5)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(2), 'ord', '002');
editor.setSelections([new Selection(3, 2, 3, 5), new Selection(3, 7, 3, 7)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(3), 'world', '003');
editor.setSelections([new Selection(4, 3, 4, 3), new Selection(4, 5, 5, 4)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(4), 'lljour', '004');
editor.setSelections([new Selection(5, 3, 6, 3), new Selection(6, 5, 7, 5), new Selection(7, 7, 7, 7)]);
deleteAllLeftAction.run(null, editor);
assert.equal(model.getLineContent(5), 'horlworld', '005');
});
});
});
@@ -37,8 +37,7 @@
.monaco-editor .reference-zone-widget .preview .monaco-editor,
.monaco-editor .reference-zone-widget .preview .glyph-margin,
.monaco-editor .reference-zone-widget .preview .monaco-editor-background,
.monaco-editor .reference-zone-widget .preview .monaco-editor .line-numbers,
.monaco-editor .reference-zone-widget .preview .monaco-editor .lines-decorations {
.monaco-editor .reference-zone-widget .preview .monaco-editor .margin .view-line {
background-color: #F2F8FC;
}
@@ -115,8 +114,7 @@
.monaco-editor.vs-dark .reference-zone-widget .preview .monaco-editor,
.monaco-editor.vs-dark .reference-zone-widget .preview .glyph-margin,
.monaco-editor.vs-dark .reference-zone-widget .preview .monaco-editor-background,
.monaco-editor.vs-dark .reference-zone-widget .preview .monaco-editor .line-numbers,
.monaco-editor.vs-dark .reference-zone-widget .preview .monaco-editor .lines-decorations {
.monaco-editor.vs-dark .reference-zone-widget .preview .monaco-editor .margin .view-line {
background-color: #001F33;
}
@@ -154,8 +152,7 @@
.monaco-editor.hc-black .reference-zone-widget,
.monaco-editor.hc-black .reference-zone-widget .preview .monaco-editor,
.monaco-editor.hc-black .reference-zone-widget .preview .monaco-editor-background,
.monaco-editor.hc-black .reference-zone-widget .preview .monaco-editor .line-numbers,
.monaco-editor.hc-black .reference-zone-widget .preview .monaco-editor .lines-decorations {
.monaco-editor.hc-black .reference-zone-widget .preview .monaco-editor .margin .view-line {
background-color: #0C141F;
}
@@ -371,6 +371,45 @@ interface IPreparedSnippet {
adaptedSnippet: ICodeSnippet;
}
class BeforeAfterData {
static create(model: editorCommon.IModel, selection: Selection, overwriteBefore: number, overwriteAfter: number) {
let contentBefore = '';
if (overwriteBefore > 0) {
contentBefore = model.getLineContent(selection.startLineNumber).substring(selection.startColumn - 1 - overwriteBefore, selection.startColumn);
}
let contentAfter = '';
if (overwriteAfter > 0) {
contentAfter = model.getLineContent(selection.endLineNumber).substring(selection.endColumn - 1, selection.endColumn + overwriteAfter);
}
return new BeforeAfterData(model, contentBefore, contentAfter, overwriteBefore, overwriteAfter);
}
constructor(private readonly _model: editorCommon.IModel,
private readonly _contentBefore: string,
private readonly _contentAfter: string,
public readonly overwriteBefore: number,
public readonly overwriteAfter: number
) {
//
}
next(selection: Selection) {
const data = BeforeAfterData.create(this._model, selection, this.overwriteBefore, this.overwriteAfter);
let {overwriteBefore, overwriteAfter} = data;
if (data._contentBefore !== this._contentBefore) {
overwriteBefore = 0;
}
if (data._contentAfter !== this._contentAfter) {
overwriteAfter = 0;
}
return new BeforeAfterData(this._model, null, null, overwriteBefore, overwriteAfter);
}
}
@commonEditorContribution
export class SnippetController {
@@ -496,6 +535,7 @@ export class SnippetController {
const edits: editorCommon.IIdentifiedSingleEditOperation[] = [];
const selections = this._editor.getSelections();
const model = this._editor.getModel();
const primaryBeforeAfter = BeforeAfterData.create(model, selections[0], overwriteBefore, overwriteAfter);
let totalDelta = 0;
const newSelections: { offset: number; i: number }[] = [];
@@ -508,7 +548,18 @@ export class SnippetController {
for (const {selection, i} of selectionEntries) {
let {adaptedSnippet, typeRange} = SnippetController._prepareSnippet(this._editor, selection, snippet, overwriteBefore, overwriteAfter, stripPrefix);
// only use overwrite[Before|After] for secondary cursors
// when the same text as with the primary cursor is selected
const beforeAfter = i !== 0 ? primaryBeforeAfter.next(selection) : primaryBeforeAfter;
let {adaptedSnippet, typeRange} = SnippetController._prepareSnippet(
this._editor,
selection,
snippet,
beforeAfter.overwriteBefore,
beforeAfter.overwriteAfter,
stripPrefix
);
SnippetController._addCommandForSnippet(this._editor.getModel(), adaptedSnippet, typeRange, edits);
@@ -448,4 +448,62 @@ suite('SnippetController', () => {
}, ['af', '\taf']);
});
test('Multiple cursor and overwriteBefore/After, issue #11060', () => {
snippetTest((editor, cursor, codeSnippet, controller) => {
editor.setSelections([
new Selection(1, 7, 1, 7),
new Selection(2, 4, 2, 4)
]);
codeSnippet = CodeSnippet.fromTextmate('_foo');
controller.run(codeSnippet, 1, 0);
assert.equal(editor.getModel().getValue(), 'this._foo\nabc_foo');
}, ['this._', 'abc']);
snippetTest((editor, cursor, codeSnippet, controller) => {
editor.setSelections([
new Selection(1, 7, 1, 7),
new Selection(2, 4, 2, 4)
]);
codeSnippet = CodeSnippet.fromTextmate('XX');
controller.run(codeSnippet, 1, 0);
assert.equal(editor.getModel().getValue(), 'this.XX\nabcXX');
}, ['this._', 'abc']);
snippetTest((editor, cursor, codeSnippet, controller) => {
editor.setSelections([
new Selection(1, 7, 1, 7),
new Selection(2, 4, 2, 4),
new Selection(3, 5, 3, 5)
]);
codeSnippet = CodeSnippet.fromTextmate('_foo');
controller.run(codeSnippet, 1, 0);
assert.equal(editor.getModel().getValue(), 'this._foo\nabc_foo\ndef_foo');
}, ['this._', 'abc', 'def_']);
snippetTest((editor, cursor, codeSnippet, controller) => {
editor.setSelections([
new Selection(1, 7, 1, 7),
new Selection(2, 4, 2, 4),
new Selection(3, 6, 3, 6)
]);
codeSnippet = CodeSnippet.fromTextmate('._foo');
controller.run(codeSnippet, 2, 0);
assert.equal(editor.getModel().getValue(), 'this._foo\nabc._foo\ndef._foo');
}, ['this._', 'abc', 'def._']);
});
});
@@ -10,7 +10,7 @@ import { compare } from 'vs/base/common/strings';
import { assign } from 'vs/base/common/objects';
import { onUnexpectedError } from 'vs/base/common/errors';
import { TPromise } from 'vs/base/common/winjs.base';
import { IReadOnlyModel, IPosition } from 'vs/editor/common/editorCommon';
import { IModel, IPosition } from 'vs/editor/common/editorCommon';
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
import { ISuggestResult, ISuggestSupport, ISuggestion, SuggestRegistry } from 'vs/editor/common/modes';
import { ISnippetsRegistry, Extensions } from 'vs/editor/common/modes/snippetsRegistry';
@@ -42,7 +42,7 @@ export const snippetSuggestSupport: ISuggestSupport = {
triggerCharacters: [],
provideCompletionItems(model: IReadOnlyModel, position: Position): ISuggestResult {
provideCompletionItems(model: IModel, position: Position): ISuggestResult {
const suggestions = Registry.as<ISnippetsRegistry>(Extensions.Snippets).getSnippetCompletions(model, position);
if (suggestions) {
return { suggestions };
@@ -50,7 +50,7 @@ export const snippetSuggestSupport: ISuggestSupport = {
}
};
export function provideSuggestionItems(model: IReadOnlyModel, position: Position, snippetConfig: SnippetConfig = 'bottom', onlyFrom?: ISuggestSupport[]): TPromise<ISuggestionItem[]> {
export function provideSuggestionItems(model: IModel, position: Position, snippetConfig: SnippetConfig = 'bottom', onlyFrom?: ISuggestSupport[]): TPromise<ISuggestionItem[]> {
const allSuggestions: ISuggestionItem[] = [];
const acceptSuggestion = createSuggesionFilter(snippetConfig);
@@ -132,7 +132,7 @@ function fixOverwriteBeforeAfter(suggestion: ISuggestion, container: ISuggestRes
}
}
function createSuggestionResolver(provider: ISuggestSupport, suggestion: ISuggestion, model: IReadOnlyModel, position: Position): () => TPromise<void> {
function createSuggestionResolver(provider: ISuggestSupport, suggestion: ISuggestion, model: IModel, position: Position): () => TPromise<void> {
return () => {
if (typeof provider.resolveCompletionItem === 'function') {
return asWinJsPromise(token => provider.resolveCompletionItem(model, position, suggestion, token))
@@ -36,8 +36,11 @@ class ShowSnippetsActions extends EditorAction {
return;
}
const {lineNumber, column} = editor.getPosition();
const modeId = editor.getModel().getModeIdAtPosition(lineNumber, column);
const picks: ISnippetPick[] = [];
Registry.as<ISnippetsRegistry>(Extensions.Snippets).visitSnippets(editor.getModel().getModeId(), snippet => {
Registry.as<ISnippetsRegistry>(Extensions.Snippets).visitSnippets(modeId, snippet => {
picks.push({
label: snippet.prefix,
detail: snippet.description,
@@ -87,6 +87,11 @@ suite('EditorSimpleWorker', () => {
assertPositionAt(Number.MAX_VALUE, 4, 30);
});
test('ICommonModel#validatePosition, issue #15882', function () {
let model = worker.addModel(['{"id": "0001","type": "donut","name": "Cake","image":{"url": "images/0001.jpg","width": 200,"height": 200},"thumbnail":{"url": "images/thumbnails/0001.jpg","width": 32,"height": 32}}']);
assert.equal(model.offsetAt({ lineNumber: 1, column: 2 }), 1);
});
test('MoreMinimal', function () {
return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: 'This is line One', range: new Range(1, 1, 1, 17) }], []).then(edits => {
+2 -3
View File
@@ -3406,7 +3406,6 @@ declare module monaco.editor {
DeleteWordRight: string;
DeleteWordStartRight: string;
DeleteWordEndRight: string;
DeleteAllLeft: string;
DeleteAllRight: string;
RemoveSecondaryCursors: string;
CancelSelection: string;
@@ -4365,7 +4364,7 @@ declare module monaco.languages {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
}
/**
@@ -4383,7 +4382,7 @@ declare module monaco.languages {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
/**
* The parameters of this signature.
*/
@@ -93,12 +93,12 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
return TPromise.wrap(false);
}
private enableExtension(identifier: string, scope: StorageScope): TPromise<boolean> {
private enableExtension(identifier: string, scope: StorageScope, fireEvent = true): TPromise<boolean> {
let disabledExtensions = this.getDisabledExtensions(scope);
const index = disabledExtensions.indexOf(identifier);
if (index !== -1) {
disabledExtensions.splice(index, 1);
this.setDisabledExtensions(disabledExtensions, scope, identifier);
this.setDisabledExtensions(disabledExtensions, scope, identifier, fireEvent);
return TPromise.wrap(true);
}
return TPromise.wrap(false);
@@ -112,20 +112,22 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
return value ? distinct(value.split(',')) : [];
}
private setDisabledExtensions(disabledExtensions: string[], scope: StorageScope, extension: string): void {
private setDisabledExtensions(disabledExtensions: string[], scope: StorageScope, extension: string, fireEvent = true): void {
if (disabledExtensions.length) {
this.storageService.store(DISABLED_EXTENSIONS_STORAGE_PATH, disabledExtensions.join(','), scope);
} else {
this.storageService.remove(DISABLED_EXTENSIONS_STORAGE_PATH, scope);
}
this._onEnablementChanged.fire(extension);
if (fireEvent) {
this._onEnablementChanged.fire(extension);
}
}
private onDidUninstallExtension({id, error}: DidUninstallExtensionEvent): void {
if (!error) {
id = stripVersion(id);
this.enableExtension(id, StorageScope.WORKSPACE);
this.enableExtension(id, StorageScope.GLOBAL);
this.enableExtension(id, StorageScope.WORKSPACE, false);
this.enableExtension(id, StorageScope.GLOBAL, false);
}
}
@@ -286,7 +286,9 @@ export interface IExtensionTipsService {
_serviceBrand: any;
getRecommendations(): string[];
getWorkspaceRecommendations(): TPromise<string[]>;
getKeymapRecommendations(): string[];
}
export const ExtensionsLabel = localize('extensions', "Extensions");
export const ExtensionsChannelId = 'extensions';
export const ExtensionsChannelId = 'extensions';
export const PreferencesLabel = localize('preferences', "Preferences");
@@ -296,7 +296,7 @@ export class KeybindingResolver {
}
public resolve(context: any, currentChord: number, keypress: number): IResolveResult {
// console.log('resolve: ' + Keybinding.toLabel(keypress));
// console.log('resolve: ' + Keybinding.toUserSettingsLabel(keypress));
let lookupMap: ICommandEntry[] = null;
if (currentChord !== 0) {
@@ -411,7 +411,7 @@ export class IOSupport {
} else {
out.write(`${quotedSerializeCommand} `);
}
// out.write(String(item.weight));
// out.write(String(item.weight1 + '-' + item.weight2));
out.write('}');
}
+1
View File
@@ -26,6 +26,7 @@ export interface IProductConfiguration {
};
extensionTips: { [id: string]: string; };
extensionImportantTips: { [id: string]: { name: string; pattern: string; }; };
keymapExtensionTips: string[];
crashReporter: Electron.CrashReporterStartOptions;
welcomePage: string;
enableTelemetry: boolean;
@@ -23,7 +23,7 @@ export interface ITelemetryInfo {
export interface ITelemetryExperiments {
showDefaultViewlet: boolean;
showCommandsWatermark: boolean;
showFirstSessionWatermark: boolean;
openUntitledFile: boolean;
}
@@ -46,7 +46,7 @@ export interface ITelemetryService {
export const defaultExperiments: ITelemetryExperiments = {
showDefaultViewlet: false,
showCommandsWatermark: false,
showFirstSessionWatermark: false,
openUntitledFile: true
};
@@ -80,7 +80,7 @@ export function loadExperiments(storageService: IStorageService, configurationSe
const random0 = parseFloat(valueString);
let [random1, showDefaultViewlet] = splitRandom(random0);
const [random2, showCommandsWatermark] = splitRandom(random1);
let [random2, showFirstSessionWatermark] = splitRandom(random1);
let [, openUntitledFile] = splitRandom(random2);
// is the user a first time user?
@@ -88,12 +88,13 @@ export function loadExperiments(storageService: IStorageService, configurationSe
if (!isNewSession) {
// for returning users we fall back to the default configuration for the sidebar and the initially opened, empty editor
showDefaultViewlet = defaultExperiments.showDefaultViewlet;
showFirstSessionWatermark = defaultExperiments.showFirstSessionWatermark;
openUntitledFile = defaultExperiments.openUntitledFile;
}
return applyOverrides(configurationService, {
showDefaultViewlet,
showCommandsWatermark,
showFirstSessionWatermark,
openUntitledFile
});
}
+2 -1
View File
@@ -37,6 +37,7 @@ export interface IWindowsService {
unmaximizeWindow(windowId: number): TPromise<void>;
setDocumentEdited(windowId: number, flag: boolean): TPromise<void>;
toggleMenuBar(windowId: number): TPromise<void>;
quit(): TPromise<void>;
// Global methods
// TODO@joao: rename, shouldn't this be openWindow?
@@ -89,7 +90,7 @@ export interface IWindowSettings {
openFilesInNewWindow: boolean;
reopenFolders: 'all' | 'one' | 'none';
restoreFullscreen: boolean;
fullScreenFocusMode: boolean;
fullScreenZenMode: boolean;
zoomLevel: number;
titleBarStyle: 'native' | 'custom';
}
@@ -30,6 +30,7 @@ export interface IWindowsChannel extends IChannel {
call(command: 'unmaximizeWindow', arg: number): TPromise<void>;
call(command: 'setDocumentEdited', arg: [number, boolean]): TPromise<void>;
call(command: 'toggleMenuBar', arg: number): TPromise<void>;
call(command: 'quit'): TPromise<void>;
call(command: 'windowOpen', arg: [string[], boolean]): TPromise<void>;
call(command: 'openNewWindow'): TPromise<void>;
call(command: 'showWindow', arg: number): TPromise<void>;
@@ -80,6 +81,7 @@ export class WindowsChannel implements IWindowsChannel {
case 'showWindow': return this.service.showWindow(arg);
case 'getWindows': return this.service.getWindows();
case 'getWindowCount': return this.service.getWindowCount();
case 'quit': return this.service.quit();
case 'log': return this.service.log(arg[0], arg[1]);
case 'closeExtensionHostWindow': return this.service.closeExtensionHostWindow(arg);
case 'showItemInFolder': return this.service.showItemInFolder(arg);
@@ -173,6 +175,10 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('toggleMenuBar', windowId);
}
quit(): TPromise<void> {
return this.channel.call('quit');
}
windowOpen(paths: string[], forceNewWindow?: boolean): TPromise<void> {
return this.channel.call('windowOpen', [paths, forceNewWindow]);
}
@@ -260,6 +260,11 @@ export class WindowsService implements IWindowsService, IDisposable {
return TPromise.as(null);
}
quit(): TPromise<void> {
this.windowsMainService.quit();
return TPromise.as(null);
}
private openFileForURI(filePath: string): TPromise<void> {
const cli = assign(Object.create(null), this.environmentService.args, { goto: true });
const pathsToOpen = [filePath];
+11 -1
View File
@@ -294,7 +294,7 @@ export class TestPartService implements IPartService {
}
public toggleFocusMode(): void { }
public toggleZenMode(): void { }
}
export class TestEventService extends EventEmitter implements IEventService {
@@ -668,6 +668,16 @@ export class TestBackupFileService implements IBackupFileService {
return TPromise.as(false);
}
public loadBackupResource(resource: URI): TPromise<URI> {
return this.hasBackup(resource).then(hasBackup => {
if (hasBackup) {
return this.getBackupResource(resource);
}
return void 0;
});
}
public registerResourceForBackup(resource: URI): TPromise<void> {
return TPromise.as(void 0);
}
+126 -74
View File
@@ -218,7 +218,7 @@ declare module 'vscode' {
* @param regex Optional regular expression that describes what a word is.
* @return A range spanning a word, or `undefined`.
*/
getWordRangeAtPosition(position: Position, regex?: RegExp): Range;
getWordRangeAtPosition(position: Position, regex?: RegExp): Range | undefined;
/**
* Ensure a range is completely contained in this document.
@@ -436,7 +436,7 @@ declare module 'vscode' {
* @return A range of the greater start and smaller end positions. Will
* return undefined when there is no overlap.
*/
intersection(range: Range): Range;
intersection(range: Range): Range | undefined;
/**
* Compute the union of `other` with this range.
@@ -533,15 +533,15 @@ declare module 'vscode' {
* The [text editor](#TextEditor) for which the selections have changed.
*/
textEditor: TextEditor;
/**
* The [change kind](#TextEditorSelectionChangeKind) which has triggered this
* event. Can be `undefined`.
*/
kind: TextEditorSelectionChangeKind;
/**
* The new value for the [text editor's selections](#TextEditor.selections).
*/
selections: Selection[];
/**
* The [change kind](#TextEditorSelectionChangeKind) which has triggered this
* event. Can be `undefined`.
*/
kind?: TextEditorSelectionChangeKind;
}
/**
@@ -952,7 +952,7 @@ declare module 'vscode' {
* The column in which this editor shows. Will be `undefined` in case this
* isn't one of the three main editors, e.g an embedded editor.
*/
viewColumn: ViewColumn;
viewColumn?: ViewColumn;
/**
* Perform an edit on the document associated with this text editor.
@@ -1347,7 +1347,7 @@ declare module 'vscode' {
* @param token A cancellation token.
* @return A string or a thenable that resolves to such.
*/
provideTextDocumentContent(uri: Uri, token: CancellationToken): string | Thenable<string>;
provideTextDocumentContent(uri: Uri, token: CancellationToken): ProviderResult<string>;
}
/**
@@ -1399,7 +1399,7 @@ declare module 'vscode' {
/**
* An optional function that is invoked whenever an item is selected.
*/
onDidSelectItem?: <T extends QuickPickItem>(item: T | string) => any;
onDidSelectItem?<T extends QuickPickItem>(item: T | string): any;
}
/**
@@ -1462,7 +1462,7 @@ declare module 'vscode' {
* @return A human readable string which is presented as diagnostic message.
* Return `undefined`, `null`, or the empty string when 'value' is valid.
*/
validateInput?(value: string): string;
validateInput?(value: string): string | undefined | null;
}
/**
@@ -1500,6 +1500,39 @@ declare module 'vscode' {
*/
export type DocumentSelector = string | DocumentFilter | (string | DocumentFilter)[];
/**
* A provider result represents the values a provider, like the [`HoverProvider`](#HoverProvider),
* may return. For once this is the actual result type `T`, like `Hover`, or a thenable that resolves
* to that type `T`. In addition, `null` and `undefined` can be returned - either directly or from a
* thenable.
*
* The snippets below are all valid implementions of the [`HoverProvider`](#HoverProvider):
*
* ```ts
* let a: HoverProvider = {
* provideHover(doc, pos, token): ProviderResult<Hover> {
* return new Hover('Hello World');
* }
* }
*
* let b: HoverProvider = {
* provideHover(doc, pos, token): ProviderResult<Hover> {
* return new Promise(resolve => {
* resolve(new Hover('Hello World'));
* });
* }
* }
*
* let c: HoverProvider = {
* provideHover(doc, pos, token): ProviderResult<Hover> {
* return; // undefined
* }
* }
*```
*/
export type ProviderResult<T> = T | undefined | null | Thenable<T | undefined | null>
/**
* Contains additional diagnostic information about the context in which
* a [code action](#CodeActionProvider.provideCodeActions) is run.
@@ -1532,7 +1565,7 @@ declare module 'vscode' {
* @return An array of commands or a thenable of such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): Command[] | Thenable<Command[]>;
provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): ProviderResult<Command[]>;
}
/**
@@ -1555,10 +1588,12 @@ declare module 'vscode' {
/**
* The command this code lens represents.
*/
command: Command;
command?: Command;
/**
* `true` when there is a command associated.
*
* @readonly
*/
isResolved: boolean;
@@ -1587,7 +1622,7 @@ declare module 'vscode' {
* @return An array of code lenses or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]>;
provideCodeLenses(document: TextDocument, token: CancellationToken): ProviderResult<CodeLens[]>;
/**
* This function will be called for each visible code lens, usually when scrolling and after
@@ -1597,7 +1632,7 @@ declare module 'vscode' {
* @param token A cancellation token.
* @return The given, resolved code lens or thenable that resolves to such.
*/
resolveCodeLens?(codeLens: CodeLens, token: CancellationToken): CodeLens | Thenable<CodeLens>;
resolveCodeLens?(codeLens: CodeLens, token: CancellationToken): ProviderResult<CodeLens>;
}
/**
@@ -1623,7 +1658,7 @@ declare module 'vscode' {
* @return A definition or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined` or `null`.
*/
provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition>;
}
/**
@@ -1649,7 +1684,7 @@ declare module 'vscode' {
* editor will use the range at the current position or the
* current position itself.
*/
range: Range;
range?: Range;
/**
* Creates a new hover object.
@@ -1677,7 +1712,7 @@ declare module 'vscode' {
* @return A hover or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined` or `null`.
*/
provideHover(document: TextDocument, position: Position, token: CancellationToken): Hover | Thenable<Hover>;
provideHover(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Hover>;
}
/**
@@ -1716,7 +1751,7 @@ declare module 'vscode' {
/**
* The highlight kind, default is [text](#DocumentHighlightKind.Text).
*/
kind: DocumentHighlightKind;
kind?: DocumentHighlightKind;
/**
* Creates a new document highlight object.
@@ -1743,7 +1778,7 @@ declare module 'vscode' {
* @return An array of document highlights or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideDocumentHighlights(document: TextDocument, position: Position, token: CancellationToken): DocumentHighlight[] | Thenable<DocumentHighlight[]>;
provideDocumentHighlights(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<DocumentHighlight[]>;
}
/**
@@ -1837,7 +1872,7 @@ declare module 'vscode' {
* @return An array of document highlights or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideDocumentSymbols(document: TextDocument, token: CancellationToken): SymbolInformation[] | Thenable<SymbolInformation[]>;
provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult<SymbolInformation[]>;
}
/**
@@ -1857,7 +1892,7 @@ declare module 'vscode' {
* @return An array of document highlights or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideWorkspaceSymbols(query: string, token: CancellationToken): SymbolInformation[] | Thenable<SymbolInformation[]>;
provideWorkspaceSymbols(query: string, token: CancellationToken): ProviderResult<SymbolInformation[]>;
/**
* Given a symbol fill in its [location](#SymbolInformation.location). This method is called whenever a symbol
@@ -1871,7 +1906,7 @@ declare module 'vscode' {
* @return The resolved symbol or a thenable that resolves to that. When no result is returned,
* the given `symbol` is used.
*/
resolveWorkspaceSymbol?(symbol: SymbolInformation, token: CancellationToken): SymbolInformation | Thenable<SymbolInformation>;
resolveWorkspaceSymbol?(symbol: SymbolInformation, token: CancellationToken): ProviderResult<SymbolInformation>;
}
/**
@@ -1902,7 +1937,7 @@ declare module 'vscode' {
* @return An array of locations or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideReferences(document: TextDocument, position: Position, context: ReferenceContext, token: CancellationToken): Location[] | Thenable<Location[]>;
provideReferences(document: TextDocument, position: Position, context: ReferenceContext, token: CancellationToken): ProviderResult<Location[]>;
}
/**
@@ -2112,7 +2147,7 @@ declare module 'vscode' {
* @return A workspace edit or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined` or `null`.
*/
provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): WorkspaceEdit | Thenable<WorkspaceEdit>;
provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): ProviderResult<WorkspaceEdit>;
}
/**
@@ -2151,7 +2186,7 @@ declare module 'vscode' {
* @return A set of text edits or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable<TextEdit[]>;
provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]>;
}
/**
@@ -2174,7 +2209,7 @@ declare module 'vscode' {
* @return A set of text edits or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable<TextEdit[]>;
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]>;
}
/**
@@ -2198,7 +2233,7 @@ declare module 'vscode' {
* @return A set of text edits or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable<TextEdit[]>;
provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]>;
}
/**
@@ -2217,7 +2252,7 @@ declare module 'vscode' {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
/**
* Creates a new parameter information object.
@@ -2245,7 +2280,7 @@ declare module 'vscode' {
* The human-readable doc-comment of this signature. Will be shown
* in the UI but can be omitted.
*/
documentation: string;
documentation?: string;
/**
* The parameters of this signature.
@@ -2299,7 +2334,7 @@ declare module 'vscode' {
* @return Signature help or a thenable that resolves to such. The lack of a result can be
* signaled by returning `undefined` or `null`.
*/
provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): SignatureHelp | Thenable<SignatureHelp>;
provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<SignatureHelp>;
}
/**
@@ -2354,39 +2389,39 @@ declare module 'vscode' {
* The kind of this completion item. Based on the kind
* an icon is chosen by the editor.
*/
kind: CompletionItemKind;
kind?: CompletionItemKind;
/**
* A human-readable string with additional information
* about this item, like type or symbol information.
*/
detail: string;
detail?: string;
/**
* A human-readable string that represents a doc-comment.
*/
documentation: string;
documentation?: string;
/**
* A string that should be used when comparing this item
* with other items. When `falsy` the [label](#CompletionItem.label)
* is used.
*/
sortText: string;
sortText?: string;
/**
* A string that should be used when filtering a set of
* completion items. When `falsy` the [label](#CompletionItem.label)
* is used.
*/
filterText: string;
filterText?: string;
/**
* A string or snippet that should be inserted in a document when selecting
* this completion. When `falsy` the [label](#CompletionItem.label)
* is used.
*/
insertText: string | SnippetString;
insertText?: string | SnippetString;
/**
* A range of text that should be replaced by this completion item.
@@ -2397,7 +2432,7 @@ declare module 'vscode' {
* *Note:* The range must be a [single line](#Range.isSingleLine) and it must
* [contain](#Range.contains) the position at which completion has been [requested](#CompletionItemProvider.provideCompletionItems).
*/
range: Range;
range?: Range;
/**
* @deprecated **Deprecated** in favor of `CompletionItem.insertText` and `CompletionItem.range`.
@@ -2409,21 +2444,21 @@ declare module 'vscode' {
* ~~The [range](#Range) of the edit must be single-line and on the same
* line completions were [requested](#CompletionItemProvider.provideCompletionItems) at.~~
*/
textEdit: TextEdit;
textEdit?: TextEdit;
/**
* An optional array of additional [text edits](#TextEdit) that are applied when
* selecting this completion. Edits must not overlap with the main [edit](#CompletionItem.textEdit)
* nor with themselves.
*/
additionalTextEdits: TextEdit[];
additionalTextEdits?: TextEdit[];
/**
* An optional [command](#Command) that is executed *after* inserting this completion. *Note* that
* additional modifications to the current document should be described with the
* [additionalTextEdits](#CompletionItem.additionalTextEdits)-property.
*/
command: Command;
command?: Command;
/**
* Creates a new completion item.
@@ -2447,7 +2482,7 @@ declare module 'vscode' {
* This list it not complete. Further typing should result in recomputing
* this list.
*/
isIncomplete: boolean;
isIncomplete?: boolean;
/**
* The completion items.
@@ -2488,7 +2523,7 @@ declare module 'vscode' {
* @return An array of completions, a [completion list](#CompletionList), or a thenable that resolves to either.
* The lack of a result can be signaled by returning `undefined`, `null`, or an empty array.
*/
provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>;
provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<CompletionItem[] | CompletionList>;
/**
* Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation)
@@ -2501,7 +2536,7 @@ declare module 'vscode' {
* @return The resolved completion item or a thenable that resolves to of such. It is OK to return the given
* `item`. When no result is returned, the given `item` will be used.
*/
resolveCompletionItem?(item: CompletionItem, token: CancellationToken): CompletionItem | Thenable<CompletionItem>;
resolveCompletionItem?(item: CompletionItem, token: CancellationToken): ProviderResult<CompletionItem>;
}
@@ -2543,9 +2578,9 @@ declare module 'vscode' {
* @param document The document in which the command was invoked.
* @param token A cancellation token.
* @return An array of [document links](#DocumentLink) or a thenable that resolves to such. The lack of a result
* can be signaled by returning `undefined`, `null`, or an empty array.
* can be signaled by returning `undefined`, `null`, or an empty array.
*/
provideDocumentLinks(document: TextDocument, token: CancellationToken): DocumentLink[] | Thenable<DocumentLink[]>;
provideDocumentLinks(document: TextDocument, token: CancellationToken): ProviderResult<DocumentLink[]>;
/**
* Given a link fill in its [target](#DocumentLink.target). This method is called when an incomplete
@@ -2556,7 +2591,7 @@ declare module 'vscode' {
* @param link The link that is to be resolved.
* @param token A cancellation token.
*/
resolveDocumentLink?(link: DocumentLink, token: CancellationToken): DocumentLink | Thenable<DocumentLink>;
resolveDocumentLink?(link: DocumentLink, token: CancellationToken): ProviderResult<DocumentLink>;
}
/**
@@ -2756,6 +2791,14 @@ declare module 'vscode' {
*/
export interface WorkspaceConfiguration {
/**
* Return a value from this configuration.
*
* @param section Configuration name, supports _dotted_ names.
* @return The value `section` denotes or `undefined`.
*/
get<T>(section: string): T | undefined;
/**
* Return a value from this configuration.
*
@@ -2763,7 +2806,8 @@ declare module 'vscode' {
* @param defaultValue A value should be returned when no value could be found, is `undefined`.
* @return The value `section` denotes or the default.
*/
get<T>(section: string, defaultValue?: T): T;
get<T>(section: string, defaultValue: T): T;
/**
* Check if this configuration has a certain value.
@@ -2786,7 +2830,7 @@ declare module 'vscode' {
* @param section Configuration name, supports _dotted_ names.
* @return Information about a configuration setting or `undefined`.
*/
inspect<T>(section: string): { key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T };
inspect<T>(section: string): { key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T } | undefined;
/**
* Update a configuration value. A value can be changed for the current
@@ -2933,7 +2977,7 @@ declare module 'vscode' {
* @param uri A resource identifier.
* @param diagnostics Array of diagnostics or `undefined`
*/
set(uri: Uri, diagnostics: Diagnostic[]): void;
set(uri: Uri, diagnostics: Diagnostic[] | undefined): void;
/**
* Replace all entries in this collection.
@@ -2945,7 +2989,7 @@ declare module 'vscode' {
*
* @param entries An array of tuples, like `[[file1, [d1, d2]], [file2, [d3, d4, d5]]]`, or `undefined`.
*/
set(entries: [Uri, Diagnostic[]][]): void;
set(entries: [Uri, Diagnostic[] | undefined][]): void;
/**
* Remove all diagnostics from this collection that belong
@@ -2976,7 +3020,7 @@ declare module 'vscode' {
* @param uri A resource identifier.
* @returns An immutable array of [diagnostics](#Diagnostic) or `undefined`.
*/
get(uri: Uri): Diagnostic[];
get(uri: Uri): Diagnostic[] | undefined;
/**
* Check if this collection contains diagnostics for a
@@ -3291,8 +3335,8 @@ declare module 'vscode' {
* can store private state. The directory might not exist on disk and creation is
* up to the extension. However, the parent directory is guaranteed to be existent.
*
* Use [`workspaceState`](ExtensionContext#workspaceState) or
* [`globalState`](ExtensionContext#globalState) to store key value data.
* Use [`workspaceState`](#ExtensionContext.workspaceState) or
* [`globalState`](#ExtensionContext.globalState) to store key value data.
*/
storagePath: string;
}
@@ -3303,15 +3347,23 @@ declare module 'vscode' {
*/
export interface Memento {
/**
* Return a value.
*
* @param key A string.
* @return The stored value or `undefined`.
*/
get<T>(key: string): T | undefined;
/**
* Return a value.
*
* @param key A string.
* @param defaultValue A value that should be returned when there is no
* value (`undefined`) with the given key.
* @return The stored value, `undefined`, or the defaultValue.
* @return The stored value or the defaultValue.
*/
get<T>(key: string, defaultValue?: T): T;
get<T>(key: string, defaultValue: T): T;
/**
* Store a value. The value must be JSON-stringifyable.
@@ -3438,7 +3490,7 @@ declare module 'vscode' {
* @return A thenable that resolves to the returned value of the given command. `undefined` when
* the command handler function doesn't return anything.
*/
export function executeCommand<T>(command: string, ...rest: any[]): Thenable<T>;
export function executeCommand<T>(command: string, ...rest: any[]): Thenable<T | undefined>;
/**
* Retrieve the list of all available commands. Commands starting an underscore are
@@ -3462,7 +3514,7 @@ declare module 'vscode' {
* that currently has focus or, when none has focus, the one that has changed
* input most recently.
*/
export let activeTextEditor: TextEditor;
export let activeTextEditor: TextEditor | undefined;
/**
* The currently visible editors or an empty array.
@@ -3530,7 +3582,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showInformationMessage(message: string, ...items: string[]): Thenable<string>;
export function showInformationMessage(message: string, ...items: string[]): Thenable<string | undefined>;
/**
* Show an information message.
@@ -3541,7 +3593,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showInformationMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T>;
export function showInformationMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T | undefined>;
/**
* Show a warning message.
@@ -3552,7 +3604,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showWarningMessage(message: string, ...items: string[]): Thenable<string>;
export function showWarningMessage(message: string, ...items: string[]): Thenable<string | undefined>;
/**
* Show a warning message.
@@ -3563,7 +3615,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showWarningMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T>;
export function showWarningMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T | undefined>;
/**
* Show an error message.
@@ -3574,7 +3626,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showErrorMessage(message: string, ...items: string[]): Thenable<string>;
export function showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined>;
/**
* Show an error message.
@@ -3585,7 +3637,7 @@ declare module 'vscode' {
* @param items A set of items that will be rendered as actions in the message.
* @return A thenable that resolves to the selected item or `undefined` when being dismissed.
*/
export function showErrorMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T>;
export function showErrorMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T | undefined>;
/**
* Shows a selection list.
@@ -3593,9 +3645,9 @@ declare module 'vscode' {
* @param items An array of strings, or a promise that resolves to an array of strings.
* @param options Configures the behavior of the selection list.
* @param token A token that can be used to signal cancellation.
* @return A promise that resolves to the selection or undefined.
* @return A promise that resolves to the selection or `undefined`.
*/
export function showQuickPick(items: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string>;
export function showQuickPick(items: string[] | Thenable<string[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<string | undefined>;
/**
* Shows a selection list.
@@ -3603,14 +3655,14 @@ declare module 'vscode' {
* @param items An array of items, or a promise that resolves to an array of items.
* @param options Configures the behavior of the selection list.
* @param token A token that can be used to signal cancellation.
* @return A promise that resolves to the selected item or undefined.
* @return A promise that resolves to the selected item or `undefined`.
*/
export function showQuickPick<T extends QuickPickItem>(items: T[] | Thenable<T[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<T>;
export function showQuickPick<T extends QuickPickItem>(items: T[] | Thenable<T[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<T | undefined>;
/**
* Opens an input box to ask the user for input.
*
* The returned value will be undefined if the input box was canceled (e.g. pressing ESC). Otherwise the
* The returned value will be `undefined` if the input box was canceled (e.g. pressing ESC). Otherwise the
* returned value will be the string typed by the user or an empty string if the user did not type
* anything but dismissed the input box with OK.
*
@@ -3618,7 +3670,7 @@ declare module 'vscode' {
* @param token A token that can be used to signal cancellation.
* @return A promise that resolves to a string the user provided or to `undefined` in case of dismissal.
*/
export function showInputBox(options?: InputBoxOptions, token?: CancellationToken): Thenable<string>;
export function showInputBox(options?: InputBoxOptions, token?: CancellationToken): Thenable<string | undefined>;
/**
* Create a new [output channel](#OutputChannel) with the given name.
@@ -3814,7 +3866,7 @@ declare module 'vscode' {
*
* @readonly
*/
export let rootPath: string;
export let rootPath: string | undefined;
/**
* Returns a path that is relative to the workspace root.
@@ -3837,7 +3889,7 @@ declare module 'vscode' {
* @param token A token that can be used to signal cancellation to the underlying search engine.
* @return A thenable that resolves to an array of resource identifiers.
*/
export function findFiles(include: string, exclude: string, maxResults?: number, token?: CancellationToken): Thenable<Uri[]>;
export function findFiles(include: string, exclude?: string, maxResults?: number, token?: CancellationToken): Thenable<Uri[]>;
/**
* Save all dirty files.
@@ -4280,7 +4332,7 @@ declare module 'vscode' {
* @param extensionId An extension identifier.
* @return An extension or `undefined`.
*/
export function getExtension(extensionId: string): Extension<any>;
export function getExtension(extensionId: string): Extension<any> | undefined;
/**
* Get an extension its full identifier in the form of: `publisher.name`.
@@ -4288,7 +4340,7 @@ declare module 'vscode' {
* @param extensionId An extension identifier.
* @return An extension or `undefined`.
*/
export function getExtension<T>(extensionId: string): Extension<T>;
export function getExtension<T>(extensionId: string): Extension<T> | undefined;
/**
* All extensions currently known to the system.
@@ -10,6 +10,7 @@ import { WorkspaceConfiguration } from 'vscode';
import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol';
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IWorkspaceConfiguration } from 'vs/workbench/services/configuration/common/configuration';
import { toValuesTree } from 'vs/platform/configuration/common/model';
function lookUp(tree: any, key: string) {
if (key) {
@@ -22,37 +23,19 @@ function lookUp(tree: any, key: string) {
}
}
function insert(tree: any, key: string, value: any) {
const parts = key.split('.');
let node = tree;
let i: number;
let to = parts.length - 1;
for (i = 0; i < to; i++) {
let child = node[parts[i]];
if (child) {
node = child;
} else {
break;
}
}
for (; i < to; i++) {
node = node[parts[i]] = Object.create(null);
}
node[parts[to]] = value;
}
interface UsefulConfiguration {
data: IWorkspaceConfiguration;
valueTree: any;
}
function createUsefulConfiguration(data: IWorkspaceConfiguration): { data: IWorkspaceConfiguration, valueTree: any } {
const valueTree = Object.create(null);
const valueMap: { [key: string]: any } = Object.create(null);
for (let key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
insert(valueTree, key, data[key].value);
valueMap[key] = data[key].value;
}
}
const valueTree = toValuesTree(valueMap);
return {
data,
valueTree
+3 -3
View File
@@ -781,7 +781,7 @@ export class CodeLens {
export class ParameterInformation {
label: string;
documentation: string;
documentation?: string;
constructor(label: string, documentation?: string) {
this.label = label;
@@ -792,7 +792,7 @@ export class ParameterInformation {
export class SignatureInformation {
label: string;
documentation: string;
documentation?: string;
parameters: ParameterInformation[];
constructor(label: string, documentation?: string) {
@@ -869,7 +869,7 @@ export class CompletionItem {
export class CompletionList {
isIncomplete: boolean;
isIncomplete?: boolean;
items: vscode.CompletionItem[];
@@ -6,16 +6,16 @@
import { TPromise } from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import { Action } from 'vs/base/common/actions';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { Registry } from 'vs/platform/platform';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IPartService } from 'vs/workbench/services/part/common/partService';
class ToggleFocusMode extends Action {
class ToggleZenMode extends Action {
public static ID = 'workbench.action.toggleFocusMode';
public static LABEL = nls.localize('toggle', "Toggle Focus Mode");
public static ID = 'workbench.action.toggleZenMode';
public static LABEL = nls.localize('toggleZenMode', "Toggle Zen Mode");
constructor(
id: string,
@@ -27,10 +27,10 @@ class ToggleFocusMode extends Action {
}
public run(): TPromise<any> {
this.partService.toggleFocusMode();
this.partService.toggleZenMode();
return TPromise.as(null);
}
}
let registry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFocusMode, ToggleFocusMode.ID, ToggleFocusMode.LABEL, { primary: KeyMod.Shift | KeyCode.F11, mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'Toggle Focus Mode');
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleZenMode, ToggleZenMode.ID, ToggleZenMode.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_Z) }), 'View: Toggle Zen Mode', nls.localize('view', "View"));
@@ -53,7 +53,7 @@ export class ActivitybarPart extends Part implements IActivityService {
this.toUnbind.push(this.viewletService.onDidViewletClose(viewlet => this.onCompositeClosed(viewlet)));
// Update viewlet switcher when external viewlets become ready
this.toUnbind.push(this.viewletService.onDidExtViewletsLoad(() => this.refreshViewletSwitcher()));
this.toUnbind.push(this.viewletService.onDidExtensionViewletsLoad(() => this.refreshViewletSwitcher()));
// Update viewlet switcher on toggling of a viewlet
this.toUnbind.push(this.viewletService.onDidViewletToggle(() => this.refreshViewletSwitcher()));
@@ -110,6 +110,7 @@ export class ActivitybarPart extends Part implements IActivityService {
}
private fillViewletSwitcher(viewlets: ViewletDescriptor[]) {
// Pull out viewlets no longer needed
const newViewletIds = viewlets.map(v => v.id);
const existingViewletIds = Object.keys(this.compositeIdToActions);
@@ -119,26 +120,40 @@ export class ActivitybarPart extends Part implements IActivityService {
}
});
// Built actions for viewlets to show
const actionsToPush = viewlets
.filter(viewlet => !this.compositeIdToActions[viewlet.id])
.map(viewlet => this.toAction(viewlet));
// Add to viewlet switcher
this.viewletSwitcherBar.push(actionsToPush, { label: true, icon: true });
// Make sure to activate the active one
const activeViewlet = this.viewletService.getActiveViewlet();
if (activeViewlet) {
const activeViewletEntry = this.compositeIdToActions[activeViewlet.getId()];
if (activeViewletEntry) {
activeViewletEntry.activate();
}
}
}
private pullViewlet(viewletId: string): void {
const index = Object.keys(this.compositeIdToActions).indexOf(viewletId);
const action = this.compositeIdToActions[viewletId];
const actionItem = this.activityActionItems[action.id];
delete this.compositeIdToActions[viewletId];
delete this.activityActionItems[action.id];
action.dispose();
delete this.compositeIdToActions[viewletId];
const actionItem = this.activityActionItems[action.id];
actionItem.dispose();
delete this.activityActionItems[action.id];
this.viewletSwitcherBar.pull(index);
}
private toAction(composite: ViewletDescriptor): ActivityAction {
const action = this.instantiationService.createInstance(ViewletActivityAction, composite.id + '.activity-bar-action', composite);
const action = this.instantiationService.createInstance(ViewletActivityAction, `${composite.id}.activity-bar-action`, composite);
this.activityActionItems[action.id] = new ActivityActionItem(action, composite.name, this.getKeybindingLabel(composite.id));
this.compositeIdToActions[composite.id] = action;

Some files were not shown because too many files have changed in this diff Show More