diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe
index 3ff950f8732..45069658999 100644
--- a/build/monaco/monaco.d.ts.recipe
+++ b/build/monaco/monaco.d.ts.recipe
@@ -73,7 +73,7 @@ declare module monaco.editor {
declare module monaco.languages {
#includeAll(vs/editor/browser/standalone/standaloneLanguages;modes.=>;editorCommon.=>editor.):
-#include(vs/editor/common/modes/supports/richEditSupport): CommentRule, IRichLanguageConfiguration
+#include(vs/editor/common/modes/languageConfigurationRegistry): CommentRule, IRichLanguageConfiguration
#include(vs/editor/common/modes/supports/onEnter): IIndentationRules, IOnEnterRegExpRules
#include(vs/editor/common/modes/supports/electricCharacter): IBracketElectricCharacterContribution, IDocComment
#includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.;IToken2=>IToken;ILineTokens2=>ILineTokens;IState2=>IState):
diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js
index 76f1ff18155..590bc6a7ddc 100644
--- a/build/npm/postinstall.js
+++ b/build/npm/postinstall.js
@@ -10,6 +10,7 @@ const extensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'json',
+ 'configuration-editing',
'typescript',
'php',
'javascript'
diff --git a/extensions/configuration-editing/OSSREADME.json b/extensions/configuration-editing/OSSREADME.json
new file mode 100644
index 00000000000..4744d2b3f24
--- /dev/null
+++ b/extensions/configuration-editing/OSSREADME.json
@@ -0,0 +1,9 @@
+// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
+
+[{
+ "name": "Microsoft/node-jsonc-parser",
+ "version": "0.0.0",
+ "license": "MIT",
+ "isProd": true,
+ "repositoryURL": "https://github.com/Microsoft/node-jsonc-parser"
+}]
diff --git a/extensions/configuration-editing/package.json b/extensions/configuration-editing/package.json
new file mode 100644
index 00000000000..60ca2473717
--- /dev/null
+++ b/extensions/configuration-editing/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "configuration-editing",
+ "version": "0.0.1",
+ "publisher": "vscode",
+ "engines": {
+ "vscode": "^1.0.0"
+ },
+ "categories": [
+ "Languages", "Other"
+ ],
+ "activationEvents": [
+ "onLanguage:json"
+ ],
+ "main": "./out/extension",
+ "scripts": {
+ "compile": "gulp compile-extension:configuration-editing",
+ "watch": "gulp watch-extension:configuration-editing"
+ },
+ "devDependencies": {
+ "vscode": "^0.11.0"
+ },
+ "dependencies": {
+ "jsonc-parser": "^0.2.1"
+ }
+}
diff --git a/extensions/configuration-editing/src/extension.ts b/extensions/configuration-editing/src/extension.ts
new file mode 100644
index 00000000000..71a11ba355f
--- /dev/null
+++ b/extensions/configuration-editing/src/extension.ts
@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------------------------
+ * 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 vscode from 'vscode';
+import {getLocation} from 'jsonc-parser';
+
+export function activate(context) {
+
+ const commands = vscode.commands.getCommands(true);
+
+ //keybindings.json command-suggestions
+ const disposable = vscode.languages.registerCompletionItemProvider({ pattern: '**/keybindings.json' }, {
+
+ provideCompletionItems(document, position, token) {
+ const location = getLocation(document.getText(), document.offsetAt(position));
+ if (location.path[1] === 'command') {
+ return commands.then(ids => ids.map(id => {
+ let item = new vscode.CompletionItem(id);
+ item.kind = vscode.CompletionItemKind.Value;
+ return item;
+ }));
+ }
+ }
+ });
+
+ context.subscriptions.push(disposable);
+}
diff --git a/extensions/configuration-editing/src/typings/ref.d.ts b/extensions/configuration-editing/src/typings/ref.d.ts
new file mode 100644
index 00000000000..7f4835e6747
--- /dev/null
+++ b/extensions/configuration-editing/src/typings/ref.d.ts
@@ -0,0 +1,10 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+///
+///
+///
+///
+///
\ No newline at end of file
diff --git a/extensions/configuration-editing/tsconfig.json b/extensions/configuration-editing/tsconfig.json
new file mode 100644
index 00000000000..8cb16334377
--- /dev/null
+++ b/extensions/configuration-editing/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "noLib": true,
+ "target": "es5",
+ "module": "commonjs",
+ "outDir": "./out"
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/extensions/json/client/src/jsonMain.ts b/extensions/json/client/src/jsonMain.ts
index 5ab4f70c634..98c256c04fd 100644
--- a/extensions/json/client/src/jsonMain.ts
+++ b/extensions/json/client/src/jsonMain.ts
@@ -10,10 +10,6 @@ import {workspace, languages, ExtensionContext, extensions, Uri} from 'vscode';
import {LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType} from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
-namespace TelemetryNotification {
- export const type: NotificationType<{ key: string, data: any }> = { get method() { return 'telemetry'; } };
-}
-
namespace VSCodeContentRequest {
export const type: RequestType = { get method() { return 'vscode/content'; } };
}
@@ -68,7 +64,7 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('JSON Server', serverOptions, clientOptions);
- client.onNotification(TelemetryNotification.type, e => {
+ client.onTelemetry(e => {
if (telemetryReporter) {
telemetryReporter.sendTelemetryEvent(e.key, e.data);
}
diff --git a/extensions/json/package.json b/extensions/json/package.json
index 3f38671cc12..cca25933dc6 100644
--- a/extensions/json/package.json
+++ b/extensions/json/package.json
@@ -128,7 +128,7 @@
}
},
"dependencies": {
- "vscode-languageclient": "^1.3.1",
+ "vscode-languageclient": "^2.2.1",
"vscode-extension-telemetry": "^0.0.5"
}
}
\ No newline at end of file
diff --git a/extensions/json/server/package.json b/extensions/json/server/package.json
index 5afc0268f70..ab47aa2efc5 100644
--- a/extensions/json/server/package.json
+++ b/extensions/json/server/package.json
@@ -10,7 +10,7 @@
"dependencies": {
"request-light": "^0.1.0",
"jsonc-parser": "^0.2.0",
- "vscode-languageserver": "^1.3.0",
+ "vscode-languageserver": "^2.2.0",
"vscode-nls": "^1.0.4"
},
"scripts": {
diff --git a/extensions/json/server/src/jsonCompletion.ts b/extensions/json/server/src/jsonCompletion.ts
index 103869f3fdb..7cb9f3925a6 100644
--- a/extensions/json/server/src/jsonCompletion.ts
+++ b/extensions/json/server/src/jsonCompletion.ts
@@ -10,7 +10,7 @@ import SchemaService = require('./jsonSchemaService');
import JsonSchema = require('./jsonSchema');
import {IJSONWorkerContribution} from './jsonContributions';
-import {CompletionItem, CompletionItemKind, CompletionList, ITextDocument, TextDocumentPosition, Range, TextEdit, RemoteConsole} from 'vscode-languageserver';
+import {CompletionItem, CompletionItemKind, CompletionList, TextDocument, Position, Range, TextEdit, RemoteConsole} from 'vscode-languageserver';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
@@ -46,9 +46,9 @@ export class JSONCompletion {
return Promise.resolve(item);
}
- public doSuggest(document: ITextDocument, textDocumentPosition: TextDocumentPosition, doc: Parser.JSONDocument): Thenable {
+ public doSuggest(document: TextDocument, position: Position, doc: Parser.JSONDocument): Thenable {
- let offset = document.offsetAt(textDocumentPosition.position);
+ let offset = document.offsetAt(position);
let node = doc.getNodeFromOffsetEndInclusive(offset);
let currentWord = this.getCurrentWord(document, offset);
@@ -61,7 +61,7 @@ export class JSONCompletion {
if (node && (node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) {
overwriteRange = Range.create(document.positionAt(node.start), document.positionAt(node.end));
} else {
- overwriteRange = Range.create(document.positionAt(offset - currentWord.length), textDocumentPosition.position);
+ overwriteRange = Range.create(document.positionAt(offset - currentWord.length), position);
}
let proposed: { [key: string]: boolean } = {};
@@ -87,7 +87,7 @@ export class JSONCompletion {
}
};
- return this.schemaService.getSchemaForResource(textDocumentPosition.uri, doc).then((schema) => {
+ return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
let collectionPromises: Thenable[] = [];
let addValue = true;
@@ -134,7 +134,7 @@ export class JSONCompletion {
let location = node.getNodeLocation();
this.contributions.forEach((contribution) => {
- let collectPromise = contribution.collectPropertySuggestions(textDocumentPosition.uri, location, currentWord, addValue, isLast, collector);
+ let collectPromise = contribution.collectPropertySuggestions(document.uri, location, currentWord, addValue, isLast, collector);
if (collectPromise) {
collectionPromises.push(collectPromise);
}
@@ -157,7 +157,7 @@ export class JSONCompletion {
if (!node) {
this.contributions.forEach((contribution) => {
- let collectPromise = contribution.collectDefaultSuggestions(textDocumentPosition.uri, collector);
+ let collectPromise = contribution.collectDefaultSuggestions(document.uri, collector);
if (collectPromise) {
collectionPromises.push(collectPromise);
}
@@ -170,7 +170,7 @@ export class JSONCompletion {
if (!valueNode || offset <= valueNode.end) {
let location = node.parent.getNodeLocation();
this.contributions.forEach((contribution) => {
- let collectPromise = contribution.collectValueSuggestions(textDocumentPosition.uri, location, parentKey, collector);
+ let collectPromise = contribution.collectValueSuggestions(document.uri, location, parentKey, collector);
if (collectPromise) {
collectionPromises.push(collectPromise);
}
@@ -230,7 +230,7 @@ export class JSONCompletion {
}
}
- private getSchemaLessValueSuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, document: ITextDocument, collector: ISuggestionsCollector): void {
+ private getSchemaLessValueSuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, document: TextDocument, collector: ISuggestionsCollector): void {
let collectSuggestionsForValues = (value: Parser.ASTNode) => {
if (!value.contains(offset)) {
let content = this.getTextForMatchingNode(value, document);
@@ -449,7 +449,7 @@ export class JSONCompletion {
}
- private getTextForMatchingNode(node: Parser.ASTNode, document: ITextDocument): string {
+ private getTextForMatchingNode(node: Parser.ASTNode, document: TextDocument): string {
switch (node.type) {
case 'array':
return '[]';
@@ -513,7 +513,7 @@ export class JSONCompletion {
return this.getTextForValue(key);
}
- private getCurrentWord(document: ITextDocument, offset: number) {
+ private getCurrentWord(document: TextDocument, offset: number) {
var i = offset - 1;
var text = document.getText();
while (i >= 0 && ' \t\n\r\v":{[,'.indexOf(text.charAt(i)) === -1) {
diff --git a/extensions/json/server/src/jsonDocumentSymbols.ts b/extensions/json/server/src/jsonDocumentSymbols.ts
index 54de7054eea..9597fdad830 100644
--- a/extensions/json/server/src/jsonDocumentSymbols.ts
+++ b/extensions/json/server/src/jsonDocumentSymbols.ts
@@ -7,14 +7,14 @@
import Parser = require('./jsonParser');
import Strings = require('./utils/strings');
-import {SymbolInformation, SymbolKind, ITextDocument, Range, Location} from 'vscode-languageserver';
+import {SymbolInformation, SymbolKind, TextDocument, Range, Location} from 'vscode-languageserver';
export class JSONDocumentSymbols {
constructor() {
}
- public compute(document: ITextDocument, doc: Parser.JSONDocument): Promise {
+ public compute(document: TextDocument, doc: Parser.JSONDocument): Promise {
let root = doc.root;
if (!root) {
diff --git a/extensions/json/server/src/jsonFormatter.ts b/extensions/json/server/src/jsonFormatter.ts
index f64f79c7b51..c95ec714d53 100644
--- a/extensions/json/server/src/jsonFormatter.ts
+++ b/extensions/json/server/src/jsonFormatter.ts
@@ -5,9 +5,9 @@
'use strict';
import Json = require('jsonc-parser');
-import {ITextDocument, Range, Position, FormattingOptions, TextEdit} from 'vscode-languageserver';
+import {TextDocument, Range, Position, FormattingOptions, TextEdit} from 'vscode-languageserver';
-export function format(document: ITextDocument, range: Range, options: FormattingOptions): TextEdit[] {
+export function format(document: TextDocument, range: Range, options: FormattingOptions): TextEdit[] {
const documentText = document.getText();
let initialIndentLevel: number;
let value: string;
@@ -83,7 +83,7 @@ export function format(document: ITextDocument, range: Range, options: Formattin
replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
secondToken = scanNext();
}
-
+
if (secondToken === Json.SyntaxKind.CloseBraceToken) {
if (firstToken !== Json.SyntaxKind.OpenBraceToken) {
indentLevel--;
@@ -163,7 +163,7 @@ function computeIndentLevel(content: string, offset: number, options: Formatting
return Math.floor(nChars / tabSize);
}
-function getEOL(document: ITextDocument): string {
+function getEOL(document: TextDocument): string {
let text = document.getText();
if (document.lineCount > 1) {
let to = document.offsetAt(Position.create(1, 0));
diff --git a/extensions/json/server/src/jsonHover.ts b/extensions/json/server/src/jsonHover.ts
index 5aa6cf6e9ae..987e7f4a6a0 100644
--- a/extensions/json/server/src/jsonHover.ts
+++ b/extensions/json/server/src/jsonHover.ts
@@ -9,7 +9,7 @@ import Parser = require('./jsonParser');
import SchemaService = require('./jsonSchemaService');
import {IJSONWorkerContribution} from './jsonContributions';
-import {Hover, ITextDocument, TextDocumentPosition, Range, MarkedString} from 'vscode-languageserver';
+import {Hover, TextDocument, Position, Range, MarkedString} from 'vscode-languageserver';
export class JSONHover {
@@ -21,9 +21,9 @@ export class JSONHover {
this.contributions = contributions;
}
- public doHover(document: ITextDocument, textDocumentPosition: TextDocumentPosition, doc: Parser.JSONDocument): Thenable {
+ public doHover(document: TextDocument, position: Position, doc: Parser.JSONDocument): Thenable {
- let offset = document.offsetAt(textDocumentPosition.position);
+ let offset = document.offsetAt(position);
let node = doc.getNodeFromOffset(offset);
// use the property description when hovering over an object key
@@ -39,7 +39,7 @@ export class JSONHover {
if (!node) {
return Promise.resolve(void 0);
}
-
+
var createHover = (contents: MarkedString[]) => {
let range = Range.create(document.positionAt(node.start), document.positionAt(node.end));
let result: Hover = {
@@ -47,18 +47,18 @@ export class JSONHover {
range: range
};
return result;
- };
-
+ };
+
let location = node.getNodeLocation();
for (let i = this.contributions.length - 1; i >= 0; i--) {
let contribution = this.contributions[i];
- let promise = contribution.getInfoContribution(textDocumentPosition.uri, location);
+ let promise = contribution.getInfoContribution(document.uri, location);
if (promise) {
return promise.then(htmlContent => createHover(htmlContent));
}
}
- return this.schemaService.getSchemaForResource(textDocumentPosition.uri, doc).then((schema) => {
+ return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
if (schema) {
let matchingSchemas: Parser.IApplicableSchema[] = [];
doc.validate(schema.schema, matchingSchemas, node.start);
diff --git a/extensions/json/server/src/server.ts b/extensions/json/server/src/server.ts
index b91d4ca9e12..384aeeea6a8 100644
--- a/extensions/json/server/src/server.ts
+++ b/extensions/json/server/src/server.ts
@@ -5,11 +5,10 @@
'use strict';
import {
- IPCMessageReader, IPCMessageWriter,
- createConnection, IConnection,
- TextDocuments, ITextDocument, Diagnostic, DiagnosticSeverity,
- InitializeParams, InitializeResult, TextDocumentIdentifier, TextDocumentPosition, CompletionList,
- CompletionItem, Hover, SymbolInformation, DocumentFormattingParams,
+ IPCMessageReader, IPCMessageWriter, createConnection, IConnection,
+ TextDocuments, TextDocument, Diagnostic, DiagnosticSeverity,
+ InitializeParams, InitializeResult, TextDocumentPositionParams, CompletionList,
+ CompletionItem, Hover, SymbolInformation, DocumentFormattingParams, DocumentSymbolParams,
DocumentRangeFormattingParams, NotificationType, RequestType
} from 'vscode-languageserver';
@@ -33,10 +32,6 @@ import {FileAssociationContribution} from './jsoncontributions/fileAssociationCo
import * as nls from 'vscode-nls';
nls.config(process.env['VSCODE_NLS_CONFIG']);
-namespace TelemetryNotification {
- export const type: NotificationType<{ key: string, data: any }> = { get method() { return 'telemetry'; } };
-}
-
namespace SchemaAssociationNotification {
export const type: NotificationType = { get method() { return 'json/schemaAssociations'; } };
}
@@ -89,7 +84,7 @@ let workspaceContext = {
let telemetry = {
log: (key: string, data: any) => {
- connection.sendNotification(TelemetryNotification.type, { key, data });
+ connection.telemetry.logEvent({ key, data });
}
};
@@ -208,7 +203,7 @@ function updateConfiguration() {
}
-function validateTextDocument(textDocument: ITextDocument): void {
+function validateTextDocument(textDocument: TextDocument): void {
if (textDocument.getText().length === 0) {
// ignore empty documents
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
@@ -268,28 +263,28 @@ connection.onDidChangeWatchedFiles((change) => {
}
});
-function getJSONDocument(document: ITextDocument): JSONDocument {
+function getJSONDocument(document: TextDocument): JSONDocument {
return parseJSON(document.getText());
}
-connection.onCompletion((textDocumentPosition: TextDocumentPosition): Thenable => {
- let document = documents.get(textDocumentPosition.uri);
+connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): Thenable => {
+ let document = documents.get(textDocumentPosition.textDocument.uri);
let jsonDocument = getJSONDocument(document);
- return jsonCompletion.doSuggest(document, textDocumentPosition, jsonDocument);
+ return jsonCompletion.doSuggest(document, textDocumentPosition.position, jsonDocument);
});
connection.onCompletionResolve((item: CompletionItem) : Thenable => {
return jsonCompletion.doResolve(item);
});
-connection.onHover((textDocumentPosition: TextDocumentPosition): Thenable => {
- let document = documents.get(textDocumentPosition.uri);
+connection.onHover((textDocumentPosition: TextDocumentPositionParams): Thenable => {
+ let document = documents.get(textDocumentPosition.textDocument.uri);
let jsonDocument = getJSONDocument(document);
- return jsonHover.doHover(document, textDocumentPosition, jsonDocument);
+ return jsonHover.doHover(document, textDocumentPosition.position, jsonDocument);
});
-connection.onDocumentSymbol((textDocumentIdentifier: TextDocumentIdentifier): Thenable => {
- let document = documents.get(textDocumentIdentifier.uri);
+connection.onDocumentSymbol((documentSymbolParams: DocumentSymbolParams): Thenable => {
+ let document = documents.get(documentSymbolParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return jsonDocumentSymbols.compute(document, jsonDocument);
});
diff --git a/extensions/json/server/src/test/completion.test.ts b/extensions/json/server/src/test/completion.test.ts
index a4c92879951..995b23b1fa4 100644
--- a/extensions/json/server/src/test/completion.test.ts
+++ b/extensions/json/server/src/test/completion.test.ts
@@ -11,7 +11,7 @@ import JsonSchema = require('../jsonSchema');
import {JSONCompletion} from '../jsonCompletion';
import {XHROptions, XHRResponse} from 'request-light';
-import {CompletionItem, CompletionItemKind, CompletionOptions, ITextDocument, TextDocumentIdentifier, TextDocumentPosition, Range, Position, TextEdit} from 'vscode-languageserver';
+import {CompletionItem, CompletionItemKind, CompletionOptions, TextDocument, TextDocumentIdentifier, Range, Position, TextEdit} from 'vscode-languageserver';
import {applyEdits} from './textEditSupport';
suite('JSON Completion', () => {
@@ -20,7 +20,7 @@ suite('JSON Completion', () => {
return Promise.reject({ responseText: '', status: 404 });
}
- var assertSuggestion = function(completions: CompletionItem[], label: string, documentation?: string, document?: ITextDocument, resultText?: string) {
+ var assertSuggestion = function(completions: CompletionItem[], label: string, documentation?: string, document?: TextDocument, resultText?: string) {
var matches = completions.filter(function(completion: CompletionItem) {
return completion.label === label && (!documentation || completion.documentation === documentation);
});
@@ -31,7 +31,7 @@ suite('JSON Completion', () => {
};
- var testSuggestionsFor = function(value: string, stringAfter: string, schema: JsonSchema.IJSONSchema, test: (items: CompletionItem[], document: ITextDocument) => void) : Thenable {
+ var testSuggestionsFor = function(value: string, stringAfter: string, schema: JsonSchema.IJSONSchema, test: (items: CompletionItem[], document: TextDocument) => void) : Thenable {
var uri = 'test://test.json';
var idx = stringAfter ? value.indexOf(stringAfter) : 0;
@@ -42,10 +42,10 @@ suite('JSON Completion', () => {
schemaService.registerExternalSchema(id, ["*.json"], schema);
}
- var document = ITextDocument.create(uri, value);
- var textDocumentLocation = TextDocumentPosition.create(uri, Position.create(0, idx));
+ var document = TextDocument.create(uri, 'json', 0, value);
+ var position = Position.create(0, idx);
var jsonDoc = Parser.parse(value);
- return completionProvider.doSuggest(document, textDocumentLocation, jsonDoc).then(list => list.items).then(completions => {
+ return completionProvider.doSuggest(document, position, jsonDoc).then(list => list.items).then(completions => {
test(completions, document);
return null;
})
diff --git a/extensions/json/server/src/test/documentSymbols.test.ts b/extensions/json/server/src/test/documentSymbols.test.ts
index 6f27e9134e4..2e41c69b852 100644
--- a/extensions/json/server/src/test/documentSymbols.test.ts
+++ b/extensions/json/server/src/test/documentSymbols.test.ts
@@ -11,7 +11,7 @@ import JsonSchema = require('../jsonSchema');
import {JSONCompletion} from '../jsonCompletion';
import {JSONDocumentSymbols} from '../jsonDocumentSymbols';
-import {SymbolInformation, SymbolKind, TextDocumentIdentifier, ITextDocument, TextDocumentPosition, Range, Position, TextEdit} from 'vscode-languageserver';
+import {SymbolInformation, SymbolKind, TextDocumentIdentifier, TextDocument, Range, Position, TextEdit} from 'vscode-languageserver';
suite('JSON Document Symbols', () => {
@@ -20,7 +20,7 @@ suite('JSON Document Symbols', () => {
var symbolProvider = new JSONDocumentSymbols();
- var document = ITextDocument.create(uri, value);
+ var document = TextDocument.create(uri, 'json', 0, value);
var jsonDoc = Parser.parse(value);
return symbolProvider.compute(document, jsonDoc);
}
diff --git a/extensions/json/server/src/test/formatter.test.ts b/extensions/json/server/src/test/formatter.test.ts
index 5254ee88b57..a1e367ecc10 100644
--- a/extensions/json/server/src/test/formatter.test.ts
+++ b/extensions/json/server/src/test/formatter.test.ts
@@ -5,7 +5,7 @@
'use strict';
import Json = require('jsonc-parser');
-import {ITextDocument, DocumentFormattingParams, Range, Position, FormattingOptions, TextEdit} from 'vscode-languageserver';
+import {TextDocument, DocumentFormattingParams, Range, Position, FormattingOptions, TextEdit} from 'vscode-languageserver';
import Formatter = require('../jsonFormatter');
import assert = require('assert');
import {applyEdits} from './textEditSupport';
@@ -20,14 +20,14 @@ suite('JSON Formatter', () => {
let rangeEnd = unformatted.lastIndexOf('|');
if (rangeStart !== -1 && rangeEnd !== -1) {
// remove '|'
- var unformattedDoc = ITextDocument.create(uri, unformatted);
+ var unformattedDoc = TextDocument.create(uri, 'json', 0, unformatted);
unformatted = unformatted.substring(0, rangeStart) + unformatted.substring(rangeStart + 1, rangeEnd) + unformatted.substring(rangeEnd + 1);
let startPos = unformattedDoc.positionAt(rangeStart);
let endPos = unformattedDoc.positionAt(rangeEnd);
range = Range.create(startPos, endPos);
}
- var document = ITextDocument.create(uri, unformatted);
+ var document = TextDocument.create(uri, 'json', 0, unformatted);
let edits = Formatter.format(document, range, { tabSize: 2, insertSpaces: insertSpaces });
let formatted = applyEdits(document, edits);
assert.equal(formatted, expected);
@@ -308,7 +308,7 @@ suite('JSON Formatter', () => {
format(content, expected);
});
-
+
test('multiple mixed comments on same line', () => {
var content = [
'[ /*comment*/ /*comment*/ // comment ',
diff --git a/extensions/json/server/src/test/hover.test.ts b/extensions/json/server/src/test/hover.test.ts
index c442801d144..8315e6a5cda 100644
--- a/extensions/json/server/src/test/hover.test.ts
+++ b/extensions/json/server/src/test/hover.test.ts
@@ -12,7 +12,7 @@ import {JSONCompletion} from '../jsonCompletion';
import {XHROptions, XHRResponse} from 'request-light';
import {JSONHover} from '../jsonHover';
-import {Hover, ITextDocument, TextDocumentIdentifier, TextDocumentPosition, Range, Position, TextEdit} from 'vscode-languageserver';
+import {Hover, TextDocument, TextDocumentIdentifier, TextDocumentPositionParams, Range, Position, TextEdit} from 'vscode-languageserver';
suite('JSON Hover', () => {
@@ -24,10 +24,9 @@ suite('JSON Hover', () => {
var id = "http://myschemastore/test1";
schemaService.registerExternalSchema(id, ["*.json"], schema);
- var document = ITextDocument.create(uri, value);
- var textDocumentLocation = TextDocumentPosition.create(uri, position);
+ var document = TextDocument.create(uri, 'json', 0, value);
var jsonDoc = Parser.parse(value);
- return hoverProvider.doHover(document, textDocumentLocation, jsonDoc);
+ return hoverProvider.doHover(document, position, jsonDoc);
}
var requestService = function(options: XHROptions): Promise {
diff --git a/extensions/json/server/src/test/textEditSupport.ts b/extensions/json/server/src/test/textEditSupport.ts
index 5f04be02f3c..9160177f756 100644
--- a/extensions/json/server/src/test/textEditSupport.ts
+++ b/extensions/json/server/src/test/textEditSupport.ts
@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
-import {ITextDocument, TextEdit} from 'vscode-languageserver';
+import {TextDocument, TextEdit} from 'vscode-languageserver';
import assert = require('assert');
-export function applyEdits(document: ITextDocument, edits: TextEdit[]) : string {
+export function applyEdits(document: TextDocument, edits: TextEdit[]) : string {
let formatted = document.getText();
let sortedEdits = edits.sort((a, b) => document.offsetAt(b.range.start) - document.offsetAt(a.range.start));
let lastOffset = formatted.length;
diff --git a/extensions/typescript/src/features/bufferSyncSupport.ts b/extensions/typescript/src/features/bufferSyncSupport.ts
index 1e6e9e60c90..89ade4b5e1a 100644
--- a/extensions/typescript/src/features/bufferSyncSupport.ts
+++ b/extensions/typescript/src/features/bufferSyncSupport.ts
@@ -2,9 +2,10 @@
* 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 fs from 'fs';
+
import { workspace, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Disposable } from 'vscode';
import * as Proto from '../protocol';
import { ITypescriptServiceClient } from '../typescriptService';
@@ -67,12 +68,17 @@ class SyncedBuffer {
}
}
+export interface Diagnostics {
+ delete(file: string): void;
+}
+
export default class BufferSyncSupport {
private client: ITypescriptServiceClient;
private _validate: boolean;
private modeIds: Map;
+ private diagnostics: Diagnostics;
private disposables: Disposable[] = [];
private syncedBuffers: Map;
private closedFiles: Map;
@@ -80,10 +86,11 @@ export default class BufferSyncSupport {
private pendingDiagnostics: { [key: string]: number; };
private diagnosticDelayer: Delayer;
- constructor(client: ITypescriptServiceClient, modeIds: string[], validate: boolean = true) {
+ constructor(client: ITypescriptServiceClient, modeIds: string[], diagnostics: Diagnostics, validate: boolean = true) {
this.client = client;
this.modeIds = Object.create(null);
modeIds.forEach(modeId => this.modeIds[modeId] = true);
+ this.diagnostics = diagnostics;
this._validate = validate;
this.pendingDiagnostics = Object.create(null);
@@ -94,10 +101,23 @@ export default class BufferSyncSupport {
}
public listen(): void {
- workspace.onDidOpenTextDocument(this.onDidAddDocument, this, this.disposables);
- workspace.onDidCloseTextDocument(this.onDidRemoveDocument, this, this.disposables);
- workspace.onDidChangeTextDocument(this.onDidChangeDocument, this, this.disposables);
- workspace.textDocuments.forEach(this.onDidAddDocument, this);
+ workspace.onDidOpenTextDocument(this.onDidOpenTextDocument, this, this.disposables);
+ workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this.disposables);
+ workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this.disposables);
+ workspace.textDocuments.forEach(this.onDidOpenTextDocument, this);
+ workspace.createFileSystemWatcher('**/*', true, true, false).onDidDelete((resource) => {
+ let filepath = this.client.asAbsolutePath(resource);
+ if (!filepath) {
+ return;
+ }
+ if (!this.syncedBuffers[filepath]) {
+ // The file is not synced (open in an editor) and got
+ // removed from disk. Make sure it is not in the closedFiles
+ // list since we shouldn't revalidate it.
+ delete this.closedFiles[filepath];
+ this.diagnostics.delete(filepath);
+ }
+ });
}
public get validate(): boolean {
@@ -124,7 +144,7 @@ export default class BufferSyncSupport {
}
}
- private onDidAddDocument(document: TextDocument): void {
+ private onDidOpenTextDocument(document: TextDocument): void {
if (!this.modeIds[document.languageId]) {
return;
}
@@ -143,7 +163,7 @@ export default class BufferSyncSupport {
this.requestDiagnostic(filepath);
}
- private onDidRemoveDocument(document: TextDocument): void {
+ private onDidCloseTextDocument(document: TextDocument): void {
let filepath: string = this.client.asAbsolutePath(document.uri);
if (!filepath) {
return;
@@ -152,12 +172,19 @@ export default class BufferSyncSupport {
if (!syncedBuffer) {
return;
}
- this.closedFiles[filepath] = true;
+ // If the file still exists on disk keep on validating the file.
+ if (fs.existsSync(filepath)) {
+ this.closedFiles[filepath] = true;
+ } else {
+ // Ensure we don't have the file in the map and clear all errors.
+ delete this.closedFiles[filepath];
+ this.diagnostics.delete(filepath);
+ }
delete this.syncedBuffers[filepath];
syncedBuffer.close();
}
- private onDidChangeDocument(e: TextDocumentChangeEvent): void {
+ private onDidChangeTextDocument(e: TextDocumentChangeEvent): void {
let filepath: string = this.client.asAbsolutePath(e.document.uri);
if (!filepath) {
return;
diff --git a/extensions/typescript/src/typescriptMain.ts b/extensions/typescript/src/typescriptMain.ts
index 0f88c6beede..57e05ea5ac4 100644
--- a/extensions/typescript/src/typescriptMain.ts
+++ b/extensions/typescript/src/typescriptMain.ts
@@ -98,7 +98,11 @@ class LanguageProvider {
this.description = description;
this._validate = true;
- this.bufferSyncSupport = new BufferSyncSupport(client, description.modeIds);
+ this.bufferSyncSupport = new BufferSyncSupport(client, description.modeIds, {
+ delete: (file: string) => {
+ this.currentDiagnostics.delete(Uri.file(file));
+ }
+ });
this.syntaxDiagnostics = Object.create(null);
this.currentDiagnostics = languages.createDiagnosticCollection(description.id);
diff --git a/extensions/vscode-api-tests/src/editor.test.ts b/extensions/vscode-api-tests/src/editor.test.ts
index 13388234f78..0dc0bf124e0 100644
--- a/extensions/vscode-api-tests/src/editor.test.ts
+++ b/extensions/vscode-api-tests/src/editor.test.ts
@@ -6,13 +6,10 @@
'use strict';
import * as assert from 'assert';
-import * as fs from 'fs';
-import * as os from 'os';
import {workspace, window, Position, Range} from 'vscode';
import {createRandomFile, deleteFile, cleanUp} from './utils';
-import {join} from 'path';
-suite("editor tests", () => {
+suite('editor tests', () => {
teardown(cleanUp);
diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts
index 0c0e944ddf2..68b84190f41 100644
--- a/src/vs/base/common/async.ts
+++ b/src/vs/base/common/async.ts
@@ -572,7 +572,7 @@ export class RunOnceScheduler {
*/
schedule(delay = this.timeout): void {
this.cancel();
- this.timeoutToken = platform.setTimeout(this.timeoutHandler, this.timeout);
+ this.timeoutToken = platform.setTimeout(this.timeoutHandler, delay);
}
/**
diff --git a/src/vs/base/common/paths.ts b/src/vs/base/common/paths.ts
index 908cf68781e..dbba825648e 100644
--- a/src/vs/base/common/paths.ts
+++ b/src/vs/base/common/paths.ts
@@ -77,139 +77,75 @@ export function extname(path: string): string {
return idx ? path.substring(~idx) : '';
}
-export function normalize2(path: string, toOSPath: boolean): string {
+const _posixBadPath = /(\/\.\.?\/)|(\/\.\.?)$|^(\.\.?\/)|(\/\/+)|(\\)/;
+const _winBadPath = /(\\\.\.?\\)|(\\\.\.?)$|^(\.\.?\\)|(\\\\+)|(\/)/;
- if (path === null || path === void 0) {
- return path;
- }
-
- let len = path.length;
- if (len === 0) {
- return '.';
- }
-
- const sep = isWindows && toOSPath ? '\\' : '/';
- const root = getRoot(path, sep);
-
- let lastCode = -1;
-
- for (let pos = root.length; pos < len; pos++) {
- let code = path.charCodeAt(pos);
- if (code === 64/*.*/) {
-
- if (lastCode === -1 || lastCode === 47 || lastCode === 92) {
-
- if (pos + 1 < len) {
- code = path.charCodeAt(++pos);
- if (code === 47 || code === 92) {
-
- }
- }
- }
- }
- }
+function _isNormal(path: string, win: boolean): boolean {
+ return win
+ ? !_winBadPath.test(path)
+ : !_posixBadPath.test(path);
}
-function _isNormal(path: string, badSep: number): boolean {
- let lastCode = -1;
- for (let pos = 0; pos < path.length; pos++) {
- let code = path.charCodeAt(pos);
- // bad separator
- if (code === badSep) {
- return false;
- }
- // double separator
- if ((code === _slash || code === _backslash)
- && (lastCode === _slash || lastCode === _backslash)) {
-
- return false;
- }
- // ./ ../ segments
- if (code === _dot && (lastCode === -1 || lastCode === _slash || lastCode === _backslash)) {
- if (pos + 1 >= path.length) {
- // /.
- return false;
- }
- code = path.charCodeAt(++pos);
- if (code === _slash || code === _backslash) {
- // /./
- return false;
-
- } else if (code === _dot) {
- if (pos + 1 >= path.length) {
- // /..
- return false;
- }
- code = path.charCodeAt(++pos);
- if (code === _slash || code === _backslash) {
- // /../
- return false;
- }
- }
- }
- lastCode = code;
- }
- return true;
-}
-
-
export function normalize(path: string, toOSPath?: boolean): string {
if (path === null || path === void 0) {
return path;
}
- let len = path.length;
+ const len = path.length;
if (len === 0) {
return '.';
}
- if (_isNormal(path, isWindows && toOSPath ? _slash : _backslash)) {
+ const wantsBackslash = isWindows && toOSPath;
+ if (_isNormal(path, wantsBackslash)) {
return path;
}
- // operate on the 'path-portion' only
- const sep = isWindows && toOSPath ? '\\' : '/';
+ const sep = wantsBackslash ? '\\' : '/';
const root = getRoot(path, sep);
- path = path.slice(root.length);
- len -= root.length;
+ // skip the root-portion of the path
+ let start = root.length;
+ let skip = false;
let res = '';
- let start = 0;
- for (let end = 0; end <= len; end++) {
+ for (let end = root.length; end <= len; end++) {
// either at the end or at a path-separator character
if (end === len || path.charCodeAt(end) === _slash || path.charCodeAt(end) === _backslash) {
- let part = path.slice(start, end);
- start = end + 1;
-
- if (part === '.' && (root || res || end < len - 1)) {
- // skip current (if there is already something or if there is more to come)
- continue;
- }
-
- if (part === '..') {
+ if (streql(path, start, end, '..')) {
// skip current and remove parent (if there is already something)
let prev_start = res.lastIndexOf(sep);
let prev_part = res.slice(prev_start + 1);
if ((root || prev_part.length > 0) && prev_part !== '..') {
res = prev_start === -1 ? '' : res.slice(0, prev_start);
- continue;
+ skip = true;
}
+ } else if (streql(path, start, end, '.') && (root || res || end < len - 1)) {
+ // skip current (if there is already something or if there is more to come)
+ skip = true;
}
- if (res !== '' && res[res.length - 1] !== sep) {
- res += sep;
+ if (!skip) {
+ let part = path.slice(start, end);
+ if (res !== '' && res[res.length - 1] !== sep) {
+ res += sep;
+ }
+ res += part;
}
- res += part;
+ start = end + 1;
}
}
return root + res;
}
+function streql(value: string, start: number, end: number, other: string): boolean {
+ return start + other.length === end && value.indexOf(other, start) === start;
+}
+
/**
* Computes the _root_ this path, like `getRoot('c:\files') === c:\`,
* `getRoot('files:///files/path') === files:///`,
@@ -374,7 +310,6 @@ export function isRelative(path: string): boolean {
const _slash = '/'.charCodeAt(0);
const _backslash = '\\'.charCodeAt(0);
const _colon = ':'.charCodeAt(0);
-const _dot = '.'.charCodeAt(0);
const _a = 'a'.charCodeAt(0);
const _A = 'A'.charCodeAt(0);
const _z = 'z'.charCodeAt(0);
diff --git a/src/vs/editor/browser/standalone/standaloneEditor.ts b/src/vs/editor/browser/standalone/standaloneEditor.ts
index 3f2d71ec5b9..66a1189da9a 100644
--- a/src/vs/editor/browser/standalone/standaloneEditor.ts
+++ b/src/vs/editor/browser/standalone/standaloneEditor.ts
@@ -20,8 +20,6 @@ import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {IModel} from 'vs/editor/common/editorCommon';
-import {ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
-import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
import {IModelService} from 'vs/editor/common/services/modelService';
import {ICodeEditor, IDiffEditor} from 'vs/editor/browser/editorBrowser';
import {Colorizer, IColorizerElementOptions, IColorizerOptions} from 'vs/editor/browser/standalone/colorizer';
@@ -208,35 +206,6 @@ export function configureMode(modeId: string, options: any): void {
modeService.configureModeById(modeId, options);
}
-/**
- * @internal
- */
-export function createCustomMode(language:ILanguage): TPromise {
- startup.initStaticServicesIfNecessary();
- let staticPlatformServices = ensureStaticPlatformServices(null);
- let modeService = staticPlatformServices.modeService;
- let modelService = staticPlatformServices.modelService;
- let editorWorkerService = staticPlatformServices.editorWorkerService;
-
- let modeId = language.name;
- let name = language.name;
-
- ModesRegistry.registerLanguage({
- id: modeId,
- aliases: [name]
- });
-
- let disposable = modeService.onDidCreateMode((mode) => {
- if (mode.getId() !== modeId) {
- return;
- }
- modeService.registerMonarchDefinition(modelService, editorWorkerService, modeId, language);
- disposable.dispose();
- });
-
- return modeService.getOrCreateMode(modeId);
-}
-
interface IMonacoWebWorkerState {
myProxy:StandaloneWorker;
foreignProxy:T;
@@ -345,8 +314,6 @@ export function createMonacoEditorAPI(): typeof monaco.editor {
onDidChangeModelLanguage: onDidChangeModelLanguage,
- // getOrCreateMode: getOrCreateMode,
- // createCustomMode: createCustomMode,
createWebWorker: createWebWorker,
colorizeElement: colorizeElement,
colorize: colorize,
diff --git a/src/vs/editor/browser/standalone/standaloneLanguages.ts b/src/vs/editor/browser/standalone/standaloneLanguages.ts
index 49e0ca3d876..88bf600d1c4 100644
--- a/src/vs/editor/browser/standalone/standaloneLanguages.ts
+++ b/src/vs/editor/browser/standalone/standaloneLanguages.ts
@@ -17,12 +17,15 @@ import {ILanguageExtensionPoint} from 'vs/editor/common/services/modeService';
import {ensureStaticPlatformServices} from 'vs/editor/browser/standalone/standaloneServices';
import * as modes from 'vs/editor/common/modes';
import {startup} from './standaloneCodeEditor';
-import {IRichLanguageConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
+import {IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {CancellationToken} from 'vs/base/common/cancellation';
import {toThenable} from 'vs/base/common/async';
+import {compile} from 'vs/editor/common/modes/monarch/monarchCompile';
+import {createTokenizationSupport} from 'vs/editor/common/modes/monarch/monarchLexer';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export function register(language:ILanguageExtensionPoint): void {
ModesRegistry.registerLanguage(language);
@@ -48,9 +51,7 @@ export function onLanguage(languageId:string, callback:()=>void): IDisposable {
}
export function setLanguageConfiguration(languageId:string, configuration:IRichLanguageConfiguration): IDisposable {
- startup.initStaticServicesIfNecessary();
- let staticPlatformServices = ensureStaticPlatformServices(null);
- return staticPlatformServices.modeService.registerRichEditSupport(languageId, configuration);
+ return LanguageConfigurationRegistry.register(languageId, configuration);
}
export function setTokensProvider(languageId:string, support:modes.TokensProvider): IDisposable {
@@ -295,7 +296,7 @@ export function registerMonarchStandaloneLanguage(language:ILanguageExtensionPoi
ModesRegistry.registerLanguage(language);
ExtensionsRegistry.registerOneTimeActivationEventListener('onLanguage:' + language.id, () => {
- require([defModule], (value:{language:ILanguage}) => {
+ require([defModule], (value:{language:ILanguage;conf:IRichLanguageConfiguration}) => {
if (!value.language) {
console.error('Expected ' + defModule + ' to export a `language`');
return;
@@ -304,10 +305,14 @@ export function registerMonarchStandaloneLanguage(language:ILanguageExtensionPoi
startup.initStaticServicesIfNecessary();
let staticPlatformServices = ensureStaticPlatformServices(null);
let modeService = staticPlatformServices.modeService;
- let modelService = staticPlatformServices.modelService;
- let editorWorkerService = staticPlatformServices.editorWorkerService;
- modeService.registerMonarchDefinition(modelService, editorWorkerService, language.id, value.language);
+ let lexer = compile(language.id, value.language);
+
+ modeService.registerTokenizationSupport(language.id, (mode) => {
+ return createTokenizationSupport(modeService, mode, lexer);
+ });
+
+ LanguageConfigurationRegistry.register(language.id, value.conf);
}, (err) => {
console.error('Cannot find module ' + defModule, err);
});
diff --git a/src/vs/editor/common/commands/shiftCommand.ts b/src/vs/editor/common/commands/shiftCommand.ts
index 7d5bdbcab7a..63e2e77aee6 100644
--- a/src/vs/editor/common/commands/shiftCommand.ts
+++ b/src/vs/editor/common/commands/shiftCommand.ts
@@ -9,7 +9,7 @@ import {CursorMoveHelper} from 'vs/editor/common/controller/cursorMoveHelper';
import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import {ICommand, ICursorStateComputerData, IEditOperationBuilder, ITokenizedModel} from 'vs/editor/common/editorCommon';
-import {getRawEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface IShiftCommandOpts {
isUnshift: boolean;
@@ -101,7 +101,7 @@ export class ShiftCommand implements ICommand {
if (contentStartVisibleColumn % tabSize !== 0) {
// The current line is "miss-aligned", so let's see if this is expected...
// This can only happen when it has trailing commas in the indent
- let enterAction = getRawEnterActionAtPosition(model, lineNumber - 1, model.getLineMaxColumn(lineNumber - 1));
+ let enterAction = LanguageConfigurationRegistry.getRawEnterActionAtPosition(model, lineNumber - 1, model.getLineMaxColumn(lineNumber - 1));
if (enterAction) {
extraSpaces = previousLineExtraSpaces;
if (enterAction.appendText) {
diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts
index be45e38ff64..4e3265c38f5 100644
--- a/src/vs/editor/common/controller/cursor.ts
+++ b/src/vs/editor/common/controller/cursor.ts
@@ -16,6 +16,7 @@ import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IColumnSelectResult} from 'vs/editor/common/controller/cursorMoveHelper';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface ITypingListener {
(): void;
@@ -140,8 +141,8 @@ export class Cursor extends EventEmitter {
this.modelUnbinds.push(this.model.onDidChangeMode((e) => {
this._onModelModeChanged();
}));
- this.modelUnbinds.push(this.model.onDidChangeModeSupport((e) => {
- // TODO@Alex: react only if certain supports changed?
+ this.modelUnbinds.push(LanguageConfigurationRegistry.onDidChange(() => {
+ // TODO@Alex: react only if certain supports changed? (and if my model's mode changed)
this._onModelModeChanged();
}));
diff --git a/src/vs/editor/common/controller/cursorCollection.ts b/src/vs/editor/common/controller/cursorCollection.ts
index 395273ddfcf..f2f977ffbc5 100644
--- a/src/vs/editor/common/controller/cursorCollection.ts
+++ b/src/vs/editor/common/controller/cursorCollection.ts
@@ -10,6 +10,7 @@ import {Selection} from 'vs/editor/common/core/selection';
import {IConfiguration, IModel, ISelection} from 'vs/editor/common/editorCommon';
import {IAutoClosingPair} from 'vs/editor/common/modes';
import {Position} from 'vs/editor/common/core/position';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface ICursorCollectionState {
primary: IOneCursorState;
@@ -326,51 +327,50 @@ export class CursorCollection {
surroundingPairs: {}
};
- let richEditSupport = this.model.getMode().richEditSupport;
- let electricChars: string[];
- if (richEditSupport && richEditSupport.electricCharacter) {
+ let electricCharSupport = LanguageConfigurationRegistry.getElectricCharacterSupport(this.model.getMode().getId());
+ if (electricCharSupport) {
+ let electricChars: string[] = null;
try {
- electricChars = richEditSupport.electricCharacter.getElectricCharacters();
+ electricChars = electricCharSupport.getElectricCharacters();
} catch(e) {
onUnexpectedError(e);
electricChars = null;
}
- }
- if (electricChars) {
- for (i = 0; i < electricChars.length; i++) {
- result.electricChars[electricChars[i]] = true;
+ if (electricChars) {
+ for (i = 0; i < electricChars.length; i++) {
+ result.electricChars[electricChars[i]] = true;
+ }
}
}
- let autoClosingPairs: IAutoClosingPair[];
- if (richEditSupport && richEditSupport.characterPair) {
+ let characterPairSupport = LanguageConfigurationRegistry.getCharacterPairSupport(this.model.getMode().getId());
+ if (characterPairSupport) {
+ let autoClosingPairs: IAutoClosingPair[];
try {
- autoClosingPairs = richEditSupport.characterPair.getAutoClosingPairs();
+ autoClosingPairs = characterPairSupport.getAutoClosingPairs();
} catch(e) {
onUnexpectedError(e);
autoClosingPairs = null;
}
- }
- if (autoClosingPairs) {
- for (i = 0; i < autoClosingPairs.length; i++) {
- result.autoClosingPairsOpen[autoClosingPairs[i].open] = autoClosingPairs[i].close;
- result.autoClosingPairsClose[autoClosingPairs[i].close] = autoClosingPairs[i].open;
+ if (autoClosingPairs) {
+ for (i = 0; i < autoClosingPairs.length; i++) {
+ result.autoClosingPairsOpen[autoClosingPairs[i].open] = autoClosingPairs[i].close;
+ result.autoClosingPairsClose[autoClosingPairs[i].close] = autoClosingPairs[i].open;
+ }
}
- }
- let surroundingPairs: IAutoClosingPair[];
- if (richEditSupport && richEditSupport.characterPair) {
+ let surroundingPairs: IAutoClosingPair[];
try {
- surroundingPairs = richEditSupport.characterPair.getSurroundingPairs();
+ surroundingPairs = characterPairSupport.getSurroundingPairs();
} catch(e) {
onUnexpectedError(e);
surroundingPairs = null;
}
- }
- if (surroundingPairs) {
- for (i = 0; i < surroundingPairs.length; i++) {
- result.surroundingPairs[surroundingPairs[i].open] = surroundingPairs[i].close;
+ if (surroundingPairs) {
+ for (i = 0; i < surroundingPairs.length; i++) {
+ result.surroundingPairs[surroundingPairs[i].open] = surroundingPairs[i].close;
+ }
}
}
diff --git a/src/vs/editor/common/controller/oneCursor.ts b/src/vs/editor/common/controller/oneCursor.ts
index 1764dc4bbfc..2551c7e4aa3 100644
--- a/src/vs/editor/common/controller/oneCursor.ts
+++ b/src/vs/editor/common/controller/oneCursor.ts
@@ -15,7 +15,7 @@ import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IElectricAction, IndentAction} from 'vs/editor/common/modes';
-import {getEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface IPostOperationRunnable {
(ctx: IOneCursorOperationContext): void;
@@ -1196,7 +1196,7 @@ export class OneCursorOp {
}
ctx.shouldPushStackElementBefore = true;
- let r = getEnterActionAtPosition(cursor.model, position.lineNumber, position.column);
+ let r = LanguageConfigurationRegistry.getEnterActionAtPosition(cursor.model, position.lineNumber, position.column);
let enterAction = r.enterAction;
let indentation = r.indentation;
@@ -1269,9 +1269,9 @@ export class OneCursorOp {
return false;
}
- let richEditSupport = cursor.model.getMode().richEditSupport;
+ let characterPairSupport = LanguageConfigurationRegistry.getCharacterPairSupport(cursor.model.getMode().getId());
- if(!richEditSupport || !richEditSupport.characterPair) {
+ if(!characterPairSupport) {
return false;
}
@@ -1297,7 +1297,7 @@ export class OneCursorOp {
let shouldAutoClosePair = false;
try {
- shouldAutoClosePair = richEditSupport.characterPair.shouldAutoClosePair(ch, lineContext, position.column - 1);
+ shouldAutoClosePair = characterPairSupport.shouldAutoClosePair(ch, lineContext, position.column - 1);
} catch(e) {
onUnexpectedError(e);
}
@@ -1380,10 +1380,10 @@ export class OneCursorOp {
let lineContext = cursor.model.getLineContext(position.lineNumber);
let electricAction:IElectricAction;
- let richEditSupport = cursor.model.getMode().richEditSupport;
- if(richEditSupport && richEditSupport.electricCharacter) {
+ let electricCharSupport = LanguageConfigurationRegistry.getElectricCharacterSupport(cursor.model.getMode().getId());
+ if (electricCharSupport) {
try {
- electricAction = richEditSupport.electricCharacter.onElectricCharacter(lineContext, position.column - 2);
+ electricAction = electricCharSupport.onElectricCharacter(lineContext, position.column - 2);
} catch(e) {
onUnexpectedError(e);
}
@@ -1488,7 +1488,7 @@ export class OneCursorOp {
return '\t';
}
- let r = getEnterActionAtPosition(cursor.model, lastLineNumber, cursor.model.getLineMaxColumn(lastLineNumber));
+ let r = LanguageConfigurationRegistry.getEnterActionAtPosition(cursor.model, lastLineNumber, cursor.model.getLineMaxColumn(lastLineNumber));
let indentation: string;
if (r.enterAction.indentAction === IndentAction.Outdent) {
diff --git a/src/vs/editor/common/core/modeTransition.ts b/src/vs/editor/common/core/modeTransition.ts
index 33882fa2084..77cfa4b45b6 100644
--- a/src/vs/editor/common/core/modeTransition.ts
+++ b/src/vs/editor/common/core/modeTransition.ts
@@ -12,10 +12,12 @@ export class ModeTransition {
public startIndex:number;
public mode:IMode;
+ public modeId: string;
constructor(startIndex:number, mode:IMode) {
this.startIndex = startIndex|0;
this.mode = mode;
+ this.modeId = mode.getId();
}
public static findIndexInSegmentsArray(arr:ModeTransition[], desiredIndex: number): number {
diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts
index 3de5cc1824a..4bab8cced1d 100644
--- a/src/vs/editor/common/editorCommon.ts
+++ b/src/vs/editor/common/editorCommon.ts
@@ -10,13 +10,14 @@ import {IHTMLContentElement} from 'vs/base/common/htmlContent';
import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {IInstantiationService, IConstructorSignature1, IConstructorSignature2} from 'vs/platform/instantiation/common/instantiation';
-import {ILineContext, IMode, IModeTransition, IToken} from 'vs/editor/common/modes';
+import {ILineContext, IMode, IToken} from 'vs/editor/common/modes';
import {ViewLineToken} from 'vs/editor/common/core/viewLineToken';
import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import {IDisposable} from 'vs/base/common/lifecycle';
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
+import {ModeTransition} from 'vs/editor/common/core/modeTransition';
/**
* @internal
@@ -953,7 +954,6 @@ export interface IConfigurationChangedEvent {
*/
export interface IModeSupportChangedEvent {
tokenizationSupport:boolean;
- richEditSupport: boolean;
}
/**
@@ -1677,7 +1677,7 @@ export interface ITokenizedModel extends ITextModel {
/**
* @internal
*/
- _getLineModeTransitions(lineNumber:number): IModeTransition[];
+ _getLineModeTransitions(lineNumber:number): ModeTransition[];
/**
* Get the current language mode associated with the model.
@@ -1702,7 +1702,7 @@ export interface ITokenizedModel extends ITextModel {
* Returns the true (inner-most) language mode at a given position.
* @internal
*/
- getModeAtPosition(lineNumber:number, column:number): IMode;
+ getModeIdAtPosition(lineNumber:number, column:number): string;
/**
* Get the word under or besides `position`.
diff --git a/src/vs/editor/common/languages.common.ts b/src/vs/editor/common/languages.common.ts
index 76bf17a9d9b..8268267aea3 100644
--- a/src/vs/editor/common/languages.common.ts
+++ b/src/vs/editor/common/languages.common.ts
@@ -33,10 +33,9 @@ import 'vs/editor/common/modes';
import 'vs/editor/common/modes/abstractMode';
import 'vs/editor/common/modes/abstractState';
import 'vs/editor/common/modes/monarch/monarchCommon';
-import 'vs/editor/common/modes/monarch/monarchDefinition';
import 'vs/editor/common/modes/monarch/monarchLexer';
import 'vs/editor/common/modes/monarch/monarchCompile';
-import 'vs/editor/common/modes/supports/richEditSupport';
+import 'vs/editor/common/modes/languageConfigurationRegistry';
import 'vs/editor/common/modes/supports/suggestSupport';
import 'vs/editor/common/modes/supports/tokenizationSupport';
import 'vs/editor/common/services/modelService';
diff --git a/src/vs/editor/common/model/mirrorModel.ts b/src/vs/editor/common/model/mirrorModel.ts
index f0d67503968..a6772272684 100644
--- a/src/vs/editor/common/model/mirrorModel.ts
+++ b/src/vs/editor/common/model/mirrorModel.ts
@@ -255,9 +255,9 @@ export class MirrorModel extends AbstractMirrorModel implements editorCommon.IMi
}
public getEmbeddedAtPosition(position:editorCommon.IPosition):editorCommon.IMirrorModel {
- var modeAtPosition = this.getModeAtPosition(position.lineNumber, position.column);
- if (this._embeddedModels.hasOwnProperty(modeAtPosition.getId())) {
- return this._embeddedModels[modeAtPosition.getId()];
+ var modeIdAtPosition = this.getModeIdAtPosition(position.lineNumber, position.column);
+ if (this._embeddedModels.hasOwnProperty(modeIdAtPosition)) {
+ return this._embeddedModels[modeIdAtPosition];
}
return null;
}
@@ -299,7 +299,7 @@ export class MirrorModel extends AbstractMirrorModel implements editorCommon.IMi
for (var i = 0; i < modeTransitions.length; i++) {
var modeTransition = modeTransitions[i];
- if (modeTransition.mode.getId() !== currentModeId) {
+ if (modeTransition.modeId !== currentModeId) {
var modeRange = getOrCreateEmbeddedModeRange(currentModeId, currentMode);
modeRange.ranges.push({
@@ -309,7 +309,7 @@ export class MirrorModel extends AbstractMirrorModel implements editorCommon.IMi
endColumn: modeTransition.startIndex + 1
});
- currentModeId = modeTransition.mode.getId();
+ currentModeId = modeTransition.modeId;
currentMode = modeTransition.mode;
currentStartLineNumber = lineNumber;
currentStartColumn = modeTransition.startIndex + 1;
diff --git a/src/vs/editor/common/model/textModelWithTokens.ts b/src/vs/editor/common/model/textModelWithTokens.ts
index fd8b9739a3f..ff3c5dc9da8 100644
--- a/src/vs/editor/common/model/textModelWithTokens.ts
+++ b/src/vs/editor/common/model/textModelWithTokens.ts
@@ -25,6 +25,7 @@ import {ModeTransition} from 'vs/editor/common/core/modeTransition';
import {LineToken} from 'vs/editor/common/model/lineToken';
import {TokensInflatorMap} from 'vs/editor/common/model/tokensBinaryEncoding';
import {Position} from 'vs/editor/common/core/position';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
class ModeToModelBinder implements IDisposable {
@@ -440,7 +441,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
}
}
- public getModeAtPosition(_lineNumber:number, _column:number): IMode {
+ public getModeIdAtPosition(_lineNumber:number, _column:number): string {
var validPosition = this.validatePosition({
lineNumber: _lineNumber,
column: _column
@@ -450,13 +451,13 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
var column = validPosition.column;
if (column === 1) {
- return this.getStateBeforeLine(lineNumber).getMode();
+ return this.getStateBeforeLine(lineNumber).getMode().getId();
} else if (column === this.getLineMaxColumn(lineNumber)) {
- return this.getStateAfterLine(lineNumber).getMode();
+ return this.getStateAfterLine(lineNumber).getMode().getId();
} else {
var modeTransitions = this._getLineModeTransitions(lineNumber);
var modeTransitionIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, column - 1);
- return modeTransitions[modeTransitionIndex].mode;
+ return modeTransitions[modeTransitionIndex].modeId;
}
}
@@ -761,7 +762,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let modeTransitions = this._lines[position.lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let currentMode = modeTransitions[currentModeIndex];
- let currentModeBrackets = currentMode.mode.richEditSupport ? currentMode.mode.richEditSupport.brackets : null;
+ let currentModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(currentMode.modeId);
if (!currentModeBrackets) {
return null;
@@ -791,7 +792,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
let currentMode = modeTransitions[currentModeIndex];
- let currentModeBrackets = currentMode.mode.richEditSupport ? currentMode.mode.richEditSupport.brackets : null;
+ let currentModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(currentMode.modeId);
// If position is in between two tokens, try first looking in the previous token
if (currentTokenIndex > 0 && currentTokenStart === position.column - 1) {
@@ -807,7 +808,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
// check if previous token is in a different mode
if (currentModeIndex > 0 && currentMode.startIndex === position.column - 1) {
prevMode = modeTransitions[currentModeIndex - 1];
- prevModeBrackets = prevMode.mode.richEditSupport ? prevMode.mode.richEditSupport.brackets : null;
+ prevModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(prevMode.modeId);
}
if (prevModeBrackets) {
@@ -897,7 +898,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = modeTransitions.length - 1;
let currentModeStart = modeTransitions[currentModeIndex].startIndex;
- let currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ let currentModeId = modeTransitions[currentModeIndex].modeId;
let tokensLength = lineTokens.getTokenCount() - 1;
let currentTokenEnd = lineText.length;
@@ -907,7 +908,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
currentModeStart = modeTransitions[currentModeIndex].startIndex;
- currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ currentModeId = modeTransitions[currentModeIndex].modeId;
}
for (let tokenIndex = tokensLength; tokenIndex >= 0; tokenIndex--) {
@@ -917,7 +918,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
if (currentTokenStart < currentModeStart) {
currentModeIndex--;
currentModeStart = modeTransitions[currentModeIndex].startIndex;
- currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ currentModeId = modeTransitions[currentModeIndex].modeId;
}
if (currentModeId === modeId && !ignoreBracketsInToken(currentTokenType)) {
@@ -964,7 +965,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode);
let currentModeIndex = 0;
let nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
- let currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ let currentModeId = modeTransitions[currentModeIndex].modeId;
let startTokenIndex = 0;
let currentTokenStart = lineTokens.getTokenStartIndex(startTokenIndex);
@@ -974,7 +975,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1);
nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
- currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ currentModeId = modeTransitions[currentModeIndex].modeId;
}
for (let tokenIndex = startTokenIndex, tokensLength = lineTokens.getTokenCount(); tokenIndex < tokensLength; tokenIndex++) {
@@ -984,7 +985,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
if (currentTokenStart >= nextModeStart) {
currentModeIndex++;
nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
- currentModeId = modeTransitions[currentModeIndex].mode.getId();
+ currentModeId = modeTransitions[currentModeIndex].modeId;
}
if (currentModeId === modeId && !ignoreBracketsInToken(currentTokenType)) {
diff --git a/src/vs/editor/common/model/textModelWithTokensHelpers.ts b/src/vs/editor/common/model/textModelWithTokensHelpers.ts
index c55991f1d49..63016ce25a4 100644
--- a/src/vs/editor/common/model/textModelWithTokensHelpers.ts
+++ b/src/vs/editor/common/model/textModelWithTokensHelpers.ts
@@ -8,6 +8,7 @@ import {IPosition, IWordAtPosition} from 'vs/editor/common/editorCommon';
import {IMode, IModeTransition} from 'vs/editor/common/modes';
import {NullMode} from 'vs/editor/common/modes/nullMode';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface ITextSource {
@@ -27,7 +28,7 @@ export interface INonWordTokenMap {
export class WordHelper {
private static _safeGetWordDefinition(mode:IMode): RegExp {
- return (mode.richEditSupport ? mode.richEditSupport.wordDefinition : null);
+ return LanguageConfigurationRegistry.getWordDefinition(mode.getId());
}
public static ensureValidWordDefinition(wordDefinition?:RegExp): RegExp {
diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts
index f9b7fd283ee..b68ebc3a310 100644
--- a/src/vs/editor/common/modes.ts
+++ b/src/vs/editor/common/modes.ts
@@ -180,27 +180,6 @@ export interface ILineContext {
findIndexOfOffset(offset:number): number;
}
-/**
- * @internal
- */
-export enum MutableSupport {
- RichEditSupport = 1,
- TokenizationSupport = 2
-}
-
-/**
- * @internal
- */
-export function mutableSupportToString(registerableSupport:MutableSupport) {
- if (registerableSupport === MutableSupport.RichEditSupport) {
- return 'richEditSupport';
- }
- if (registerableSupport === MutableSupport.TokenizationSupport) {
- return 'tokenizationSupport';
- }
- throw new Error('Illegal argument!');
-}
-
export interface IMode {
@@ -221,7 +200,7 @@ export interface IMode {
* Register a support by name. Only optional.
* @internal
*/
- registerSupport?(support:MutableSupport, callback:(mode:IMode)=>T): IDisposable;
+ setTokenizationSupport?(callback:(mode:IMode)=>T): IDisposable;
/**
* Optional adapter to support tokenization.
@@ -246,12 +225,6 @@ export interface IMode {
* @internal
*/
configSupport?:IConfigurationSupport;
-
- /**
- * Optional adapter to support rich editing.
- * @internal
- */
- richEditSupport?: IRichEditSupport;
}
/**
@@ -787,41 +760,6 @@ export interface IRichEditBrackets {
textIsOpenBracket: {[text:string]:boolean;};
}
-/**
- * @internal
- */
-export interface IRichEditSupport {
- /**
- * Optional adapter for electric characters.
- */
- electricCharacter?:IRichEditElectricCharacter;
-
- /**
- * Optional adapter for comment insertion.
- */
- comments?:ICommentsConfiguration;
-
- /**
- * Optional adapter for insertion of character pair.
- */
- characterPair?:IRichEditCharacterPair;
-
- /**
- * Optional adapter for classification of tokens.
- */
- wordDefinition?: RegExp;
-
- /**
- * Optional adapter for custom Enter handling.
- */
- onEnter?: IRichEditOnEnter;
-
- /**
- * Optional adapter for brackets.
- */
- brackets?: IRichEditBrackets;
-}
-
// --- feature registries ------
/**
diff --git a/src/vs/editor/common/modes/abstractMode.ts b/src/vs/editor/common/modes/abstractMode.ts
index 9c68600bc5a..cc74556cae1 100644
--- a/src/vs/editor/common/modes/abstractMode.ts
+++ b/src/vs/editor/common/modes/abstractMode.ts
@@ -102,17 +102,16 @@ export abstract class AbstractMode implements modes.IMode {
return this._eventEmitter.addListener2('modeSupportChanged', callback);
}
- public registerSupport(supportEnum:modes.MutableSupport, callback:(mode:modes.IMode) => T) : IDisposable {
- let supportStr = modes.mutableSupportToString(supportEnum);
+ public setTokenizationSupport(callback:(mode:modes.IMode) => T) : IDisposable {
var supportImpl = callback(this);
- this[supportStr] = supportImpl;
- this._eventEmitter.emit('modeSupportChanged', _createModeSupportChangedEvent(supportEnum));
+ this['tokenizationSupport'] = supportImpl;
+ this._eventEmitter.emit('modeSupportChanged', _createModeSupportChangedEvent());
return {
dispose: () => {
- if (this[supportStr] === supportImpl) {
- delete this[supportStr];
- this._eventEmitter.emit('modeSupportChanged', _createModeSupportChangedEvent(supportEnum));
+ if (this['tokenizationSupport'] === supportImpl) {
+ delete this['tokenizationSupport'];
+ this._eventEmitter.emit('modeSupportChanged', _createModeSupportChangedEvent());
}
}
};
@@ -122,7 +121,6 @@ export abstract class AbstractMode implements modes.IMode {
class SimplifiedMode implements modes.IMode {
tokenizationSupport: modes.ITokenizationSupport;
- richEditSupport: modes.IRichEditSupport;
private _sourceMode: modes.IMode;
private _eventEmitter: EventEmitter;
@@ -152,7 +150,6 @@ class SimplifiedMode implements modes.IMode {
private _assignSupports(): void {
this.tokenizationSupport = this._sourceMode.tokenizationSupport;
- this.richEditSupport = this._sourceMode.richEditSupport;
}
}
@@ -235,17 +232,8 @@ export class FrankensteinMode extends AbstractMode {
}
}
-function _createModeSupportChangedEvent(supportEnum:modes.MutableSupport): IModeSupportChangedEvent {
- let e:IModeSupportChangedEvent = {
- richEditSupport: false,
- tokenizationSupport: false
+function _createModeSupportChangedEvent(): IModeSupportChangedEvent {
+ return {
+ tokenizationSupport: true
};
- if (supportEnum === modes.MutableSupport.RichEditSupport) {
- e.richEditSupport = true;
- return e;
- } else if (supportEnum === modes.MutableSupport.TokenizationSupport) {
- e.tokenizationSupport = true;
- return e;
- }
- throw new Error('Illegal argument!');
}
diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts
new file mode 100644
index 00000000000..bc629365dbd
--- /dev/null
+++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts
@@ -0,0 +1,258 @@
+/*---------------------------------------------------------------------------------------------
+ * 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 {ICommentsConfiguration, IRichEditBrackets, IRichEditCharacterPair, IAutoClosingPair,
+ IAutoClosingPairConditional, IRichEditOnEnter, CharacterPair,
+ IRichEditElectricCharacter, IEnterAction, IndentAction} from 'vs/editor/common/modes';
+import {NullMode} from 'vs/editor/common/modes/nullMode';
+import {CharacterPairSupport} from 'vs/editor/common/modes/supports/characterPair';
+import {BracketElectricCharacterSupport, IBracketElectricCharacterContribution} from 'vs/editor/common/modes/supports/electricCharacter';
+import {IIndentationRules, IOnEnterRegExpRules, IOnEnterSupportOptions, OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
+import {RichEditBrackets} from 'vs/editor/common/modes/supports/richEditBrackets';
+import Event, {Emitter} from 'vs/base/common/event';
+import {ITokenizedModel} from 'vs/editor/common/editorCommon';
+import {onUnexpectedError} from 'vs/base/common/errors';
+import {Position} from 'vs/editor/common/core/position';
+import * as strings from 'vs/base/common/strings';
+import {IDisposable} from 'vs/base/common/lifecycle';
+
+export interface CommentRule {
+ lineComment?: string;
+ blockComment?: CharacterPair;
+}
+
+export interface IRichLanguageConfiguration {
+ comments?: CommentRule;
+ brackets?: CharacterPair[];
+ wordPattern?: RegExp;
+ indentationRules?: IIndentationRules;
+ onEnterRules?: IOnEnterRegExpRules[];
+ autoClosingPairs?: IAutoClosingPairConditional[];
+ surroundingPairs?: IAutoClosingPair[];
+ __electricCharacterSupport?: IBracketElectricCharacterContribution;
+}
+
+export class RichEditSupport {
+
+ private _conf: IRichLanguageConfiguration;
+
+ public electricCharacter: BracketElectricCharacterSupport;
+ public comments: ICommentsConfiguration;
+ public characterPair: IRichEditCharacterPair;
+ public wordDefinition: RegExp;
+ public onEnter: IRichEditOnEnter;
+ public brackets: IRichEditBrackets;
+
+ constructor(modeId:string, previous:RichEditSupport, rawConf:IRichLanguageConfiguration) {
+
+ let prev:IRichLanguageConfiguration = null;
+ if (previous) {
+ prev = previous._conf;
+ }
+
+ this._conf = RichEditSupport._mergeConf(prev, rawConf);
+
+ if (this._conf.brackets) {
+ this.brackets = new RichEditBrackets(modeId, this._conf.brackets);
+ }
+
+ this._handleOnEnter(modeId, this._conf);
+
+ this._handleComments(modeId, this._conf);
+
+ if (this._conf.autoClosingPairs) {
+ this.characterPair = new CharacterPairSupport(LanguageConfigurationRegistry, modeId, this._conf);
+ }
+
+ if (this._conf.__electricCharacterSupport || this._conf.brackets) {
+ this.electricCharacter = new BracketElectricCharacterSupport(LanguageConfigurationRegistry, modeId, this.brackets, this._conf.__electricCharacterSupport);
+ }
+
+ this.wordDefinition = this._conf.wordPattern || NullMode.DEFAULT_WORD_REGEXP;
+ }
+
+ private static _mergeConf(prev:IRichLanguageConfiguration, current:IRichLanguageConfiguration): IRichLanguageConfiguration {
+ return {
+ comments: (prev ? current.comments || prev.comments : current.comments),
+ brackets: (prev ? current.brackets || prev.brackets : current.brackets),
+ wordPattern: (prev ? current.wordPattern || prev.wordPattern : current.wordPattern),
+ indentationRules: (prev ? current.indentationRules || prev.indentationRules : current.indentationRules),
+ onEnterRules: (prev ? current.onEnterRules || prev.onEnterRules : current.onEnterRules),
+ autoClosingPairs: (prev ? current.autoClosingPairs || prev.autoClosingPairs : current.autoClosingPairs),
+ surroundingPairs: (prev ? current.surroundingPairs || prev.surroundingPairs : current.surroundingPairs),
+ __electricCharacterSupport: (prev ? current.__electricCharacterSupport || prev.__electricCharacterSupport : current.__electricCharacterSupport),
+ };
+ }
+
+ private _handleOnEnter(modeId:string, conf:IRichLanguageConfiguration): void {
+ // on enter
+ let onEnter: IOnEnterSupportOptions = {};
+ let empty = true;
+
+ if (conf.brackets) {
+ empty = false;
+ onEnter.brackets = conf.brackets;
+ }
+ if (conf.indentationRules) {
+ empty = false;
+ onEnter.indentationRules = conf.indentationRules;
+ }
+ if (conf.onEnterRules) {
+ empty = false;
+ onEnter.regExpRules = conf.onEnterRules;
+ }
+
+ if (!empty) {
+ this.onEnter = new OnEnterSupport(LanguageConfigurationRegistry, modeId, onEnter);
+ }
+ }
+
+ private _handleComments(modeId:string, conf:IRichLanguageConfiguration): void {
+ let commentRule = conf.comments;
+
+ // comment configuration
+ if (commentRule) {
+ this.comments = {};
+
+ if (commentRule.lineComment) {
+ this.comments.lineCommentToken = commentRule.lineComment;
+ }
+ if (commentRule.blockComment) {
+ let [blockStart, blockEnd] = commentRule.blockComment;
+ this.comments.blockCommentStartToken = blockStart;
+ this.comments.blockCommentEndToken = blockEnd;
+ }
+ }
+ }
+
+}
+
+export class LanguageConfigurationRegistryImpl {
+
+ private _entries: {[languageId:string]:RichEditSupport;};
+
+ private _onDidChange: Emitter = new Emitter();
+ public onDidChange: Event = this._onDidChange.event;
+
+ constructor() {
+ this._entries = Object.create(null);
+ }
+
+ public register(languageId:string, configuration:IRichLanguageConfiguration): IDisposable {
+ let previous = this._entries[languageId] || null;
+ this._entries[languageId] = new RichEditSupport(languageId, previous, configuration);
+ this._onDidChange.fire(void 0);
+ return {
+ dispose: () => {}
+ };
+ }
+
+ private _getRichEditSupport(modeId:string): RichEditSupport {
+ return this._entries[modeId];
+ }
+
+ public getElectricCharacterSupport(modeId:string): IRichEditElectricCharacter {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.electricCharacter || null;
+ }
+
+ public getComments(modeId:string): ICommentsConfiguration {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.comments || null;
+ }
+
+ public getCharacterPairSupport(modeId:string): IRichEditCharacterPair {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.characterPair || null;
+ }
+
+ public getWordDefinition(modeId:string): RegExp {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.wordDefinition || null;
+ }
+
+ public getOnEnterSupport(modeId:string): IRichEditOnEnter {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.onEnter || null;
+ }
+
+ public getRawEnterActionAtPosition(model:ITokenizedModel, lineNumber:number, column:number): IEnterAction {
+ let result:IEnterAction;
+
+ let onEnterSupport = this.getOnEnterSupport(model.getMode().getId());
+
+ if (onEnterSupport) {
+ try {
+ result = onEnterSupport.onEnter(model, new Position(lineNumber, column));
+ } catch (e) {
+ onUnexpectedError(e);
+ }
+ }
+
+ return result;
+ }
+
+ public getEnterActionAtPosition(model:ITokenizedModel, lineNumber:number, column:number): { enterAction: IEnterAction; indentation: string; } {
+ let lineText = model.getLineContent(lineNumber);
+ let indentation = strings.getLeadingWhitespace(lineText);
+ if (indentation.length > column - 1) {
+ indentation = indentation.substring(0, column - 1);
+ }
+
+ let enterAction = this.getRawEnterActionAtPosition(model, lineNumber, column);
+ if (!enterAction) {
+ enterAction = {
+ indentAction: IndentAction.None,
+ appendText: '',
+ };
+ } else {
+ if(!enterAction.appendText) {
+ if (
+ (enterAction.indentAction === IndentAction.Indent) ||
+ (enterAction.indentAction === IndentAction.IndentOutdent)
+ ) {
+ enterAction.appendText = '\t';
+ } else {
+ enterAction.appendText = '';
+ }
+ }
+ }
+
+ if (enterAction.removeText) {
+ indentation = indentation.substring(0, indentation.length - 1);
+ }
+
+ return {
+ enterAction: enterAction,
+ indentation: indentation
+ };
+ }
+
+ public getBracketsSupport(modeId:string): IRichEditBrackets {
+ let value = this._getRichEditSupport(modeId);
+ if (!value) {
+ return null;
+ }
+ return value.brackets || null;
+ }
+}
+
+export const LanguageConfigurationRegistry = new LanguageConfigurationRegistryImpl();
diff --git a/src/vs/editor/common/modes/monarch/monarchCommon.ts b/src/vs/editor/common/modes/monarch/monarchCommon.ts
index d4762e29cd0..a6eb7879559 100644
--- a/src/vs/editor/common/modes/monarch/monarchCommon.ts
+++ b/src/vs/editor/common/modes/monarch/monarchCommon.ts
@@ -4,8 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
-import {CharacterPair, IAutoClosingPairConditional} from 'vs/editor/common/modes';
-
/*
* This module exports common types and functionality shared between
* the Monarch compiler that compiles JSON to ILexer, and the Monarch
@@ -24,10 +22,9 @@ export enum MonarchBracket {
}
export interface ILexerMin {
+ languageId: string;
noThrow: boolean;
ignoreCase: boolean;
- displayName: string;
- name: string;
usesEmbedded: boolean;
defaultToken: string;
stateNames: Object;
@@ -37,30 +34,10 @@ export interface ILexer extends ILexerMin {
maxStack: number;
start: string;
ignoreCase: boolean;
- lineComment: string;
- blockCommentStart: string;
- blockCommentEnd: string;
tokenPostfix: string;
tokenizer: IRule[][];
brackets: IBracket[];
- wordDefinition: RegExp;
- autoClosingPairs: IAutoClosingPairConditional[];
-
- standardBrackets: CharacterPair[];
- // enhancedBrackets: IRegexBracketPair[];
- outdentTriggers: string;
-}
-
-export interface IAutoIndent {
- match: RegExp;
- matchAfter: RegExp;
-}
-
-export interface IAutoComplete {
- triggers: string;
- match: RegExp;
- complete: string;
}
export interface IBracket {
@@ -130,7 +107,7 @@ export function sanitize(s: string) {
* Logs a message.
*/
export function log(lexer: ILexerMin, msg: string) {
- console.log(`${lexer.name}: ${msg}`);
+ console.log(`${lexer.languageId}: ${msg}`);
}
// Throwing errors
@@ -139,7 +116,7 @@ export function log(lexer: ILexerMin, msg: string) {
* Throws error. May actually just log the error and continue.
*/
export function throwError(lexer: ILexerMin, msg: string) {
- throw new Error(`${lexer.name}: ${msg}`);
+ throw new Error(`${lexer.languageId}: ${msg}`);
}
// Helper functions for rule finding and substitution
diff --git a/src/vs/editor/common/modes/monarch/monarchCompile.ts b/src/vs/editor/common/modes/monarch/monarchCompile.ts
index b363ff200ae..913651b60d1 100644
--- a/src/vs/editor/common/modes/monarch/monarchCompile.ts
+++ b/src/vs/editor/common/modes/monarch/monarchCompile.ts
@@ -10,7 +10,6 @@
*/
import * as objects from 'vs/base/common/objects';
-import {IAutoClosingPairConditional, CharacterPair} from 'vs/editor/common/modes';
import * as monarchCommon from 'vs/editor/common/modes/monarch/monarchCommon';
import {ILanguage, ILanguageBracket} from 'vs/editor/common/modes/monarch/monarchTypes';
@@ -387,20 +386,14 @@ class Rule implements monarchCommon.IRule {
* (Currently we have no samples that need this so perhaps we should always have
* jsonStrict to true).
*/
-export function compile(json: ILanguage): monarchCommon.ILexer {
+export function compile(languageId:string, json: ILanguage): monarchCommon.ILexer {
if (!json || typeof (json) !== 'object') {
throw new Error('Monarch: expecting a language definition object');
}
- // Get names
- if (typeof (json.name) !== 'string') {
- throw new Error('Monarch: a language definition must include a string \'name\' attribute');
- }
-
// Create our lexer
var lexer: monarchCommon.ILexer = {};
- lexer.name = json.name;
- lexer.displayName = string(json.displayName, lexer.name);
+ lexer.languageId = languageId;
lexer.noThrow = false; // raise exceptions during compilation
lexer.maxStack = 100;
@@ -408,29 +401,14 @@ export function compile(json: ILanguage): monarchCommon.ILexer {
lexer.start = string(json.start);
lexer.ignoreCase = bool(json.ignoreCase, false);
- lexer.lineComment = string(json.lineComment, '//');
- lexer.blockCommentStart = string(json.blockCommentStart, '/*');
- lexer.blockCommentEnd = string(json.blockCommentEnd, '*/');
- lexer.tokenPostfix = string(json.tokenPostfix, '.' + lexer.name);
+ lexer.tokenPostfix = string(json.tokenPostfix, '.' + lexer.languageId);
lexer.defaultToken = string(json.defaultToken, 'source', function () { monarchCommon.throwError(lexer, 'the \'defaultToken\' must be a string'); });
lexer.usesEmbedded = false; // becomes true if we find a nextEmbedded action
- lexer.wordDefinition = json.wordDefinition || undefined;
-
- // COMPAT: with earlier monarch versions
- if (!lexer.lineComment && (json).lineComments) {
- if (typeof ((json).lineComments) === 'string') {
- lexer.lineComment = (json).lineComments;
- }
- else if (typeof ((json).lineComments[0]) === 'string') {
- lexer.lineComment = (json).lineComments[0];
- }
- }
// For calling compileAction later on
var lexerMin: monarchCommon.ILexerMin = json;
- lexerMin.name = lexer.name;
- lexerMin.displayName = lexer.displayName;
+ lexerMin.languageId = languageId;
lexerMin.ignoreCase = lexer.ignoreCase;
lexerMin.noThrow = lexer.noThrow;
lexerMin.usesEmbedded = lexer.usesEmbedded;
@@ -559,105 +537,6 @@ export function compile(json: ILanguage): monarchCommon.ILexer {
}
lexer.brackets = brackets;
- // Set default auto closing pairs
- var autoClosingPairs: any/*string[][]*/;
- if (json.autoClosingPairs) {
- if (!(Array.isArray(json.autoClosingPairs))) {
- monarchCommon.throwError(lexer, 'the \'autoClosingPairs\' attribute must be an array of string pairs (as arrays)');
- }
- autoClosingPairs = json.autoClosingPairs.slice(0);
- }
- else {
- autoClosingPairs = [['"', '"'], ['\'', '\''], ['@brackets']];
- }
-
- // set auto closing pairs
- lexer.autoClosingPairs = [];
- if (autoClosingPairs) {
- for (var autoClosingPairIdx in autoClosingPairs) {
- if (autoClosingPairs.hasOwnProperty(autoClosingPairIdx)) {
- var pair = autoClosingPairs[autoClosingPairIdx];
- var openClose: IAutoClosingPairConditional;
- if (pair === '@brackets' || pair[0] === '@brackets') {
- var bidx: string;
- for (bidx in brackets) {
- if (brackets.hasOwnProperty(bidx)) {
- if (brackets[bidx].open && brackets[bidx].open.length === 1 &&
- brackets[bidx].close && brackets[bidx].close.length === 1) {
- openClose = { open: brackets[bidx].open, close: brackets[bidx].close, notIn:['string', 'comment'] };
- lexer.autoClosingPairs.push(openClose);
- }
- }
- }
- }
- else if (Array.isArray(pair) && pair.length === 2 &&
- typeof (pair[0]) === 'string' && pair[0].length === 1 &&
- typeof (pair[1]) === 'string' && pair[1].length === 1) {
- openClose = { open: monarchCommon.fixCase(lexer, pair[0]), close: monarchCommon.fixCase(lexer, pair[1]), notIn:['string', 'comment'] };
- lexer.autoClosingPairs.push(openClose);
- }
- else if (typeof (pair.open) === 'string' && pair.open.length === 1 &&
- typeof (pair.close) === 'string' && pair.close.length === 1) {
- openClose = { open: monarchCommon.fixCase(lexer, pair.open[0]), close: monarchCommon.fixCase(lexer, pair.close[0]), notIn:['string', 'comment'] };
- lexer.autoClosingPairs.push(openClose);
- }
- else {
- monarchCommon.throwError(lexer, 'every element in an \'autoClosingPairs\' array must be a pair of 1 character strings, or a \'@brackets\' directive');
- }
- }
- }
- }
-
- // Set enhanced brackets
- // var enhancedBrackets : IRegexBracketPair[] = [];
- // if (json.enhancedBrackets) {
- // if (!(Array.isArray(json.enhancedBrackets))) {
- // monarchCommon.throwError(lexer, 'the \'enhancedBrackets\' attribute must be defined as an array');
- // }
-
- // for (var bracketIdx in json.enhancedBrackets) {
- // if (json.enhancedBrackets.hasOwnProperty(bracketIdx)) {
- // var desc = json.enhancedBrackets[bracketIdx];
- // if (desc.hasOwnProperty('openTrigger') && typeof (desc.openTrigger) !== 'string') {
- // monarchCommon.throwError(lexer, 'openTrigger in the \'enhancedBrackets\' array must be a string');
- // }
- // if (desc.hasOwnProperty('open') && !(desc.open instanceof RegExp)) {
- // monarchCommon.throwError(lexer, 'open in the \'enhancedBrackets\' array must be a regex');
- // }
- // if (desc.hasOwnProperty('closeComplete') && typeof (desc.closeComplete) !== 'string') {
- // monarchCommon.throwError(lexer, 'closeComplete in the \'enhancedBrackets\' array must be a string');
- // }
- // if (desc.hasOwnProperty('matchCase') && typeof (desc.matchCase) !== 'boolean') {
- // monarchCommon.throwError(lexer, 'matchCase in the \'enhancedBrackets\' array must be a boolean');
- // }
- // if (desc.hasOwnProperty('closeTrigger') && typeof (desc.closeTrigger) !== 'string') {
- // monarchCommon.throwError(lexer, 'closeTrigger in the \'enhancedBrackets\' array must be a string');
- // }
- // if (desc.hasOwnProperty('close') && !(desc.close instanceof RegExp)) {
- // monarchCommon.throwError(lexer, 'close in the \'enhancedBrackets\' array must be a regex');
- // }
- // if (desc.hasOwnProperty('tokenType')) {
- // if (typeof (desc.tokenType) !== 'string') {
- // monarchCommon.throwError(lexer, 'tokenType in the \'enhancedBrackets\' array must be a string');
- // }
- // else {
- // desc.tokenType += lexer.tokenPostfix;
- // }
- // }
- // enhancedBrackets.push(desc);
- // }
- // }
- // }
- // lexer.enhancedBrackets = enhancedBrackets;
-
- var standardBrackets: CharacterPair[] = [];
- for (var i = 0; i < brackets.length; ++i) {
- standardBrackets.push([brackets[i].open, brackets[i].close]);
- }
- lexer.standardBrackets = standardBrackets;
-
- lexer.outdentTriggers = string(json.outdentTriggers, '');
-
// Disable throw so the syntax highlighter goes, no matter what
lexer.noThrow = true;
return lexer;
diff --git a/src/vs/editor/common/modes/monarch/monarchDefinition.ts b/src/vs/editor/common/modes/monarch/monarchDefinition.ts
deleted file mode 100644
index bc47b51531f..00000000000
--- a/src/vs/editor/common/modes/monarch/monarchDefinition.ts
+++ /dev/null
@@ -1,36 +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';
-
-/**
- * Create a syntax highighter with a fully declarative JSON style lexer description
- * using regular expressions.
- */
-
-import {ILexer} from 'vs/editor/common/modes/monarch/monarchCommon';
-import {IRichLanguageConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
-
-export function createRichEditSupport(lexer: ILexer): IRichLanguageConfiguration {
-
- return {
-
- wordPattern: lexer.wordDefinition,
-
- comments: {
- lineComment: lexer.lineComment,
- blockComment: [lexer.blockCommentStart, lexer.blockCommentEnd]
- },
-
- brackets: lexer.standardBrackets,
-
- autoClosingPairs: lexer.autoClosingPairs,
-
- __electricCharacterSupport: {
- // regexBrackets: lexer.enhancedBrackets,
- caseInsensitive: lexer.ignoreCase,
- embeddedElectricCharacters: lexer.outdentTriggers.split('')
- }
- };
-}
diff --git a/src/vs/editor/common/modes/monarch/monarchLexer.ts b/src/vs/editor/common/modes/monarch/monarchLexer.ts
index 2ac624182f7..3bd663a24ef 100644
--- a/src/vs/editor/common/modes/monarch/monarchLexer.ts
+++ b/src/vs/editor/common/modes/monarch/monarchLexer.ts
@@ -72,7 +72,7 @@ export class MonarchLexer extends AbstractState {
return false;
}
var otherm: MonarchLexer = other;
- if ((this.stack.length !== otherm.stack.length) || (this.lexer.name !== otherm.lexer.name) ||
+ if ((this.stack.length !== otherm.stack.length) || (this.lexer.languageId !== otherm.lexer.languageId) ||
(this.embeddedMode !== otherm.embeddedMode)) {
return false;
}
@@ -288,7 +288,7 @@ export class MonarchLexer extends AbstractState {
}
if (action.log && typeof (action.log) === 'string') {
- monarchCommon.log(this.lexer, this.lexer.displayName + ': ' + monarchCommon.substituteMatches(this.lexer, action.log, matched, matches, state));
+ monarchCommon.log(this.lexer, this.lexer.languageId + ': ' + monarchCommon.substituteMatches(this.lexer, action.log, matched, matches, state));
}
}
diff --git a/src/vs/editor/common/modes/monarch/monarchTypes.ts b/src/vs/editor/common/modes/monarch/monarchTypes.ts
index 2e818456203..5473b804fa8 100644
--- a/src/vs/editor/common/modes/monarch/monarchTypes.ts
+++ b/src/vs/editor/common/modes/monarch/monarchTypes.ts
@@ -14,35 +14,14 @@
* A Monarch language definition
*/
export interface ILanguage {
- /**
- * unique name to identify the language.
- */
- name: string;
/**
* map from string to ILanguageRule[]
*/
tokenizer: Object;
-
- /**
- * nice display name
- */
- displayName?: string;
/**
* is the language case insensitive?
*/
ignoreCase?: boolean;
- /**
- * used to insert/delete line comments in the editor
- */
- lineComment?: string;
- /**
- * used to insert/delete block comments in the editor
- */
- blockCommentStart?: string;
- /**
- * used to insert/delete block comments in the editor
- */
- blockCommentEnd?: string;
/**
* if no match in the tokenizer assign this token class (default 'source')
*/
@@ -51,8 +30,6 @@ export interface ILanguage {
* for example [['{','}','delimiter.curly']]
*/
brackets?: ILanguageBracket[];
-
- // advanced
/**
* start symbol in the tokenizer (by default the first entry is used)
*/
@@ -60,23 +37,7 @@ export interface ILanguage {
/**
* attach this to every token class (by default '.' + name)
*/
- tokenPostfix?: string;
- /**
- * for example [['"','"']]
- */
- autoClosingPairs?: string[][];
- /**
- * word definition regular expression
- */
- wordDefinition?: RegExp;
- /**
- * characters that could potentially cause outdentation
- */
- outdentTriggers?: string;
- // /**
- // * Advanced auto completion, auto indenting, and bracket matching
- // */
- // enhancedBrackets?: IRegexBracketPair[];
+ tokenPostfix: string;
}
/**
diff --git a/src/vs/editor/common/modes/nullMode.ts b/src/vs/editor/common/modes/nullMode.ts
index daaec7053cf..f27f72c6a54 100644
--- a/src/vs/editor/common/modes/nullMode.ts
+++ b/src/vs/editor/common/modes/nullMode.ts
@@ -81,12 +81,7 @@ export class NullMode implements modes.IMode {
public static ID = 'vs.editor.modes.nullMode';
- public richEditSupport: modes.IRichEditSupport;
-
constructor() {
- this.richEditSupport = {
- wordDefinition: NullMode.DEFAULT_WORD_REGEXP
- };
}
public getId():string {
diff --git a/src/vs/editor/common/modes/supports.ts b/src/vs/editor/common/modes/supports.ts
index ad60086e7c6..62f69a3ba33 100644
--- a/src/vs/editor/common/modes/supports.ts
+++ b/src/vs/editor/common/modes/supports.ts
@@ -45,10 +45,10 @@ export class LineTokens implements modes.ILineTokens {
}
}
-export function handleEvent(context:modes.ILineContext, offset:number, runner:(mode:modes.IMode, newContext:modes.ILineContext, offset:number)=>T):T {
+export function handleEvent(context:modes.ILineContext, offset:number, runner:(modeId:string, newContext:modes.ILineContext, offset:number)=>T):T {
var modeTransitions = context.modeTransitions;
if (modeTransitions.length === 1) {
- return runner(modeTransitions[0].mode, context, offset);
+ return runner(modeTransitions[0].modeId, context, offset);
}
var modeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, offset);
@@ -68,7 +68,7 @@ export function handleEvent(context:modes.ILineContext, offset:number, runner
var firstTokenCharacterOffset = context.getTokenStartIndex(firstTokenInModeIndex);
var newCtx = new FilteredLineContext(context, nestedMode, firstTokenInModeIndex, nextTokenAfterMode, firstTokenCharacterOffset, nextCharacterAfterModeIndex);
- return runner(nestedMode, newCtx, offset - firstTokenCharacterOffset);
+ return runner(nestedMode.getId(), newCtx, offset - firstTokenCharacterOffset);
}
export class FilteredLineContext implements modes.ILineContext {
diff --git a/src/vs/editor/common/modes/supports/characterPair.ts b/src/vs/editor/common/modes/supports/characterPair.ts
index cc49392b049..5ec20e82c0b 100644
--- a/src/vs/editor/common/modes/supports/characterPair.ts
+++ b/src/vs/editor/common/modes/supports/characterPair.ts
@@ -4,16 +4,19 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
-import {IAutoClosingPair, IAutoClosingPairConditional, ILineContext, IMode, IRichEditCharacterPair, CharacterPair} from 'vs/editor/common/modes';
+import {IAutoClosingPair, IAutoClosingPairConditional, ILineContext, IRichEditCharacterPair, CharacterPair} from 'vs/editor/common/modes';
import {handleEvent} from 'vs/editor/common/modes/supports';
+import {LanguageConfigurationRegistryImpl} from 'vs/editor/common/modes/languageConfigurationRegistry';
export class CharacterPairSupport implements IRichEditCharacterPair {
+ private _registry: LanguageConfigurationRegistryImpl;
private _modeId: string;
private _autoClosingPairs: IAutoClosingPairConditional[];
private _surroundingPairs: IAutoClosingPair[];
- constructor(modeId: string, config: { brackets?: CharacterPair[]; autoClosingPairs?: IAutoClosingPairConditional[], surroundingPairs?: IAutoClosingPair[]}) {
+ constructor(registry: LanguageConfigurationRegistryImpl, modeId: string, config: { brackets?: CharacterPair[]; autoClosingPairs?: IAutoClosingPairConditional[], surroundingPairs?: IAutoClosingPair[]}) {
+ this._registry = registry;
this._modeId = modeId;
this._autoClosingPairs = config.autoClosingPairs;
if (!this._autoClosingPairs) {
@@ -27,8 +30,8 @@ export class CharacterPairSupport implements IRichEditCharacterPair {
}
public shouldAutoClosePair(character:string, context:ILineContext, offset:number): boolean {
- return handleEvent(context, offset, (nestedMode:IMode, context:ILineContext, offset:number) => {
- if (this._modeId === nestedMode.getId()) {
+ return handleEvent(context, offset, (nestedModeId:string, context:ILineContext, offset:number) => {
+ if (this._modeId === nestedModeId) {
// Always complete on empty line
if (context.getTokenCount() === 0) {
@@ -52,11 +55,14 @@ export class CharacterPairSupport implements IRichEditCharacterPair {
}
return true;
- } else if (nestedMode.richEditSupport && nestedMode.richEditSupport.characterPair) {
- return nestedMode.richEditSupport.characterPair.shouldAutoClosePair(character, context, offset);
- } else {
- return null;
}
+
+ let characterPairSupport = this._registry.getCharacterPairSupport(nestedModeId);
+ if (characterPairSupport) {
+ return characterPairSupport.shouldAutoClosePair(character, context, offset);
+ }
+
+ return null;
});
}
diff --git a/src/vs/editor/common/modes/supports/electricCharacter.ts b/src/vs/editor/common/modes/supports/electricCharacter.ts
index 674f10c47ec..0cc1f70a177 100644
--- a/src/vs/editor/common/modes/supports/electricCharacter.ts
+++ b/src/vs/editor/common/modes/supports/electricCharacter.ts
@@ -8,6 +8,7 @@ import * as strings from 'vs/base/common/strings';
import * as modes from 'vs/editor/common/modes';
import {handleEvent, ignoreBracketsInToken} from 'vs/editor/common/modes/supports';
import {BracketsUtils} from 'vs/editor/common/modes/supports/richEditBrackets';
+import {LanguageConfigurationRegistryImpl} from 'vs/editor/common/modes/languageConfigurationRegistry';
/**
* Definition of documentation comments (e.g. Javadoc/JSdoc)
@@ -21,20 +22,21 @@ export interface IDocComment {
export interface IBracketElectricCharacterContribution {
docComment?: IDocComment;
- caseInsensitive?: boolean;
embeddedElectricCharacters?: string[];
}
export class BracketElectricCharacterSupport implements modes.IRichEditElectricCharacter {
+ private _registry: LanguageConfigurationRegistryImpl;
private _modeId: string;
private contribution: IBracketElectricCharacterContribution;
private brackets: Brackets;
- constructor(modeId: string, brackets: modes.IRichEditBrackets, contribution: IBracketElectricCharacterContribution) {
+ constructor(registry:LanguageConfigurationRegistryImpl, modeId: string, brackets: modes.IRichEditBrackets, contribution: IBracketElectricCharacterContribution) {
+ this._registry = registry;
this._modeId = modeId;
this.contribution = contribution || {};
- this.brackets = new Brackets(modeId, brackets, this.contribution.docComment, this.contribution.caseInsensitive);
+ this.brackets = new Brackets(modeId, brackets, this.contribution.docComment);
}
public getElectricCharacters(): string[]{
@@ -45,14 +47,15 @@ export class BracketElectricCharacterSupport implements modes.IRichEditElectricC
}
public onElectricCharacter(context:modes.ILineContext, offset:number): modes.IElectricAction {
- return handleEvent(context, offset, (nestedMode:modes.IMode, context:modes.ILineContext, offset:number) => {
- if (this._modeId === nestedMode.getId()) {
+ return handleEvent(context, offset, (nestedModeId:string, context:modes.ILineContext, offset:number) => {
+ if (this._modeId === nestedModeId) {
return this.brackets.onElectricCharacter(context, offset);
- } else if (nestedMode.richEditSupport && nestedMode.richEditSupport.electricCharacter) {
- return nestedMode.richEditSupport.electricCharacter.onElectricCharacter(context, offset);
- } else {
- return null;
}
+ let electricCharacterSupport = this._registry.getElectricCharacterSupport(nestedModeId);
+ if (electricCharacterSupport) {
+ return electricCharacterSupport.onElectricCharacter(context, offset);
+ }
+ return null;
});
}
}
@@ -65,7 +68,7 @@ export class Brackets {
private _richEditBrackets: modes.IRichEditBrackets;
private _docComment: IDocComment;
- constructor(modeId: string, richEditBrackets: modes.IRichEditBrackets, docComment: IDocComment = null, caseInsensitive: boolean = false) {
+ constructor(modeId: string, richEditBrackets: modes.IRichEditBrackets, docComment: IDocComment = null) {
this._modeId = modeId;
this._richEditBrackets = richEditBrackets;
this._docComment = docComment ? docComment : null;
diff --git a/src/vs/editor/common/modes/supports/onEnter.ts b/src/vs/editor/common/modes/supports/onEnter.ts
index 72bb27cc6b7..b82d2c02e3f 100644
--- a/src/vs/editor/common/modes/supports/onEnter.ts
+++ b/src/vs/editor/common/modes/supports/onEnter.ts
@@ -6,10 +6,10 @@
import {onUnexpectedError} from 'vs/base/common/errors';
import * as strings from 'vs/base/common/strings';
-import {Position} from 'vs/editor/common/core/position';
import {IPosition, ITextModel, ITokenizedModel} from 'vs/editor/common/editorCommon';
-import {IEnterAction, ILineContext, IMode, IRichEditOnEnter, IndentAction, CharacterPair} from 'vs/editor/common/modes';
+import {IEnterAction, ILineContext, IRichEditOnEnter, IndentAction, CharacterPair} from 'vs/editor/common/modes';
import {handleEvent} from 'vs/editor/common/modes/supports';
+import {LanguageConfigurationRegistryImpl} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface IIndentationRules {
decreaseIndentPattern: RegExp;
@@ -43,12 +43,14 @@ export class OnEnterSupport implements IRichEditOnEnter {
private static _INDENT_OUTDENT: IEnterAction = { indentAction: IndentAction.IndentOutdent };
private static _OUTDENT: IEnterAction = { indentAction: IndentAction.Outdent };
+ private _registry: LanguageConfigurationRegistryImpl;
private _modeId: string;
private _brackets: IProcessedBracketPair[];
private _indentationRules: IIndentationRules;
private _regExpRules: IOnEnterRegExpRules[];
- constructor(modeId: string, opts?:IOnEnterSupportOptions) {
+ constructor(registry: LanguageConfigurationRegistryImpl, modeId: string, opts?:IOnEnterSupportOptions) {
+ this._registry = registry;
opts = opts || {};
opts.brackets = opts.brackets || [
['(', ')'],
@@ -72,14 +74,17 @@ export class OnEnterSupport implements IRichEditOnEnter {
public onEnter(model:ITokenizedModel, position: IPosition): IEnterAction {
var context = model.getLineContext(position.lineNumber);
- return handleEvent(context, position.column - 1, (nestedMode:IMode, context:ILineContext, offset:number) => {
- if (this._modeId === nestedMode.getId()) {
+ return handleEvent(context, position.column - 1, (nestedModeId:string, context:ILineContext, offset:number) => {
+ if (this._modeId === nestedModeId) {
return this._onEnter(model, position);
- } else if (nestedMode.richEditSupport && nestedMode.richEditSupport.onEnter) {
- return nestedMode.richEditSupport.onEnter.onEnter(model, position);
- } else {
- return null;
}
+
+ let onEnterSupport = this._registry.getOnEnterSupport(nestedModeId);
+ if (onEnterSupport) {
+ return onEnterSupport.onEnter(model, position);
+ }
+
+ return null;
});
}
@@ -178,53 +183,3 @@ export class OnEnterSupport implements IRichEditOnEnter {
}
}
-export function getRawEnterActionAtPosition(model:ITokenizedModel, lineNumber:number, column:number): IEnterAction {
- let result:IEnterAction;
- let richEditSupport = model.getMode().richEditSupport;
-
- if (richEditSupport && richEditSupport.onEnter) {
- try {
- result = richEditSupport.onEnter.onEnter(model, new Position(lineNumber, column));
- } catch (e) {
- onUnexpectedError(e);
- }
- }
-
- return result;
-}
-
-export function getEnterActionAtPosition(model:ITokenizedModel, lineNumber:number, column:number): { enterAction: IEnterAction; indentation: string; } {
- let lineText = model.getLineContent(lineNumber);
- let indentation = strings.getLeadingWhitespace(lineText);
- if (indentation.length > column - 1) {
- indentation = indentation.substring(0, column - 1);
- }
-
- let enterAction = getRawEnterActionAtPosition(model, lineNumber, column);
- if (!enterAction) {
- enterAction = {
- indentAction: IndentAction.None,
- appendText: '',
- };
- } else {
- if(!enterAction.appendText) {
- if (
- (enterAction.indentAction === IndentAction.Indent) ||
- (enterAction.indentAction === IndentAction.IndentOutdent)
- ) {
- enterAction.appendText = '\t';
- } else {
- enterAction.appendText = '';
- }
- }
- }
-
- if (enterAction.removeText) {
- indentation = indentation.substring(0, indentation.length - 1);
- }
-
- return {
- enterAction: enterAction,
- indentation: indentation
- };
-}
diff --git a/src/vs/editor/common/modes/supports/richEditBrackets.ts b/src/vs/editor/common/modes/supports/richEditBrackets.ts
index a684e74f3d6..cfe3e9c713a 100644
--- a/src/vs/editor/common/modes/supports/richEditBrackets.ts
+++ b/src/vs/editor/common/modes/supports/richEditBrackets.ts
@@ -7,14 +7,14 @@
import * as strings from 'vs/base/common/strings';
import {Range} from 'vs/editor/common/core/range';
import {IRichEditBracket} from 'vs/editor/common/editorCommon';
-import * as modes from 'vs/editor/common/modes';
+import {IRichEditBrackets, CharacterPair} from 'vs/editor/common/modes';
interface ISimpleInternalBracket {
open: string;
close: string;
}
-export class RichEditBrackets implements modes.IRichEditBrackets {
+export class RichEditBrackets implements IRichEditBrackets {
public brackets: IRichEditBracket[];
public forwardRegex: RegExp;
@@ -23,7 +23,7 @@ export class RichEditBrackets implements modes.IRichEditBrackets {
public textIsBracket: {[text:string]:IRichEditBracket;};
public textIsOpenBracket: {[text:string]:boolean;};
- constructor(modeId: string, brackets: modes.CharacterPair[]) {
+ constructor(modeId: string, brackets: CharacterPair[]) {
this.brackets = brackets.map((b) => {
return {
modeId: modeId,
diff --git a/src/vs/editor/common/modes/supports/richEditSupport.ts b/src/vs/editor/common/modes/supports/richEditSupport.ts
deleted file mode 100644
index 301a4cafb41..00000000000
--- a/src/vs/editor/common/modes/supports/richEditSupport.ts
+++ /dev/null
@@ -1,124 +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';
-
-import {ICommentsConfiguration, IRichEditBrackets, IRichEditCharacterPair, IAutoClosingPair,
- IAutoClosingPairConditional, IRichEditOnEnter, IRichEditSupport, CharacterPair} from 'vs/editor/common/modes';
-import {NullMode} from 'vs/editor/common/modes/nullMode';
-import {CharacterPairSupport} from 'vs/editor/common/modes/supports/characterPair';
-import {BracketElectricCharacterSupport, IBracketElectricCharacterContribution} from 'vs/editor/common/modes/supports/electricCharacter';
-import {IIndentationRules, IOnEnterRegExpRules, IOnEnterSupportOptions, OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
-import {RichEditBrackets} from 'vs/editor/common/modes/supports/richEditBrackets';
-
-export interface CommentRule {
- lineComment?: string;
- blockComment?: CharacterPair;
-}
-
-export interface IRichLanguageConfiguration {
- comments?: CommentRule;
- brackets?: CharacterPair[];
- wordPattern?: RegExp;
- indentationRules?: IIndentationRules;
- onEnterRules?: IOnEnterRegExpRules[];
- autoClosingPairs?: IAutoClosingPairConditional[];
- surroundingPairs?: IAutoClosingPair[];
- __electricCharacterSupport?: IBracketElectricCharacterContribution;
-}
-
-export class RichEditSupport implements IRichEditSupport {
-
- private _conf: IRichLanguageConfiguration;
-
- public electricCharacter: BracketElectricCharacterSupport;
- public comments: ICommentsConfiguration;
- public characterPair: IRichEditCharacterPair;
- public wordDefinition: RegExp;
- public onEnter: IRichEditOnEnter;
- public brackets: IRichEditBrackets;
-
- constructor(modeId:string, previous:IRichEditSupport, rawConf:IRichLanguageConfiguration) {
-
- let prev:IRichLanguageConfiguration = null;
- if (previous instanceof RichEditSupport) {
- prev = previous._conf;
- }
-
- this._conf = RichEditSupport._mergeConf(prev, rawConf);
-
- if (this._conf.brackets) {
- this.brackets = new RichEditBrackets(modeId, this._conf.brackets);
- }
-
- this._handleOnEnter(modeId, this._conf);
-
- this._handleComments(modeId, this._conf);
-
- if (this._conf.autoClosingPairs) {
- this.characterPair = new CharacterPairSupport(modeId, this._conf);
- }
-
- if (this._conf.__electricCharacterSupport || this._conf.brackets) {
- this.electricCharacter = new BracketElectricCharacterSupport(modeId, this.brackets, this._conf.__electricCharacterSupport);
- }
-
- this.wordDefinition = this._conf.wordPattern || NullMode.DEFAULT_WORD_REGEXP;
- }
-
- private static _mergeConf(prev:IRichLanguageConfiguration, current:IRichLanguageConfiguration): IRichLanguageConfiguration {
- return {
- comments: (prev ? current.comments || prev.comments : current.comments),
- brackets: (prev ? current.brackets || prev.brackets : current.brackets),
- wordPattern: (prev ? current.wordPattern || prev.wordPattern : current.wordPattern),
- indentationRules: (prev ? current.indentationRules || prev.indentationRules : current.indentationRules),
- onEnterRules: (prev ? current.onEnterRules || prev.onEnterRules : current.onEnterRules),
- autoClosingPairs: (prev ? current.autoClosingPairs || prev.autoClosingPairs : current.autoClosingPairs),
- surroundingPairs: (prev ? current.surroundingPairs || prev.surroundingPairs : current.surroundingPairs),
- __electricCharacterSupport: (prev ? current.__electricCharacterSupport || prev.__electricCharacterSupport : current.__electricCharacterSupport),
- };
- }
-
- private _handleOnEnter(modeId:string, conf:IRichLanguageConfiguration): void {
- // on enter
- let onEnter: IOnEnterSupportOptions = {};
- let empty = true;
-
- if (conf.brackets) {
- empty = false;
- onEnter.brackets = conf.brackets;
- }
- if (conf.indentationRules) {
- empty = false;
- onEnter.indentationRules = conf.indentationRules;
- }
- if (conf.onEnterRules) {
- empty = false;
- onEnter.regExpRules = conf.onEnterRules;
- }
-
- if (!empty) {
- this.onEnter = new OnEnterSupport(modeId, onEnter);
- }
- }
-
- private _handleComments(modeId:string, conf:IRichLanguageConfiguration): void {
- let commentRule = conf.comments;
-
- // comment configuration
- if (commentRule) {
- this.comments = {};
-
- if (commentRule.lineComment) {
- this.comments.lineCommentToken = commentRule.lineComment;
- }
- if (commentRule.blockComment) {
- let [blockStart, blockEnd] = commentRule.blockComment;
- this.comments.blockCommentStartToken = blockStart;
- this.comments.blockCommentEndToken = blockEnd;
- }
- }
- }
-
-}
diff --git a/src/vs/editor/common/modes/supports/tokenizationSupport.ts b/src/vs/editor/common/modes/supports/tokenizationSupport.ts
index a4eb4543602..695a9092b57 100644
--- a/src/vs/editor/common/modes/supports/tokenizationSupport.ts
+++ b/src/vs/editor/common/modes/supports/tokenizationSupport.ts
@@ -85,7 +85,7 @@ export class TokenizationSupport implements modes.ITokenizationSupport, IDisposa
this.supportsNestedModes = supportsNestedModes;
this._embeddedModesListeners = {};
if (this.supportsNestedModes) {
- if (!this._mode.registerSupport) {
+ if (!this._mode.setTokenizationSupport) {
throw new Error('Cannot be a mode with nested modes unless I can emit a tokenizationSupport changed event!');
}
}
@@ -239,7 +239,7 @@ export class TokenizationSupport implements modes.ITokenizationSupport, IDisposa
}
if (e.tokenizationSupport) {
emitting = true;
- this._mode.registerSupport(modes.MutableSupport.TokenizationSupport, (mode) => {
+ this._mode.setTokenizationSupport((mode) => {
return mode.tokenizationSupport;
});
emitting = false;
diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts
index ccaaeb52c72..123098a7a34 100644
--- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts
+++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts
@@ -32,7 +32,7 @@ export class EditorWorkerServiceImpl implements IEditorWorkerService {
private _workerManager:WorkerManager;
- constructor(modelService:IModelService) {
+ constructor(@IModelService modelService:IModelService) {
this._workerManager = new WorkerManager(modelService);
}
diff --git a/src/vs/editor/common/services/modeService.ts b/src/vs/editor/common/services/modeService.ts
index 8679b09bc72..95aca6a6743 100644
--- a/src/vs/editor/common/services/modeService.ts
+++ b/src/vs/editor/common/services/modeService.ts
@@ -9,10 +9,6 @@ import {IDisposable} from 'vs/base/common/lifecycle';
import {TPromise} from 'vs/base/common/winjs.base';
import {ServiceIdentifier, createDecorator} from 'vs/platform/instantiation/common/instantiation';
import * as modes from 'vs/editor/common/modes';
-import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
-import {IRichLanguageConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
-import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
-import {IModelService} from 'vs/editor/common/services/modelService';
export var IModeService = createDecorator('modeService');
@@ -73,8 +69,6 @@ export interface IModeService {
getOrCreateModeByLanguageName(languageName: string): TPromise;
getOrCreateModeByFilenameOrFirstLine(filename: string, firstLine?:string): TPromise;
- registerRichEditSupport(modeId: string, support: IRichLanguageConfiguration): IDisposable;
registerTokenizationSupport(modeId: string, callback: (mode: modes.IMode) => modes.ITokenizationSupport): IDisposable;
registerTokenizationSupport2(modeId: string, support: modes.TokensProvider): IDisposable;
- registerMonarchDefinition(modelService: IModelService, editorWorkerService: IEditorWorkerService, modeId:string, language:ILanguage): IDisposable;
}
diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts
index 7a5e3acc1c1..8b08c71f2a6 100644
--- a/src/vs/editor/common/services/modeServiceImpl.ts
+++ b/src/vs/editor/common/services/modeServiceImpl.ts
@@ -7,7 +7,7 @@
import * as nls from 'vs/nls';
import {onUnexpectedError} from 'vs/base/common/errors';
import Event, {Emitter} from 'vs/base/common/event';
-import {IDisposable, combinedDisposable, empty as EmptyDisposable} from 'vs/base/common/lifecycle'; // TODO@Alex
+import {IDisposable, empty as EmptyDisposable} from 'vs/base/common/lifecycle'; // TODO@Alex
import * as objects from 'vs/base/common/objects';
import * as paths from 'vs/base/common/paths';
import {TPromise} from 'vs/base/common/winjs.base';
@@ -20,16 +20,8 @@ import {IThreadService, Remotable, ThreadAffinity} from 'vs/platform/thread/comm
import * as modes from 'vs/editor/common/modes';
import {FrankensteinMode} from 'vs/editor/common/modes/abstractMode';
import {ILegacyLanguageDefinition, ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
-import {ILexer} from 'vs/editor/common/modes/monarch/monarchCommon';
-import {compile} from 'vs/editor/common/modes/monarch/monarchCompile';
-import {createRichEditSupport} from 'vs/editor/common/modes/monarch/monarchDefinition';
-import {createTokenizationSupport} from 'vs/editor/common/modes/monarch/monarchLexer';
-import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
-import {IRichLanguageConfiguration, RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
-import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
import {LanguagesRegistry} from 'vs/editor/common/services/languagesRegistry';
import {ILanguageExtensionPoint, IValidLanguageExtensionPoint, IModeLookupResult, IModeService} from 'vs/editor/common/services/modeService';
-import {IModelService} from 'vs/editor/common/services/modelService';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {AbstractState} from 'vs/editor/common/modes/abstractState';
import {Token} from 'vs/editor/common/modes/supports';
@@ -395,18 +387,18 @@ export class ModeServiceImpl implements IModeService {
};
}
- private _registerModeSupport(mode:modes.IMode, support: modes.MutableSupport, callback: (mode: modes.IMode) => T): IDisposable {
- if (mode.registerSupport) {
- return mode.registerSupport(support, callback);
+ private _registerTokenizationSupport(mode:modes.IMode, callback: (mode: modes.IMode) => T): IDisposable {
+ if (mode.setTokenizationSupport) {
+ return mode.setTokenizationSupport(callback);
} else {
- console.warn('Cannot register support ' + modes.mutableSupportToString(support) + ' on mode ' + mode.getId() + ' because it does not support it.');
+ console.warn('Cannot register tokenizationSupport on mode ' + mode.getId() + ' because it does not support it.');
return EmptyDisposable;
}
}
- protected registerModeSupport(modeId: string, support: modes.MutableSupport, callback: (mode: modes.IMode) => T): IDisposable {
+ private registerModeSupport(modeId: string, callback: (mode: modes.IMode) => T): IDisposable {
if (this._instantiatedModes.hasOwnProperty(modeId)) {
- return this._registerModeSupport(this._instantiatedModes[modeId], support, callback);
+ return this._registerTokenizationSupport(this._instantiatedModes[modeId], callback);
}
let cc: (disposable:IDisposable)=>void;
@@ -417,7 +409,7 @@ export class ModeServiceImpl implements IModeService {
return;
}
- cc(this._registerModeSupport(mode, support, callback));
+ cc(this._registerTokenizationSupport(mode, callback));
disposable.dispose();
});
@@ -428,31 +420,12 @@ export class ModeServiceImpl implements IModeService {
};
}
- protected doRegisterMonarchDefinition(modeId:string, lexer: ILexer): IDisposable {
- return combinedDisposable(
- this.registerTokenizationSupport(modeId, (mode: modes.IMode) => {
- return createTokenizationSupport(this, mode, lexer);
- }),
-
- this.registerRichEditSupport(modeId, createRichEditSupport(lexer))
- );
- }
-
- public registerMonarchDefinition(modelService: IModelService, editorWorkerService:IEditorWorkerService, modeId:string, language:ILanguage): IDisposable {
- var lexer = compile(objects.clone(language));
- return this.doRegisterMonarchDefinition(modeId, lexer);
- }
-
- public registerRichEditSupport(modeId: string, support: IRichLanguageConfiguration): IDisposable {
- return this.registerModeSupport(modeId, modes.MutableSupport.RichEditSupport, (mode) => new RichEditSupport(modeId, mode.richEditSupport, support));
- }
-
public registerTokenizationSupport(modeId: string, callback: (mode: modes.IMode) => modes.ITokenizationSupport): IDisposable {
- return this.registerModeSupport(modeId, modes.MutableSupport.TokenizationSupport, callback);
+ return this.registerModeSupport(modeId, callback);
}
public registerTokenizationSupport2(modeId: string, support: modes.TokensProvider): IDisposable {
- return this.registerModeSupport(modeId, modes.MutableSupport.TokenizationSupport, (mode) => {
+ return this.registerModeSupport(modeId, (mode) => {
return new TokenizationSupport2Adapter(mode, support);
});
}
@@ -550,9 +523,9 @@ export class MainThreadModeServiceImpl extends ModeServiceImpl {
private _onReadyPromise: TPromise;
constructor(
- threadService:IThreadService,
- extensionService:IExtensionService,
- configurationService: IConfigurationService
+ @IThreadService threadService:IThreadService,
+ @IExtensionService extensionService:IExtensionService,
+ @IConfigurationService configurationService:IConfigurationService
) {
super(threadService, extensionService);
this._configurationService = configurationService;
@@ -648,12 +621,6 @@ export class MainThreadModeServiceImpl extends ModeServiceImpl {
this._getModeServiceWorkerHelper().instantiateMode(modeId);
return super._createMode(modeId);
}
-
- public registerMonarchDefinition(modelService: IModelService, editorWorkerService:IEditorWorkerService, modeId:string, language:ILanguage): IDisposable {
- this._getModeServiceWorkerHelper().registerMonarchDefinition(modeId, language);
- var lexer = compile(objects.clone(language));
- return super.doRegisterMonarchDefinition(modeId, lexer);
- }
}
export interface IWorkerInitData {
@@ -689,8 +656,4 @@ export class ModeServiceWorkerHelper {
public configureModeById(modeId:string, options:any):void {
this._modeService.configureMode(modeId, options);
}
-
- public registerMonarchDefinition(modeId:string, language:ILanguage): void {
- this._modeService.registerMonarchDefinition(null, null, modeId, language);
- }
}
diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts
index 977946b6f24..d3bdb5cf9d8 100644
--- a/src/vs/editor/common/services/modelServiceImpl.ts
+++ b/src/vs/editor/common/services/modelServiceImpl.ts
@@ -210,11 +210,11 @@ export class ModelServiceImpl implements IModelService {
private _models: { [modelId: string]: ModelData; };
constructor(
- threadService: IThreadService,
- markerService: IMarkerService,
- modeService: IModeService,
- configurationService: IConfigurationService,
- messageService: IMessageService
+ @IThreadService threadService: IThreadService,
+ @IMarkerService markerService: IMarkerService,
+ @IModeService modeService: IModeService,
+ @IConfigurationService configurationService: IConfigurationService,
+ @IMessageService messageService: IMessageService
) {
this._modelCreationOptions = {
tabSize: DEFAULT_INDENTATION.tabSize,
diff --git a/src/vs/editor/contrib/comment/common/blockCommentCommand.ts b/src/vs/editor/contrib/comment/common/blockCommentCommand.ts
index 30d6bd41cfc..36b24d4f79b 100644
--- a/src/vs/editor/contrib/comment/common/blockCommentCommand.ts
+++ b/src/vs/editor/contrib/comment/common/blockCommentCommand.ts
@@ -10,6 +10,7 @@ import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {ICommentsConfiguration} from 'vs/editor/common/modes';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export class BlockCommentCommand implements editorCommon.ICommand {
@@ -121,8 +122,8 @@ export class BlockCommentCommand implements editorCommon.ICommand {
var endLineNumber = this._selection.endLineNumber;
var endColumn = this._selection.endColumn;
- let richEditSupport = model.getModeAtPosition(startLineNumber, startColumn).richEditSupport;
- let config = richEditSupport ? richEditSupport.comments : null;
+ let modeId = model.getModeIdAtPosition(startLineNumber, startColumn);
+ let config = LanguageConfigurationRegistry.getComments(modeId);
if (!config || !config.blockCommentStartToken || !config.blockCommentEndToken) {
// Mode does not support block comments
return;
diff --git a/src/vs/editor/contrib/comment/common/lineCommentCommand.ts b/src/vs/editor/contrib/comment/common/lineCommentCommand.ts
index 57cb19c4942..9997968a87a 100644
--- a/src/vs/editor/contrib/comment/common/lineCommentCommand.ts
+++ b/src/vs/editor/contrib/comment/common/lineCommentCommand.ts
@@ -10,8 +10,9 @@ import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
-import {ICommentsConfiguration, IMode} from 'vs/editor/common/modes';
+import {ICommentsConfiguration} from 'vs/editor/common/modes';
import {BlockCommentCommand} from './blockCommentCommand';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface IInsertionPoint {
ignore: boolean;
@@ -69,19 +70,17 @@ export class LineCommentCommand implements editorCommon.ICommand {
i:number,
lineCount:number,
lineNumber:number,
- mode: IMode,
modeId: string;
for (i = 0, lineCount = endLineNumber - startLineNumber + 1; i < lineCount; i++) {
lineNumber = startLineNumber + i;
- mode = model.getModeAtPosition(lineNumber, 1);
- modeId = mode.getId();
+ modeId = model.getModeIdAtPosition(lineNumber, 1);
// Find the commentStr for this line, if none is found then bail out: we cannot do line comments
if (seenModes[modeId]) {
commentStr = seenModes[modeId];
} else {
- config = (mode.richEditSupport ? mode.richEditSupport.comments : null);
+ config = LanguageConfigurationRegistry.getComments(modeId);
commentStr = (config ? config.lineCommentToken : null);
if (!commentStr) {
// Mode does not support line comments
@@ -273,8 +272,8 @@ export class LineCommentCommand implements editorCommon.ICommand {
* Given an unsuccessful analysis, delegate to the block comment command
*/
private _executeBlockComment(model:editorCommon.ITokenizedModel, builder:editorCommon.IEditOperationBuilder, s:Selection): void {
- let richEditSupport = model.getModeAtPosition(s.startLineNumber, s.startColumn).richEditSupport;
- let config = richEditSupport ? richEditSupport.comments : null;
+ let modeId = model.getModeIdAtPosition(s.startLineNumber, s.startColumn);
+ let config = LanguageConfigurationRegistry.getComments(modeId);
if (!config || !config.blockCommentStartToken || !config.blockCommentEndToken) {
// Mode does not support block comments
return;
diff --git a/src/vs/editor/contrib/comment/test/common/blockCommentCommand.test.ts b/src/vs/editor/contrib/comment/test/common/blockCommentCommand.test.ts
index b821b9ad6c2..f9c436feadc 100644
--- a/src/vs/editor/contrib/comment/test/common/blockCommentCommand.test.ts
+++ b/src/vs/editor/contrib/comment/test/common/blockCommentCommand.test.ts
@@ -10,7 +10,7 @@ import {testCommand} from 'vs/editor/test/common/commands/commandTestUtils';
import {CommentMode} from 'vs/editor/test/common/testModes';
function testBlockCommentCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
- var mode = new CommentMode({ lineCommentToken: '!@#', blockCommentStartToken: '<0', blockCommentEndToken: '0>' });
+ var mode = new CommentMode({ lineComment: '!@#', blockComment: ['<0', '0>'] });
testCommand(lines, mode, selection, (sel) => new BlockCommentCommand(sel), expectedLines, expectedSelection);
}
diff --git a/src/vs/editor/contrib/comment/test/common/lineCommentCommand.test.ts b/src/vs/editor/contrib/comment/test/common/lineCommentCommand.test.ts
index 7d022fdcf4b..3374bd80401 100644
--- a/src/vs/editor/contrib/comment/test/common/lineCommentCommand.test.ts
+++ b/src/vs/editor/contrib/comment/test/common/lineCommentCommand.test.ts
@@ -13,12 +13,12 @@ import {CommentMode} from 'vs/editor/test/common/testModes';
suite('Editor Contrib - Line Comment Command', () => {
function testLineCommentCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
- var mode = new CommentMode({ lineCommentToken: '!@#', blockCommentStartToken: '' });
+ var mode = new CommentMode({ lineComment: '!@#', blockComment: [''] });
testCommand(lines, mode, selection, (sel) => new LineCommentCommand(sel, 4, Type.Toggle), expectedLines, expectedSelection);
}
function testAddLineCommentCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
- var mode = new CommentMode({ lineCommentToken: '!@#', blockCommentStartToken: '' });
+ var mode = new CommentMode({ lineComment: '!@#', blockComment: [''] });
testCommand(lines, mode, selection, (sel) => new LineCommentCommand(sel, 4, Type.ForceAdd), expectedLines, expectedSelection);
}
@@ -520,7 +520,7 @@ suite('Editor Contrib - Line Comment Command', () => {
suite('Editor Contrib - Line Comment As Block Comment', () => {
function testLineCommentCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
- var mode = new CommentMode({ lineCommentToken: '', blockCommentStartToken: '(', blockCommentEndToken: ')' });
+ var mode = new CommentMode({ lineComment: '', blockComment: ['(', ')'] });
testCommand(lines, mode, selection, (sel) => new LineCommentCommand(sel, 4, Type.Toggle), expectedLines, expectedSelection);
}
@@ -630,7 +630,7 @@ suite('Editor Contrib - Line Comment As Block Comment', () => {
suite('Editor Contrib - Line Comment As Block Comment 2', () => {
function testLineCommentCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
- var mode = new CommentMode({ lineCommentToken: null, blockCommentStartToken: '' });
+ var mode = new CommentMode({ lineComment: null, blockComment: [''] });
testCommand(lines, mode, selection, (sel) => new LineCommentCommand(sel, 4, Type.Toggle), expectedLines, expectedSelection);
}
diff --git a/src/vs/editor/contrib/smartSelect/common/tokenTree.ts b/src/vs/editor/contrib/smartSelect/common/tokenTree.ts
index 6df50038259..6d542e4015e 100644
--- a/src/vs/editor/contrib/smartSelect/common/tokenTree.ts
+++ b/src/vs/editor/contrib/smartSelect/common/tokenTree.ts
@@ -7,9 +7,11 @@
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {ILineTokens, IModel, IPosition, IRange, IRichEditBracket} from 'vs/editor/common/editorCommon';
-import {IModeTransition, IRichEditBrackets} from 'vs/editor/common/modes';
+import {IRichEditBrackets} from 'vs/editor/common/modes';
import {ignoreBracketsInToken} from 'vs/editor/common/modes/supports';
import {BracketsUtils} from 'vs/editor/common/modes/supports/richEditBrackets';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
+import {ModeTransition} from 'vs/editor/common/core/modeTransition';
export enum TokenTreeBracket {
None = 0,
@@ -117,7 +119,7 @@ class TokenScanner {
private _currentTokenIndex: number;
private _currentTokenStart: number;
private _currentLineTokens: ILineTokens;
- private _currentLineModeTransitions: IModeTransition[];
+ private _currentLineModeTransitions: ModeTransition[];
private _currentModeIndex: number;
private _nextModeStart: number;
private _currentModeBrackets: IRichEditBrackets;
@@ -159,7 +161,7 @@ class TokenScanner {
this._currentModeIndex++;
this._nextModeStart = (this._currentModeIndex + 1 < this._currentLineModeTransitions.length ? this._currentLineModeTransitions[this._currentModeIndex + 1].startIndex : this._currentLineText.length + 1);
let mode = (this._currentModeIndex < this._currentLineModeTransitions.length ? this._currentLineModeTransitions[this._currentModeIndex] : null);
- this._currentModeBrackets = (mode && mode.mode.richEditSupport ? mode.mode.richEditSupport.brackets : null);
+ this._currentModeBrackets = (mode ? LanguageConfigurationRegistry.getBracketsSupport(mode.modeId) : null);
}
let tokenType = this._currentLineTokens.getTokenType(this._currentTokenIndex);
diff --git a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts
index 2c60be0d67a..5027d748740 100644
--- a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts
+++ b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts
@@ -7,20 +7,18 @@
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
import {Range} from 'vs/editor/common/core/range';
-import {IMode, IRichEditSupport, IndentAction} from 'vs/editor/common/modes';
+import {IMode, IndentAction} from 'vs/editor/common/modes';
import {TokenSelectionSupport} from 'vs/editor/contrib/smartSelect/common/tokenSelectionSupport';
import {createMockModelService} from 'vs/editor/test/common/servicesTestUtils';
import {MockTokenizingMode} from 'vs/editor/test/common/mocks/mockMode';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
class MockJSMode extends MockTokenizingMode {
- public richEditSupport: IRichEditSupport;
-
constructor() {
- super('js', 'mock-js');
+ super('js-tokenSelectionSupport', 'mock-js');
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
+ LanguageConfigurationRegistry.register(this.getId(), {
brackets: [
['(', ')'],
['{', '}'],
diff --git a/src/vs/editor/node/languageConfiguration.ts b/src/vs/editor/node/languageConfiguration.ts
index ee164b73212..b036c4cd5b2 100644
--- a/src/vs/editor/node/languageConfiguration.ts
+++ b/src/vs/editor/node/languageConfiguration.ts
@@ -7,9 +7,10 @@
import * as nls from 'vs/nls';
import {parse} from 'vs/base/common/json';
import {readFile} from 'vs/base/node/pfs';
-import {IRichLanguageConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
+import {IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {IModeService} from 'vs/editor/common/services/modeService';
import {IAutoClosingPair} from 'vs/editor/common/modes';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
type CharacterPair = [string, string];
@@ -88,7 +89,7 @@ export class LanguageConfigurationFileHandler {
richEditConfig.surroundingPairs = this._mapCharacterPairs(configuration.surroundingPairs);
}
- this._modeService.registerRichEditSupport(modeId, richEditConfig);
+ LanguageConfigurationRegistry.register(modeId, richEditConfig);
}
private _mapCharacterPairs(pairs:CharacterPair[]): IAutoClosingPair[] {
diff --git a/src/vs/editor/standalone-languages/bat.ts b/src/vs/editor/standalone-languages/bat.ts
index f4467fc2c9a..9d178571e5f 100644
--- a/src/vs/editor/standalone-languages/bat.ts
+++ b/src/vs/editor/standalone-languages/bat.ts
@@ -5,24 +5,19 @@
'use strict';
-import {ILanguage} from './types';
-
-export var language = {
- displayName: 'Batch',
- name: 'bat',
- defaultToken: '',
- ignoreCase: true,
-
- lineComment: 'REM',
-
- autoClosingPairs: [ ['{','}' ], ['[',']' ], ['(',')' ], ['"','"' ]], // Exclude '
-
- brackets: [
- { token: 'punctuation.bracket', open: '{', close: '}' },
- { token: 'punctuation.parenthesis', open: '(', close: ')' },
- { token: 'punctuation.square', open: '[', close: ']' }
- ],
+import {ILanguage, IRichLanguageConfiguration} from './types';
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: 'REM'
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
// enhancedBrackets: [
// {
// openTrigger: 'l',
@@ -34,6 +29,18 @@ export var language = {
// tokenType: 'keyword.tag-setlocal'
// }
// ],
+};
+
+export var language = {
+ defaultToken: '',
+ ignoreCase: true,
+ tokenPostfix: '.bat',
+
+ brackets: [
+ { token: 'punctuation.bracket', open: '{', close: '}' },
+ { token: 'punctuation.parenthesis', open: '(', close: ')' },
+ { token: 'punctuation.square', open: '[', close: ']' }
+ ],
keywords: /call|defined|echo|errorlevel|exist|for|goto|if|pause|set|shift|start|title|not|pushd|popd/,
diff --git a/src/vs/editor/standalone-languages/coffee.ts b/src/vs/editor/standalone-languages/coffee.ts
index fa4e845f713..87dd292ab73 100644
--- a/src/vs/editor/standalone-languages/coffee.ts
+++ b/src/vs/editor/standalone-languages/coffee.ts
@@ -5,17 +5,33 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\$\-\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+ comments: {
+ blockComment: ['###', '###'],
+ lineComment: '#'
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+ // enhancedBrackets: [
+ // { open: /for$/ }, { open: /while$/ }, { open: /loop$/ }, { open: /if$/ }, { open: /unless$/ },
+ // { open: /else$/ }, { open: /switch$/ }, { open: /try$/ }, { open: /catch$/ }, { open: /finally$/ },
+ // { open: /class$/ }, { open: /->$/ }
+ // ],
+};
export var language = {
- displayName: 'CoffeeScript',
- name: 'coffee',
defaultToken: '',
ignoreCase: true,
-
- lineComment: '#',
- blockCommentStart: '###',
- blockCommentEnd: '###',
+ tokenPostfix: '.coffee',
brackets: [
{ open:'{', close:'}', token:'delimiter.curly'},
@@ -23,14 +39,6 @@ export var language = {
{ open:'(', close:')', token:'delimiter.parenthesis'}
],
- // enhancedBrackets: [
- // { open: /for$/ }, { open: /while$/ }, { open: /loop$/ }, { open: /if$/ }, { open: /unless$/ },
- // { open: /else$/ }, { open: /switch$/ }, { open: /try$/ }, { open: /catch$/ }, { open: /finally$/ },
- // { open: /class$/ }, { open: /->$/ }
- // ],
-
- // the default separators
- wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\$\-\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
regEx: /\/(?!\/\/)(?:[^\/\\]|\\.)*\/[igm]*/,
keywords: [
diff --git a/src/vs/editor/standalone-languages/cpp.ts b/src/vs/editor/standalone-languages/cpp.ts
index 1012ac3602d..ed3a5382700 100644
--- a/src/vs/editor/standalone-languages/cpp.ts
+++ b/src/vs/editor/standalone-languages/cpp.ts
@@ -5,16 +5,25 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'C++',
- name: 'cpp',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
+ tokenPostfix: '.cpp',
brackets: [
{ token: 'delimiter.curly', open: '{', close: '}' },
@@ -23,8 +32,6 @@ export var language = {
{ token: 'delimiter.angle', open: '<', close: '>' }
],
- autoClosingPairs: [ ['{', '}'], ['[', ']'], ['(', ')'], ['"', '"']], // Skip < > which would be there by default.
-
keywords: [
'abstract',
'amp',
diff --git a/src/vs/editor/standalone-languages/csharp.ts b/src/vs/editor/standalone-languages/csharp.ts
index 3134a172f67..1c097ad6e36 100644
--- a/src/vs/editor/standalone-languages/csharp.ts
+++ b/src/vs/editor/standalone-languages/csharp.ts
@@ -5,28 +5,27 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: '',
- name: 'cs',
defaultToken: '',
-
- // used in the editor to insert comments (ctrl+/ or shift+alt+A)
- lineComment: '// ',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
-
- // the default separators except `@`
- wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
-
- autoClosingPairs: [
- ['"', '"'],
- ['\'', '\''],
- ['{', '}'],
- ['[', ']'],
- ['(', ')'],
- ],
+ tokenPostfix: '.cs',
brackets: [
{ open: '{', close: '}', token: 'delimiter.curly' },
diff --git a/src/vs/editor/standalone-languages/dockerfile.ts b/src/vs/editor/standalone-languages/dockerfile.ts
index af3530fc548..2516932d878 100644
--- a/src/vs/editor/standalone-languages/dockerfile.ts
+++ b/src/vs/editor/standalone-languages/dockerfile.ts
@@ -5,12 +5,23 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Dockerfile',
- name: 'dockerfile',
defaultToken: '',
+ tokenPostfix: '.dockerfile',
instructions: /FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|VOLUME|LABEL|USER|WORKDIR|COPY|CMD|ENTRYPOINT/,
diff --git a/src/vs/editor/standalone-languages/fsharp.ts b/src/vs/editor/standalone-languages/fsharp.ts
index d9c226423f2..82605e111f4 100644
--- a/src/vs/editor/standalone-languages/fsharp.ts
+++ b/src/vs/editor/standalone-languages/fsharp.ts
@@ -5,18 +5,25 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['(*', '*)'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '"', close: '"', notIn: ['string', 'comment'] }
+ ]
+};
export var language = {
- displayName: 'F#',
- name: 'fs',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '(*',
- blockCommentEnd: '*)',
-
- autoClosingPairs: [ ['{', '}'], ['[', ']'], ['(', ')'], ['"', '"']], // Skip < > which would be there by default.
+ tokenPostfix: '.fs',
keywords: [
'abstract', 'and', 'atomic', 'as',
diff --git a/src/vs/editor/standalone-languages/go.ts b/src/vs/editor/standalone-languages/go.ts
index 687ca733e90..77d2eaabd57 100644
--- a/src/vs/editor/standalone-languages/go.ts
+++ b/src/vs/editor/standalone-languages/go.ts
@@ -5,19 +5,26 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '"', close: '"', notIn: ['string', 'comment'] }
+ ]
+};
export var language = {
- displayName: 'Go',
- name: 'go',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
-
- autoClosingPairs: [ ['{', '}'], ['[', ']'], ['(', ')'], ['"', '"']], // Skip < > which would be there by default.
+ tokenPostfix: '.go',
keywords: [
'break',
diff --git a/src/vs/editor/standalone-languages/ini.ts b/src/vs/editor/standalone-languages/ini.ts
index e7924706fd9..b36bf454daf 100644
--- a/src/vs/editor/standalone-languages/ini.ts
+++ b/src/vs/editor/standalone-languages/ini.ts
@@ -5,16 +5,26 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '#'
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Ini',
- name: 'ini',
defaultToken: '',
-
- lineComment: '#',
- blockCommentStart: '#',
- blockCommentEnd: ' ',
+ tokenPostfix: '.ini',
// we include these common regular expressions
escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
diff --git a/src/vs/editor/standalone-languages/jade.ts b/src/vs/editor/standalone-languages/jade.ts
index bcc0a419c10..aefe907764e 100644
--- a/src/vs/editor/standalone-languages/jade.ts
+++ b/src/vs/editor/standalone-languages/jade.ts
@@ -5,17 +5,28 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//'
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Jade',
- name: 'jade',
- defaultToken: '',
+ defaultToken: '',
+ tokenPostfix: '.jade',
ignoreCase: true,
- lineComment: '//',
-
brackets: [
{ token:'delimiter.curly', open: '{', close: '}' },
{ token:'delimiter.array', open: '[', close: ']' },
diff --git a/src/vs/editor/standalone-languages/java.ts b/src/vs/editor/standalone-languages/java.ts
index e9f75b8325b..24653f8c653 100644
--- a/src/vs/editor/standalone-languages/java.ts
+++ b/src/vs/editor/standalone-languages/java.ts
@@ -5,19 +5,29 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ // the default separators except `@$`
+ wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Java',
- name: 'java',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
-
- // the default separators except `@$`
- wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+ tokenPostfix: '.java',
keywords: [
'abstract', 'continue', 'for', 'new', 'switch', 'assert', 'default',
diff --git a/src/vs/editor/standalone-languages/lua.ts b/src/vs/editor/standalone-languages/lua.ts
index fca9794696c..51250f1d5f0 100644
--- a/src/vs/editor/standalone-languages/lua.ts
+++ b/src/vs/editor/standalone-languages/lua.ts
@@ -5,34 +5,44 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '--',
+ blockComment: ['--[[', ']]'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Lua',
- name: 'lua',
defaultToken: '',
-
- lineComment: '--',
- blockCommentStart: '--[[',
- blockCommentEnd: ']]',
+ tokenPostfix: '.lua',
keywords: [
'and', 'break', 'do', 'else', 'elseif',
- 'end', 'false', 'for', 'function', 'goto', 'if',
- 'in', 'local', 'nil', 'not', 'or',
- 'repeat', 'return', 'then', 'true', 'until',
- 'while'
+ 'end', 'false', 'for', 'function', 'goto', 'if',
+ 'in', 'local', 'nil', 'not', 'or',
+ 'repeat', 'return', 'then', 'true', 'until',
+ 'while'
],
brackets: [
- { token: 'delimiter.bracket', open: '{', close: '}'},
- { token: 'delimiter.array', open: '[', close: ']'},
- { token: 'delimiter.parenthesis', open: '(', close: ')'}
+ { token: 'delimiter.bracket', open: '{', close: '}'},
+ { token: 'delimiter.array', open: '[', close: ']'},
+ { token: 'delimiter.parenthesis', open: '(', close: ')'}
],
operators: [
'+', '-', '*', '/', '%', '^', '#', '==', '~=', '<=', '>=', '<', '>', '=',
- ';', ':', ',', '.', '..', '...'
+ ';', ':', ',', '.', '..', '...'
],
// we include these common regular expressions
@@ -44,7 +54,7 @@ export var language = {
root: [
// identifiers and keywords
[/[a-zA-Z_]\w*/, { cases: { '@keywords': {token:'keyword.$0'},
- '@default': 'identifier' } }],
+ '@default': 'identifier' } }],
// whitespace
{ include: '@whitespace' },
@@ -55,7 +65,7 @@ export var language = {
// delimiters and operators
[/[{}()\[\]]/, '@brackets'],
[/@symbols/, { cases: { '@operators': 'delimiter',
- '@default' : '' } } ],
+ '@default' : '' } } ],
// numbers
[/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
@@ -89,7 +99,7 @@ export var language = {
[/@escapes/, 'string.escape'],
[/\\./, 'string.escape.invalid'],
[/["']/, { cases: { '$#==$S2' : { token: 'string', next: '@pop' },
- '@default': 'string' }} ]
+ '@default': 'string' }} ]
],
},
diff --git a/src/vs/editor/standalone-languages/objective-c.ts b/src/vs/editor/standalone-languages/objective-c.ts
index 86c5e50f4a5..ceeea41e8aa 100644
--- a/src/vs/editor/standalone-languages/objective-c.ts
+++ b/src/vs/editor/standalone-languages/objective-c.ts
@@ -5,16 +5,27 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Objective-C',
- name: 'objective-c',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
+ tokenPostfix: '.objective-c',
keywords: [
'#import',
diff --git a/src/vs/editor/standalone-languages/powershell.ts b/src/vs/editor/standalone-languages/powershell.ts
index 1921efa51e7..72432bc0645 100644
--- a/src/vs/editor/standalone-languages/powershell.ts
+++ b/src/vs/editor/standalone-languages/powershell.ts
@@ -5,36 +5,39 @@
'use strict';
-import {ILanguage} from './types';
-
-export var language = {
- displayName: 'PowerShell',
- name: 'ps1',
- defaultToken: '',
- ignoreCase: true,
-
- lineComment: '#',
- blockCommentStart: '<#',
- blockCommentEnd: '#>',
+import {ILanguage, IRichLanguageConfiguration} from './types';
+export var conf:IRichLanguageConfiguration = {
// the default separators except `$-`
- wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
-
- brackets: [
- { token: 'delimiter.curly', open: '{', close: '}' },
- { token: 'delimiter.square', open: '[', close: ']' },
- { token: 'delimiter.parenthesis', open: '(', close: ')' }],
-
+ wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+ comments: {
+ lineComment: '#',
+ blockComment: ['<#', '#>'],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
// enhancedBrackets: [
// { tokenType:'string', openTrigger: '"', open: /@"$/, closeComplete: '"@' },
// { tokenType:'string', openTrigger: '\'', open: /@'$/, closeComplete: '\'@' },
// { tokenType:'string', openTrigger: '"', open: /"$/, closeComplete: '"' },
// { tokenType: 'string', openTrigger: '\'', open: /'$/, closeComplete: '\'' }
// ],
+};
- autoClosingPairs: [['{', '}'], ['[', ']'], ['(', ')']], // Defined explicitly, to suppress the
- // default auto-closing of ' and " which is
- // override above by enhancedBrackets
+export var language = {
+ defaultToken: '',
+ ignoreCase: true,
+ tokenPostfix: '.ps1',
+
+ brackets: [
+ { token: 'delimiter.curly', open: '{', close: '}' },
+ { token: 'delimiter.square', open: '[', close: ']' },
+ { token: 'delimiter.parenthesis', open: '(', close: ')' }
+ ],
keywords: [
'begin', 'break', 'catch', 'class', 'continue', 'data',
diff --git a/src/vs/editor/standalone-languages/python.ts b/src/vs/editor/standalone-languages/python.ts
index 0f77fcda89f..239c9855f10 100644
--- a/src/vs/editor/standalone-languages/python.ts
+++ b/src/vs/editor/standalone-languages/python.ts
@@ -5,16 +5,28 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '#',
+ blockComment: ['\'\'\'', '\'\'\''],
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+ // Cause an automatic indent to occur after lines ending in :.
+ // enhancedBrackets: [ { open: /.*:\s*$/, closeComplete: 'else:' } ],
+};
export var language = {
- displayName: '',
- name: 'python',
defaultToken: '',
-
- lineComment: '#',
- blockCommentStart: '\'\'\'',
- blockCommentEnd: '\'\'\'',
+ tokenPostfix: '.python',
keywords: [
'and',
@@ -155,9 +167,6 @@ export var language = {
{ open: '(', close: ')', token: 'delimiter.parenthesis' }
],
- // Cause an automatic indent to occur after lines ending in :.
- // enhancedBrackets: [ { open: /.*:\s*$/, closeComplete: 'else:' } ],
-
tokenizer: {
root: [
{ include: '@whitespace' },
diff --git a/src/vs/editor/standalone-languages/r.ts b/src/vs/editor/standalone-languages/r.ts
index f8200fb07ac..d4af395dc9b 100644
--- a/src/vs/editor/standalone-languages/r.ts
+++ b/src/vs/editor/standalone-languages/r.ts
@@ -5,16 +5,25 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '#'
+ },
+ brackets: [['{','}'], ['[',']'], ['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'R',
- name: 'r',
defaultToken: '',
-
- lineComment: '#',
- blockCommentStart: '',
- blockCommentEnd: '',
+ tokenPostfix: '.r',
roxygen: [
'@param',
diff --git a/src/vs/editor/standalone-languages/ruby.ts b/src/vs/editor/standalone-languages/ruby.ts
index 7ad7eaa2961..6434fb7d196 100644
--- a/src/vs/editor/standalone-languages/ruby.ts
+++ b/src/vs/editor/standalone-languages/ruby.ts
@@ -5,7 +5,26 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '#',
+ blockComment: ['=begin', '=end'],
+ },
+ brackets: [['(',')'],['{','}'], ['[',']']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ ],
+ __electricCharacterSupport: {
+ // trigger outdenting on 'end'
+ embeddedElectricCharacters: ['d']
+ }
+};
/*
* Ruby language definition
@@ -57,12 +76,7 @@ import {ILanguage} from './types';
*/
export var language = {
- displayName: '',
- name: 'ruby',
-
- lineComment: '#',
- blockCommentStart: '=begin',
- blockCommentEnd: '=end',
+ tokenPostfix: '.ruby',
keywords: [
'__LINE__', '__ENCODING__', '__FILE__', 'BEGIN', 'END', 'alias', 'and', 'begin',
@@ -102,9 +116,6 @@ export var language = {
{ open: '[', close: ']', token: 'delimiter.square'}
],
- // trigger outdenting on 'end'
- outdentTriggers: 'd',
-
// we include these common regular expressions
symbols: /[=> {
- displayName: 'SQL',
- name: 'sql',
- defaultToken: '',
- ignoreCase: true,
- brackets: [
- { open: '[', close: ']', token: 'delimiter.square' },
- { open: '(', close: ')', token: 'delimiter.parenthesis' }
- ],
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '--',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['[',']'],['(',')']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ ]
// enhancedBrackets:[
// { openTrigger: 'n', open: /begin$/i, closeComplete: 'end', matchCase: true },
// { openTrigger: 'e', open: /case$/i, closeComplete: 'end', matchCase: true },
// { openTrigger: 'n', open: /when$/i, closeComplete: 'then', matchCase: true }
// ],
- noindentBrackets: '()',
- lineComment: '--',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
+};
+
+export var language = {
+ defaultToken: '',
+ tokenPostfix: '.sql',
+ ignoreCase: true,
+
+ brackets: [
+ { open: '[', close: ']', token: 'delimiter.square' },
+ { open: '(', close: ')', token: 'delimiter.parenthesis' }
+ ],
+
keywords: [
'ABORT_AFTER_WAIT',
'ABSENT',
diff --git a/src/vs/editor/standalone-languages/swift.ts b/src/vs/editor/standalone-languages/swift.ts
index c88abece100..f229db1afb4 100644
--- a/src/vs/editor/standalone-languages/swift.ts
+++ b/src/vs/editor/standalone-languages/swift.ts
@@ -4,16 +4,27 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [['{','}'],['[',']'],['(',')'],['<','>']],
+ autoClosingPairs: [
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'Swift',
- name: 'swift',
defaultToken: '',
-
- lineComment: '//',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
+ tokenPostfix: '.swift',
// TODO(owensd): Support the full range of unicode valid identifiers.
identifier: /[a-zA-Z_][\w$]*/,
diff --git a/src/vs/editor/standalone-languages/test/bat.test.ts b/src/vs/editor/standalone-languages/test/bat.test.ts
index d27e58552be..e534d2cc022 100644
--- a/src/vs/editor/standalone-languages/test/bat.test.ts
+++ b/src/vs/editor/standalone-languages/test/bat.test.ts
@@ -5,7 +5,7 @@
'use strict';
-import {language} from 'vs/editor/standalone-languages/bat';
+import {language, conf} from 'vs/editor/standalone-languages/bat';
import {testOnEnter, testTokenization} from 'vs/editor/standalone-languages/test/testUtil';
testTokenization('bat', language, [
@@ -333,7 +333,7 @@ testTokenization('bat', language, [
]}]
]);
-testOnEnter('bat', language, (assertOnEnter) => {
+testOnEnter('bat', conf, (assertOnEnter) => {
assertOnEnter.nothing('', ' a', '');
assertOnEnter.indents('', ' {', '');
assertOnEnter.indents('', '( ', '');
diff --git a/src/vs/editor/standalone-languages/test/coffee.test.ts b/src/vs/editor/standalone-languages/test/coffee.test.ts
index 0155005fcc9..e8c2a6b74a5 100644
--- a/src/vs/editor/standalone-languages/test/coffee.test.ts
+++ b/src/vs/editor/standalone-languages/test/coffee.test.ts
@@ -5,10 +5,10 @@
'use strict';
-import {language} from 'vs/editor/standalone-languages/coffee';
+import {language, conf} from 'vs/editor/standalone-languages/coffee';
import {testOnEnter, testTokenization} from 'vs/editor/standalone-languages/test/testUtil';
-testOnEnter('coffeescript', language, (assertOnEnter) => {
+testOnEnter('coffeescript', conf, (assertOnEnter) => {
assertOnEnter.nothing('', ' a', '');
assertOnEnter.indents('', ' {', '');
assertOnEnter.indents('', '( ', '');
diff --git a/src/vs/editor/standalone-languages/test/cpp.test.ts b/src/vs/editor/standalone-languages/test/cpp.test.ts
index b0388ebb60e..9566afd9f62 100644
--- a/src/vs/editor/standalone-languages/test/cpp.test.ts
+++ b/src/vs/editor/standalone-languages/test/cpp.test.ts
@@ -5,10 +5,10 @@
'use strict';
-import {language} from 'vs/editor/standalone-languages/cpp';
+import {language, conf} from 'vs/editor/standalone-languages/cpp';
import {testOnEnter, testTokenization} from 'vs/editor/standalone-languages/test/testUtil';
-testOnEnter('cpp', language, (assertOnEnter) => {
+testOnEnter('cpp', conf, (assertOnEnter) => {
assertOnEnter.nothing('', ' a', '');
assertOnEnter.indents('', ' <', '');
assertOnEnter.indents('', ' {', '');
diff --git a/src/vs/editor/standalone-languages/test/java.test.ts b/src/vs/editor/standalone-languages/test/java.test.ts
index afc102b87da..21ffd379b7c 100644
--- a/src/vs/editor/standalone-languages/test/java.test.ts
+++ b/src/vs/editor/standalone-languages/test/java.test.ts
@@ -6,7 +6,7 @@
'use strict';
import * as assert from 'assert';
-import {language} from 'vs/editor/standalone-languages/java';
+import {language, conf} from 'vs/editor/standalone-languages/java';
import {testTokenization} from 'vs/editor/standalone-languages/test/testUtil';
testTokenization('java', language, [
@@ -605,7 +605,7 @@ testTokenization('java', language, [
suite('java', () => {
test('word definition', () => {
- var wordDefinition = language.wordDefinition;
+ var wordDefinition = conf.wordPattern;
assert.deepEqual('a b cde'.match(wordDefinition), ['a', 'b', 'cde']);
assert.deepEqual('public static void main(String[] args) {'.match(wordDefinition),
diff --git a/src/vs/editor/standalone-languages/test/powershell.test.ts b/src/vs/editor/standalone-languages/test/powershell.test.ts
index 7347cecff8c..dc166d39087 100644
--- a/src/vs/editor/standalone-languages/test/powershell.test.ts
+++ b/src/vs/editor/standalone-languages/test/powershell.test.ts
@@ -6,7 +6,7 @@
'use strict';
import * as assert from 'assert';
-import {language} from 'vs/editor/standalone-languages/powershell';
+import {language, conf} from 'vs/editor/standalone-languages/powershell';
import {testTokenization} from 'vs/editor/standalone-languages/test/testUtil';
testTokenization('powershell', language, [
@@ -738,7 +738,7 @@ testTokenization('powershell', language, [
suite('powershell', () => {
test('word definition', () => {
- var wordDefinition = language.wordDefinition;
+ var wordDefinition = conf.wordPattern;
assert.deepEqual('a b cde'.match(wordDefinition), ['a', 'b', 'cde']);
assert.deepEqual('if ($parameterSet["class"] -eq "blank")'.match(wordDefinition), ['if', '$parameterSet', 'class', '-eq', 'blank']);
diff --git a/src/vs/editor/standalone-languages/test/testUtil.ts b/src/vs/editor/standalone-languages/test/testUtil.ts
index a5e2453079c..2f8f506a65d 100644
--- a/src/vs/editor/standalone-languages/test/testUtil.ts
+++ b/src/vs/editor/standalone-languages/test/testUtil.ts
@@ -5,11 +5,8 @@
'use strict';
-import {compile} from 'vs/editor/common/modes/monarch/monarchCompile';
-import {createRichEditSupport} from 'vs/editor/common/modes/monarch/monarchDefinition';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
import {createOnEnterAsserter, executeMonarchTokenizationTests} from 'vs/editor/test/common/modesUtil';
-import {ILanguage} from '../types';
+import {ILanguage, IRichLanguageConfiguration} from '../types';
export interface IRelaxedToken {
startIndex: number;
@@ -28,19 +25,17 @@ export interface IOnEnterAsserter {
}
export function testTokenization(name:string, language: ILanguage, tests:ITestItem[][]): void {
- suite(language.displayName || name, () => {
+ suite(name, () => {
test('Tokenization', () => {
executeMonarchTokenizationTests(name, language, tests);
});
});
}
-export function testOnEnter(name:string, language: ILanguage, callback:(assertOnEnter: IOnEnterAsserter)=>void): void {
- suite(language.displayName || name, () => {
+export function testOnEnter(name:string, conf: IRichLanguageConfiguration, callback:(assertOnEnter: IOnEnterAsserter)=>void): void {
+ suite(name, () => {
test('onEnter', () => {
- var lexer = compile(language);
- var richEditSupport = new RichEditSupport('test', null, createRichEditSupport(lexer));
- callback(createOnEnterAsserter('test', richEditSupport));
+ callback(createOnEnterAsserter('test', conf));
});
});
}
diff --git a/src/vs/editor/standalone-languages/types.ts b/src/vs/editor/standalone-languages/types.ts
index 0039d16eb4c..7c9293c936a 100644
--- a/src/vs/editor/standalone-languages/types.ts
+++ b/src/vs/editor/standalone-languages/types.ts
@@ -17,63 +17,87 @@ export interface ILanguageDef {
export interface ILanguage {
// required
- name: string; // unique name to identify the language
tokenizer: Object; // map from string to ILanguageRule[]
+ tokenPostfix: string; // attach this to every token class (by default '.' + name)
// optional
- displayName?: string; // nice display name
ignoreCase?: boolean; // is the language case insensitive?
- lineComment?: string; // used to insert/delete line comments in the editor
- blockCommentStart?: string; // used to insert/delete block comments in the editor
- blockCommentEnd?: string;
defaultToken?: string; // if no match in the tokenizer assign this token class (default 'source')
brackets?: ILanguageBracket[]; // for example [['{','}','delimiter.curly']]
// advanced
start?: string; // start symbol in the tokenizer (by default the first entry is used)
- tokenPostfix?: string; // attach this to every token class (by default '.' + name)
- autoClosingPairs?: string[][]; // for example [['"','"']]
- wordDefinition?: RegExp; // word definition regular expression
- outdentTriggers?: string; // characters that could potentially cause outdentation
- // enhancedBrackets?: IRegexBracketPair[]; // Advanced auto completion, auto indenting, and bracket matching
}
/**
- * This interface can be shortened as an array, ie. ['{','}','delimiter.curly']
- */
+ * This interface can be shortened as an array, ie. ['{','}','delimiter.curly']
+ */
export interface ILanguageBracket {
open: string; // open bracket
close: string; // closeing bracket
token: string; // token class
}
-// export interface ILanguageAutoComplete {
-// triggers: string; // characters that trigger auto completion rules
-// match: string|RegExp; // autocomplete if this matches
-// complete: string; // complete with this string
-// }
+export type CharacterPair = [string, string];
-// export interface ILanguageAutoIndent {
-// match: string|RegExp; // auto indent if this matches on enter
-// matchAfter: string|RegExp; // and auto-outdent if this matches on the next line
-// }
+export interface CommentRule {
+ lineComment?: string;
+ blockComment?: CharacterPair;
+}
-// /**
-// * Regular expression based brackets. These are always electric.
-// */
-// export interface IRegexBracketPair {
-// // openTrigger?: string; // The character that will trigger the evaluation of 'open'.
-// open: RegExp; // The definition of when an opening brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character).
-// closeComplete?: string; // How to complete a matching open brace. Matches from 'open' will be expanded, e.g. '$1>'
-// matchCase?: boolean; // If set to true, the case of the string captured in 'open' will be detected an applied also to 'closeComplete'.
-// // This is useful for cases like BEGIN/END or begin/end where the opening and closing phrases are unrelated.
-// // For identical phrases, use the $1 replacement syntax above directly in closeComplete, as it will
-// // include the proper casing from the captured string in 'open'.
-// // Upper/Lower/Camel cases are detected. Camel case dection uses only the first two characters and assumes
-// // that 'closeComplete' contains wors separated by spaces (e.g. 'End Loop')
+export interface IIndentationRules {
+ decreaseIndentPattern: RegExp;
+ increaseIndentPattern: RegExp;
+ indentNextLinePattern?: RegExp;
+ unIndentedLinePattern?: RegExp;
+}
-// // closeTrigger?: string; // The character that will trigger the evaluation of 'close'.
-// close?: RegExp; // The definition of when a closing brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character).
-// tokenType?: string; // The type of the token. Matches from 'open' or 'close' will be expanded, e.g. 'keyword.$1'.
-// // Only used to auto-(un)indent a closing bracket.
-// }
+export interface IOnEnterRegExpRules {
+ beforeText: RegExp;
+ afterText?: RegExp;
+ action: IEnterAction;
+}
+
+export interface IEnterAction {
+ indentAction:IndentAction;
+ appendText?:string;
+ removeText?:number;
+}
+
+export enum IndentAction {
+ None,
+ Indent,
+ IndentOutdent,
+ Outdent
+}
+export interface IAutoClosingPair {
+ open:string;
+ close:string;
+}
+
+export interface IAutoClosingPairConditional extends IAutoClosingPair {
+ notIn?: string[];
+}
+
+export interface IDocComment {
+ scope: string; // What tokens should be used to detect a doc comment (e.g. 'comment.documentation').
+ open: string; // The string that starts a doc comment (e.g. '/**')
+ lineStart: string; // The string that appears at the start of each line, except the first and last (e.g. ' * ').
+ close?: string; // The string that appears on the last line and closes the doc comment (e.g. ' */').
+}
+
+export interface IBracketElectricCharacterContribution {
+ docComment?: IDocComment;
+ embeddedElectricCharacters?: string[];
+}
+
+export interface IRichLanguageConfiguration {
+ comments?: CommentRule;
+ brackets?: CharacterPair[];
+ wordPattern?: RegExp;
+ indentationRules?: IIndentationRules;
+ onEnterRules?: IOnEnterRegExpRules[];
+ autoClosingPairs?: IAutoClosingPairConditional[];
+ surroundingPairs?: IAutoClosingPair[];
+ __electricCharacterSupport?: IBracketElectricCharacterContribution;
+}
diff --git a/src/vs/editor/standalone-languages/vb.ts b/src/vs/editor/standalone-languages/vb.ts
index 2bada8d0fa2..a24004fcb89 100644
--- a/src/vs/editor/standalone-languages/vb.ts
+++ b/src/vs/editor/standalone-languages/vb.ts
@@ -5,57 +5,92 @@
'use strict';
-import {ILanguage} from './types';
+import {ILanguage, IRichLanguageConfiguration} from './types';
+
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ lineComment: '\'',
+ blockComment: ['/*', '*/'],
+ },
+ brackets: [
+ ['{','}'],['[',']'],['(',')'],['<','>'],
+ ['addhandler','end addhandler'],
+ ['class','end class'],
+ ['enum','end enum'],
+ ['event','end event'],
+ ['function','end function'],
+ ['get','end get'],
+ ['if','end if'],
+ ['interface','end interface'],
+ ['module','end module'],
+ ['namespace','end namespace'],
+ ['operator','end operator'],
+ ['property','end property'],
+ ['raiseevent','end raiseevent'],
+ ['removehandler','end removehandler'],
+ ['select','end select'],
+ ['set','end set'],
+ ['structure','end structure'],
+ ['sub','end sub'],
+ ['synclock','end synclock'],
+ ['try','end try'],
+ ['while','end while'],
+ ['with','end with'],
+ ['using','end using'],
+ ['do','loop'],
+ ['for','next']
+ ],
+ autoClosingPairs: [
+ { open: '{', close: '}', notIn: ['string', 'comment'] },
+ { open: '[', close: ']', notIn: ['string', 'comment'] },
+ { open: '(', close: ')', notIn: ['string', 'comment'] },
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ { open: '<', close: '>', notIn: ['string', 'comment'] },
+ ]
+};
export var language = {
- displayName: 'VB',
- name: 'vb',
defaultToken: '',
+ tokenPostfix: '.vb',
ignoreCase: true,
brackets: [
- { token:'delimiter.bracket', open: '{', close: '}'},
- { token:'delimiter.array', open: '[', close: ']'},
- { token:'delimiter.parenthesis', open: '(', close: ')'},
- { token:'delimiter.angle', open: '<', close: '>'},
+ { token:'delimiter.bracket', open: '{', close: '}'},
+ { token:'delimiter.array', open: '[', close: ']'},
+ { token:'delimiter.parenthesis', open: '(', close: ')'},
+ { token:'delimiter.angle', open: '<', close: '>'},
- // Special bracket statement pairs
- // according to https://msdn.microsoft.com/en-us/library/tsw2a11z.aspx
- { token: 'keyword.tag-addhandler', open: 'addhandler', close: 'end addhandler'},
- { token: 'keyword.tag-class', open: 'class', close: 'end class'},
- { token: 'keyword.tag-enum', open: 'enum', close: 'end enum'},
- { token: 'keyword.tag-event', open: 'event', close: 'end event'},
- { token: 'keyword.tag-function', open: 'function', close: 'end function'},
- { token: 'keyword.tag-get', open: 'get', close: 'end get'},
- { token: 'keyword.tag-if', open: 'if', close: 'end if'},
- { token: 'keyword.tag-interface', open: 'interface', close: 'end interface'},
- { token: 'keyword.tag-module', open: 'module', close: 'end module'},
- { token: 'keyword.tag-namespace', open: 'namespace', close: 'end namespace'},
- { token: 'keyword.tag-operator', open: 'operator', close: 'end operator'},
- { token: 'keyword.tag-property', open: 'property', close: 'end property'},
- { token: 'keyword.tag-raiseevent', open: 'raiseevent', close: 'end raiseevent'},
- { token: 'keyword.tag-removehandler', open: 'removehandler', close: 'end removehandler'},
- { token: 'keyword.tag-select', open: 'select', close: 'end select'},
- { token: 'keyword.tag-set', open: 'set', close: 'end set'},
- { token: 'keyword.tag-structure', open: 'structure', close: 'end structure'},
- { token: 'keyword.tag-sub', open: 'sub', close: 'end sub'},
- { token: 'keyword.tag-synclock', open: 'synclock', close: 'end synclock'},
- { token: 'keyword.tag-try', open: 'try', close: 'end try'},
- { token: 'keyword.tag-while', open: 'while', close: 'end while'},
- { token: 'keyword.tag-with', open: 'with', close: 'end with'},
+ // Special bracket statement pairs
+ // according to https://msdn.microsoft.com/en-us/library/tsw2a11z.aspx
+ { token: 'keyword.tag-addhandler', open: 'addhandler', close: 'end addhandler'},
+ { token: 'keyword.tag-class', open: 'class', close: 'end class'},
+ { token: 'keyword.tag-enum', open: 'enum', close: 'end enum'},
+ { token: 'keyword.tag-event', open: 'event', close: 'end event'},
+ { token: 'keyword.tag-function', open: 'function', close: 'end function'},
+ { token: 'keyword.tag-get', open: 'get', close: 'end get'},
+ { token: 'keyword.tag-if', open: 'if', close: 'end if'},
+ { token: 'keyword.tag-interface', open: 'interface', close: 'end interface'},
+ { token: 'keyword.tag-module', open: 'module', close: 'end module'},
+ { token: 'keyword.tag-namespace', open: 'namespace', close: 'end namespace'},
+ { token: 'keyword.tag-operator', open: 'operator', close: 'end operator'},
+ { token: 'keyword.tag-property', open: 'property', close: 'end property'},
+ { token: 'keyword.tag-raiseevent', open: 'raiseevent', close: 'end raiseevent'},
+ { token: 'keyword.tag-removehandler', open: 'removehandler', close: 'end removehandler'},
+ { token: 'keyword.tag-select', open: 'select', close: 'end select'},
+ { token: 'keyword.tag-set', open: 'set', close: 'end set'},
+ { token: 'keyword.tag-structure', open: 'structure', close: 'end structure'},
+ { token: 'keyword.tag-sub', open: 'sub', close: 'end sub'},
+ { token: 'keyword.tag-synclock', open: 'synclock', close: 'end synclock'},
+ { token: 'keyword.tag-try', open: 'try', close: 'end try'},
+ { token: 'keyword.tag-while', open: 'while', close: 'end while'},
+ { token: 'keyword.tag-with', open: 'with', close: 'end with'},
- // Other pairs
- { token: 'keyword.tag-using', open: 'using', close: 'end using' },
- { token: 'keyword.tag-do', open: 'do', close: 'loop' },
- { token: 'keyword.tag-for', open: 'for', close: 'next' }
+ // Other pairs
+ { token: 'keyword.tag-using', open: 'using', close: 'end using' },
+ { token: 'keyword.tag-do', open: 'do', close: 'loop' },
+ { token: 'keyword.tag-for', open: 'for', close: 'next' }
],
- autoClosingPairs: [ ['{', '}'], ['[', ']'], ['(', ')'], ['"', '"'], ['<', '>'], ],
-
- lineComment: '\'',
- blockCommentStart: '/*',
- blockCommentEnd: '*/',
-
keywords: [
'AddHandler', 'AddressOf', 'Alias', 'And', 'AndAlso', 'As', 'Async', 'Boolean', 'ByRef', 'Byte', 'ByVal', 'Call',
'Case', 'Catch', 'CBool', 'CByte', 'CChar', 'CDate', 'CDbl', 'CDec', 'Char', 'CInt', 'Class', 'CLng',
diff --git a/src/vs/editor/standalone-languages/xml.ts b/src/vs/editor/standalone-languages/xml.ts
index 5e530c28110..22ebfae022b 100644
--- a/src/vs/editor/standalone-languages/xml.ts
+++ b/src/vs/editor/standalone-languages/xml.ts
@@ -5,22 +5,17 @@
'use strict';
-import {ILanguage} from './types';
-
-export var language = {
- displayName: 'XML',
- name: 'xml',
- defaultToken: '',
-
- ignoreCase: true,
-
- lineComment: '', // no line comment in xml
- blockCommentStart: '',
-
- // Useful regular expressions
- qualifiedName: /(?:[\w\.\-]+:)?[\w\.\-]+/,
+import {ILanguage, IRichLanguageConfiguration} from './types';
+export var conf:IRichLanguageConfiguration = {
+ comments: {
+ blockComment: [''],
+ },
+ brackets: [['{','}'],['[',']'],['(',')'],['<','>']],
+ autoClosingPairs: [
+ { open: '\'', close: '\'', notIn: ['string', 'comment'] },
+ { open: '"', close: '"', notIn: ['string', 'comment'] },
+ ]
// enhancedBrackets: [{
// tokenType: 'tag.tag-$1.xml',
// openTrigger: '>',
@@ -29,8 +24,16 @@ export var language = {
// closeTrigger: '>',
// close: /<\/(\w[\w\d]*)\s*>$/i
// }],
+};
- autoClosingPairs: [['\'', '\''], ['"', '"'] ],
+export var language = {
+ defaultToken: '',
+ tokenPostfix: '.xml',
+
+ ignoreCase: true,
+
+ // Useful regular expressions
+ qualifiedName: /(?:[\w\.\-]+:)?[\w\.\-]+/,
tokenizer: {
root: [
diff --git a/src/vs/editor/test/common/commands/shiftCommand.test.ts b/src/vs/editor/test/common/commands/shiftCommand.test.ts
index 1efc7d72172..df15da8e2ea 100644
--- a/src/vs/editor/test/common/commands/shiftCommand.test.ts
+++ b/src/vs/editor/test/common/commands/shiftCommand.test.ts
@@ -8,8 +8,8 @@ import * as assert from 'assert';
import {ShiftCommand} from 'vs/editor/common/commands/shiftCommand';
import {Selection} from 'vs/editor/common/core/selection';
import {IIdentifiedSingleEditOperation} from 'vs/editor/common/editorCommon';
-import {IRichEditSupport, IndentAction} from 'vs/editor/common/modes';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {IndentAction} from 'vs/editor/common/modes';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {createSingleEditOp, getEditOperation, testCommand} from 'vs/editor/test/common/commands/commandTestUtils';
import {withEditorModel} from 'vs/editor/test/common/editorTestUtils';
import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
@@ -32,11 +32,9 @@ function testUnshiftCommand(lines: string[], selection: Selection, expectedLines
class DocBlockCommentMode extends MockMode {
- public richEditSupport: IRichEditSupport;
-
constructor() {
super();
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
+ LanguageConfigurationRegistry.register(this.getId(), {
brackets: [
['(', ')'],
['{', '}'],
diff --git a/src/vs/editor/test/common/controller/cursor.test.ts b/src/vs/editor/test/common/controller/cursor.test.ts
index 4595547c5ec..67c1ba94118 100644
--- a/src/vs/editor/test/common/controller/cursor.test.ts
+++ b/src/vs/editor/test/common/controller/cursor.test.ts
@@ -16,10 +16,11 @@ import {
ITokenizedModel, IEditOperationBuilder, ICursorStateComputerData
} from 'vs/editor/common/editorCommon';
import {Model} from 'vs/editor/common/model/model';
-import {IMode, IRichEditSupport, IndentAction} from 'vs/editor/common/modes';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {IMode, IndentAction} from 'vs/editor/common/modes';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {MockConfiguration} from 'vs/editor/test/common/mocks/mockConfiguration';
import {BracketMode} from 'vs/editor/test/common/testModes';
+import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
let H = Handler;
@@ -1062,41 +1063,26 @@ suite('Editor Controller - Cursor', () => {
});
});
-class TestMode {
- public getId():string {
- return 'testing';
- }
-
- public toSimplifiedMode(): IMode {
- return this;
- }
-}
-
-class SurroundingMode extends TestMode {
- public richEditSupport: IRichEditSupport;
-
+class SurroundingMode extends MockMode {
constructor() {
super();
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
+ LanguageConfigurationRegistry.register(this.getId(), {
autoClosingPairs: [{ open: '(', close: ')' }]
});
}
}
-class OnEnterMode extends TestMode {
- public richEditSupport: IRichEditSupport;
-
+class OnEnterMode extends MockMode {
constructor(indentAction: IndentAction) {
super();
- this.richEditSupport = {
- onEnter: {
- onEnter: (model, position) => {
- return {
- indentAction: indentAction
- };
+ LanguageConfigurationRegistry.register(this.getId(), {
+ onEnterRules: [{
+ beforeText: /.*/,
+ action: {
+ indentAction: indentAction
}
- }
- };
+ }]
+ });
}
}
diff --git a/src/vs/editor/test/common/mocks/mockMode.ts b/src/vs/editor/test/common/mocks/mockMode.ts
index d2edd055a3f..0fdd4b18fc1 100644
--- a/src/vs/editor/test/common/mocks/mockMode.ts
+++ b/src/vs/editor/test/common/mocks/mockMode.ts
@@ -9,10 +9,13 @@ import {AbstractState} from 'vs/editor/common/modes/abstractState';
import {TokenizationSupport} from 'vs/editor/common/modes/supports/tokenizationSupport';
export class MockMode implements IMode {
-
+ private static instanceCount = 0;
private _id:string;
- constructor(id:string = 'mockMode') {
+ constructor(id?:string) {
+ if (typeof id === 'undefined') {
+ id = 'mockMode' + (++MockMode.instanceCount);
+ }
this._id = id;
}
diff --git a/src/vs/editor/test/common/mocks/mockModeService.ts b/src/vs/editor/test/common/mocks/mockModeService.ts
index d6b2de4549c..6941fc9d362 100644
--- a/src/vs/editor/test/common/mocks/mockModeService.ts
+++ b/src/vs/editor/test/common/mocks/mockModeService.ts
@@ -9,10 +9,6 @@ import {IDisposable} from 'vs/base/common/lifecycle';
import {TPromise} from 'vs/base/common/winjs.base';
import {ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation';
import * as modes from 'vs/editor/common/modes';
-import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
-import {IRichLanguageConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
-import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
-import {IModelService} from 'vs/editor/common/services/modelService';
import {IModeService, IModeLookupResult} from 'vs/editor/common/services/modeService';
export class MockModeService implements IModeService {
@@ -83,16 +79,10 @@ export class MockModeService implements IModeService {
throw new Error('Not implemented');
}
- registerRichEditSupport(modeId: string, support: IRichLanguageConfiguration): IDisposable {
- throw new Error('Not implemented');
- }
registerTokenizationSupport(modeId: string, callback: (mode: modes.IMode) => modes.ITokenizationSupport): IDisposable {
throw new Error('Not implemented');
}
registerTokenizationSupport2(modeId: string, support: modes.TokensProvider): IDisposable {
throw new Error('Not implemented');
}
- registerMonarchDefinition(modelService: IModelService, editorWorkerService: IEditorWorkerService, modeId:string, language:ILanguage): IDisposable {
- throw new Error('Not implemented');
- }
}
diff --git a/src/vs/editor/test/common/modes/supports/onEnter.test.ts b/src/vs/editor/test/common/modes/supports/onEnter.test.ts
index b050594c95f..4ec3eb14888 100644
--- a/src/vs/editor/test/common/modes/supports/onEnter.test.ts
+++ b/src/vs/editor/test/common/modes/supports/onEnter.test.ts
@@ -11,7 +11,7 @@ import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
suite('OnEnter', () => {
test('uses indentationRules', () => {
- var support = new OnEnterSupport(null, {
+ var support = new OnEnterSupport(null, null, {
indentationRules: {
decreaseIndentPattern: /^\s*((?!\S.*\/[*]).*[*]\/\s*)?[})\]]|^\s*(case\b.*|default):\s*(\/\/.*|\/[*].*[*]\/\s*)?$/,
increaseIndentPattern: /(\{[^}"']*|\([^)"']*|\[[^\]"']*|^\s*(\{\}|\(\)|\[\]|(case\b.*|default):))\s*(\/\/.*|\/[*].*[*]\/\s*)?$/,
@@ -42,7 +42,7 @@ suite('OnEnter', () => {
['(', ')'],
['begin', 'end']
];
- var support = new OnEnterSupport(null, {
+ var support = new OnEnterSupport(null, null, {
brackets: brackets
});
var testIndentAction = (beforeText:string, afterText:string, expected:IndentAction) => {
@@ -75,7 +75,7 @@ suite('OnEnter', () => {
});
test('uses regExpRules', () => {
- var support = new OnEnterSupport(null, {
+ var support = new OnEnterSupport(null, null, {
regExpRules: [
{
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
diff --git a/src/vs/editor/test/common/modes/tokenization.test.ts b/src/vs/editor/test/common/modes/tokenization.test.ts
index dbe1b45918c..c56db2344f2 100644
--- a/src/vs/editor/test/common/modes/tokenization.test.ts
+++ b/src/vs/editor/test/common/modes/tokenization.test.ts
@@ -104,7 +104,7 @@ export class SwitchingMode extends MockMode {
this.tokenizationSupport = new TokenizationSupport(this, this, true, false);
}
- registerSupport(support:modes.MutableSupport, callback:(mode:modes.IMode)=>T): IDisposable {
+ setTokenizationSupport(callback:(mode:modes.IMode)=>T): IDisposable {
return EmptyDisposable;
}
@@ -336,8 +336,8 @@ suite('Editor Modes - Tokenization', () => {
{ startIndex: 5, id: 'B' }
]);
- handleEvent(createMockLineContext('abc (def', lineTokens), 0, (mode:modes.IMode, context:modes.ILineContext, offset:number) => {
- assert.deepEqual(mode.getId(), 'A');
+ handleEvent(createMockLineContext('abc (def', lineTokens), 0, (modeId:string, context:modes.ILineContext, offset:number) => {
+ assert.deepEqual(modeId, 'A');
assert.equal(context.getTokenCount(), 3);
assert.equal(context.getTokenStartIndex(0), 0);
assert.equal(context.getTokenType(0), 'A.abc');
@@ -349,8 +349,8 @@ suite('Editor Modes - Tokenization', () => {
assert.equal(context.getLineContent(), 'abc (');
});
- handleEvent(createMockLineContext('abc (def', lineTokens), 6, (mode:modes.IMode, context:modes.ILineContext, offset:number) => {
- assert.deepEqual(mode.getId(), 'B');
+ handleEvent(createMockLineContext('abc (def', lineTokens), 6, (modeId:string, context:modes.ILineContext, offset:number) => {
+ assert.deepEqual(modeId, 'B');
assert.equal(context.getTokenCount(), 1);
assert.equal(context.getTokenStartIndex(0), 0);
assert.equal(context.getTokenType(0), 'B.def');
diff --git a/src/vs/editor/test/common/modesTestUtils.ts b/src/vs/editor/test/common/modesTestUtils.ts
index 10edb1a5162..90ff862fba4 100644
--- a/src/vs/editor/test/common/modesTestUtils.ts
+++ b/src/vs/editor/test/common/modesTestUtils.ts
@@ -6,26 +6,8 @@
import {Arrays} from 'vs/editor/common/core/arrays';
import * as modes from 'vs/editor/common/modes';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
-import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
-class ModeWithRichEditSupport extends MockMode {
-
- public richEditSupport: modes.IRichEditSupport;
-
- constructor(id:string, wordRegExp:RegExp) {
- super(id);
- this.richEditSupport = new RichEditSupport(id, null, {
- wordPattern: wordRegExp
- });
- }
-}
-
-export function createMockMode(id:string, wordRegExp:RegExp = null):modes.IMode {
- return new ModeWithRichEditSupport(id, wordRegExp);
-}
-
export interface TokenText {
text: string;
type: string;
diff --git a/src/vs/editor/test/common/modesUtil.ts b/src/vs/editor/test/common/modesUtil.ts
index afa1cdd2eab..5f31e19bda5 100644
--- a/src/vs/editor/test/common/modesUtil.ts
+++ b/src/vs/editor/test/common/modesUtil.ts
@@ -12,6 +12,7 @@ import {createTokenizationSupport} from 'vs/editor/common/modes/monarch/monarchL
import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
import {createMockModeService} from 'vs/editor/test/common/servicesTestUtils';
import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
+import {RichEditSupport, IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
export interface ITestItem {
line: string;
@@ -47,13 +48,14 @@ export interface IOnEnterAsserter {
indentsOutdents(oneLineAboveText:string, beforeText:string, afterText:string): void;
}
-export function createOnEnterAsserter(modeId:string, richEditSupport: modes.IRichEditSupport): IOnEnterAsserter {
+export function createOnEnterAsserter(modeId:string, conf: IRichLanguageConfiguration): IOnEnterAsserter {
var assertOne = (oneLineAboveText:string, beforeText:string, afterText:string, expected: modes.IndentAction) => {
var model = new Model(
[ oneLineAboveText, beforeText + afterText ].join('\n'),
Model.DEFAULT_CREATION_OPTIONS,
new MockMode(modeId)
);
+ var richEditSupport = new RichEditSupport(modeId, null, conf);
var actual = richEditSupport.onEnter.onEnter(model, { lineNumber: 2, column: beforeText.length + 1 });
if (expected === modes.IndentAction.None) {
assert.equal(actual, null, oneLineAboveText + '\\n' + beforeText + '|' + afterText);
@@ -92,9 +94,8 @@ export function executeTests2(tokenizationSupport: modes.TokensProvider, tests:I
}
}
-
export function executeMonarchTokenizationTests(name:string, language:ILanguage, tests:ITestItem[][]): void {
- var lexer = compile(language);
+ var lexer = compile(name, language);
var modeService = createMockModeService();
diff --git a/src/vs/editor/test/common/testModes.ts b/src/vs/editor/test/common/testModes.ts
index 49e782ed37c..3b5fcb607d3 100644
--- a/src/vs/editor/test/common/testModes.ts
+++ b/src/vs/editor/test/common/testModes.ts
@@ -6,7 +6,7 @@
import * as modes from 'vs/editor/common/modes';
import {AbstractState} from 'vs/editor/common/modes/abstractState';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry, CommentRule} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {TokenizationSupport} from 'vs/editor/common/modes/supports/tokenizationSupport';
import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
@@ -33,17 +33,16 @@ export class CommentState extends AbstractState {
export class CommentMode extends MockMode {
public tokenizationSupport: modes.ITokenizationSupport;
- public richEditSupport: modes.IRichEditSupport;
- constructor(commentsConfig:modes.ICommentsConfiguration) {
+ constructor(commentsConfig:CommentRule) {
super();
this.tokenizationSupport = new TokenizationSupport(this, {
getInitialState: () => new CommentState(this, 0)
}, false, false);
- this.richEditSupport = {
- comments:commentsConfig
- };
+ LanguageConfigurationRegistry.register(this.getId(), {
+ comments: commentsConfig
+ });
}
}
@@ -141,11 +140,9 @@ export class ModelMode2 extends MockMode {
export class BracketMode extends MockMode {
- public richEditSupport: modes.IRichEditSupport;
-
constructor() {
super();
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
+ LanguageConfigurationRegistry.register(this.getId(), {
brackets: [
['{', '}'],
['[', ']'],
diff --git a/src/vs/languages/css/common/css.ts b/src/vs/languages/css/common/css.ts
index 83a5aed0df6..9eb39e601e3 100644
--- a/src/vs/languages/css/common/css.ts
+++ b/src/vs/languages/css/common/css.ts
@@ -17,7 +17,7 @@ import {AbstractState} from 'vs/editor/common/modes/abstractState';
import {IMarker} from 'vs/platform/markers/common/markers';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IThreadService, ThreadAffinity} from 'vs/platform/thread/common/thread';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry, IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {TokenizationSupport} from 'vs/editor/common/modes/supports/tokenizationSupport';
import {wireCancellationToken} from 'vs/base/common/async';
@@ -278,8 +278,30 @@ export class State extends AbstractState {
export class CSSMode extends AbstractMode {
+ public static LANG_CONFIG:IRichLanguageConfiguration = {
+ // TODO@Martin: This definition does not work with umlauts for example
+ wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,
+
+ comments: {
+ blockComment: ['/*', '*/']
+ },
+
+ brackets: [
+ ['{', '}'],
+ ['[', ']'],
+ ['(', ')']
+ ],
+
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"', notIn: ['string'] },
+ { open: '\'', close: '\'', notIn: ['string'] }
+ ]
+ };
+
public tokenizationSupport: modes.ITokenizationSupport;
- public richEditSupport: modes.IRichEditSupport;
public inplaceReplaceSupport:modes.IInplaceReplaceSupport;
public configSupport:modes.IConfigurationSupport;
@@ -299,28 +321,7 @@ export class CSSMode extends AbstractMode {
getInitialState: () => new State(this, States.Selector, false, null, false, 0)
}, false, false);
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
- // TODO@Martin: This definition does not work with umlauts for example
- wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,
-
- comments: {
- blockComment: ['/*', '*/']
- },
-
- brackets: [
- ['{', '}'],
- ['[', ']'],
- ['(', ')']
- ],
-
- autoClosingPairs: [
- { open: '{', close: '}' },
- { open: '[', close: ']' },
- { open: '(', close: ')' },
- { open: '"', close: '"', notIn: ['string'] },
- { open: '\'', close: '\'', notIn: ['string'] }
- ]
- });
+ LanguageConfigurationRegistry.register(this.getId(), CSSMode.LANG_CONFIG);
this.inplaceReplaceSupport = this;
this.configSupport = this;
diff --git a/src/vs/languages/css/test/common/css-worker.test.ts b/src/vs/languages/css/test/common/css-worker.test.ts
index 43ec70606e6..ffefcef5a3d 100644
--- a/src/vs/languages/css/test/common/css-worker.test.ts
+++ b/src/vs/languages/css/test/common/css-worker.test.ts
@@ -14,12 +14,24 @@ import Modes = require('vs/editor/common/modes');
import WinJS = require('vs/base/common/winjs.base');
import cssErrors = require('vs/languages/css/common/parser/cssErrors');
import servicesUtil2 = require('vs/editor/test/common/servicesTestUtils');
-import modesUtil = require('vs/editor/test/common/modesTestUtils');
import {NULL_THREAD_SERVICE} from 'vs/platform/test/common/nullThreadService';
import {IMarker} from 'vs/platform/markers/common/markers';
+import {MockMode} from 'vs/editor/test/common/mocks/mockMode';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
+
+export class CSSMockMode extends MockMode {
+ constructor() {
+ super('css-mock-mode-id');
+ LanguageConfigurationRegistry.register(this.getId(), {
+ wordPattern: /(#?-?\d*\.\d\w*%?)|([@#.:!]?[\w-?]+%?)|[@#.!]/g
+ });
+ }
+}
+
+var cssMockMode = new CSSMockMode();
export function mockMirrorModel(content:string, url:URI = null) : mm.MirrorModel {
- return mm.createTestMirrorModelFromString(content, modesUtil.createMockMode('mock.mode.id', /(#?-?\d*\.\d\w*%?)|([@#.:!]?[\w-?]+%?)|[@#.!]/g), url);
+ return mm.createTestMirrorModelFromString(content, cssMockMode, url);
}
suite('Validation - CSS', () => {
@@ -39,7 +51,7 @@ suite('Validation - CSS', () => {
resourceService: resourceService,
markerService: markerService
});
- var worker = new cssWorker.CSSWorker('mock.mode.id', services.resourceService, services.markerService);
+ var worker = new cssWorker.CSSWorker('css-mock-mode-id', services.resourceService, services.markerService);
worker.doValidate([url]);
var markers = markerService.read({ resource: url });
@@ -61,7 +73,7 @@ suite('Validation - CSS', () => {
markerService: markerService
});
- var worker = new cssWorker.CSSWorker('mock.mode.id', services.resourceService, services.markerService);
+ var worker = new cssWorker.CSSWorker('css-mock-mode-id', services.resourceService, services.markerService);
worker.doValidate([url]);
var markers = markerService.read({ resource: url });
diff --git a/src/vs/languages/css/test/common/css.test.ts b/src/vs/languages/css/test/common/css.test.ts
index 8509272daf8..659dd2a5c6c 100644
--- a/src/vs/languages/css/test/common/css.test.ts
+++ b/src/vs/languages/css/test/common/css.test.ts
@@ -11,6 +11,7 @@ import {NULL_THREAD_SERVICE} from 'vs/platform/test/common/nullThreadService';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
suite('CSS Colorizing', () => {
@@ -31,8 +32,8 @@ suite('CSS Colorizing', () => {
);
tokenizationSupport = mode.tokenizationSupport;
- assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
- wordDefinition = mode.richEditSupport.wordDefinition;
+ assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), CSSMode.LANG_CONFIG);
+ wordDefinition = LanguageConfigurationRegistry.getWordDefinition(mode.getId());
})();
test('Skip whitespace', () => {
diff --git a/src/vs/languages/handlebars/common/handlebars.ts b/src/vs/languages/handlebars/common/handlebars.ts
index 15164883363..965c1b68d61 100644
--- a/src/vs/languages/handlebars/common/handlebars.ts
+++ b/src/vs/languages/handlebars/common/handlebars.ts
@@ -10,7 +10,7 @@ import handlebarsTokenTypes = require('vs/languages/handlebars/common/handlebars
import htmlWorker = require('vs/languages/html/common/htmlWorker');
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IModeService} from 'vs/editor/common/services/modeService';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry, IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {createWordRegExp} from 'vs/editor/common/modes/abstractMode';
import {ILeavingNestedModeData} from 'vs/editor/common/modes/supports/tokenizationSupport';
import {IThreadService} from 'vs/platform/thread/common/thread';
@@ -107,6 +107,49 @@ export class HandlebarsState extends htmlMode.State {
export class HandlebarsMode extends htmlMode.HTMLMode {
+ public static LANG_CONFIG:IRichLanguageConfiguration = {
+ wordPattern: createWordRegExp('#-?%'),
+
+ comments: {
+ blockComment: ['']
+ },
+
+ brackets: [
+ [''],
+ ['{{', '}}']
+ ],
+
+ __electricCharacterSupport: {
+ embeddedElectricCharacters: ['*', '}', ']', ')']
+ },
+
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"' },
+ { open: '\'', close: '\'' }
+ ],
+
+ surroundingPairs: [
+ { open: '<', close: '>' },
+ { open: '"', close: '"' },
+ { open: '\'', close: '\'' }
+ ],
+
+ onEnterRules: [
+ {
+ beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
+ afterText: /^<\/(\w[\w\d]*)\s*>$/i,
+ action: { indentAction: modes.IndentAction.IndentOutdent }
+ },
+ {
+ beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
+ action: { indentAction: modes.IndentAction.Indent }
+ }
+ ],
+ };
+
constructor(
descriptor:modes.IModeDescriptor,
@IInstantiationService instantiationService: IInstantiationService,
@@ -148,53 +191,8 @@ export class HandlebarsMode extends htmlMode.HTMLMode {
return wireCancellationToken(token, this._provideLinks(model.uri));
}
}, true);
- }
- protected _createRichEditSupport(): modes.IRichEditSupport {
- return new RichEditSupport(this.getId(), null, {
-
- wordPattern: createWordRegExp('#-?%'),
-
- comments: {
- blockComment: ['']
- },
-
- brackets: [
- [''],
- ['{{', '}}']
- ],
-
- __electricCharacterSupport: {
- caseInsensitive: true,
- embeddedElectricCharacters: ['*', '}', ']', ')']
- },
-
- autoClosingPairs: [
- { open: '{', close: '}' },
- { open: '[', close: ']' },
- { open: '(', close: ')' },
- { open: '"', close: '"' },
- { open: '\'', close: '\'' }
- ],
-
- surroundingPairs: [
- { open: '<', close: '>' },
- { open: '"', close: '"' },
- { open: '\'', close: '\'' }
- ],
-
- onEnterRules: [
- {
- beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
- afterText: /^<\/(\w[\w\d]*)\s*>$/i,
- action: { indentAction: modes.IndentAction.IndentOutdent }
- },
- {
- beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
- action: { indentAction: modes.IndentAction.Indent }
- }
- ],
- });
+ LanguageConfigurationRegistry.register(this.getId(), HandlebarsMode.LANG_CONFIG);
}
public getInitialState() : modes.IState {
diff --git a/src/vs/languages/html/common/html.ts b/src/vs/languages/html/common/html.ts
index ad6191580ab..29ab8545fad 100644
--- a/src/vs/languages/html/common/html.ts
+++ b/src/vs/languages/html/common/html.ts
@@ -16,7 +16,7 @@ import {IModeService} from 'vs/editor/common/services/modeService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import * as htmlTokenTypes from 'vs/languages/html/common/htmlTokenTypes';
import {EMPTY_ELEMENTS} from 'vs/languages/html/common/htmlEmptyTagsShared';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry, IRichLanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {TokenizationSupport, IEnteringNestedModeData, ILeavingNestedModeData, ITokenizationCustomization} from 'vs/editor/common/modes/supports/tokenizationSupport';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {wireCancellationToken} from 'vs/base/common/async';
@@ -285,8 +285,49 @@ export class State extends AbstractState {
export class HTMLMode extends AbstractMode implements ITokenizationCustomization {
+ public static LANG_CONFIG:IRichLanguageConfiguration = {
+ wordPattern: createWordRegExp('#-?%'),
+
+ comments: {
+ blockComment: ['']
+ },
+
+ brackets: [
+ [''],
+ ['<', '>'],
+ ],
+
+ __electricCharacterSupport: {
+ embeddedElectricCharacters: ['*', '}', ']', ')']
+ },
+
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '"', close: '"' },
+ { open: '\'', close: '\'' }
+ ],
+
+ surroundingPairs: [
+ { open: '"', close: '"' },
+ { open: '\'', close: '\'' }
+ ],
+
+ onEnterRules: [
+ {
+ beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
+ afterText: /^<\/([_:\w][_:\w-.\d]*)\s*>$/i,
+ action: { indentAction: modes.IndentAction.IndentOutdent }
+ },
+ {
+ beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
+ action: { indentAction: modes.IndentAction.Indent }
+ }
+ ],
+ };
+
public tokenizationSupport: modes.ITokenizationSupport;
- public richEditSupport: modes.IRichEditSupport;
public configSupport: modes.IConfigurationSupport;
private modeService:IModeService;
@@ -308,8 +349,6 @@ export class HTMLMode extends AbstractMode impl
this.tokenizationSupport = new TokenizationSupport(this, this, true, true);
this.configSupport = this;
- this.richEditSupport = this._createRichEditSupport();
-
this._registerSupports();
}
@@ -362,6 +401,8 @@ export class HTMLMode extends AbstractMode impl
return wireCancellationToken(token, this._provideLinks(model.uri));
}
}, true);
+
+ LanguageConfigurationRegistry.register(this.getId(), HTMLMode.LANG_CONFIG);
}
protected _createModeWorkerManager(descriptor:modes.IModeDescriptor, instantiationService: IInstantiationService): ModeWorkerManager {
@@ -372,52 +413,6 @@ export class HTMLMode extends AbstractMode impl
return this._modeWorkerManager.worker(runner);
}
- protected _createRichEditSupport(): modes.IRichEditSupport {
- return new RichEditSupport(this.getId(), null, {
-
- wordPattern: createWordRegExp('#-?%'),
-
- comments: {
- blockComment: ['']
- },
-
- brackets: [
- [''],
- ['<', '>'],
- ],
-
- __electricCharacterSupport: {
- caseInsensitive: true,
- embeddedElectricCharacters: ['*', '}', ']', ')']
- },
-
- autoClosingPairs: [
- { open: '{', close: '}' },
- { open: '[', close: ']' },
- { open: '(', close: ')' },
- { open: '"', close: '"' },
- { open: '\'', close: '\'' }
- ],
-
- surroundingPairs: [
- { open: '"', close: '"' },
- { open: '\'', close: '\'' }
- ],
-
- onEnterRules: [
- {
- beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
- afterText: /^<\/([_:\w][_:\w-.\d]*)\s*>$/i,
- action: { indentAction: modes.IndentAction.IndentOutdent }
- },
- {
- beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
- action: { indentAction: modes.IndentAction.Indent }
- }
- ],
- });
- }
-
// TokenizationSupport
public getInitialState():modes.IState {
diff --git a/src/vs/languages/html/test/common/html.test.ts b/src/vs/languages/html/test/common/html.test.ts
index 1b4dba831f1..c123ed6cd8e 100644
--- a/src/vs/languages/html/test/common/html.test.ts
+++ b/src/vs/languages/html/test/common/html.test.ts
@@ -5,12 +5,10 @@
'use strict';
import assert = require('assert');
-import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import modesUtil = require('vs/editor/test/common/modesUtil');
import {Model} from 'vs/editor/common/model/model';
import {getTag, DELIM_END, DELIM_START, DELIM_ASSIGN, ATTRIB_NAME, ATTRIB_VALUE, COMMENT, DELIM_COMMENT, DELIM_DOCTYPE, DOCTYPE} from 'vs/languages/html/common/htmlTokenTypes';
-import {getRawEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
import {TextModelWithTokens} from 'vs/editor/common/model/textModelWithTokens';
import {TextModel} from 'vs/editor/common/model/textModel';
import {Range} from 'vs/editor/common/core/range';
@@ -23,16 +21,14 @@ import {InstantiationService} from 'vs/platform/instantiation/common/instantiati
import {HTMLMode} from 'vs/languages/html/common/html';
import htmlWorker = require('vs/languages/html/common/htmlWorker');
import {MockTokenizingMode} from 'vs/editor/test/common/mocks/mockMode';
-import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
+import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
class MockJSMode extends MockTokenizingMode {
- public richEditSupport: Modes.IRichEditSupport;
-
constructor() {
- super('js', 'mock-js');
+ super('html-js-mock', 'mock-js');
- this.richEditSupport = new RichEditSupport(this.getId(), null, {
+ LanguageConfigurationRegistry.register(this.getId(), {
brackets: [
['(', ')'],
['{', '}'],
@@ -97,6 +93,7 @@ suite('Colorizing - HTML', () => {
let tokenizationSupport: Modes.ITokenizationSupport;
let _mode: Modes.IMode;
+ let onEnterSupport: Modes.IRichEditOnEnter;
(function() {
let threadService = NULL_THREAD_SERVICE;
@@ -115,6 +112,8 @@ suite('Colorizing - HTML', () => {
);
tokenizationSupport = _mode.tokenizationSupport;
+
+ onEnterSupport = LanguageConfigurationRegistry.getOnEnterSupport(_mode.getId());
})();
test('Open Start Tag #1', () => {
@@ -708,7 +707,7 @@ suite('Colorizing - HTML', () => {
test('onEnter 1', function() {
var model = new Model('