mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-26 01:38:40 +01:00
Merge branch 'master' into tyriar/install_extension_ret_zero
This commit is contained in:
Vendored
+15
@@ -74,6 +74,21 @@
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/src/vs/languages/css/common/buildscripts/generate_browserjs.js",
|
||||
"stopOnEntry": false
|
||||
},
|
||||
{
|
||||
"name": "Debug monaco",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/lib/monaco.js",
|
||||
"stopOnEntry": false,
|
||||
"args": [
|
||||
],
|
||||
"cwd": "${workspaceRoot}/build/lib"
|
||||
// ,
|
||||
|
||||
// "port": 5870,
|
||||
// "sourceMaps": true,
|
||||
// "outDir": "${workspaceRoot}/out"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -33,17 +33,11 @@ exports.loaderConfig = function (emptyPaths) {
|
||||
var result = {
|
||||
paths: {
|
||||
'vs': 'out-build/vs',
|
||||
'vs/extensions': 'extensions',
|
||||
'vscode': 'empty:'
|
||||
},
|
||||
'vs/text': {
|
||||
paths: {
|
||||
'vs/extensions': 'extensions'
|
||||
}
|
||||
}
|
||||
nodeModules: emptyPaths||[]
|
||||
};
|
||||
|
||||
(emptyPaths || []).forEach(function(m) { result.paths[m] = 'empty:'; });
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -55,7 +49,6 @@ function loader(bundledFileHeader) {
|
||||
'out-build/vs/loader.js',
|
||||
'out-build/vs/css.js',
|
||||
'out-build/vs/nls.js',
|
||||
'out-build/vs/text.js'
|
||||
], { base: 'out-build' })
|
||||
.pipe(es.through(function(data) {
|
||||
if (isFirst) {
|
||||
|
||||
@@ -34,8 +34,7 @@ var editorResources = [
|
||||
|
||||
var editorOtherSources = [
|
||||
'out-build/vs/css.js',
|
||||
'out-build/vs/nls.js',
|
||||
'out-build/vs/text.js'
|
||||
'out-build/vs/nls.js'
|
||||
];
|
||||
|
||||
var BUNDLED_FILE_HEADER = [
|
||||
|
||||
@@ -48,7 +48,6 @@ var indentationFilter = [
|
||||
'!**/vs/base/common/marked/raw.marked.js',
|
||||
'!**/vs/base/common/winjs.base.raw.js',
|
||||
'!**/vs/base/node/terminateProcess.sh',
|
||||
'!**/vs/text.js',
|
||||
'!**/vs/nls.js',
|
||||
'!**/vs/css.js',
|
||||
'!**/vs/loader.js',
|
||||
|
||||
@@ -32,7 +32,7 @@ var baseModules = [
|
||||
'applicationinsights', 'assert', 'child_process', 'chokidar', 'crypto', 'emmet',
|
||||
'events', 'fs', 'getmac', 'glob', 'graceful-fs', 'http', 'http-proxy-agent',
|
||||
'https', 'https-proxy-agent', 'iconv-lite', 'electron', 'net',
|
||||
'os', 'path', 'readline', 'sax', 'semver', 'stream', 'string_decoder', 'url',
|
||||
'os', 'path', 'pty.js', 'readline', 'sax', 'semver', 'stream', 'string_decoder', 'url', 'term.js',
|
||||
'vscode-textmate', 'winreg', 'yauzl', 'native-keymap', 'zlib', 'minimist'
|
||||
];
|
||||
|
||||
@@ -68,6 +68,7 @@ var vscodeResources = [
|
||||
'out-build/vs/workbench/parts/html/browser/webview.html',
|
||||
'out-build/vs/workbench/parts/markdown/**/*.md',
|
||||
'out-build/vs/workbench/parts/tasks/**/*.json',
|
||||
'out-build/vs/workbench/parts/terminal/electron-browser/terminalProcess.js',
|
||||
'out-build/vs/workbench/services/files/**/*.exe',
|
||||
'out-build/vs/workbench/services/files/**/*.md',
|
||||
'!**/test/**'
|
||||
|
||||
Vendored
+3387
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
|
||||
declare module monaco.editor {
|
||||
|
||||
export function create(domElement: HTMLElement, options: IEditorConstructionOptions, services?: any): ICodeEditor;
|
||||
export function createDiffEditor(domElement: HTMLElement, options: IDiffEditorConstructionOptions, services?: any): IDiffEditor;
|
||||
export function createModel(value:string, mode:string|ILanguage|IMode, associatedResource?:any|string): IModel;
|
||||
export function getOrCreateMode(modeId: string): TPromise<IMode>;
|
||||
export function createCustomMode(description:ILanguage): TPromise<IMode>;
|
||||
export function colorize(text: string, modeId: string, options: IColorizerOptions): TPromise<string>;
|
||||
export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void>;
|
||||
// export function colorizeLine(line: string, tokens: ViewLineToken[], tabSize?: number): string;
|
||||
export function colorizeModelLine(model: IModel, lineNumber: number, tabSize?: number): string;
|
||||
export function registerWorkerParticipant(modeId:string, moduleName:string, ctorName:string): void;
|
||||
export function configureMode(modeId: string, options: any): void;
|
||||
|
||||
export interface IColorizerOptions {
|
||||
tabSize?: number;
|
||||
}
|
||||
|
||||
export interface IColorizerElementOptions extends IColorizerOptions {
|
||||
theme?: string;
|
||||
mimeType?: string;
|
||||
}
|
||||
|
||||
export interface IEditorConstructionOptions extends ICodeEditorWidgetCreationOptions {
|
||||
value?: string;
|
||||
/**
|
||||
* A mode name (such as text/javascript, etc.) or an IMonarchLanguage
|
||||
*/
|
||||
mode?: any;
|
||||
enableTelemetry?: boolean;
|
||||
}
|
||||
|
||||
export interface IDiffEditorConstructionOptions extends IDiffEditorOptions {
|
||||
}
|
||||
}
|
||||
|
||||
declare module monaco {
|
||||
|
||||
interface Thenable<R> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
||||
}
|
||||
|
||||
export interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, TPromise
|
||||
|
||||
#include(vs/base/common/uri): URI
|
||||
|
||||
#include(vs/base/common/eventEmitter): EmitterEvent, BulkListenerCallback
|
||||
|
||||
#include(vs/base/common/keyCodes): KeyCode, KeyMod
|
||||
|
||||
#include(vs/base/common/htmlContent): IHTMLContentElementCode, IHTMLContentElement
|
||||
|
||||
#include(vs/base/common/actions): IAction
|
||||
|
||||
#include(vs/base/browser/keyboardEvent): IKeyboardEvent
|
||||
#include(vs/base/browser/mouseEvent): IMouseEvent
|
||||
#include(vs/editor/common/editorCommon): IScrollEvent
|
||||
|
||||
#include(vs/editor/common/editorCommon): IPosition, IRange, SelectionDirection, ISelection
|
||||
#include(vs/editor/common/core/position): Position
|
||||
#include(vs/editor/common/core/range): Range
|
||||
#include(vs/editor/common/core/selection): Selection
|
||||
}
|
||||
|
||||
|
||||
declare module monaco.editor {
|
||||
|
||||
#include(vs/editor/common/modes/monarch/monarchTypes): ILanguage, ILanguageBracket
|
||||
|
||||
export interface IMode {
|
||||
|
||||
}
|
||||
|
||||
#include(vs/base/browser/ui/scrollbar/scrollableElementOptions): ScrollbarVisibility
|
||||
|
||||
#includeAll(vs/editor/common/editorCommon): IPosition, IRange, ISelection, SelectionDirection, IScrollEvent
|
||||
|
||||
#includeAll(vs/editor/browser/editorBrowser):
|
||||
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
"use strict";
|
||||
// PREREQUISITE:
|
||||
// SET VSCODE_BUILD_DECLARATION_FILES=1
|
||||
// run gulp watch once
|
||||
var fs = require('fs');
|
||||
var ts = require('typescript');
|
||||
var path = require('path');
|
||||
var SRC = path.join(__dirname, '../../src');
|
||||
var OUT = path.join(__dirname, '../../out');
|
||||
function moduleIdToPath(moduleId) {
|
||||
if (/\.d\.ts/.test(moduleId)) {
|
||||
return path.join(SRC, moduleId);
|
||||
}
|
||||
return path.join(OUT, moduleId) + '.d.ts';
|
||||
}
|
||||
var SOURCE_FILE_MAP = {};
|
||||
function getSourceFile(moduleId) {
|
||||
if (!SOURCE_FILE_MAP[moduleId]) {
|
||||
var filePath = moduleIdToPath(moduleId);
|
||||
var fileContents = fs.readFileSync(filePath).toString();
|
||||
var sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
|
||||
SOURCE_FILE_MAP[moduleId] = sourceFile;
|
||||
}
|
||||
return SOURCE_FILE_MAP[moduleId];
|
||||
}
|
||||
function isDeclaration(a) {
|
||||
return (a.kind === ts.SyntaxKind.InterfaceDeclaration
|
||||
|| a.kind === ts.SyntaxKind.EnumDeclaration
|
||||
|| a.kind === ts.SyntaxKind.ClassDeclaration
|
||||
|| a.kind === ts.SyntaxKind.TypeAliasDeclaration
|
||||
|| a.kind === ts.SyntaxKind.FunctionDeclaration);
|
||||
}
|
||||
function visitTopLevelDeclarations(sourceFile, visitor) {
|
||||
var stop = false;
|
||||
var visit = function (node) {
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
case ts.SyntaxKind.EnumDeclaration:
|
||||
case ts.SyntaxKind.ClassDeclaration:
|
||||
case ts.SyntaxKind.VariableStatement:
|
||||
case ts.SyntaxKind.TypeAliasDeclaration:
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
stop = visitor(node);
|
||||
}
|
||||
// if (node.kind !== ts.SyntaxKind.SourceFile) {
|
||||
// if (getNodeText(sourceFile, node).indexOf('Handler') >= 0) {
|
||||
// console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]);
|
||||
// console.log(getNodeText(sourceFile, node));
|
||||
// }
|
||||
// }
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
ts.forEachChild(node, visit);
|
||||
};
|
||||
visit(sourceFile);
|
||||
}
|
||||
function getAllTopLevelDeclarations(sourceFile) {
|
||||
var all = [];
|
||||
visitTopLevelDeclarations(sourceFile, function (node) {
|
||||
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
||||
var interfaceDeclaration = node;
|
||||
var triviaStart = interfaceDeclaration.pos;
|
||||
var triviaEnd = interfaceDeclaration.name.pos;
|
||||
var triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
|
||||
if (triviaText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var nodeText = getNodeText(sourceFile, node);
|
||||
if (nodeText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
}
|
||||
return false /*continue*/;
|
||||
});
|
||||
return all;
|
||||
}
|
||||
function getTopLevelDeclaration(sourceFile, typeName) {
|
||||
var result = null;
|
||||
visitTopLevelDeclarations(sourceFile, function (node) {
|
||||
if (isDeclaration(node)) {
|
||||
if (node.name.text === typeName) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
}
|
||||
return false /*continue*/;
|
||||
}
|
||||
// node is ts.VariableStatement
|
||||
if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
}
|
||||
return false /*continue*/;
|
||||
});
|
||||
if (result === null) {
|
||||
console.log('COULD NOT FIND ' + typeName + '!');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getNodeText(sourceFile, node) {
|
||||
return sourceFile.getFullText().substring(node.pos, node.end);
|
||||
}
|
||||
function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
|
||||
var result = getNodeText(sourceFile, declaration);
|
||||
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
var interfaceDeclaration = declaration;
|
||||
var members = interfaceDeclaration.members;
|
||||
members.forEach(function (member) {
|
||||
try {
|
||||
var memberText = getNodeText(sourceFile, member);
|
||||
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
|
||||
// console.log('BEFORE: ', result);
|
||||
result = result.replace(memberText, '');
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
});
|
||||
}
|
||||
result = result.replace(/export default/g, 'export');
|
||||
result = result.replace(/export declare/g, 'export');
|
||||
return result;
|
||||
}
|
||||
function format(text) {
|
||||
var options = getDefaultOptions();
|
||||
// Parse the source text
|
||||
var sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
|
||||
// Get the formatting edits on the input sources
|
||||
var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(options), options);
|
||||
// Apply the edits on the input code
|
||||
return applyEdits(text, edits);
|
||||
function getRuleProvider(options) {
|
||||
// Share this between multiple formatters using the same options.
|
||||
// This represents the bulk of the space the formatter uses.
|
||||
var ruleProvider = new ts.formatting.RulesProvider();
|
||||
ruleProvider.ensureUpToDate(options);
|
||||
return ruleProvider;
|
||||
}
|
||||
function applyEdits(text, edits) {
|
||||
// Apply edits in reverse on the existing text
|
||||
var result = text;
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
var change = edits[i];
|
||||
var head = result.slice(0, change.span.start);
|
||||
var tail = result.slice(change.span.start + change.span.length);
|
||||
result = head + change.newText + tail;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getDefaultOptions() {
|
||||
return {
|
||||
IndentSize: 4,
|
||||
TabSize: 4,
|
||||
NewLineCharacter: '\r\n',
|
||||
ConvertTabsToSpaces: true,
|
||||
IndentStyle: ts.IndentStyle.Block,
|
||||
InsertSpaceAfterCommaDelimiter: true,
|
||||
InsertSpaceAfterSemicolonInForStatements: true,
|
||||
InsertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
InsertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true,
|
||||
PlaceOpenBraceOnNewLineForFunctions: false,
|
||||
PlaceOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
var recipe = fs.readFileSync(path.join(__dirname, './monaco-editor.d.ts.recipe')).toString();
|
||||
var lines = recipe.split(/\r\n|\n|\r/);
|
||||
var result = [];
|
||||
lines.forEach(function (line) {
|
||||
var m1 = line.match(/^\s*#include\(([^\)]*)\)\:(.*)$/);
|
||||
if (m1) {
|
||||
console.log('HANDLING META: ' + line);
|
||||
var moduleId = m1[1];
|
||||
var sourceFile_1 = getSourceFile(moduleId);
|
||||
var typeNames = m1[2].split(/,/);
|
||||
typeNames.forEach(function (typeName) {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
|
||||
result.push(getMassagedTopLevelDeclarationText(sourceFile_1, declaration));
|
||||
});
|
||||
return;
|
||||
}
|
||||
var m2 = line.match(/^\s*#includeAll\(([^\)]*)\)\:(.*)$/);
|
||||
if (m2) {
|
||||
console.log('HANDLING META: ' + line);
|
||||
var moduleId = m2[1];
|
||||
var sourceFile_2 = getSourceFile(moduleId);
|
||||
var typeNames = m2[2].split(/,/);
|
||||
var typesToExcludeMap_1 = {};
|
||||
var typesToExcludeArr_1 = [];
|
||||
typeNames.forEach(function (typeName) {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
typesToExcludeMap_1[typeName] = true;
|
||||
typesToExcludeArr_1.push(typeName);
|
||||
});
|
||||
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
|
||||
if (isDeclaration(declaration)) {
|
||||
if (typesToExcludeMap_1[declaration.name.text]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// node is ts.VariableStatement
|
||||
var nodeText = getNodeText(sourceFile_2, declaration);
|
||||
for (var i = 0; i < typesToExcludeArr_1.length; i++) {
|
||||
if (nodeText.indexOf(typesToExcludeArr_1[i]) >= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push(getMassagedTopLevelDeclarationText(sourceFile_2, declaration));
|
||||
});
|
||||
return;
|
||||
}
|
||||
result.push(line);
|
||||
});
|
||||
var resultTxt = result.join('\n');
|
||||
resultTxt = resultTxt.replace(/\beditorCommon\./g, '');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = format(resultTxt);
|
||||
resultTxt = resultTxt.replace(/\r\n/g, '\n');
|
||||
fs.writeFileSync(path.join(__dirname, './monaco-editor.d.ts'), resultTxt);
|
||||
@@ -0,0 +1,292 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// PREREQUISITE:
|
||||
// SET VSCODE_BUILD_DECLARATION_FILES=1
|
||||
// run gulp watch once
|
||||
|
||||
|
||||
import fs = require('fs');
|
||||
import ts = require('typescript');
|
||||
import path = require('path');
|
||||
|
||||
|
||||
const SRC = path.join(__dirname, '../../src');
|
||||
const OUT = path.join(__dirname, '../../out');
|
||||
|
||||
|
||||
function moduleIdToPath(moduleId:string): string {
|
||||
if (/\.d\.ts/.test(moduleId)) {
|
||||
return path.join(SRC, moduleId);
|
||||
}
|
||||
return path.join(OUT, moduleId) + '.d.ts';
|
||||
}
|
||||
|
||||
|
||||
var SOURCE_FILE_MAP: {[moduleId:string]:ts.SourceFile;} = {};
|
||||
function getSourceFile(moduleId:string): ts.SourceFile {
|
||||
if (!SOURCE_FILE_MAP[moduleId]) {
|
||||
let filePath = moduleIdToPath(moduleId);
|
||||
let fileContents = fs.readFileSync(filePath).toString();
|
||||
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
|
||||
|
||||
SOURCE_FILE_MAP[moduleId] = sourceFile;
|
||||
}
|
||||
return SOURCE_FILE_MAP[moduleId];
|
||||
}
|
||||
|
||||
|
||||
type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration;
|
||||
type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement;
|
||||
|
||||
function isDeclaration(a:TSTopLevelDeclare): a is TSTopLevelDeclaration {
|
||||
return (
|
||||
a.kind === ts.SyntaxKind.InterfaceDeclaration
|
||||
|| a.kind === ts.SyntaxKind.EnumDeclaration
|
||||
|| a.kind === ts.SyntaxKind.ClassDeclaration
|
||||
|| a.kind === ts.SyntaxKind.TypeAliasDeclaration
|
||||
|| a.kind === ts.SyntaxKind.FunctionDeclaration
|
||||
);
|
||||
}
|
||||
|
||||
function visitTopLevelDeclarations(sourceFile:ts.SourceFile, visitor:(node:TSTopLevelDeclare)=>boolean): void {
|
||||
let stop = false;
|
||||
|
||||
let visit = (node: ts.Node): void => {
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
case ts.SyntaxKind.EnumDeclaration:
|
||||
case ts.SyntaxKind.ClassDeclaration:
|
||||
case ts.SyntaxKind.VariableStatement:
|
||||
case ts.SyntaxKind.TypeAliasDeclaration:
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
stop = visitor(<TSTopLevelDeclare>node);
|
||||
}
|
||||
|
||||
// if (node.kind !== ts.SyntaxKind.SourceFile) {
|
||||
// if (getNodeText(sourceFile, node).indexOf('Handler') >= 0) {
|
||||
// console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]);
|
||||
// console.log(getNodeText(sourceFile, node));
|
||||
// }
|
||||
// }
|
||||
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
ts.forEachChild(node, visit);
|
||||
};
|
||||
|
||||
visit(sourceFile);
|
||||
}
|
||||
|
||||
|
||||
function getAllTopLevelDeclarations(sourceFile:ts.SourceFile): TSTopLevelDeclare[] {
|
||||
let all:TSTopLevelDeclare[] = [];
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
||||
let interfaceDeclaration = <ts.InterfaceDeclaration>node;
|
||||
let triviaStart = interfaceDeclaration.pos;
|
||||
let triviaEnd = interfaceDeclaration.name.pos;
|
||||
let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
|
||||
if (triviaText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
} else {
|
||||
let nodeText = getNodeText(sourceFile, node);
|
||||
if (nodeText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
}
|
||||
return false /*continue*/;
|
||||
});
|
||||
return all;
|
||||
}
|
||||
|
||||
|
||||
function getTopLevelDeclaration(sourceFile:ts.SourceFile, typeName:string): TSTopLevelDeclare {
|
||||
let result:TSTopLevelDeclare = null;
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (isDeclaration(node)) {
|
||||
if (node.name.text === typeName) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
}
|
||||
return false /*continue*/;
|
||||
}
|
||||
// node is ts.VariableStatement
|
||||
if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
}
|
||||
return false /*continue*/;
|
||||
});
|
||||
if (result === null) {
|
||||
console.log('COULD NOT FIND ' + typeName + '!');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function getNodeText(sourceFile:ts.SourceFile, node:{pos:number; end:number;}): string {
|
||||
return sourceFile.getFullText().substring(node.pos, node.end);
|
||||
}
|
||||
|
||||
|
||||
function getMassagedTopLevelDeclarationText(sourceFile:ts.SourceFile, declaration: TSTopLevelDeclare): string {
|
||||
let result = getNodeText(sourceFile, declaration);
|
||||
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
let interfaceDeclaration = <ts.InterfaceDeclaration | ts.ClassDeclaration>declaration;
|
||||
|
||||
let members:ts.NodeArray<ts.Node> = interfaceDeclaration.members;
|
||||
members.forEach((member) => {
|
||||
try {
|
||||
let memberText = getNodeText(sourceFile, member);
|
||||
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
|
||||
// console.log('BEFORE: ', result);
|
||||
result = result.replace(memberText, '');
|
||||
// console.log('AFTER: ', result);
|
||||
}
|
||||
} catch (err) {
|
||||
// life..
|
||||
}
|
||||
});
|
||||
}
|
||||
result = result.replace(/export default/g, 'export');
|
||||
result = result.replace(/export declare/g, 'export');
|
||||
return result;
|
||||
}
|
||||
|
||||
function format(text:string): string {
|
||||
let options = getDefaultOptions();
|
||||
|
||||
// Parse the source text
|
||||
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
|
||||
|
||||
// Get the formatting edits on the input sources
|
||||
let edits = (<any>ts).formatting.formatDocument(sourceFile, getRuleProvider(options), options);
|
||||
|
||||
// Apply the edits on the input code
|
||||
return applyEdits(text, edits);
|
||||
|
||||
function getRuleProvider(options: ts.FormatCodeOptions) {
|
||||
// Share this between multiple formatters using the same options.
|
||||
// This represents the bulk of the space the formatter uses.
|
||||
let ruleProvider = new (<any>ts).formatting.RulesProvider();
|
||||
ruleProvider.ensureUpToDate(options);
|
||||
return ruleProvider;
|
||||
}
|
||||
|
||||
function applyEdits(text: string, edits: ts.TextChange[]): string {
|
||||
// Apply edits in reverse on the existing text
|
||||
let result = text;
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
let change = edits[i];
|
||||
let head = result.slice(0, change.span.start);
|
||||
let tail = result.slice(change.span.start + change.span.length);
|
||||
result = head + change.newText + tail;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultOptions(): ts.FormatCodeOptions {
|
||||
return {
|
||||
IndentSize: 4,
|
||||
TabSize: 4,
|
||||
NewLineCharacter: '\r\n',
|
||||
ConvertTabsToSpaces: true,
|
||||
IndentStyle: ts.IndentStyle.Block,
|
||||
|
||||
InsertSpaceAfterCommaDelimiter: true,
|
||||
InsertSpaceAfterSemicolonInForStatements: true,
|
||||
InsertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
InsertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true,
|
||||
PlaceOpenBraceOnNewLineForFunctions: false,
|
||||
PlaceOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var recipe = fs.readFileSync(path.join(__dirname, './monaco-editor.d.ts.recipe')).toString();
|
||||
var lines = recipe.split(/\r\n|\n|\r/);
|
||||
var result = [];
|
||||
|
||||
lines.forEach(line => {
|
||||
|
||||
let m1 = line.match(/^\s*#include\(([^\)]*)\)\:(.*)$/);
|
||||
if (m1) {
|
||||
console.log('HANDLING META: ' + line);
|
||||
let moduleId = m1[1];
|
||||
let sourceFile = getSourceFile(moduleId);
|
||||
|
||||
let typeNames = m1[2].split(/,/);
|
||||
typeNames.forEach((typeName) => {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
let declaration = getTopLevelDeclaration(sourceFile, typeName);
|
||||
result.push(getMassagedTopLevelDeclarationText(sourceFile, declaration));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let m2 = line.match(/^\s*#includeAll\(([^\)]*)\)\:(.*)$/);
|
||||
if (m2) {
|
||||
console.log('HANDLING META: ' + line);
|
||||
let moduleId = m2[1];
|
||||
let sourceFile = getSourceFile(moduleId);
|
||||
|
||||
let typeNames = m2[2].split(/,/);
|
||||
let typesToExcludeMap: {[typeName:string]:boolean;} = {};
|
||||
let typesToExcludeArr: string[] = [];
|
||||
typeNames.forEach((typeName) => {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
typesToExcludeMap[typeName] = true;
|
||||
typesToExcludeArr.push(typeName);
|
||||
});
|
||||
|
||||
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(declaration)) {
|
||||
if (typesToExcludeMap[declaration.name.text]) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// node is ts.VariableStatement
|
||||
let nodeText = getNodeText(sourceFile, declaration);
|
||||
for (let i = 0; i < typesToExcludeArr.length; i++) {
|
||||
if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push(getMassagedTopLevelDeclarationText(sourceFile, declaration));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
result.push(line);
|
||||
});
|
||||
|
||||
let resultTxt = result.join('\n');
|
||||
resultTxt = resultTxt.replace(/\beditorCommon\./g, '');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
|
||||
resultTxt = format(resultTxt);
|
||||
|
||||
resultTxt = resultTxt.replace(/\r\n/g, '\n');
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, './monaco-editor.d.ts'), resultTxt);
|
||||
@@ -2,6 +2,6 @@
|
||||
[{
|
||||
"name": "textmate/coffee-script.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/textmate/coffee-script.tmbundle"
|
||||
}]
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "language-c",
|
||||
"version": "0.51.3",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/atom/language-c",
|
||||
"description": "The files syntaxes/c.json and syntaxes/c++.json were derived from the Atom package https://atom.io/packages/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle."
|
||||
}]
|
||||
[
|
||||
{
|
||||
"name": "atom/language-c",
|
||||
"version": "0.51.3",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/atom/language-c",
|
||||
"description": "The files syntaxes/c.json and syntaxes/c++.json were derived from the Atom package https://atom.io/packages/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle."
|
||||
},
|
||||
{
|
||||
"name": "textmate/c.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/textmate/c.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) textmate-c.tmbundle authors",
|
||||
"",
|
||||
"If not otherwise specified (see below), files in this repository fall under the following license:",
|
||||
"",
|
||||
"Permission to copy, use, modify, sell and distribute this",
|
||||
"software is granted. This software is provided \"as is\" without",
|
||||
"express or implied warranty, and with no claim as to its",
|
||||
"suitability for any purpose.",
|
||||
"",
|
||||
"An exception is made for files in readable text which contain their own license information,",
|
||||
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
|
||||
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
|
||||
"\"tidy\" is accompanied by \"tidy-license.txt\"."
|
||||
]
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "html",
|
||||
"extensions": [ ".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm" ],
|
||||
"extensions": [ ".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm", ".vue" ],
|
||||
"aliases": [ "HTML", "htm", "html", "xhtml" ],
|
||||
"mimetypes": ["text/html", "text/x-jshtm", "text/template", "text/ng-template", "application/xhtml+xml"]
|
||||
}],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "ini",
|
||||
"extensions": [ ".ini", ".properties", ".gitconfig" ],
|
||||
"extensions": [ ".desktop", ".ini", ".properties", ".gitconfig" ],
|
||||
"filenames": ["config", ".gitattributes", ".gitconfig", "gitconfig", ".editorconfig"],
|
||||
"aliases": [ "Ini", "ini" ],
|
||||
"configuration": "./ini.configuration.json"
|
||||
@@ -17,4 +17,4 @@
|
||||
"path": "./syntaxes/Ini.plist"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
@@ -186,34 +186,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^(\s*):(markdown)(?=\(|$)$</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>constant.language.name.markdown.filter.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>^(?!(\1\s)|\s*$)</string>
|
||||
<key>name</key>
|
||||
<string>text.markdown.filter.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>text.html.markdown</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^(\s*):(sass)(?=\(|$)$</string>
|
||||
<string>^(\s*):(sass)(?=\(|$)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>2</key>
|
||||
@@ -230,7 +203,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
@@ -240,7 +213,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^(\s*):(less)(?=\(|$)$</string>
|
||||
<string>^(\s*):(less)(?=\(|$)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>2</key>
|
||||
@@ -257,7 +230,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
@@ -267,7 +240,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^(\s*):(stylus)(?=\(|$)$</string>
|
||||
<string>^(\s*):(stylus)(?=\(|$)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>2</key>
|
||||
@@ -282,7 +255,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
@@ -309,7 +282,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
@@ -332,8 +305,6 @@
|
||||
<string>Generic Jade filter.</string>
|
||||
<key>end</key>
|
||||
<string>^(?!(\1\s)|\s*$)</string>
|
||||
<key>name</key>
|
||||
<string>text.generic.filter.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
@@ -353,13 +324,13 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\w</string>
|
||||
<string>[\w-]</string>
|
||||
<key>name</key>
|
||||
<string>constant.language.name.generic.filter.jade</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args</string>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
@@ -779,73 +750,6 @@
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>filter_args</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\G(\()</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>meta.args.filter.jade</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>invalid.illegal.extra.args.filter.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))(.*?$)</string>
|
||||
<key>name</key>
|
||||
<string>args.filter.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>([^\s(),=]+)(=?)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.tag.jade</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.separator.key-value.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>contentName</key>
|
||||
<string>string.value.args.filter.jade</string>
|
||||
<key>end</key>
|
||||
<string>((?=\))|,|$)</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args_paren</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>filter_args_paren</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\(</string>
|
||||
<key>end</key>
|
||||
<string>\)|$</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#filter_args_paren</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>flow_control</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {Location, getLocation, createScanner, SyntaxKind} from 'jsonc-parser';
|
||||
import {Location, getLocation, createScanner, SyntaxKind, ScanError} from 'jsonc-parser';
|
||||
import {basename} from 'path';
|
||||
import {BowerJSONContribution} from './bowerJSONContribution';
|
||||
import {PackageJSONContribution} from './packageJSONContribution';
|
||||
@@ -122,10 +122,7 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
|
||||
|
||||
if (location.isAtPropertyKey) {
|
||||
let addValue = !location.previousNode || !location.previousNode.columnOffset;
|
||||
let scanner = createScanner(document.getText(), true);
|
||||
scanner.setPosition(offset);
|
||||
scanner.scan();
|
||||
let isLast = scanner.getToken() === SyntaxKind.CloseBraceToken || scanner.getToken() === SyntaxKind.EOF;
|
||||
let isLast = this.isLast(document, position);
|
||||
collectPromise = this.jsonContribution.collectPropertySuggestions(fileName, location, currentWord, addValue, isLast, collector);
|
||||
} else {
|
||||
if (location.path.length === 0) {
|
||||
@@ -153,4 +150,14 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
|
||||
}
|
||||
return text.substring(i+1, position.character);
|
||||
}
|
||||
|
||||
private isLast(document: TextDocument, position: Position):boolean {
|
||||
let scanner = createScanner(document.getText(), true);
|
||||
scanner.setPosition(document.offsetAt(position));
|
||||
let nextToken = scanner.scan();
|
||||
if (nextToken === SyntaxKind.StringLiteral && scanner.getTokenError() === ScanError.UnexpectedEndOfString) {
|
||||
nextToken= scanner.scan();
|
||||
}
|
||||
return nextToken === SyntaxKind.CloseBraceToken || nextToken === SyntaxKind.EOF;
|
||||
}
|
||||
}
|
||||
@@ -438,10 +438,10 @@ export class JSONCompletion {
|
||||
type = array.length > 0 ? array[0] : null;
|
||||
}
|
||||
if (!type) {
|
||||
return CompletionItemKind.Text;
|
||||
return CompletionItemKind.Value;
|
||||
}
|
||||
switch (type) {
|
||||
case 'string': return CompletionItemKind.Text;
|
||||
case 'string': return CompletionItemKind.Value;
|
||||
case 'object': return CompletionItemKind.Module;
|
||||
case 'property': return CompletionItemKind.Property;
|
||||
default: return CompletionItemKind.Value;
|
||||
|
||||
@@ -376,7 +376,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>@[a-zA-Z0-9_-][\w-]*</string>
|
||||
<string>(@[a-zA-Z0-9_-][\w-]*)|(\-\-[^:\),]+)</string>
|
||||
<key>name</key>
|
||||
<string>variable.other.less</string>
|
||||
</dict>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": "monacobuild",
|
||||
"container": "debuggers",
|
||||
"zip": "48428c0/node-debug.zip",
|
||||
"zip": "73e0456/node-debug.zip",
|
||||
"output": ""
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<key>comment</key>
|
||||
<string>string.regexp.compile.perl</string>
|
||||
<key>end</key>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|$))</string>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|\s*$))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
@@ -309,7 +309,7 @@
|
||||
<key>comment</key>
|
||||
<string>string.regexp.find-m.perl</string>
|
||||
<key>end</key>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|$))</string>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|\s*$))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
@@ -595,7 +595,7 @@
|
||||
<key>comment</key>
|
||||
<string>string.regexp.replace.perl</string>
|
||||
<key>end</key>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)\]>]|$))</string>
|
||||
<string>((([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)\]>]|\s*$))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
@@ -1161,7 +1161,7 @@
|
||||
<key>contentName</key>
|
||||
<string>string.regexp.find.perl</string>
|
||||
<key>end</key>
|
||||
<string>((\1([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|$))</string>
|
||||
<string>((\1([egimosxradlupc]*)))(?=(\s+\S|\s*[;\,\#\{\}\)]|\s*$))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
die("[$sheet->{label}] Unexpected sheet format.") unless (
|
||||
$sheet->{"$date_col$row"} =~ /CALL_DATE/i &&
|
||||
$sheet->{"$pixel_cols[4]$row"} =~ /Home_Bind_Count/i
|
||||
);
|
||||
|
||||
$row++;
|
||||
while ($row < $sheet->{maxrow}) {
|
||||
$row++;
|
||||
$total_lines++;
|
||||
|
||||
my $date = $sheet->{"$date_col$row"};
|
||||
next unless $date;
|
||||
(warning "Unexpected date format: '$date'"), next unless ($date =~ /^2\d\d\d-\d\d-\d\d$/);
|
||||
|
||||
my $phone = trim($sheet->{"$phone_col$row"});
|
||||
(warning "Unexpected phone format: '$phone'."), next unless ($phone =~ /^\d{10}$/);
|
||||
|
||||
info $phone;
|
||||
next if ($date gt $date_to || $date lt $date_from);
|
||||
|
||||
my @pixels = (0) x 5;
|
||||
for (1..4) {
|
||||
$pixels[$_] = trim($sheet->{"$pixel_cols[4]$row"});
|
||||
(warning "Pixel $_ is not a number in the row # $row."), next unless looks_like_number($pixels[$_]);
|
||||
};
|
||||
|
||||
for (1..4) {
|
||||
add_phone_activity($date, $phone, "pixel-$_", $pixels[$_]) if $pixels[$_];
|
||||
};
|
||||
$parsed_lines++;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,7 @@
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["\"", "\""],
|
||||
["'", "'"]
|
||||
["\"", "\""]
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
@@ -22,4 +21,4 @@
|
||||
["\"", "\""],
|
||||
["'", "'"]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
"languages": [{
|
||||
"id": "shellscript",
|
||||
"aliases": ["Shell Script (Bash)", "shellscript", "bash", "sh", "zsh"],
|
||||
"extensions": [".sh", ".bash", ".bashrc", ".bash_profile", ".bash_login", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv"],
|
||||
"extensions": [".sh", ".bash", ".bashrc", ".bash_profile", ".bash_login", ".ebuild", ".install", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv"],
|
||||
"filenames": ["PKGBUILD"],
|
||||
"firstLine": "^#!.*\\b(bash|zsh|sh|tcsh)|^#\\s*-\\*-[^*]*mode:\\s*shell-script[^*]*-\\*-",
|
||||
"configuration": "./shellscript.configuration.json",
|
||||
"mimetypes": ["text/x-shellscript"]
|
||||
@@ -18,4 +19,4 @@
|
||||
"path": "./syntaxes/Shell-Unix-Bash.tmLanguage"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"name": "Microsoft Corp."
|
||||
},
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "1.8.9",
|
||||
"version": "1.8.10",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/TypeScript.git"
|
||||
"url": "git+https://github.com/Microsoft/TypeScript.git"
|
||||
},
|
||||
"main": "./lib/typescript.js",
|
||||
"typings": "./lib/typescript.d.ts",
|
||||
@@ -58,11 +58,12 @@
|
||||
"os": false,
|
||||
"path": false
|
||||
},
|
||||
"gitHead": "9ef75534e0fd5f92bef86b520dff768c11a2df4d",
|
||||
"_id": "typescript@1.8.9",
|
||||
"_shasum": "b3b3a74059fd31cbd3ecad95d62465939e7ed5fa",
|
||||
"gitHead": "794c57478ec2a44ee15fb3e245a4c5d2d1612375",
|
||||
"_id": "typescript@1.8.10",
|
||||
"_shasum": "b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e",
|
||||
"_from": "typescript@latest",
|
||||
"_npmVersion": "2.0.0",
|
||||
"_npmVersion": "2.14.2",
|
||||
"_nodeVersion": "5.9.0",
|
||||
"_npmUser": {
|
||||
"name": "typescript",
|
||||
"email": "typescript@microsoft.com"
|
||||
@@ -74,13 +75,14 @@
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "b3b3a74059fd31cbd3ecad95d62465939e7ed5fa",
|
||||
"tarball": "http://registry.npmjs.org/typescript/-/typescript-1.8.9.tgz"
|
||||
"shasum": "b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e",
|
||||
"tarball": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz"
|
||||
},
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-12-west.internal.npmjs.com",
|
||||
"tmp": "tmp/typescript-1.8.9.tgz_1458169371557_0.7292261146940291"
|
||||
"tmp": "tmp/typescript-1.8.10.tgz_1460493736776_0.9304528103675693"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.9.tgz"
|
||||
"_resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export function create(client: ITypescriptServiceClient, isOpen:(path:string)=>P
|
||||
projectHinted[configFileName] = true;
|
||||
item.hide();
|
||||
|
||||
return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath, 'jsconfig.json')))
|
||||
return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + encodeURIComponent(join(vscode.workspace.rootPath, 'jsconfig.json'))))
|
||||
.then(doc => vscode.window.showTextDocument(doc, vscode.ViewColumn.Three))
|
||||
.then(editor => editor.edit(builder => builder.insert(new vscode.Position(0, 0), defaultConfig)));
|
||||
}
|
||||
|
||||
@@ -40,23 +40,6 @@ suite('commands namespace tests', () => {
|
||||
}, done);
|
||||
});
|
||||
|
||||
test('api-command: workbench.html.preview', function () {
|
||||
|
||||
let registration = workspace.registerTextDocumentContentProvider('speciale', {
|
||||
provideTextDocumentContent(uri) {
|
||||
return `content of URI <b>${uri.toString()}</b>`;
|
||||
}
|
||||
});
|
||||
|
||||
let virtualDocumentUri = Uri.parse('speciale://authority/path');
|
||||
|
||||
return commands.executeCommand('vscode.previewHtml', virtualDocumentUri).then(success => {
|
||||
assert.ok(success);
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('editorCommand with extra args', function () {
|
||||
|
||||
let args: IArguments;
|
||||
@@ -77,4 +60,46 @@ suite('commands namespace tests', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('api-command: vscode.previewHtm', function () {
|
||||
|
||||
let registration = workspace.registerTextDocumentContentProvider('speciale', {
|
||||
provideTextDocumentContent(uri) {
|
||||
return `content of URI <b>${uri.toString()}</b>`;
|
||||
}
|
||||
});
|
||||
|
||||
let virtualDocumentUri = Uri.parse('speciale://authority/path');
|
||||
|
||||
return commands.executeCommand('vscode.previewHtml', virtualDocumentUri).then(success => {
|
||||
assert.ok(success);
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('api-command: vscode.diff', function () {
|
||||
|
||||
let registration = workspace.registerTextDocumentContentProvider('sc', {
|
||||
provideTextDocumentContent(uri) {
|
||||
return `content of URI <b>${uri.toString()}</b>#${Math.random()}`;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let a = commands.executeCommand('vscode.diff', Uri.parse('sc:a'), Uri.parse('sc:b'), 'DIFF').then(value => {
|
||||
assert.ok(value === void 0);
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
let b = commands.executeCommand('vscode.diff', Uri.parse('sc:a'), Uri.parse('sc:b')).then(value => {
|
||||
assert.ok(value === void 0);
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
let c = commands.executeCommand('vscode.diff').then(() => assert.ok(false), () => assert.ok(true));
|
||||
let d = commands.executeCommand('vscode.diff', 1, 2, 3).then(() => assert.ok(false), () => assert.ok(true));
|
||||
|
||||
return Promise.all([a, b, c]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,6 +79,55 @@ suite('languages namespace tests', () => {
|
||||
collection.dispose();
|
||||
});
|
||||
|
||||
test('diagnostics collection, set with dupliclated tuples', function () {
|
||||
let collection = languages.createDiagnosticCollection('test');
|
||||
let uri = Uri.parse('sc:hightower');
|
||||
collection.set([
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-1')]],
|
||||
[Uri.parse('some:thing'), [new Diagnostic(new Range(0, 0, 1, 1), 'something')]],
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-2')]],
|
||||
]);
|
||||
|
||||
let array = collection.get(uri);
|
||||
assert.equal(array.length, 2);
|
||||
let [first, second] = array;
|
||||
assert.equal(first.message, 'message-1');
|
||||
assert.equal(second.message, 'message-2');
|
||||
|
||||
// clear
|
||||
collection.delete(uri);
|
||||
assert.ok(!collection.has(uri));
|
||||
|
||||
// bad tuple clears 1/2
|
||||
collection.set([
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-1')]],
|
||||
[Uri.parse('some:thing'), [new Diagnostic(new Range(0, 0, 1, 1), 'something')]],
|
||||
[uri, undefined]
|
||||
]);
|
||||
assert.ok(!collection.has(uri));
|
||||
|
||||
// clear
|
||||
collection.delete(uri);
|
||||
assert.ok(!collection.has(uri));
|
||||
|
||||
// bad tuple clears 2/2
|
||||
collection.set([
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-1')]],
|
||||
[Uri.parse('some:thing'), [new Diagnostic(new Range(0, 0, 1, 1), 'something')]],
|
||||
[uri, undefined],
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-2')]],
|
||||
[uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-3')]],
|
||||
]);
|
||||
|
||||
array = collection.get(uri);
|
||||
assert.equal(array.length, 2);
|
||||
[first, second] = array;
|
||||
assert.equal(first.message, 'message-2');
|
||||
assert.equal(second.message, 'message-3');
|
||||
|
||||
collection.dispose();
|
||||
});
|
||||
|
||||
test('diagnostics & CodeActionProvider', function (done) {
|
||||
|
||||
class D2 extends Diagnostic {
|
||||
|
||||
@@ -294,6 +294,23 @@ suite('workspace-namespace', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('registerTextDocumentContentProvider, empty doc', function () {
|
||||
|
||||
let registration = workspace.registerTextDocumentContentProvider('foo', {
|
||||
provideTextDocumentContent(uri) {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
const uri = Uri.parse('foo:doc/empty');
|
||||
|
||||
return workspace.openTextDocument(uri).then(doc => {
|
||||
assert.equal(doc.getText(), '');
|
||||
assert.equal(doc.uri.toString(), uri.toString());
|
||||
registration.dispose();
|
||||
});
|
||||
});
|
||||
|
||||
test('registerTextDocumentContentProvider, change event', function () {
|
||||
|
||||
let callCount = 0;
|
||||
|
||||
@@ -25,10 +25,12 @@ var sourcemaps = require('gulp-sourcemaps');
|
||||
var _ = require('underscore');
|
||||
var assign = require('object-assign');
|
||||
var quiet = !!process.env['VSCODE_BUILD_QUIET'];
|
||||
var declaration = !!process.env['VSCODE_BUILD_DECLARATION_FILES'];
|
||||
|
||||
var rootDir = path.join(__dirname, 'src');
|
||||
var tsOptions = {
|
||||
target: 'ES5',
|
||||
declaration: declaration,
|
||||
module: 'amd',
|
||||
verbose: !quiet,
|
||||
preserveConstEnums: true,
|
||||
|
||||
Generated
+16
-6
@@ -340,6 +340,11 @@
|
||||
"from": "preserve@>=0.2.0 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz"
|
||||
},
|
||||
"pty.js": {
|
||||
"version": "0.3.0",
|
||||
"from": "https://github.com/Tyriar/pty.js/tarball/fffbf86eb9e8051b5b2be4ba9c7b07faa018ce8d",
|
||||
"resolved": "https://github.com/Tyriar/pty.js/tarball/fffbf86eb9e8051b5b2be4ba9c7b07faa018ce8d"
|
||||
},
|
||||
"randomatic": {
|
||||
"version": "1.1.5",
|
||||
"from": "randomatic@>=1.1.3 <2.0.0",
|
||||
@@ -390,20 +395,25 @@
|
||||
"from": "string_decoder@>=0.10.0 <0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
|
||||
},
|
||||
"term.js": {
|
||||
"version": "0.0.7",
|
||||
"from": "https://github.com/jeremyramin/term.js/tarball/master",
|
||||
"resolved": "https://github.com/jeremyramin/term.js/tarball/master"
|
||||
},
|
||||
"typechecker": {
|
||||
"version": "2.0.8",
|
||||
"from": "typechecker@>=2.0.1 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz"
|
||||
},
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.8.0",
|
||||
"from": "vscode-debugprotocol@1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.8.0.tgz"
|
||||
"version": "1.9.0",
|
||||
"from": "vscode-debugprotocol@1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.9.0.tgz"
|
||||
},
|
||||
"vscode-textmate": {
|
||||
"version": "1.0.11",
|
||||
"from": "vscode-textmate@1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-1.0.11.tgz"
|
||||
"version": "1.1.0",
|
||||
"from": "vscode-textmate@1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-1.1.0.tgz"
|
||||
},
|
||||
"windows-mutex": {
|
||||
"version": "0.2.0",
|
||||
|
||||
+4
-2
@@ -27,10 +27,12 @@
|
||||
"iconv-lite": "0.4.13",
|
||||
"minimist": "^1.2.0",
|
||||
"native-keymap": "0.1.2",
|
||||
"pty.js": "https://github.com/Tyriar/pty.js/tarball/prebuilt",
|
||||
"sax": "1.1.2",
|
||||
"semver": "4.3.6",
|
||||
"vscode-debugprotocol": "1.8.0",
|
||||
"vscode-textmate": "1.0.11",
|
||||
"term.js": "https://github.com/jeremyramin/term.js/tarball/master",
|
||||
"vscode-debugprotocol": "1.9.0",
|
||||
"vscode-textmate": "1.1.0",
|
||||
"winreg": "1.2.0",
|
||||
"yauzl": "2.3.1"
|
||||
},
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
ARGS=$@
|
||||
|
||||
# If root, ensure that --user-data-dir is specified
|
||||
if [ "$(id -u)" = "0" ]; then
|
||||
while test $# -gt 0
|
||||
@@ -35,5 +33,5 @@ fi
|
||||
|
||||
ELECTRON="$VSCODE_PATH/@@NAME@@"
|
||||
CLI="$VSCODE_PATH/resources/app/out/cli.js"
|
||||
ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" $ARGS
|
||||
ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
|
||||
exit $?
|
||||
@@ -12,6 +12,11 @@ ln -s /usr/share/@@NAME@@/bin/@@NAME@@ /usr/bin/@@NAME@@
|
||||
# developers would prefer a terminal editor as the default.
|
||||
update-alternatives --install /usr/bin/editor editor /usr/bin/@@NAME@@ 0
|
||||
|
||||
# Install the desktop entry
|
||||
if hash desktop-file-install 2>/dev/null; then
|
||||
desktop-file-install /usr/share/applications/@@NAME@@.desktop
|
||||
fi
|
||||
|
||||
if [ "@@NAME@@" != "code-oss" ]; then
|
||||
# Remove the legacy bin command if this is the stable build
|
||||
if [ "@@NAME@@" = "code" ]; then
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
@@ -8,7 +8,7 @@ Packager: Visual Studio Code Team <vscode-linux@microsoft.com>
|
||||
License: MIT
|
||||
URL: https://code.visualstudio.com/
|
||||
Icon: @@NAME@@.xpm
|
||||
Requires: git
|
||||
Requires: git, glibc >= 2.15
|
||||
AutoReq: 0
|
||||
|
||||
%description
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ function code() {
|
||||
VSCODE_DEV=1 \
|
||||
ELECTRON_ENABLE_LOGGING=1 \
|
||||
ELECTRON_ENABLE_STACK_DUMPING=1 \
|
||||
"$ELECTRON" "$CLI" . $@
|
||||
"$ELECTRON" "$CLI" . "$@"
|
||||
}
|
||||
|
||||
code "$@"
|
||||
|
||||
+1
-1
@@ -12,5 +12,5 @@ exports.standaloneLanguages = require('./vs/editor/standalone-languages/buildfil
|
||||
exports.standaloneLanguages2 = require('./vs/languages/buildfile-editor-languages').collectModules();
|
||||
|
||||
exports.entrypoint = function (name) {
|
||||
return [{ name: name, include: [], exclude: ['vs/css', 'vs/nls', 'vs/text'] }];
|
||||
return [{ name: name, include: [], exclude: ['vs/css', 'vs/nls'] }];
|
||||
};
|
||||
|
||||
+30
-14
@@ -65,7 +65,8 @@ function getNLSConfiguration() {
|
||||
}
|
||||
}
|
||||
|
||||
locale = locale || app.getLocale();
|
||||
var appLocale = app.getLocale();
|
||||
locale = locale || appLocale;
|
||||
// Language tags are case insensitve however an amd loader is case sensitive
|
||||
// To make this work on case preserving & insensitive FS we do the following:
|
||||
// the language bundles have lower case language tags and we always lower case
|
||||
@@ -78,23 +79,38 @@ function getNLSConfiguration() {
|
||||
if (process.env['VSCODE_DEV']) {
|
||||
return { locale: locale, availableLanguages: {} };
|
||||
}
|
||||
|
||||
// We have a built version so we have extracted nls file. Try to find
|
||||
// the right file to use.
|
||||
while (locale) {
|
||||
var candidate = path.join(__dirname, 'vs', 'code', 'electron-main', 'main.nls.') + locale + '.js';
|
||||
if (fs.existsSync(candidate)) {
|
||||
return { locale: initialLocale, availableLanguages: { '*': locale } };
|
||||
} else {
|
||||
var index = locale.lastIndexOf('-');
|
||||
if (index > 0) {
|
||||
locale = locale.substring(0, index);
|
||||
} else {
|
||||
locale = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have an English locale. If so fall to default since that is our
|
||||
// English translation (we don't ship *.nls.en.json files)
|
||||
if (locale && (locale == 'en' || locale.startsWith('en-'))) {
|
||||
return { locale: locale, availableLanguages: {} };
|
||||
}
|
||||
|
||||
return { locale: initialLocale, availableLanguages: {} };
|
||||
function resolveLocale(locale) {
|
||||
while (locale) {
|
||||
var candidate = path.join(__dirname, 'vs', 'code', 'electron-main', 'main.nls.') + locale + '.js';
|
||||
if (fs.existsSync(candidate)) {
|
||||
return { locale: initialLocale, availableLanguages: { '*': locale } };
|
||||
} else {
|
||||
var index = locale.lastIndexOf('-');
|
||||
if (index > 0) {
|
||||
locale = locale.substring(0, index);
|
||||
} else {
|
||||
locale = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
var resolvedLocale = resolveLocale(locale);
|
||||
if (!resolvedLocale && appLocale && appLocale !== locale) {
|
||||
resolvedLocale = resolveLocale(appLocale);
|
||||
}
|
||||
return resolvedLocale ? resolvedLocale : { locale: initialLocale, availableLanguages: {} };
|
||||
}
|
||||
|
||||
// Update cwd based on environment and platform
|
||||
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'pty.js' {
|
||||
export function fork(file: string, args: string[], options: any): Terminal;
|
||||
export function spawn(file: string, args: string[], options: any): Terminal;
|
||||
export function createTerminal(file: string, args: string[], options: any): Terminal;
|
||||
|
||||
export interface Terminal {
|
||||
/**
|
||||
* The title of the active process.
|
||||
*/
|
||||
process: string;
|
||||
|
||||
on(event: string, callback: (data: any) => void): void;
|
||||
|
||||
resize(columns: number, rows: number): void;
|
||||
|
||||
write(data: string): void;
|
||||
}
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'term.js' {
|
||||
function init(options: any): TermJsTerminal;
|
||||
|
||||
// There seems to be no way to export this so it can be referenced outside of this file when a
|
||||
// module is a function.
|
||||
interface TermJsTerminal {
|
||||
on(event: string, callback: (data: any) => void): void;
|
||||
resize(columns: number, rows: number): void;
|
||||
}
|
||||
|
||||
export = init;
|
||||
}
|
||||
@@ -14,9 +14,12 @@ class ZoomManager {
|
||||
public static INSTANCE = new ZoomManager();
|
||||
|
||||
private _zoomLevel: number = 0;
|
||||
private _pixelRatioCache: number = 0;
|
||||
private _pixelRatioComputed: boolean = false;
|
||||
|
||||
private _onDidChangeZoomLevel: Emitter<number> = new Emitter<number>();
|
||||
public onDidChangeZoomLevel:Event<number> = this._onDidChangeZoomLevel.event;
|
||||
|
||||
public getZoomLevel(): number {
|
||||
return this._zoomLevel;
|
||||
}
|
||||
@@ -27,13 +30,36 @@ class ZoomManager {
|
||||
}
|
||||
|
||||
this._zoomLevel = zoomLevel;
|
||||
this._pixelRatioComputed = false;
|
||||
this._onDidChangeZoomLevel.fire(this._zoomLevel);
|
||||
}
|
||||
|
||||
public getPixelRatio(): number {
|
||||
if (!this._pixelRatioComputed) {
|
||||
this._pixelRatioCache = this._computePixelRatio();
|
||||
this._pixelRatioComputed = true;
|
||||
}
|
||||
return this._pixelRatioCache;
|
||||
}
|
||||
|
||||
private _computePixelRatio(): number {
|
||||
let ctx = document.createElement('canvas').getContext('2d');
|
||||
let dpr = window.devicePixelRatio || 1;
|
||||
let bsr = (<any>ctx).webkitBackingStorePixelRatio ||
|
||||
(<any>ctx).mozBackingStorePixelRatio ||
|
||||
(<any>ctx).msBackingStorePixelRatio ||
|
||||
(<any>ctx).oBackingStorePixelRatio ||
|
||||
(<any>ctx).backingStorePixelRatio || 1;
|
||||
return dpr / bsr;
|
||||
}
|
||||
}
|
||||
|
||||
export function getZoomLevel(): number {
|
||||
return ZoomManager.INSTANCE.getZoomLevel();
|
||||
}
|
||||
export function getPixelRatio(): number {
|
||||
return ZoomManager.INSTANCE.getPixelRatio();
|
||||
}
|
||||
export function setZoomLevel(zoomLevel:number): void {
|
||||
ZoomManager.INSTANCE.setZoomLevel(zoomLevel);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import {IAction, IActionRunner, Action, ActionRunner} from 'vs/base/common/actio
|
||||
import DOM = require('vs/base/browser/dom');
|
||||
import {EventType as CommonEventType} from 'vs/base/common/events';
|
||||
import types = require('vs/base/common/types');
|
||||
import {IEventEmitter, EventEmitter, IEmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {IEventEmitter, EventEmitter, EmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {Gesture, EventType} from 'vs/base/browser/touch';
|
||||
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
|
||||
import {CommonKeybindings} from 'vs/base/common/keyCodes';
|
||||
@@ -33,7 +33,7 @@ export interface IActionItem extends IEventEmitter {
|
||||
export class BaseActionItem extends EventEmitter implements IActionItem {
|
||||
|
||||
public builder: Builder;
|
||||
public _callOnDispose: Function[];
|
||||
public _callOnDispose: lifecycle.IDisposable[];
|
||||
public _context: any;
|
||||
public _action: IAction;
|
||||
|
||||
@@ -48,7 +48,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
|
||||
this._action = action;
|
||||
|
||||
if (action instanceof Action) {
|
||||
let l = (<Action>action).addBulkListener((events: IEmitterEvent[]) => {
|
||||
let l = (<Action>action).addBulkListener2((events: EmitterEvent[]) => {
|
||||
|
||||
if (!this.builder) {
|
||||
// we have not been rendered yet, so there
|
||||
@@ -56,7 +56,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
|
||||
return;
|
||||
}
|
||||
|
||||
events.forEach((event: IEmitterEvent) => {
|
||||
events.forEach((event: EmitterEvent) => {
|
||||
|
||||
switch (event.getType()) {
|
||||
case Action.ENABLED:
|
||||
@@ -170,7 +170,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
|
||||
// implement in subclass
|
||||
}
|
||||
|
||||
public _updateUnknown(event: IEmitterEvent): void {
|
||||
public _updateUnknown(event: EmitterEvent): void {
|
||||
// can implement in subclass
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
|
||||
this.gesture = null;
|
||||
}
|
||||
|
||||
lifecycle.cAll(this._callOnDispose);
|
||||
this._callOnDispose = lifecycle.dispose(this._callOnDispose);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,13 +333,13 @@ export class ProgressItem extends BaseActionItem {
|
||||
error.textContent = '!';
|
||||
$(error).addClass('tag', 'error');
|
||||
|
||||
this.callOnDispose.push(this.addListener(CommonEventType.BEFORE_RUN, () => {
|
||||
this.callOnDispose.push(this.addListener2(CommonEventType.BEFORE_RUN, () => {
|
||||
$(progress).addClass('active');
|
||||
$(done).removeClass('active');
|
||||
$(error).removeClass('active');
|
||||
}));
|
||||
|
||||
this.callOnDispose.push(this.addListener(CommonEventType.RUN, (result) => {
|
||||
this.callOnDispose.push(this.addListener2(CommonEventType.RUN, (result) => {
|
||||
$(progress).removeClass('active');
|
||||
if (result.error) {
|
||||
$(done).removeClass('active');
|
||||
@@ -358,7 +358,6 @@ export class ProgressItem extends BaseActionItem {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
lifecycle.cAll(this.callOnDispose);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -570,7 +569,7 @@ export class ActionBar extends EventEmitter implements IActionRunner {
|
||||
|
||||
item.actionRunner = this._actionRunner;
|
||||
item.setActionContext(this.context);
|
||||
this.addEmitter(item);
|
||||
this.addEmitter2(item);
|
||||
item.render(actionItemElement);
|
||||
|
||||
if (index === null || index < 0 || index >= this.actionsList.children.length) {
|
||||
|
||||
@@ -9,10 +9,9 @@ import { Gesture } from 'vs/base/browser/touch';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollbarVisibility } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
|
||||
import { RangeMap, IRange } from './rangeMap';
|
||||
import { RangeMap, IRange, relativeComplement, each } from './rangeMap';
|
||||
import { IDelegate, IRenderer } from './list';
|
||||
import { RowCache, IRow } from './rowCache';
|
||||
import { LcsDiff, ISequence } from 'vs/base/common/diff/diff';
|
||||
|
||||
interface IItemRange<T> {
|
||||
item: IItem<T>;
|
||||
@@ -28,13 +27,6 @@ interface IItem<T> {
|
||||
row: IRow;
|
||||
}
|
||||
|
||||
function toSequence<T>(itemRanges: IItemRange<T>[]): ISequence {
|
||||
return {
|
||||
getLength: () => itemRanges.length,
|
||||
getElementHash: i => `${ itemRanges[i].item.id }:${ itemRanges[i].range.start }:${ itemRanges[i].range.end }`
|
||||
};
|
||||
}
|
||||
|
||||
const MouseEventTypes = [
|
||||
'click',
|
||||
'dblclick',
|
||||
@@ -53,16 +45,12 @@ export class ListView<T> implements IDisposable {
|
||||
private rangeMap: RangeMap;
|
||||
private cache: RowCache<T>;
|
||||
private renderers: { [templateId: string]: IRenderer<T, any>; };
|
||||
|
||||
private lastRenderTop: number;
|
||||
private lastRenderHeight: number;
|
||||
|
||||
private _domNode: HTMLElement;
|
||||
private gesture: Gesture;
|
||||
private rowsContainer: HTMLElement;
|
||||
private scrollableElement: ScrollableElement;
|
||||
|
||||
|
||||
private toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
@@ -110,7 +98,9 @@ export class ListView<T> implements IDisposable {
|
||||
}
|
||||
|
||||
splice(start: number, deleteCount: number, ...elements: T[]): T[] {
|
||||
const before = this.getRenderedItemRanges();
|
||||
const previousRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
each(previousRenderRange, i => this.removeItemFromDOM(this.items[i]));
|
||||
|
||||
const inserted = elements.map<IItem<T>>(element => ({
|
||||
id: String(this.itemId++),
|
||||
element,
|
||||
@@ -120,21 +110,11 @@ export class ListView<T> implements IDisposable {
|
||||
}));
|
||||
|
||||
this.rangeMap.splice(start, deleteCount, ...inserted);
|
||||
|
||||
const deleted = this.items.splice(start, deleteCount, ...inserted);
|
||||
|
||||
const after = this.getRenderedItemRanges();
|
||||
const lcs = new LcsDiff(toSequence(before), toSequence(after), null);
|
||||
const diffs = lcs.ComputeDiff();
|
||||
|
||||
for (const diff of diffs) {
|
||||
for (let i = 0; i < diff.originalLength; i++) {
|
||||
this.removeItemFromDOM(before[diff.originalStart + i].item);
|
||||
}
|
||||
|
||||
for (let i = 0; i < diff.modifiedLength; i++) {
|
||||
this.insertItemInDOM(after[diff.modifiedStart + i].item, after[0].index + diff.modifiedStart + i);
|
||||
}
|
||||
}
|
||||
const renderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
each(renderRange, i => this.insertItemInDOM(this.items[i], i));
|
||||
|
||||
const scrollHeight = this.getContentHeight();
|
||||
this.rowsContainer.style.height = `${ scrollHeight }px`;
|
||||
@@ -180,52 +160,18 @@ export class ListView<T> implements IDisposable {
|
||||
// Render
|
||||
|
||||
private render(renderTop: number, renderHeight: number): void {
|
||||
const renderBottom = renderTop + renderHeight;
|
||||
const thisRenderBottom = this.lastRenderTop + this.lastRenderHeight;
|
||||
let i: number, stop: number;
|
||||
const previousRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
const renderRange = this.getRenderRange(renderTop, renderHeight);
|
||||
|
||||
// when view scrolls down, start rendering from the renderBottom
|
||||
for (i = this.rangeMap.indexAfter(renderBottom) - 1, stop = this.rangeMap.indexAt(Math.max(thisRenderBottom, renderTop)); i >= stop; i--) {
|
||||
this.insertItemInDOM(this.items[i], i);
|
||||
}
|
||||
const rangesToInsert = relativeComplement(renderRange, previousRenderRange);
|
||||
const rangesToRemove = relativeComplement(previousRenderRange, renderRange);
|
||||
|
||||
// when view scrolls up, start rendering from either this.renderTop or renderBottom
|
||||
for (i = Math.min(this.rangeMap.indexAt(this.lastRenderTop), this.rangeMap.indexAfter(renderBottom)) - 1, stop = this.rangeMap.indexAt(renderTop); i >= stop; i--) {
|
||||
this.insertItemInDOM(this.items[i], i);
|
||||
}
|
||||
|
||||
// when view scrolls down, start unrendering from renderTop
|
||||
for (i = this.rangeMap.indexAt(this.lastRenderTop), stop = Math.min(this.rangeMap.indexAt(renderTop), this.rangeMap.indexAfter(thisRenderBottom)); i < stop; i++) {
|
||||
this.removeItemFromDOM(this.items[i]);
|
||||
}
|
||||
|
||||
// when view scrolls up, start unrendering from either renderBottom this.renderTop
|
||||
for (i = Math.max(this.rangeMap.indexAfter(renderBottom), this.rangeMap.indexAt(this.lastRenderTop)), stop = this.rangeMap.indexAfter(thisRenderBottom); i < stop; i++) {
|
||||
this.removeItemFromDOM(this.items[i]);
|
||||
}
|
||||
rangesToInsert.forEach(range => each(range, i => this.insertItemInDOM(this.items[i], i)));
|
||||
rangesToRemove.forEach(range => each(range, i => this.removeItemFromDOM(this.items[i])));
|
||||
|
||||
this.rowsContainer.style.transform = `translate3d(0px, -${ renderTop }px, 0px)`;
|
||||
this.lastRenderTop = renderTop;
|
||||
this.lastRenderHeight = renderBottom - renderTop;
|
||||
}
|
||||
|
||||
private getRenderedItemRanges(): IItemRange<T>[] {
|
||||
const result: IItemRange<T>[] = [];
|
||||
const renderBottom = this.lastRenderTop + this.lastRenderHeight;
|
||||
|
||||
let start = this.lastRenderTop;
|
||||
let index = this.rangeMap.indexAt(start);
|
||||
let item = this.items[index];
|
||||
let end = -1;
|
||||
|
||||
while (item && start <= renderBottom) {
|
||||
end = start + item.size;
|
||||
result.push({ item, index, range: { start, end }});
|
||||
start = end;
|
||||
item = this.items[++index];
|
||||
}
|
||||
|
||||
return result;
|
||||
this.lastRenderHeight = renderHeight;
|
||||
}
|
||||
|
||||
// DOM operations
|
||||
@@ -304,6 +250,13 @@ export class ListView<T> implements IDisposable {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private getRenderRange(renderTop: number, renderHeight: number): IRange {
|
||||
return {
|
||||
start: this.rangeMap.indexAt(renderTop),
|
||||
end: this.rangeMap.indexAfter(renderTop + renderHeight - 1)
|
||||
};
|
||||
}
|
||||
|
||||
// Dispose
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -36,6 +36,32 @@ export function intersect(one: IRange, other: IRange): IRange {
|
||||
return { start, end };
|
||||
}
|
||||
|
||||
export function isEmpty(range: IRange): boolean {
|
||||
return range.end - range.start <= 0;
|
||||
}
|
||||
|
||||
export function relativeComplement(one: IRange, other: IRange): IRange[] {
|
||||
const result: IRange[] = [];
|
||||
const first = { start: one.start, end: Math.min(other.start, one.end) };
|
||||
const second = { start: Math.max(other.end, one.start), end: one.end };
|
||||
|
||||
if (!isEmpty(first)) {
|
||||
result.push(first);
|
||||
}
|
||||
|
||||
if (!isEmpty(second)) {
|
||||
result.push(second);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function each(range: IRange, fn: (index : number) => void): void {
|
||||
for (let i = range.start; i < range.end; i++) {
|
||||
fn(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the intersection between a ranged group and a range.
|
||||
* Returns `[]` if the intersection is empty.
|
||||
|
||||
@@ -125,7 +125,7 @@ export class Sash extends EventEmitter {
|
||||
this.emit('start', startEvent);
|
||||
|
||||
let $window = $(window);
|
||||
let containerCssClass = `${this.getOrientation()}-cursor-container${isMacintosh ? '-mac' : ''}`;
|
||||
let containerCSSClass = `${this.getOrientation()}-cursor-container${isMacintosh ? '-mac' : ''}`;
|
||||
|
||||
let lastCurrentX = startX;
|
||||
let lastCurrentY = startY;
|
||||
@@ -151,12 +151,12 @@ export class Sash extends EventEmitter {
|
||||
this.emit('end');
|
||||
|
||||
$window.off('mousemove');
|
||||
document.body.classList.remove(containerCssClass);
|
||||
document.body.classList.remove(containerCSSClass);
|
||||
|
||||
$(DOM.getElementsByTagName('iframe')).style('pointer-events', 'auto');
|
||||
});
|
||||
|
||||
document.body.classList.add(containerCssClass);
|
||||
document.body.classList.add(containerCSSClass);
|
||||
}
|
||||
|
||||
private onTouchStart(event: GestureEvent): void {
|
||||
|
||||
@@ -14,7 +14,6 @@ import types = require('vs/base/common/types');
|
||||
import {Action, IActionRunner, IAction} from 'vs/base/common/actions';
|
||||
import {ActionBar, ActionsOrientation, IActionItemProvider, BaseActionItem} from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import {IContextMenuProvider, DropdownMenu, IActionProvider, ILabelRenderer, IDropdownMenuOptions} from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import {ListenerUnbind} from 'vs/base/common/eventEmitter';
|
||||
|
||||
export const CONTEXT = 'context.toolbar';
|
||||
|
||||
@@ -162,7 +161,7 @@ class ToggleMenuAction extends Action {
|
||||
export class DropdownMenuActionItem extends BaseActionItem {
|
||||
private menuActionsOrProvider: any;
|
||||
private dropdownMenu: DropdownMenu;
|
||||
private toUnbind: ListenerUnbind;
|
||||
private toUnbind: IDisposable;
|
||||
private contextMenuProvider: IContextMenuProvider;
|
||||
private actionItemProvider: IActionItemProvider;
|
||||
private clazz: string;
|
||||
@@ -214,7 +213,7 @@ export class DropdownMenuActionItem extends BaseActionItem {
|
||||
};
|
||||
|
||||
// Reemit events for running actions
|
||||
this.toUnbind = this.addEmitter(this.dropdownMenu);
|
||||
this.toUnbind = this.addEmitter2(this.dropdownMenu);
|
||||
}
|
||||
|
||||
public show(): void {
|
||||
@@ -224,7 +223,7 @@ export class DropdownMenuActionItem extends BaseActionItem {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.toUnbind();
|
||||
this.toUnbind.dispose();
|
||||
this.dropdownMenu.dispose();
|
||||
|
||||
super.dispose();
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
exports.collectModules = function() {
|
||||
return [{
|
||||
name: 'vs/base/common/worker/workerServer',
|
||||
exclude: [ 'vs/css', 'vs/nls', 'vs/text' ]
|
||||
exclude: [ 'vs/css', 'vs/nls' ]
|
||||
}, {
|
||||
name: 'vs/base/common/worker/simpleWorker',
|
||||
exclude: [ 'vs/css', 'vs/nls', 'vs/text' ]
|
||||
exclude: [ 'vs/css', 'vs/nls' ]
|
||||
}];
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import { IEventEmitter, EventEmitter, ListenerCallback, IBulkListenerCallback, ListenerUnbind } from 'vs/base/common/eventEmitter';
|
||||
import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import * as Events from 'vs/base/common/events';
|
||||
|
||||
@@ -199,74 +199,6 @@ export class Action extends EventEmitter implements IAction {
|
||||
}
|
||||
}
|
||||
|
||||
class ProxyAction extends Action implements IEventEmitter {
|
||||
|
||||
constructor(private delegate: Action, private runHandler: (e: any) => void) {
|
||||
super(delegate.id, delegate.label, delegate.class, delegate.enabled, null);
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this.delegate.id;
|
||||
}
|
||||
|
||||
public get label(): string {
|
||||
return this.delegate.label;
|
||||
}
|
||||
|
||||
public set label(value: string) {
|
||||
this.delegate.label = value;
|
||||
}
|
||||
|
||||
public get class(): string {
|
||||
return this.delegate.class;
|
||||
}
|
||||
|
||||
public set class(value: string) {
|
||||
this.delegate.class = value;
|
||||
}
|
||||
|
||||
public get enabled(): boolean {
|
||||
return this.delegate.enabled;
|
||||
}
|
||||
|
||||
public set enabled(value: boolean) {
|
||||
this.delegate.enabled = value;
|
||||
}
|
||||
|
||||
public get checked(): boolean {
|
||||
return this.delegate.checked;
|
||||
}
|
||||
|
||||
public set checked(value: boolean) {
|
||||
this.delegate.checked = value;
|
||||
}
|
||||
|
||||
public run(event?: any): TPromise<any> {
|
||||
this.runHandler(event);
|
||||
return this.delegate.run(event);
|
||||
}
|
||||
|
||||
public addListener(eventType: string, listener: ListenerCallback): ListenerUnbind {
|
||||
return this.delegate.addListener(eventType, listener);
|
||||
}
|
||||
|
||||
public addBulkListener(listener: IBulkListenerCallback): ListenerUnbind {
|
||||
return this.delegate.addBulkListener(listener);
|
||||
}
|
||||
|
||||
public addEmitter(eventEmitter: IEventEmitter, emitterType?: string): ListenerUnbind {
|
||||
return this.delegate.addEmitter(eventEmitter, emitterType);
|
||||
}
|
||||
|
||||
public addEmitterTypeListener(eventType: string, emitterType: string, listener: ListenerCallback): ListenerUnbind {
|
||||
return this.delegate.addEmitterTypeListener(eventType, emitterType, listener);
|
||||
}
|
||||
|
||||
public emit(eventType: string, data?: any): void {
|
||||
this.delegate.emit(eventType, data);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRunEvent {
|
||||
action: IAction;
|
||||
result?: any;
|
||||
|
||||
+48
-32
@@ -2,18 +2,27 @@
|
||||
* 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 errors from 'vs/base/common/errors';
|
||||
import { Promise, TPromise, ValueCallback, ErrorCallback, ProgressCallback } from 'vs/base/common/winjs.base';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import {CancellationToken, CancellationTokenSource} from 'vs/base/common/cancellation';
|
||||
import {Disposable} from 'vs/base/common/lifecycle';
|
||||
import { Promise, TPromise, ValueCallback, ErrorCallback, ProgressCallback } from 'vs/base/common/winjs.base';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
function isThenable<T>(obj: any): obj is Thenable<T> {
|
||||
return obj && typeof (<Thenable<any>>obj).then === 'function';
|
||||
}
|
||||
|
||||
export function toThenable<T>(arg: T | Thenable<T>): Thenable<T> {
|
||||
if (isThenable(arg)) {
|
||||
return arg;
|
||||
} else {
|
||||
return TPromise.as(arg);
|
||||
}
|
||||
}
|
||||
|
||||
export function asWinJsPromise<T>(callback: (token: CancellationToken) => T | Thenable<T>): TPromise<T> {
|
||||
let source = new CancellationTokenSource();
|
||||
return new TPromise<T>((resolve, reject) => {
|
||||
@@ -28,6 +37,14 @@ export function asWinJsPromise<T>(callback: (token: CancellationToken) => T | Th
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook a cancellation token to a WinJS Promise
|
||||
*/
|
||||
export function wireCancellationToken<T>(token: CancellationToken, promise: TPromise<T>): Thenable<T> {
|
||||
token.onCancellationRequested(() => promise.cancel());
|
||||
return promise;
|
||||
}
|
||||
|
||||
export interface ITask<T> {
|
||||
(): T;
|
||||
}
|
||||
@@ -47,9 +64,15 @@ export interface ITask<T> {
|
||||
* var throttler = new Throttler();
|
||||
* var letters = [];
|
||||
*
|
||||
* function letterReceived(l) {
|
||||
* function deliver() {
|
||||
* const lettersToDeliver = letters;
|
||||
* letters = [];
|
||||
* return makeTheTrip(lettersToDeliver);
|
||||
* }
|
||||
*
|
||||
* function onLetterReceived(l) {
|
||||
* letters.push(l);
|
||||
* throttler.queue(() => { return makeTheTrip(); });
|
||||
* throttler.queue(deliver);
|
||||
* }
|
||||
*/
|
||||
export class Throttler {
|
||||
@@ -64,7 +87,7 @@ export class Throttler {
|
||||
this.queuedPromiseFactory = null;
|
||||
}
|
||||
|
||||
public queue<T>(promiseFactory: ITask<TPromise<T>>): TPromise<T> {
|
||||
queue<T>(promiseFactory: ITask<TPromise<T>>): TPromise<T> {
|
||||
if (this.activePromise) {
|
||||
this.queuedPromiseFactory = promiseFactory;
|
||||
|
||||
@@ -145,7 +168,7 @@ export class Delayer<T> {
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
public trigger(task: ITask<T>, delay: number = this.defaultDelay): TPromise<T> {
|
||||
trigger(task: ITask<T>, delay: number = this.defaultDelay): TPromise<T> {
|
||||
this.task = task;
|
||||
this.cancelTimeout();
|
||||
|
||||
@@ -172,11 +195,11 @@ export class Delayer<T> {
|
||||
return this.completionPromise;
|
||||
}
|
||||
|
||||
public isTriggered(): boolean {
|
||||
isTriggered(): boolean {
|
||||
return this.timeout !== null;
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
cancel(): void {
|
||||
this.cancelTimeout();
|
||||
|
||||
if (this.completionPromise) {
|
||||
@@ -210,7 +233,7 @@ export class ThrottledDelayer<T> extends Delayer<TPromise<T>> {
|
||||
this.throttler = new Throttler();
|
||||
}
|
||||
|
||||
public trigger(promiseFactory: ITask<TPromise<T>>, delay?: number): Promise {
|
||||
trigger(promiseFactory: ITask<TPromise<T>>, delay?: number): Promise {
|
||||
return super.trigger(() => this.throttler.queue(promiseFactory), delay);
|
||||
}
|
||||
}
|
||||
@@ -231,7 +254,7 @@ export class PeriodThrottledDelayer<T> extends ThrottledDelayer<T> {
|
||||
this.periodThrottler = new Throttler();
|
||||
}
|
||||
|
||||
public trigger(promiseFactory: ITask<TPromise<T>>, delay?: number): Promise {
|
||||
trigger(promiseFactory: ITask<TPromise<T>>, delay?: number): Promise {
|
||||
return super.trigger(() => {
|
||||
return this.periodThrottler.queue(() => {
|
||||
return Promise.join([
|
||||
@@ -399,8 +422,8 @@ export class Limiter<T> {
|
||||
this.runningPromises = 0;
|
||||
}
|
||||
|
||||
public queue(promiseFactory: ITask<Promise>): Promise;
|
||||
public queue(promiseFactory: ITask<TPromise<T>>): TPromise<T> {
|
||||
queue(promiseFactory: ITask<Promise>): Promise;
|
||||
queue(promiseFactory: ITask<TPromise<T>>): TPromise<T> {
|
||||
return new TPromise<T>((c, e, p) => {
|
||||
this.outstandingPromises.push({
|
||||
factory: promiseFactory,
|
||||
@@ -438,19 +461,19 @@ export class TimeoutTimer extends Disposable {
|
||||
this._token = -1;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
this.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
cancel(): void {
|
||||
if (this._token !== -1) {
|
||||
platform.clearTimeout(this._token);
|
||||
this._token = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public cancelAndSet(runner: () => void, timeout:number): void {
|
||||
cancelAndSet(runner: () => void, timeout:number): void {
|
||||
this.cancel();
|
||||
this._token = platform.setTimeout(() => {
|
||||
this._token = -1;
|
||||
@@ -458,7 +481,7 @@ export class TimeoutTimer extends Disposable {
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
public setIfNotSet(runner: () => void, timeout: number): void {
|
||||
setIfNotSet(runner: () => void, timeout: number): void {
|
||||
if (this._token !== -1) {
|
||||
// timer is already set
|
||||
return;
|
||||
@@ -479,19 +502,19 @@ export class IntervalTimer extends Disposable {
|
||||
this._token = -1;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
this.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
cancel(): void {
|
||||
if (this._token !== -1) {
|
||||
platform.clearInterval(this._token);
|
||||
this._token = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public cancelAndSet(runner: () => void, interval:number): void {
|
||||
cancelAndSet(runner: () => void, interval:number): void {
|
||||
this.cancel();
|
||||
this._token = platform.setInterval(() => {
|
||||
runner();
|
||||
@@ -516,7 +539,7 @@ export class RunOnceScheduler {
|
||||
/**
|
||||
* Dispose RunOnceScheduler
|
||||
*/
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
this.cancel();
|
||||
this.runner = null;
|
||||
}
|
||||
@@ -524,7 +547,7 @@ export class RunOnceScheduler {
|
||||
/**
|
||||
* Cancel current scheduled runner (if any).
|
||||
*/
|
||||
public cancel(): void {
|
||||
cancel(): void {
|
||||
if (this.isScheduled()) {
|
||||
platform.clearTimeout(this.timeoutToken);
|
||||
this.timeoutToken = -1;
|
||||
@@ -534,21 +557,14 @@ export class RunOnceScheduler {
|
||||
/**
|
||||
* Replace runner. If there is a runner already scheduled, the new runner will be called.
|
||||
*/
|
||||
public setRunner(runner: () => void): void {
|
||||
setRunner(runner: () => void): void {
|
||||
this.runner = runner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeout. This change will only impact new schedule calls.
|
||||
*/
|
||||
public setTimeout(timeout: number): void {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel previous runner (if any) & schedule a new runner.
|
||||
*/
|
||||
public schedule(): void {
|
||||
schedule(delay = this.timeout): void {
|
||||
this.cancel();
|
||||
this.timeoutToken = platform.setTimeout(this.timeoutHandler, this.timeout);
|
||||
}
|
||||
@@ -556,7 +572,7 @@ export class RunOnceScheduler {
|
||||
/**
|
||||
* Returns true if scheduled.
|
||||
*/
|
||||
public isScheduled(): boolean {
|
||||
isScheduled(): boolean {
|
||||
return this.timeoutToken !== -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -380,8 +380,10 @@ export function illegalState(name?: string): Error {
|
||||
}
|
||||
}
|
||||
|
||||
export function readonly(): Error {
|
||||
return new Error('readonly property cannot be changed');
|
||||
export function readonly(name?: string): Error {
|
||||
return name
|
||||
? new Error(`readonly property '${name} cannot be changed'`)
|
||||
: new Error('readonly property cannot be changed');
|
||||
}
|
||||
|
||||
export function loaderError(err: Error): Error {
|
||||
|
||||
@@ -5,23 +5,16 @@
|
||||
'use strict';
|
||||
|
||||
import Errors = require('vs/base/common/errors');
|
||||
import Lifecycle = require('vs/base/common/lifecycle');
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IEmitterEvent {
|
||||
getType():string;
|
||||
getData():any;
|
||||
}
|
||||
|
||||
export class EmitterEvent implements IEmitterEvent {
|
||||
export class EmitterEvent {
|
||||
|
||||
private _type:string;
|
||||
private _data:any;
|
||||
private _emitterType:string;
|
||||
|
||||
constructor(eventType:string=null, data:any=null, emitterType:string=null) {
|
||||
constructor(eventType:string=null, data:any=null) {
|
||||
this._type = eventType;
|
||||
this._data = data;
|
||||
this._emitterType = emitterType;
|
||||
}
|
||||
|
||||
public getType():string {
|
||||
@@ -31,37 +24,21 @@ export class EmitterEvent implements IEmitterEvent {
|
||||
public getData():any {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
public getEmitterType():string {
|
||||
return this._emitterType;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ListenerCallback {
|
||||
(value:any):void;
|
||||
}
|
||||
|
||||
export interface IBulkListenerCallback {
|
||||
(value:IEmitterEvent[]):void;
|
||||
export interface BulkListenerCallback {
|
||||
(value:EmitterEvent[]):void;
|
||||
}
|
||||
|
||||
export interface ListenerUnbind {
|
||||
():void;
|
||||
}
|
||||
|
||||
export interface IEventEmitter extends Lifecycle.IDisposable {
|
||||
addListener(eventType:string, listener:ListenerCallback):ListenerUnbind;
|
||||
addListener2(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable;
|
||||
addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind;
|
||||
|
||||
addBulkListener(listener:IBulkListenerCallback):ListenerUnbind;
|
||||
addBulkListener2(listener:IBulkListenerCallback):Lifecycle.IDisposable;
|
||||
|
||||
addEmitter(eventEmitter:IEventEmitter, emitterType?:string):ListenerUnbind;
|
||||
addEmitter2(eventEmitter:IEventEmitter, emitterType?:string):Lifecycle.IDisposable;
|
||||
|
||||
addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind;
|
||||
emit(eventType:string, data?:any):void;
|
||||
export interface IEventEmitter extends IDisposable {
|
||||
addListener2(eventType:string, listener:ListenerCallback):IDisposable;
|
||||
addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):IDisposable;
|
||||
addBulkListener2(listener:BulkListenerCallback):IDisposable;
|
||||
addEmitter2(eventEmitter:IEventEmitter):IDisposable;
|
||||
}
|
||||
|
||||
export interface IListenersMap {
|
||||
@@ -99,7 +76,7 @@ export class EventEmitter implements IEventEmitter {
|
||||
this._allowedEventTypes = null;
|
||||
}
|
||||
|
||||
public addListener(eventType:string, listener:ListenerCallback):ListenerUnbind {
|
||||
private addListener(eventType:string, listener:ListenerCallback):IDisposable {
|
||||
if (eventType === '*') {
|
||||
throw new Error('Use addBulkListener(listener) to register your listener!');
|
||||
}
|
||||
@@ -115,73 +92,56 @@ export class EventEmitter implements IEventEmitter {
|
||||
}
|
||||
|
||||
var bound = this;
|
||||
return () => {
|
||||
if (!bound) {
|
||||
// Already called
|
||||
return;
|
||||
}
|
||||
|
||||
bound._removeListener(eventType, listener);
|
||||
|
||||
// Prevent leakers from holding on to the event emitter
|
||||
bound = null;
|
||||
listener = null;
|
||||
};
|
||||
}
|
||||
|
||||
public addListener2(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable {
|
||||
var dispose = this.addListener(eventType, listener);
|
||||
return {
|
||||
dispose: dispose
|
||||
dispose: () => {
|
||||
if (!bound) {
|
||||
// Already called
|
||||
return;
|
||||
}
|
||||
|
||||
bound._removeListener(eventType, listener);
|
||||
|
||||
// Prevent leakers from holding on to the event emitter
|
||||
bound = null;
|
||||
listener = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public on(eventType:string, listener:ListenerCallback):ListenerUnbind {
|
||||
public addListener2(eventType:string, listener:ListenerCallback):IDisposable {
|
||||
return this.addListener(eventType, listener);
|
||||
}
|
||||
|
||||
public addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind {
|
||||
var unbind:ListenerUnbind = this.addListener(eventType, function(value:any) {
|
||||
unbind();
|
||||
private addOneTimeListener(eventType:string, listener:ListenerCallback):IDisposable {
|
||||
var unbind = this.addListener(eventType, (value:any) => {
|
||||
unbind.dispose();
|
||||
listener(value);
|
||||
});
|
||||
return unbind;
|
||||
}
|
||||
|
||||
public addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable {
|
||||
var dispose = this.addOneTimeListener(eventType, listener);
|
||||
return {
|
||||
dispose: dispose
|
||||
};
|
||||
public addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):IDisposable {
|
||||
return this.addOneTimeListener(eventType, listener);
|
||||
}
|
||||
|
||||
public addBulkListener(listener:IBulkListenerCallback):ListenerUnbind {
|
||||
protected addBulkListener(listener:BulkListenerCallback):IDisposable {
|
||||
|
||||
this._bulkListeners.push(listener);
|
||||
|
||||
return () => {
|
||||
this._removeBulkListener(listener);
|
||||
};
|
||||
}
|
||||
|
||||
public addBulkListener2(listener:IBulkListenerCallback):Lifecycle.IDisposable {
|
||||
var dispose = this.addBulkListener(listener);
|
||||
return {
|
||||
dispose: dispose
|
||||
dispose: () => {
|
||||
this._removeBulkListener(listener);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public addEmitter(eventEmitter:IEventEmitter, emitterType:string=null):ListenerUnbind {
|
||||
return eventEmitter.addBulkListener((events:IEmitterEvent[]):void => {
|
||||
var newEvents = events;
|
||||
public addBulkListener2(listener:BulkListenerCallback):IDisposable {
|
||||
return this.addBulkListener(listener);
|
||||
}
|
||||
|
||||
if (emitterType) {
|
||||
// If the emitter has an emitterType, recreate events
|
||||
newEvents = [];
|
||||
for (var i = 0, len = events.length; i < len; i++) {
|
||||
newEvents.push(new EmitterEvent(events[i].getType(), events[i].getData(), emitterType));
|
||||
}
|
||||
}
|
||||
private addEmitter(eventEmitter:IEventEmitter):IDisposable {
|
||||
return eventEmitter.addBulkListener2((events:EmitterEvent[]):void => {
|
||||
var newEvents = events;
|
||||
|
||||
if (this._deferredCnt === 0) {
|
||||
this._emitEvents(<EmitterEvent[]>newEvents);
|
||||
@@ -192,23 +152,8 @@ export class EventEmitter implements IEventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
public addEmitter2(eventEmitter:IEventEmitter, emitterType?:string):Lifecycle.IDisposable {
|
||||
var dispose = this.addEmitter(eventEmitter, emitterType);
|
||||
return {
|
||||
dispose: dispose
|
||||
};
|
||||
}
|
||||
|
||||
public addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind {
|
||||
if (emitterType) {
|
||||
if (eventType === '*') {
|
||||
throw new Error('Bulk listeners cannot specify an emitter type');
|
||||
}
|
||||
|
||||
return this.addListener(eventType + '/' + emitterType, listener);
|
||||
} else {
|
||||
return this.addListener(eventType, listener);
|
||||
}
|
||||
public addEmitter2(eventEmitter:IEventEmitter):IDisposable {
|
||||
return this.addEmitter(eventEmitter);
|
||||
}
|
||||
|
||||
private _removeListener(eventType:string, listener:ListenerCallback): void {
|
||||
@@ -224,7 +169,7 @@ export class EventEmitter implements IEventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
private _removeBulkListener(listener:IBulkListenerCallback): void {
|
||||
private _removeBulkListener(listener:BulkListenerCallback): void {
|
||||
for (var i = 0, len = this._bulkListeners.length; i < len; i++) {
|
||||
if (this._bulkListeners[i] === listener) {
|
||||
this._bulkListeners.splice(i, 1);
|
||||
@@ -257,9 +202,6 @@ export class EventEmitter implements IEventEmitter {
|
||||
var e = events[i];
|
||||
|
||||
this._emitToSpecificTypeListeners(e.getType(), e.getData());
|
||||
if (e.getEmitterType()) {
|
||||
this._emitToSpecificTypeListeners(e.getType() + '/' + e.getEmitterType(), e.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ export class IdGenerator {
|
||||
this._lastId = 0;
|
||||
}
|
||||
|
||||
public generate(): string {
|
||||
public nextId(): string {
|
||||
return this._prefix + (++this._lastId);
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultGenerator = new IdGenerator('id#');
|
||||
+571
-104
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import nls = require('vs/nls');
|
||||
import {localize} from 'vs/nls';
|
||||
|
||||
export enum ScanError {
|
||||
None,
|
||||
@@ -35,19 +35,50 @@ export enum SyntaxKind {
|
||||
EOF
|
||||
}
|
||||
|
||||
/**
|
||||
* The scanner object, representing a JSON scanner at a position in the input string.
|
||||
*/
|
||||
export interface JSONScanner {
|
||||
/**
|
||||
* Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
|
||||
*/
|
||||
setPosition(pos: number);
|
||||
/**
|
||||
* Read the next token. Returns the tolen code.
|
||||
*/
|
||||
scan(): SyntaxKind;
|
||||
/**
|
||||
* Returns the current scan position, which is after the last read token.
|
||||
*/
|
||||
getPosition(): number;
|
||||
/**
|
||||
* Returns the last read token.
|
||||
*/
|
||||
getToken(): SyntaxKind;
|
||||
/**
|
||||
* Returns the last read token value. The value for strings is the decoded string content. For numbers its of type number, for boolean it's true or false.
|
||||
*/
|
||||
getTokenValue(): string;
|
||||
/**
|
||||
* The start offset of the last read token.
|
||||
*/
|
||||
getTokenOffset(): number;
|
||||
/**
|
||||
* The length of the last read token.
|
||||
*/
|
||||
getTokenLength(): number;
|
||||
/**
|
||||
* An error code of the last scan.
|
||||
*/
|
||||
getTokenError(): ScanError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export function createScanner(text:string, ignoreTrivia:boolean = false):JSONScanner {
|
||||
|
||||
var pos = 0,
|
||||
let pos = 0,
|
||||
len = text.length,
|
||||
value:string = '',
|
||||
tokenOffset = 0,
|
||||
@@ -55,10 +86,10 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
scanError:ScanError = ScanError.None;
|
||||
|
||||
function scanHexDigits(count: number, exact?: boolean): number {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
let digits = 0;
|
||||
let value = 0;
|
||||
while (digits < count || !exact) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
let ch = text.charCodeAt(pos);
|
||||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
|
||||
value = value * 16 + ch - CharacterCodes._0;
|
||||
}
|
||||
@@ -80,8 +111,16 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
return value;
|
||||
}
|
||||
|
||||
function setPosition(newPosition: number) {
|
||||
pos = newPosition;
|
||||
value = '';
|
||||
tokenOffset = 0;
|
||||
token = SyntaxKind.Unknown;
|
||||
scanError = ScanError.None;
|
||||
}
|
||||
|
||||
function scanNumber(): string {
|
||||
var start = pos;
|
||||
let start = pos;
|
||||
if (text.charCodeAt(pos) === CharacterCodes._0) {
|
||||
pos++;
|
||||
} else {
|
||||
@@ -99,10 +138,10 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
}
|
||||
} else {
|
||||
scanError = ScanError.UnexpectedEndOfNumber;
|
||||
return text.substring(start, end);
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
var end = pos;
|
||||
let end = pos;
|
||||
if (pos < text.length && (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e)) {
|
||||
pos++;
|
||||
if (pos < text.length && text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) {
|
||||
@@ -123,7 +162,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
|
||||
function scanString(): string {
|
||||
|
||||
var result = '',
|
||||
let result = '',
|
||||
start = pos;
|
||||
|
||||
while (true) {
|
||||
@@ -132,7 +171,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
scanError = ScanError.UnexpectedEndOfString;
|
||||
break;
|
||||
}
|
||||
var ch = text.charCodeAt(pos);
|
||||
let ch = text.charCodeAt(pos);
|
||||
if (ch === CharacterCodes.doubleQuote) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
@@ -172,7 +211,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
result += '\t';
|
||||
break;
|
||||
case CharacterCodes.u:
|
||||
var ch = scanHexDigits(4, true);
|
||||
let ch = scanHexDigits(4, true);
|
||||
if (ch >= 0) {
|
||||
result += String.fromCharCode(ch);
|
||||
} else {
|
||||
@@ -208,7 +247,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
return token = SyntaxKind.EOF;
|
||||
}
|
||||
|
||||
var code = text.charCodeAt(pos);
|
||||
let code = text.charCodeAt(pos);
|
||||
// trivia: whitespace
|
||||
if (isWhiteSpace(code)) {
|
||||
do {
|
||||
@@ -260,7 +299,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
|
||||
// comments
|
||||
case CharacterCodes.slash:
|
||||
var start = pos - 1;
|
||||
let start = pos - 1;
|
||||
// Single-line comment
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.slash) {
|
||||
pos += 2;
|
||||
@@ -280,10 +319,10 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) {
|
||||
pos += 2;
|
||||
|
||||
var safeLength = len - 1; // For lookahead.
|
||||
var commentClosed = false;
|
||||
let safeLength = len - 1; // For lookahead.
|
||||
let commentClosed = false;
|
||||
while (pos < safeLength) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
let ch = text.charCodeAt(pos);
|
||||
|
||||
if (ch === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) {
|
||||
pos += 2;
|
||||
@@ -371,7 +410,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
|
||||
|
||||
function scanNextNonTrivia():SyntaxKind {
|
||||
var result : SyntaxKind;
|
||||
let result : SyntaxKind;
|
||||
do {
|
||||
result = scanNext();
|
||||
} while (result >= SyntaxKind.LineCommentTrivia && result <= SyntaxKind.Trivia);
|
||||
@@ -379,6 +418,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
|
||||
}
|
||||
|
||||
return {
|
||||
setPosition: setPosition,
|
||||
getPosition: () => pos,
|
||||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
||||
getToken: () => token,
|
||||
@@ -403,10 +443,6 @@ function isDigit(ch: number): boolean {
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
|
||||
}
|
||||
|
||||
export function isLetter(ch: number): boolean {
|
||||
return ch >= CharacterCodes.a && ch <= CharacterCodes.z || ch >= CharacterCodes.A && ch <= CharacterCodes.Z;
|
||||
}
|
||||
|
||||
enum CharacterCodes {
|
||||
nullCharacter = 0,
|
||||
maxAsciiCharacter = 0x7F,
|
||||
@@ -552,7 +588,7 @@ enum CharacterCodes {
|
||||
*/
|
||||
export function stripComments(text:string, replaceCh?:string):string {
|
||||
|
||||
var _scanner = createScanner(text),
|
||||
let _scanner = createScanner(text),
|
||||
parts: string[] = [],
|
||||
kind:SyntaxKind,
|
||||
offset = 0,
|
||||
@@ -579,23 +615,421 @@ export function stripComments(text:string, replaceCh?:string):string {
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
export function parse(text:string, errors: string[] = []) : any {
|
||||
var noMatch = Object();
|
||||
var _scanner = createScanner(text, true);
|
||||
export interface ParseError {
|
||||
error: ParseErrorCode;
|
||||
}
|
||||
|
||||
function scanNext() : SyntaxKind {
|
||||
var token = _scanner.scan();
|
||||
while (token === SyntaxKind.Unknown) {
|
||||
handleError(nls.localize('UnknownSymbol', 'Invalid symbol'));
|
||||
token = _scanner.scan();
|
||||
export enum ParseErrorCode {
|
||||
InvalidSymbol,
|
||||
InvalidNumberFormat,
|
||||
PropertyNameExpected,
|
||||
ValueExpected,
|
||||
ColonExpected,
|
||||
CommaExpected,
|
||||
CloseBraceExpected,
|
||||
CloseBracketExpected,
|
||||
EndOfFileExpected
|
||||
}
|
||||
|
||||
export function getParseErrorMessage(errorCode: ParseErrorCode) : string {
|
||||
switch (errorCode) {
|
||||
case ParseErrorCode.InvalidSymbol: return localize('error.invalidSymbol', 'Invalid symbol');
|
||||
case ParseErrorCode.InvalidNumberFormat: return localize('error.invalidNumberFormat', 'Invalid number format');
|
||||
case ParseErrorCode.PropertyNameExpected: return localize('error.propertyNameExpected', 'Property name expected');
|
||||
case ParseErrorCode.ValueExpected: return localize('error.valueExpected', 'Value expected');
|
||||
case ParseErrorCode.ColonExpected: return localize('error.colonExpected', 'Colon expected');
|
||||
case ParseErrorCode.CommaExpected: return localize('error.commaExpected', 'Comma expected');
|
||||
case ParseErrorCode.CloseBraceExpected: return localize('error.closeBraceExpected', 'Closing brace expected');
|
||||
case ParseErrorCode.CloseBracketExpected: return localize('error.closeBracketExpected', 'Closing bracket expected');
|
||||
case ParseErrorCode.EndOfFileExpected: return localize('error.endOfFileExpected', 'End of file expected');
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export type NodeType = "object" | "array" | "property" | "string" | "number" | "boolean" | "null";
|
||||
|
||||
function getLiteralNodeType(value: any) : NodeType {
|
||||
switch (typeof value) {
|
||||
case 'boolean': return 'boolean';
|
||||
case 'number': return 'number';
|
||||
case 'string': return 'string';
|
||||
default: return 'null';
|
||||
}
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
type: NodeType;
|
||||
value?: any;
|
||||
offset: number;
|
||||
length: number;
|
||||
columnOffset?: number;
|
||||
parent?: Node;
|
||||
children?: Node[];
|
||||
}
|
||||
|
||||
export type Segment = string | number;
|
||||
export type JSONPath = Segment[];
|
||||
|
||||
export interface Location {
|
||||
/**
|
||||
* The previous property key or literal value (string, number, boolean or null) or undefined.
|
||||
*/
|
||||
previousNode?: Node;
|
||||
/**
|
||||
* The path describing the location in the JSON document. The path consists of a sequence strings
|
||||
* representing an object property or numbers for array indices.
|
||||
*/
|
||||
path: JSONPath;
|
||||
/**
|
||||
* Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices).
|
||||
* '*' will match a single segment, of any property name or index.
|
||||
* '**' will match a sequece of segments or no segment, of any property name or index.
|
||||
*/
|
||||
matches: (patterns: JSONPath) => boolean;
|
||||
/**
|
||||
* If set, the location's offset is at a property key.
|
||||
*/
|
||||
isAtPropertyKey: boolean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export function getLocation(text:string, position: number) : Location {
|
||||
let segments: any[] = []; // strings or numbers
|
||||
let earlyReturnException = new Object();
|
||||
let previousNode : Node = void 0;
|
||||
const previousNodeInst : Node = {
|
||||
value: void 0,
|
||||
offset: void 0,
|
||||
length: void 0,
|
||||
type: void 0
|
||||
};
|
||||
let isAtPropertyKey = false;
|
||||
function setPreviousNode(value: string, offset: number, length: number, type: NodeType) {
|
||||
previousNodeInst.value = value;
|
||||
previousNodeInst.offset = offset;
|
||||
previousNodeInst.length = length;
|
||||
previousNodeInst.type = type;
|
||||
previousNodeInst.columnOffset = void 0;
|
||||
previousNode = previousNodeInst;
|
||||
}
|
||||
try {
|
||||
|
||||
visit(text, {
|
||||
onObjectBegin: (offset: number, length: number) => {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = void 0;
|
||||
isAtPropertyKey = position > offset;
|
||||
segments.push(''); // push a placeholder (will be replaced or removed)
|
||||
},
|
||||
onObjectProperty: (name: string, offset: number, length: number) => {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(name, offset, length, 'property');
|
||||
segments[segments.length - 1] = name;
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onObjectEnd: (offset: number, length: number) => {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = void 0;
|
||||
segments.pop();
|
||||
},
|
||||
onArrayBegin: (offset: number, length: number) => {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = void 0;
|
||||
segments.push(0);
|
||||
},
|
||||
onArrayEnd: (offset: number, length: number) => {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = void 0;
|
||||
segments.pop();
|
||||
},
|
||||
onLiteralValue: (value: any, offset: number, length: number) => {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(value, offset, length, getLiteralNodeType(value));
|
||||
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onSeparator: (sep: string, offset: number, length: number) => {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
if (sep === ':' && previousNode.type === 'property') {
|
||||
previousNode.columnOffset = offset;
|
||||
isAtPropertyKey = false;
|
||||
previousNode = void 0;
|
||||
} else if (sep === ',') {
|
||||
let last = segments[segments.length - 1];
|
||||
if (typeof last === 'number') {
|
||||
segments[segments.length - 1] = last + 1;
|
||||
} else {
|
||||
isAtPropertyKey = true;
|
||||
segments[segments.length - 1] = '';
|
||||
}
|
||||
previousNode = void 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
if (e !== earlyReturnException) {
|
||||
throw e;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
function handleError(message:string, skipUntilAfter: SyntaxKind[] = [], skipUntil: SyntaxKind[] = []) : void {
|
||||
errors.push(message);
|
||||
if (segments[segments.length - 1] === '') {
|
||||
segments.pop();
|
||||
}
|
||||
return {
|
||||
path: segments,
|
||||
previousNode,
|
||||
isAtPropertyKey,
|
||||
matches: (pattern: string[]) => {
|
||||
let k = 0;
|
||||
for (let i = 0; k < pattern.length && i < segments.length; i++) {
|
||||
if (pattern[k] === segments[i] || pattern[k] === '*') {
|
||||
k++;
|
||||
} else if (pattern[k] !== '**') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return k === pattern.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface ParseOptions {
|
||||
disallowComments?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export function parse(text:string, errors: ParseError[] = [], options?: ParseOptions) : any {
|
||||
let currentProperty : string = null;
|
||||
let currentParent : any = [];
|
||||
let previousParents : any[] = [];
|
||||
|
||||
function onValue(value: any) {
|
||||
if (Array.isArray(currentParent)) {
|
||||
(<any[]> currentParent).push(value);
|
||||
} else if (currentProperty) {
|
||||
currentParent[currentProperty] = value;
|
||||
}
|
||||
}
|
||||
|
||||
let visitor : JSONVisitor = {
|
||||
onObjectBegin: () => {
|
||||
let object = {};
|
||||
onValue(object);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = object;
|
||||
currentProperty = null;
|
||||
},
|
||||
onObjectProperty: (name: string) => {
|
||||
currentProperty = name;
|
||||
},
|
||||
onObjectEnd: () => {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onArrayBegin: () => {
|
||||
let array = [];
|
||||
onValue(array);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = array;
|
||||
currentProperty = null;
|
||||
},
|
||||
onArrayEnd: () => {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onLiteralValue: onValue,
|
||||
onError:(error:ParseErrorCode) => {
|
||||
errors.push({error: error});
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
return currentParent[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export function parseTree(text:string, errors: ParseError[] = [], options?: ParseOptions) : Node {
|
||||
let currentParent : Node = { type: 'array', offset: -1, length: -1, children: [] }; // artificial root
|
||||
|
||||
function ensurePropertyComplete(endOffset:number) {
|
||||
if (currentParent.type === 'property') {
|
||||
currentParent.length = endOffset - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
function onValue(valueNode: Node) : Node {
|
||||
currentParent.children.push(valueNode);
|
||||
ensurePropertyComplete(valueNode.offset + valueNode.length);
|
||||
return valueNode;
|
||||
}
|
||||
|
||||
let visitor : JSONVisitor = {
|
||||
onObjectBegin: (offset: number) => {
|
||||
currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onObjectProperty: (name: string, offset: number, length: number) => {
|
||||
currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });
|
||||
currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent});
|
||||
},
|
||||
onObjectEnd: (offset: number, length: number) => {
|
||||
ensurePropertyComplete(offset);
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
},
|
||||
onArrayBegin: (offset: number, length: number) => {
|
||||
currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onArrayEnd: (offset: number, length: number) => {
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
},
|
||||
onLiteralValue: (value: any, offset: number, length: number) => {
|
||||
onValue({ type: getLiteralNodeType(value), offset, length, parent: currentParent, value });
|
||||
},
|
||||
onSeparator: (sep: string, offset: number, length: number) => {
|
||||
if (currentParent.type === 'property') {
|
||||
if (sep === ':') {
|
||||
currentParent.columnOffset = offset;
|
||||
} else if (sep === ',') {
|
||||
ensurePropertyComplete(offset);
|
||||
}
|
||||
}
|
||||
},
|
||||
onError:(error:ParseErrorCode) => {
|
||||
errors.push({error: error});
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
|
||||
let result = currentParent.children[0];
|
||||
if (result) {
|
||||
delete result.parent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function findNodeAtLocation(root: Node, path: JSONPath) : Node {
|
||||
if (!root) {
|
||||
return void 0;
|
||||
}
|
||||
let node = root;
|
||||
for (let segment of path) {
|
||||
if (typeof segment === 'string') {
|
||||
if (node.type !== 'object') {
|
||||
return void 0;
|
||||
}
|
||||
let found = false;
|
||||
for (let propertyNode of node.children) {
|
||||
if (propertyNode.children[0].value === segment) {
|
||||
node = propertyNode.children[1];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return void 0;
|
||||
}
|
||||
} else {
|
||||
let index = <number> segment;
|
||||
if (node.type !== 'array' || index < 0 || index >= node.children.length) {
|
||||
return void 0;
|
||||
}
|
||||
node = node.children[index];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function getNodeValue(node: Node) : any {
|
||||
if (node.type === 'array') {
|
||||
return node.children.map(getNodeValue);
|
||||
} else if (node.type === 'object') {
|
||||
let obj = {};
|
||||
for (let prop of node.children) {
|
||||
obj[prop.children[0].value] = getNodeValue(prop.children[1]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return node.value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export function visit(text:string, visitor: JSONVisitor, options?: ParseOptions) : any {
|
||||
|
||||
let _scanner = createScanner(text, false);
|
||||
|
||||
function toNoArgVisit(visitFunction: (offset: number, length: number) => void) : () => void {
|
||||
return visitFunction ? () => visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength()) : () => true;
|
||||
}
|
||||
function toOneArgVisit<T>(visitFunction: (arg: T, offset: number, length: number) => void) : (arg: T) => void {
|
||||
return visitFunction ? (arg: T) => visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength()) : () => true;
|
||||
}
|
||||
|
||||
let onObjectBegin = toNoArgVisit(visitor.onObjectBegin),
|
||||
onObjectProperty = toOneArgVisit(visitor.onObjectProperty),
|
||||
onObjectEnd = toNoArgVisit(visitor.onObjectEnd),
|
||||
onArrayBegin = toNoArgVisit(visitor.onArrayBegin),
|
||||
onArrayEnd = toNoArgVisit(visitor.onArrayEnd),
|
||||
onLiteralValue = toOneArgVisit(visitor.onLiteralValue),
|
||||
onSeparator = toOneArgVisit(visitor.onSeparator),
|
||||
onError = toOneArgVisit(visitor.onError);
|
||||
|
||||
let disallowComments = options && options.disallowComments;
|
||||
function scanNext() : SyntaxKind {
|
||||
while (true) {
|
||||
let token = _scanner.scan();
|
||||
switch (token) {
|
||||
case SyntaxKind.LineCommentTrivia:
|
||||
case SyntaxKind.BlockCommentTrivia:
|
||||
if (disallowComments) {
|
||||
handleError(ParseErrorCode.InvalidSymbol);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Unknown:
|
||||
handleError(ParseErrorCode.InvalidSymbol);
|
||||
break;
|
||||
case SyntaxKind.Trivia:
|
||||
case SyntaxKind.LineBreakTrivia:
|
||||
break;
|
||||
default:
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(error:ParseErrorCode, skipUntilAfter: SyntaxKind[] = [], skipUntil: SyntaxKind[] = []) : void {
|
||||
onError(error);
|
||||
if (skipUntilAfter.length + skipUntil.length > 0) {
|
||||
var token = _scanner.getToken();
|
||||
let token = _scanner.getToken();
|
||||
while (token !== SyntaxKind.EOF) {
|
||||
if (skipUntilAfter.indexOf(token) !== -1) {
|
||||
scanNext();
|
||||
@@ -608,156 +1042,189 @@ export function parse(text:string, errors: string[] = []) : any {
|
||||
}
|
||||
}
|
||||
|
||||
function parseString() : any {
|
||||
function parseString(isValue: boolean) : boolean {
|
||||
if (_scanner.getToken() !== SyntaxKind.StringLiteral) {
|
||||
return noMatch;
|
||||
return false;
|
||||
}
|
||||
let value = _scanner.getTokenValue();
|
||||
if (isValue) {
|
||||
onLiteralValue(value);
|
||||
} else {
|
||||
onObjectProperty(value);
|
||||
}
|
||||
var value = _scanner.getTokenValue();
|
||||
scanNext();
|
||||
return value;
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseLiteral() : any {
|
||||
var value : any;
|
||||
function parseLiteral() : boolean {
|
||||
switch (_scanner.getToken()) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
let value = 0;
|
||||
try {
|
||||
value = JSON.parse(_scanner.getTokenValue());
|
||||
if (typeof value !== 'number') {
|
||||
handleError(nls.localize('InvalidNumberFormat', 'Invalid number format'));
|
||||
handleError(ParseErrorCode.InvalidNumberFormat);
|
||||
value = 0;
|
||||
}
|
||||
} catch (e) {
|
||||
value = 0;
|
||||
handleError(ParseErrorCode.InvalidNumberFormat);
|
||||
}
|
||||
onLiteralValue(value);
|
||||
break;
|
||||
case SyntaxKind.NullKeyword:
|
||||
value = null;
|
||||
onLiteralValue(null);
|
||||
break;
|
||||
case SyntaxKind.TrueKeyword:
|
||||
value = true;
|
||||
onLiteralValue(true);
|
||||
break;
|
||||
case SyntaxKind.FalseKeyword:
|
||||
value = false;
|
||||
onLiteralValue(false);
|
||||
break;
|
||||
default:
|
||||
return noMatch;
|
||||
return false;
|
||||
}
|
||||
scanNext();
|
||||
return value;
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseProperty(result: any) : any {
|
||||
var key = parseString();
|
||||
if (key === noMatch) {
|
||||
handleError(nls.localize('PropertyExpected', 'Property name expected'), [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
function parseProperty() : boolean {
|
||||
if (!parseString(false)) {
|
||||
handleError(ParseErrorCode.PropertyNameExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
return false;
|
||||
}
|
||||
if (_scanner.getToken() === SyntaxKind.ColonToken) {
|
||||
onSeparator(':');
|
||||
scanNext(); // consume colon
|
||||
|
||||
var value = parseValue();
|
||||
if (value !== noMatch) {
|
||||
result[key] = value;
|
||||
} else {
|
||||
handleError(nls.localize('ValueExpected', 'Value expected'), [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
if (!parseValue()) {
|
||||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
}
|
||||
} else {
|
||||
handleError(nls.localize('ColonExpected', 'Colon expected'), [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
handleError(ParseErrorCode.ColonExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseObject() : any {
|
||||
function parseObject() : boolean {
|
||||
if (_scanner.getToken() !== SyntaxKind.OpenBraceToken) {
|
||||
return noMatch;
|
||||
return false;
|
||||
}
|
||||
var obj = {};
|
||||
onObjectBegin();
|
||||
scanNext(); // consume open brace
|
||||
|
||||
var needsComma = false;
|
||||
let needsComma = false;
|
||||
while (_scanner.getToken() !== SyntaxKind.CloseBraceToken && _scanner.getToken() !== SyntaxKind.EOF) {
|
||||
if (_scanner.getToken() === SyntaxKind.CommaToken) {
|
||||
if (!needsComma) {
|
||||
handleError(nls.localize('ValueExpected', 'Value expected'), [], [] );
|
||||
handleError(ParseErrorCode.ValueExpected, [], [] );
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
} else if (needsComma) {
|
||||
handleError(nls.localize('CommaExpected', 'Comma expected'), [], [] );
|
||||
handleError(ParseErrorCode.CommaExpected, [], [] );
|
||||
}
|
||||
var propertyParsed = parseProperty(obj);
|
||||
if (!propertyParsed) {
|
||||
handleError(nls.localize('ValueExpected', 'Value expected'), [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
if (!parseProperty()) {
|
||||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken] );
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
|
||||
onObjectEnd();
|
||||
if (_scanner.getToken() !== SyntaxKind.CloseBraceToken) {
|
||||
handleError(nls.localize('CloseBraceExpected', 'Closing brace expected'), [SyntaxKind.CloseBraceToken], []);
|
||||
handleError(ParseErrorCode.CloseBraceExpected, [SyntaxKind.CloseBraceToken], []);
|
||||
} else {
|
||||
scanNext(); // consume close brace
|
||||
}
|
||||
return obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseArray() : any {
|
||||
function parseArray() : boolean {
|
||||
if (_scanner.getToken() !== SyntaxKind.OpenBracketToken) {
|
||||
return noMatch;
|
||||
return false;
|
||||
}
|
||||
var arr: any[] = [];
|
||||
onArrayBegin();
|
||||
scanNext(); // consume open bracket
|
||||
|
||||
var needsComma = false;
|
||||
let needsComma = false;
|
||||
while (_scanner.getToken() !== SyntaxKind.CloseBracketToken && _scanner.getToken() !== SyntaxKind.EOF) {
|
||||
if (_scanner.getToken() === SyntaxKind.CommaToken) {
|
||||
if (!needsComma) {
|
||||
handleError(nls.localize('ValeExpected', 'Value expected'), [], [] );
|
||||
handleError(ParseErrorCode.ValueExpected, [], [] );
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
} else if (needsComma) {
|
||||
handleError(nls.localize('CommaExpected', 'Comma expected'), [], [] );
|
||||
handleError(ParseErrorCode.CommaExpected, [], [] );
|
||||
}
|
||||
var value = parseValue();
|
||||
if (value === noMatch) {
|
||||
handleError(nls.localize('ValueExpected', 'Value expected'), [], [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken] );
|
||||
} else {
|
||||
arr.push(value);
|
||||
if (!parseValue()) {
|
||||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken] );
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
|
||||
onArrayEnd();
|
||||
if (_scanner.getToken() !== SyntaxKind.CloseBracketToken) {
|
||||
handleError(nls.localize('CloseBracketExpected', 'Closing bracket expected'), [SyntaxKind.CloseBracketToken], []);
|
||||
handleError(ParseErrorCode.CloseBracketExpected, [SyntaxKind.CloseBracketToken], []);
|
||||
} else {
|
||||
scanNext(); // consume close bracket
|
||||
}
|
||||
return arr;
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseValue() : any {
|
||||
var result = parseArray();
|
||||
if (result !== noMatch) {
|
||||
return result;
|
||||
}
|
||||
result = parseObject();
|
||||
if (result !== noMatch) {
|
||||
return result;
|
||||
}
|
||||
result = parseString();
|
||||
if (result !== noMatch) {
|
||||
return result;
|
||||
}
|
||||
return parseLiteral();
|
||||
function parseValue() : boolean {
|
||||
return parseArray() || parseObject() || parseString(true) || parseLiteral();
|
||||
}
|
||||
|
||||
scanNext();
|
||||
var value = parseValue();
|
||||
if (value === noMatch) {
|
||||
handleError(nls.localize('ValueExpected', 'Value expected'), [], []);
|
||||
return void 0;
|
||||
if (_scanner.getToken() === SyntaxKind.EOF) {
|
||||
return true;
|
||||
}
|
||||
if (!parseValue()) {
|
||||
handleError(ParseErrorCode.ValueExpected, [], []);
|
||||
return false;
|
||||
}
|
||||
if (_scanner.getToken() !== SyntaxKind.EOF) {
|
||||
handleError(nls.localize('EOFExpected', 'End of content expected'), [], []);
|
||||
handleError(ParseErrorCode.EndOfFileExpected, [], []);
|
||||
}
|
||||
return value;
|
||||
return true;
|
||||
}
|
||||
|
||||
export interface JSONVisitor {
|
||||
/**
|
||||
* Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
|
||||
*/
|
||||
onObjectBegin?: (offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when a property is encountered. The offset and length represent the location of the property name.
|
||||
*/
|
||||
onObjectProperty?: (property: string, offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
|
||||
*/
|
||||
onObjectEnd?: (offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
|
||||
*/
|
||||
onArrayBegin?: (offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
|
||||
*/
|
||||
onArrayEnd?: (offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
|
||||
*/
|
||||
onLiteralValue?: (value: any, offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
|
||||
*/
|
||||
onSeparator?: (charcter: string, offset:number, length:number) => void;
|
||||
|
||||
/**
|
||||
* Invoked on an error.
|
||||
*/
|
||||
onError?: (error: ParseErrorCode, offset:number, length:number) => void;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { ParseError, Node, parseTree, findNodeAtLocation, JSONPath, Segment } from 'vs/base/common/json';
|
||||
import { Edit, FormattingOptions, format, applyEdit } from 'vs/base/common/jsonFormatter';
|
||||
|
||||
export function removeProperty(text: string, path: JSONPath, formattingOptions: FormattingOptions) : Edit[] {
|
||||
return setProperty(text, path, void 0, formattingOptions);
|
||||
}
|
||||
|
||||
export function setProperty(text: string, path: JSONPath, value: any, formattingOptions: FormattingOptions, getInsertionIndex?: (properties: string[]) => number) : Edit[] {
|
||||
let errors: ParseError[] = [];
|
||||
let root = parseTree(text, errors);
|
||||
let parent: Node = void 0;
|
||||
|
||||
let lastSegment: Segment = void 0;
|
||||
while (path.length > 0) {
|
||||
lastSegment = path.pop();
|
||||
parent = findNodeAtLocation(root, path);
|
||||
if (parent === void 0 && value !== void 0) {
|
||||
if (typeof lastSegment === 'string') {
|
||||
value = { [lastSegment]: value };
|
||||
} else {
|
||||
value = [ value ];
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
// empty document
|
||||
if (value === void 0) { // delete
|
||||
throw new Error('Can not delete in empty document');
|
||||
}
|
||||
return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions);
|
||||
} else if (parent.type === 'object' && typeof lastSegment === 'string') {
|
||||
let existing = findNodeAtLocation(parent, [ lastSegment ]);
|
||||
if (existing !== void 0) {
|
||||
if (value === void 0) { // delete
|
||||
let propertyIndex = parent.children.indexOf(existing.parent);
|
||||
let removeBegin : number;
|
||||
let removeEnd = existing.parent.offset + existing.parent.length;
|
||||
if (propertyIndex > 0) {
|
||||
// remove the comma of the previous node
|
||||
let previous = parent.children[propertyIndex - 1];
|
||||
removeBegin = previous.offset + previous.length;
|
||||
} else {
|
||||
removeBegin = parent.offset + 1;
|
||||
if (parent.children.length > 1) {
|
||||
// remove the comma of the next node
|
||||
let next = parent.children[1];
|
||||
removeEnd = next.offset;
|
||||
}
|
||||
}
|
||||
return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, formattingOptions);
|
||||
} else {
|
||||
// set value of existing property
|
||||
return [{ offset: existing.offset, length: existing.length, content: JSON.stringify(value) }];
|
||||
}
|
||||
} else {
|
||||
if (value === void 0) { // delete
|
||||
throw new Error(`Property ${lastSegment} does not exist.`);
|
||||
}
|
||||
let newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;
|
||||
let index = getInsertionIndex ? getInsertionIndex(parent.children.map(p => p.children[0].value)) : parent.children.length;
|
||||
let edit: Edit;
|
||||
if (index > 0) {
|
||||
let previous = parent.children[index - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty};
|
||||
} else if (parent.children.length === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty};
|
||||
} else {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty + ','};
|
||||
}
|
||||
return withFormatting(text, edit, formattingOptions);
|
||||
}
|
||||
} else if (parent.type === 'array' && typeof lastSegment === 'number') {
|
||||
throw new Error('Array modification not supported yet');
|
||||
} else {
|
||||
throw new Error(`Can not add ${typeof lastSegment !== 'number' ? 'index' : 'property' } to parent of type ${parent.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function withFormatting(text:string, edit: Edit, formattingOptions: FormattingOptions) : Edit[] {
|
||||
// apply the edit
|
||||
let newText = applyEdit(text, edit);
|
||||
|
||||
// format the new text
|
||||
let begin = edit.offset;
|
||||
let end = edit.offset + edit.content.length;
|
||||
let edits = format(newText, { offset: begin, length: end - begin }, formattingOptions);
|
||||
|
||||
// apply the formatting edits and track the begin and end offsets of the changes
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
let edit = edits[i];
|
||||
newText = applyEdit(newText, edit);
|
||||
begin = Math.min(begin, edit.offset);
|
||||
end = Math.max(end, edit.offset + edit.length);
|
||||
end += edit.content.length - edit.length;
|
||||
}
|
||||
// create a single edit with all changes
|
||||
let editLength = text.length - (newText.length - end) - begin;
|
||||
return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 Json = require('./json');
|
||||
|
||||
export interface FormattingOptions {
|
||||
/**
|
||||
* If indentation is based on spaces (`insertSpaces` = true), then what is the number of spaces that make an indent?
|
||||
*/
|
||||
tabSize: number;
|
||||
/**
|
||||
* Is indentation based on spaces?
|
||||
*/
|
||||
insertSpaces: boolean;
|
||||
/**
|
||||
* The default end of line line character
|
||||
*/
|
||||
eol: string;
|
||||
}
|
||||
|
||||
export interface Edit {
|
||||
offset: number;
|
||||
length: number;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export function applyEdit(text: string, edit: Edit) : string {
|
||||
return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
|
||||
}
|
||||
|
||||
export function applyEdits(text: string, edits: Edit[]) : string {
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
text = applyEdit(text, edits[i]);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export function format(documentText: string, range: { offset: number, length: number}, options: FormattingOptions): Edit[] {
|
||||
let initialIndentLevel: number;
|
||||
let value: string;
|
||||
let rangeStart: number;
|
||||
let rangeEnd: number;
|
||||
if (range) {
|
||||
rangeStart = range.offset;
|
||||
rangeEnd = rangeStart + range.length;
|
||||
while (rangeStart > 0 && !isEOL(documentText, rangeStart - 1)) {
|
||||
rangeStart--;
|
||||
}
|
||||
let scanner = Json.createScanner(documentText, true);
|
||||
scanner.setPosition(rangeEnd);
|
||||
scanner.scan();
|
||||
rangeEnd = scanner.getPosition();
|
||||
|
||||
value = documentText.substring(rangeStart, rangeEnd);
|
||||
initialIndentLevel = computeIndentLevel(value, 0, options);
|
||||
} else {
|
||||
value = documentText;
|
||||
rangeStart = 0;
|
||||
rangeEnd = documentText.length;
|
||||
initialIndentLevel = 0;
|
||||
}
|
||||
let eol = getEOL(options, documentText);
|
||||
|
||||
let lineBreak = false;
|
||||
let indentLevel = 0;
|
||||
let indentValue: string;
|
||||
if (options.insertSpaces) {
|
||||
indentValue = repeat(' ', options.tabSize);
|
||||
} else {
|
||||
indentValue = '\t';
|
||||
}
|
||||
|
||||
let scanner = Json.createScanner(value, false);
|
||||
|
||||
function newLineAndIndent(): string {
|
||||
return eol + repeat(indentValue, initialIndentLevel + indentLevel);
|
||||
}
|
||||
function scanNext(): Json.SyntaxKind {
|
||||
let token = scanner.scan();
|
||||
lineBreak = false;
|
||||
while (token === Json.SyntaxKind.Trivia || token === Json.SyntaxKind.LineBreakTrivia) {
|
||||
lineBreak = lineBreak || (token === Json.SyntaxKind.LineBreakTrivia);
|
||||
token = scanner.scan();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
let editOperations: Edit[] = [];
|
||||
function addEdit(text: string, startOffset: number, endOffset: number) {
|
||||
if (documentText.substring(startOffset, endOffset) !== text) {
|
||||
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
|
||||
}
|
||||
}
|
||||
|
||||
let firstToken = scanNext();
|
||||
if (firstToken !== Json.SyntaxKind.EOF) {
|
||||
let firstTokenStart = scanner.getTokenOffset() + rangeStart;
|
||||
let initialIndent = repeat(indentValue, initialIndentLevel);
|
||||
addEdit(initialIndent, rangeStart, firstTokenStart);
|
||||
}
|
||||
|
||||
while (firstToken !== Json.SyntaxKind.EOF) {
|
||||
let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + rangeStart;
|
||||
let secondToken = scanNext();
|
||||
|
||||
let replaceContent = '';
|
||||
while (!lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
|
||||
// comments on the same line: keep them on the same line, but ignore them otherwise
|
||||
let commentTokenStart = scanner.getTokenOffset() + rangeStart;
|
||||
addEdit(' ', firstTokenEnd, commentTokenStart);
|
||||
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + rangeStart;
|
||||
replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
|
||||
secondToken = scanNext();
|
||||
}
|
||||
|
||||
if (secondToken === Json.SyntaxKind.CloseBraceToken) {
|
||||
if (firstToken !== Json.SyntaxKind.OpenBraceToken) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
} else if (secondToken === Json.SyntaxKind.CloseBracketToken) {
|
||||
if (firstToken !== Json.SyntaxKind.OpenBracketToken) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
} else if (secondToken !== Json.SyntaxKind.EOF) {
|
||||
switch (firstToken) {
|
||||
case Json.SyntaxKind.OpenBracketToken:
|
||||
case Json.SyntaxKind.OpenBraceToken:
|
||||
indentLevel++;
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case Json.SyntaxKind.CommaToken:
|
||||
case Json.SyntaxKind.LineCommentTrivia:
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case Json.SyntaxKind.BlockCommentTrivia:
|
||||
if (lineBreak) {
|
||||
replaceContent = newLineAndIndent();
|
||||
} else {
|
||||
// symbol following comment on the same line: keep on same line, separate with ' '
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
case Json.SyntaxKind.ColonToken:
|
||||
replaceContent = ' ';
|
||||
break;
|
||||
case Json.SyntaxKind.NullKeyword:
|
||||
case Json.SyntaxKind.TrueKeyword:
|
||||
case Json.SyntaxKind.FalseKeyword:
|
||||
case Json.SyntaxKind.NumericLiteral:
|
||||
if (secondToken === Json.SyntaxKind.NullKeyword || secondToken === Json.SyntaxKind.FalseKeyword || secondToken === Json.SyntaxKind.NumericLiteral) {
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
|
||||
}
|
||||
let secondTokenStart = scanner.getTokenOffset() + rangeStart;
|
||||
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
|
||||
firstToken = secondToken;
|
||||
}
|
||||
return editOperations;
|
||||
}
|
||||
|
||||
function repeat(s: string, count: number): string {
|
||||
let result = '';
|
||||
for (let i = 0; i < count; i++) {
|
||||
result += s;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function computeIndentLevel(content: string, offset: number, options: FormattingOptions): number {
|
||||
let i = 0;
|
||||
let nChars = 0;
|
||||
let tabSize = options.tabSize || 4;
|
||||
while (i < content.length) {
|
||||
let ch = content.charAt(i);
|
||||
if (ch === ' ') {
|
||||
nChars++;
|
||||
} else if (ch === '\t') {
|
||||
nChars += tabSize;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return Math.floor(nChars / tabSize);
|
||||
}
|
||||
|
||||
function getEOL(options: FormattingOptions, text: string): string {
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
let ch = text.charAt(i);
|
||||
if (ch === '\r') {
|
||||
if (i + 1 < text.length && text.charAt(i+1) === '\n') {
|
||||
return '\r\n';
|
||||
}
|
||||
return '\r';
|
||||
} else if (ch === '\n') {
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
return (options && options.eol) || '\n';
|
||||
}
|
||||
|
||||
function isEOL(text: string, offset: number) {
|
||||
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
@@ -37,32 +37,6 @@ export function toDisposable(...fns: (() => void)[]): IDisposable {
|
||||
return combinedDisposable(fns.map(fn => ({ dispose: fn })));
|
||||
}
|
||||
|
||||
function callAll(arg: any): any {
|
||||
if (!arg) {
|
||||
return null;
|
||||
} else if (typeof arg === 'function') {
|
||||
arg();
|
||||
return null;
|
||||
} else if (Array.isArray(arg)) {
|
||||
while (arg.length > 0) {
|
||||
arg.pop()();
|
||||
}
|
||||
return arg;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface CallAll {
|
||||
(fn: Function): Function;
|
||||
(fn: Function[]): Function[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls all functions that are being passed to it.
|
||||
*/
|
||||
export const cAll: CallAll = callAll;
|
||||
|
||||
export abstract class Disposable implements IDisposable {
|
||||
|
||||
private _toDispose: IDisposable[];
|
||||
|
||||
Vendored
+1
@@ -95,6 +95,7 @@ export declare class TPromise<V> {
|
||||
public static is(value: any): value is TPromise<any>;
|
||||
public static timeout(delay:number):TPromise<void>;
|
||||
public static join<ValueType>(promises:TPromise<ValueType>[]):TPromise<ValueType[]>;
|
||||
public static join<ValueType>(promises:Thenable<ValueType>[]):Thenable<ValueType[]>;
|
||||
public static join<ValueType>(promises: {[n:string]:TPromise<ValueType>}):TPromise<{[n:string]:ValueType}>;
|
||||
public static any<ValueType>(promises:TPromise<ValueType>[]):TPromise<{ key:string; value:TPromise<ValueType>;}>;
|
||||
public static wrapError<ValueType>(error:any):TPromise<ValueType>;
|
||||
|
||||
@@ -157,9 +157,10 @@ class SimpleWorkerProtocol {
|
||||
export class SimpleWorkerClient<T> extends Disposable {
|
||||
|
||||
private _worker:IWorker;
|
||||
private _onModuleLoaded:TPromise<void>;
|
||||
private _onModuleLoaded:TPromise<string[]>;
|
||||
private _protocol: SimpleWorkerProtocol;
|
||||
private _proxy: T;
|
||||
private _lazyProxy: TPromise<T>;
|
||||
private _lastRequestTimestamp = -1;
|
||||
|
||||
constructor(workerFactory:IWorkerFactory, moduleId:string, ctor:any) {
|
||||
@@ -190,13 +191,30 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
loaderConfiguration = (<any>window).requirejs.s.contexts._.config;
|
||||
}
|
||||
|
||||
let lazyProxyFulfill : (v:T)=>void = null;
|
||||
let lazyProxyReject: (err:any)=>void = null;
|
||||
|
||||
this._lazyProxy = new TPromise((c, e, p) => {
|
||||
lazyProxyFulfill = c;
|
||||
lazyProxyReject = e;
|
||||
}, () => { /* no cancel */ });
|
||||
|
||||
// Send initialize message
|
||||
this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
|
||||
this._worker.getId(),
|
||||
moduleId,
|
||||
loaderConfiguration
|
||||
]);
|
||||
this._onModuleLoaded.then(null, (e) => this._onError('Worker failed to load ' + moduleId, e));
|
||||
this._onModuleLoaded.then((availableMethods:string[]) => {
|
||||
let proxy = <T><any>{};
|
||||
for (let i = 0; i < availableMethods.length; i++) {
|
||||
proxy[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest);
|
||||
}
|
||||
lazyProxyFulfill(proxy);
|
||||
}, (e) => {
|
||||
lazyProxyReject(e);
|
||||
this._onError('Worker failed to load ' + moduleId, e);
|
||||
});
|
||||
|
||||
// Create proxy to loaded code
|
||||
let proxyMethodRequest = (method:string, args:any[]):TPromise<any> => {
|
||||
@@ -211,10 +229,13 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
};
|
||||
|
||||
this._proxy = <T><any>{};
|
||||
for (let prop in ctor.prototype) {
|
||||
if (ctor.prototype.hasOwnProperty(prop)) {
|
||||
if (typeof ctor.prototype[prop] === 'function') {
|
||||
this._proxy[prop] = createProxyMethod(prop, proxyMethodRequest);
|
||||
if (ctor) {
|
||||
// console.warn('deprecated');
|
||||
for (let prop in ctor.prototype) {
|
||||
if (ctor.prototype.hasOwnProperty(prop)) {
|
||||
if (typeof ctor.prototype[prop] === 'function') {
|
||||
this._proxy[prop] = createProxyMethod(prop, proxyMethodRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,6 +245,10 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
return this._proxy;
|
||||
}
|
||||
|
||||
public getProxyObject(): TPromise<T> {
|
||||
return this._lazyProxy;
|
||||
}
|
||||
|
||||
public getLastRequestTimestamp(): number {
|
||||
return this._lastRequestTimestamp;
|
||||
}
|
||||
@@ -323,7 +348,15 @@ export class SimpleWorkerServer {
|
||||
require([moduleId], (...result:any[]) => {
|
||||
let handlerModule = result[0];
|
||||
this._requestHandler = handlerModule.create();
|
||||
cc(null);
|
||||
|
||||
let methods: string[] = [];
|
||||
for (let prop in this._requestHandler) {
|
||||
if (typeof this._requestHandler[prop] === 'function') {
|
||||
methods.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
cc(methods);
|
||||
}, ee);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -80,7 +80,7 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
private visible: boolean;
|
||||
private isLoosingFocus: boolean;
|
||||
private callbacks: IQuickOpenCallbacks;
|
||||
private toUnbind: { (): void; }[];
|
||||
private toUnbind: IDisposable[];
|
||||
private currentInputToken: string;
|
||||
private quickNavigateConfiguration: IQuickNavigateConfiguration;
|
||||
private container: HTMLElement;
|
||||
@@ -111,7 +111,7 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
this.builder = $().div((div: Builder) => {
|
||||
|
||||
// Eventing
|
||||
div.on(DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
||||
div.on(DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
let keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
|
||||
if (keyboardEvent.keyCode === KeyCode.Escape) {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
@@ -141,7 +141,6 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
this.inputElement.setAttribute('aria-haspopup', 'false');
|
||||
this.inputElement.setAttribute('aria-autocomplete', 'list');
|
||||
|
||||
// Listen to some keys on key-down for faster type feedback
|
||||
DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
let keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
|
||||
|
||||
@@ -157,17 +156,8 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
this.navigateInTree(keyboardEvent.keyCode, keyboardEvent.shiftKey);
|
||||
}
|
||||
|
||||
// Bug in IE 9: onInput is not fired for Backspace or Delete keys
|
||||
else if (browser.isIE9 && (keyboardEvent.keyCode === KeyCode.Backspace || keyboardEvent.keyCode === KeyCode.Delete)) {
|
||||
this.onType();
|
||||
}
|
||||
});
|
||||
|
||||
DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
||||
let keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
|
||||
|
||||
// Select element on Enter
|
||||
if (keyboardEvent.keyCode === KeyCode.Enter) {
|
||||
else if (keyboardEvent.keyCode === KeyCode.Enter) {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
|
||||
let focus = this.tree.getFocus();
|
||||
@@ -175,6 +165,11 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
this.elementSelected(focus, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Bug in IE 9: onInput is not fired for Backspace or Delete keys
|
||||
else if (browser.isIE9 && (keyboardEvent.keyCode === KeyCode.Backspace || keyboardEvent.keyCode === KeyCode.Delete)) {
|
||||
this.onType();
|
||||
}
|
||||
});
|
||||
|
||||
DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.INPUT, (e: Event) => {
|
||||
@@ -203,11 +198,11 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
this.treeElement = this.tree.getHTMLElement();
|
||||
|
||||
// Handle Focus and Selection event
|
||||
this.toUnbind.push(this.tree.addListener(EventType.FOCUS, (event: IFocusEvent) => {
|
||||
this.toUnbind.push(this.tree.addListener2(EventType.FOCUS, (event: IFocusEvent) => {
|
||||
this.elementFocused(event.focus, event);
|
||||
}));
|
||||
|
||||
this.toUnbind.push(this.tree.addListener(EventType.SELECTION, (event: ISelectionEvent) => {
|
||||
this.toUnbind.push(this.tree.addListener2(EventType.SELECTION, (event: ISelectionEvent) => {
|
||||
if (event.selection && event.selection.length > 0) {
|
||||
this.elementSelected(event.selection[0], event);
|
||||
}
|
||||
@@ -840,9 +835,7 @@ export class QuickOpenWidget implements IModelProvider {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
while (this.toUnbind.length) {
|
||||
this.toUnbind.pop()();
|
||||
}
|
||||
this.toUnbind = dispose(this.toUnbind);
|
||||
|
||||
this.progressBar.dispose();
|
||||
this.inputBox.dispose();
|
||||
|
||||
@@ -14,6 +14,8 @@ import { ScrollbarVisibility } from 'vs/base/browser/ui/scrollbar/scrollableElem
|
||||
|
||||
export interface ITree extends Events.IEventEmitter {
|
||||
|
||||
emit(eventType:string, data?:any):void;
|
||||
|
||||
/**
|
||||
* Returns the tree's DOM element.
|
||||
*/
|
||||
|
||||
@@ -76,8 +76,8 @@ export class Tree extends Events.EventEmitter implements _.ITree {
|
||||
|
||||
this.view.setModel(this.model);
|
||||
|
||||
this.addEmitter(this.model);
|
||||
this.addEmitter(this.view);
|
||||
this.addEmitter2(this.model);
|
||||
this.addEmitter2(this.view);
|
||||
}
|
||||
|
||||
public getHTMLElement(): HTMLElement {
|
||||
|
||||
@@ -81,13 +81,13 @@ export class Lock {
|
||||
var lock = this.getLock(item);
|
||||
|
||||
if (lock) {
|
||||
var unbindListener: Events.ListenerUnbind;
|
||||
var unbindListener: IDisposable;
|
||||
|
||||
return new WinJS.Promise((c, e) => {
|
||||
unbindListener = lock.addOneTimeListener('unlock', () => {
|
||||
unbindListener = lock.addOneTimeDisposableListener('unlock', () => {
|
||||
return this.run(item, fn).then(c, e);
|
||||
});
|
||||
}, () => unbindListener());
|
||||
}, () => { unbindListener.dispose(); });
|
||||
}
|
||||
|
||||
var result: WinJS.Promise;
|
||||
|
||||
@@ -401,7 +401,7 @@ export class TreeView extends HeightMap {
|
||||
private static currentExternalDragAndDropData: _.IDragAndDropData = null;
|
||||
|
||||
private context: IViewContext;
|
||||
private modelListeners: { (): void; }[];
|
||||
private modelListeners: Lifecycle.IDisposable[];
|
||||
private model: Model.TreeModel;
|
||||
|
||||
private viewListeners: Lifecycle.IDisposable[];
|
||||
@@ -663,7 +663,7 @@ export class TreeView extends HeightMap {
|
||||
this.releaseModel();
|
||||
this.model = newModel;
|
||||
|
||||
this.modelListeners.push(this.model.addBulkListener((e) => this.onModelEvents(e)));
|
||||
this.modelListeners.push(this.model.addBulkListener2((e) => this.onModelEvents(e)));
|
||||
}
|
||||
|
||||
private onModelEvents(events:any[]): void {
|
||||
@@ -1588,9 +1588,7 @@ export class TreeView extends HeightMap {
|
||||
|
||||
private releaseModel(): void {
|
||||
if (this.model) {
|
||||
while (this.modelListeners.length) {
|
||||
this.modelListeners.pop()();
|
||||
}
|
||||
this.modelListeners = Lifecycle.dispose(this.modelListeners);
|
||||
this.model = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,23 +1302,23 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
model.collapse('father');
|
||||
|
||||
var times = 0;
|
||||
var listener = dataModel.addListener('getChildren', (element) => {
|
||||
var listener = dataModel.addListener2('getChildren', (element) => {
|
||||
times++;
|
||||
assert.equal(element, 'grandfather');
|
||||
});
|
||||
|
||||
model.refresh('grandfather').done(() => {
|
||||
assert.equal(times, 1);
|
||||
listener();
|
||||
listener.dispose();
|
||||
|
||||
listener = dataModel.addListener('getChildren', (element) => {
|
||||
listener = dataModel.addListener2('getChildren', (element) => {
|
||||
times++;
|
||||
assert.equal(element, 'father');
|
||||
});
|
||||
|
||||
model.expand('father').done(() => {
|
||||
assert.equal(times, 2);
|
||||
listener();
|
||||
listener.dispose();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -1351,8 +1351,8 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
|
||||
var getTimes = 0;
|
||||
var gotTimes = 0;
|
||||
var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; });
|
||||
var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; });
|
||||
var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; });
|
||||
var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; });
|
||||
|
||||
var p1 = model.refresh('father');
|
||||
assert.equal(getTimes, 1);
|
||||
@@ -1373,8 +1373,8 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
assert.equal(nav.next().id, 'sister');
|
||||
assert.equal(nav.next() && false, null);
|
||||
|
||||
getListener();
|
||||
gotListener();
|
||||
getListener.dispose();
|
||||
gotListener.dispose();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -1399,10 +1399,10 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
counter.listen(model, 'item:refresh', (e) => { refreshTimes++; });
|
||||
|
||||
var getTimes = 0;
|
||||
var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; });
|
||||
var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; });
|
||||
|
||||
var gotTimes = 0;
|
||||
var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; });
|
||||
var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; });
|
||||
|
||||
var p1, p2;
|
||||
|
||||
@@ -1455,8 +1455,8 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
assert.equal(nav.next().id, 'son');
|
||||
assert.equal(nav.next() && false, null);
|
||||
|
||||
getListener();
|
||||
gotListener();
|
||||
getListener.dispose();
|
||||
gotListener.dispose();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -1479,8 +1479,8 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
|
||||
var getTimes = 0;
|
||||
var gotTimes = 0;
|
||||
var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; });
|
||||
var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; });
|
||||
var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; });
|
||||
var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; });
|
||||
|
||||
var p1, p2;
|
||||
|
||||
@@ -1521,8 +1521,8 @@ suite('TreeModel - Dynamic data model', () => {
|
||||
assert.equal(nav.next().id, 'son');
|
||||
assert.equal(nav.next() && false, null);
|
||||
|
||||
getListener();
|
||||
gotListener();
|
||||
getListener.dispose();
|
||||
gotListener.dispose();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('add listener, emit other event type', function () {
|
||||
var didCall = false;
|
||||
eventEmitter.addListener('eventType1', function (e) {
|
||||
eventEmitter.addListener2('eventType1', function (e) {
|
||||
didCall = true;
|
||||
});
|
||||
eventEmitter.emit('eventType2', {});
|
||||
@@ -30,7 +30,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('add listener, emit event', function () {
|
||||
var didCall = false;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
didCall = true;
|
||||
});
|
||||
eventEmitter.emit('eventType', {});
|
||||
@@ -39,11 +39,11 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('add 2 listeners, emit event', function () {
|
||||
var didCallFirst = false;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
didCallFirst = true;
|
||||
});
|
||||
var didCallSecond = false;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
didCallSecond = true;
|
||||
});
|
||||
eventEmitter.emit('eventType', {});
|
||||
@@ -53,22 +53,22 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('add 1 listener, remove it, emit event', function () {
|
||||
var didCall = false;
|
||||
var remove = eventEmitter.addListener('eventType', function (e) {
|
||||
var remove = eventEmitter.addListener2('eventType', function (e) {
|
||||
didCall = true;
|
||||
});
|
||||
remove();
|
||||
remove.dispose();
|
||||
eventEmitter.emit('eventType', {});
|
||||
assert(!didCall);
|
||||
});
|
||||
|
||||
test('add 2 listeners, emit event, remove one while processing', function () {
|
||||
var firstCallCount = 0;
|
||||
var remove1 = eventEmitter.addListener('eventType', function (e) {
|
||||
var remove1 = eventEmitter.addListener2('eventType', function (e) {
|
||||
firstCallCount++;
|
||||
remove1();
|
||||
remove1.dispose();
|
||||
});
|
||||
var secondCallCount = 0;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
secondCallCount++;
|
||||
});
|
||||
eventEmitter.emit('eventType', {});
|
||||
@@ -79,7 +79,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('event object is assert', function () {
|
||||
var data: any;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
data = e.data;
|
||||
});
|
||||
eventEmitter.emit('eventType', { data: 5 });
|
||||
@@ -88,7 +88,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('deferred emit', function () {
|
||||
var calledCount = 0;
|
||||
eventEmitter.addListener('eventType', function (e) {
|
||||
eventEmitter.addListener2('eventType', function (e) {
|
||||
calledCount++;
|
||||
});
|
||||
eventEmitter.deferredEmit(function () {
|
||||
@@ -103,11 +103,11 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('deferred emit maintains events order', function () {
|
||||
var order = 0;
|
||||
eventEmitter.addListener('eventType2', function (e) {
|
||||
eventEmitter.addListener2('eventType2', function (e) {
|
||||
order++;
|
||||
assert.equal(order, 1);
|
||||
});
|
||||
eventEmitter.addListener('eventType1', function (e) {
|
||||
eventEmitter.addListener2('eventType1', function (e) {
|
||||
order++;
|
||||
assert.equal(order, 2);
|
||||
});
|
||||
@@ -120,7 +120,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('deferred emit maintains events order for bulk listeners', function () {
|
||||
var count = 0;
|
||||
eventEmitter.addBulkListener(function (events) {
|
||||
eventEmitter.addBulkListener2(function (events) {
|
||||
assert.equal(events[0].getType(), 'eventType2');
|
||||
assert.equal(events[1].getType(), 'eventType1');
|
||||
count++;
|
||||
@@ -134,7 +134,7 @@ suite('EventEmitter', () => {
|
||||
|
||||
test('emit notifies bulk listeners', function () {
|
||||
var count = 0;
|
||||
eventEmitter.addBulkListener(function (events) {
|
||||
eventEmitter.addBulkListener2(function (events) {
|
||||
count++;
|
||||
});
|
||||
eventEmitter.emit('eventType', {});
|
||||
@@ -145,13 +145,13 @@ suite('EventEmitter', () => {
|
||||
var emitter = new EventEmitter();
|
||||
var eventBus = new EventEmitter();
|
||||
|
||||
eventBus.addEmitter(emitter, 'emitter1');
|
||||
eventBus.addEmitter2(emitter);
|
||||
var didCallFirst = false;
|
||||
eventBus.addListener('eventType', function (e) {
|
||||
eventBus.addListener2('eventType', function (e) {
|
||||
didCallFirst = true;
|
||||
});
|
||||
var didCallSecond = false;
|
||||
eventBus.addListener('eventType/emitter1', function (e) {
|
||||
eventBus.addListener2('eventType', function (e) {
|
||||
didCallSecond = true;
|
||||
});
|
||||
|
||||
@@ -166,17 +166,13 @@ suite('EventEmitter', () => {
|
||||
var emitter2 = new EventEmitter();
|
||||
var eventBus = new EventEmitter();
|
||||
|
||||
eventBus.addEmitter(emitter1, 'emitter1');
|
||||
eventBus.addEmitter(emitter2, 'emitter2');
|
||||
eventBus.addListener('eventType1', function (e) {
|
||||
eventBus.addEmitter2(emitter1);
|
||||
eventBus.addEmitter2(emitter2);
|
||||
eventBus.addListener2('eventType1', function (e) {
|
||||
assert(true);
|
||||
callCnt++;
|
||||
});
|
||||
eventBus.addListener('eventType1/emitter1', function (e) {
|
||||
assert(true);
|
||||
callCnt++;
|
||||
});
|
||||
eventBus.addEmitterTypeListener('eventType1', 'emitter1', function (e) {
|
||||
eventBus.addListener2('eventType1', function (e) {
|
||||
assert(true);
|
||||
callCnt++;
|
||||
});
|
||||
@@ -196,12 +192,12 @@ suite('EventEmitter', () => {
|
||||
var emitter3 = new EventEmitter();
|
||||
var emitter4 = new EventEmitter();
|
||||
|
||||
emitter2.addEmitter(emitter1);
|
||||
emitter3.addEmitter(emitter2);
|
||||
emitter4.addEmitter(emitter3);
|
||||
emitter2.addEmitter2(emitter1);
|
||||
emitter3.addEmitter2(emitter2);
|
||||
emitter4.addEmitter2(emitter3);
|
||||
|
||||
var didCall = false;
|
||||
emitter4.addListener('eventType', function (e) {
|
||||
emitter4.addListener2('eventType', function (e) {
|
||||
didCall = true;
|
||||
});
|
||||
|
||||
@@ -213,16 +209,16 @@ suite('EventEmitter', () => {
|
||||
var emitter = new EventEmitter();
|
||||
var actualCallOrder: string[] = [];
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener1-foo');
|
||||
emitter.emit('bar');
|
||||
});
|
||||
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener2-foo');
|
||||
});
|
||||
emitter.addListener('bar', function() {
|
||||
emitter.addListener2('bar', function() {
|
||||
actualCallOrder.push('listener2-bar');
|
||||
});
|
||||
|
||||
@@ -239,7 +235,7 @@ suite('EventEmitter', () => {
|
||||
var emitter = new EventEmitter();
|
||||
var actualCallOrder: string[] = [];
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener1-foo');
|
||||
emitter.deferredEmit(() => {
|
||||
emitter.emit('bar');
|
||||
@@ -247,10 +243,10 @@ suite('EventEmitter', () => {
|
||||
});
|
||||
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener2-foo');
|
||||
});
|
||||
emitter.addListener('bar', function() {
|
||||
emitter.addListener2('bar', function() {
|
||||
actualCallOrder.push('listener2-bar');
|
||||
});
|
||||
|
||||
@@ -269,16 +265,16 @@ suite('EventEmitter', () => {
|
||||
var emitter = new OrderGuaranteeEventEmitter();
|
||||
var actualCallOrder: string[] = [];
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener1-foo');
|
||||
emitter.emit('bar');
|
||||
});
|
||||
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener2-foo');
|
||||
});
|
||||
emitter.addListener('bar', function() {
|
||||
emitter.addListener2('bar', function() {
|
||||
actualCallOrder.push('listener2-bar');
|
||||
});
|
||||
|
||||
@@ -295,7 +291,7 @@ suite('EventEmitter', () => {
|
||||
var emitter = new OrderGuaranteeEventEmitter();
|
||||
var actualCallOrder: string[] = [];
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener1-foo');
|
||||
emitter.deferredEmit(() => {
|
||||
emitter.emit('bar');
|
||||
@@ -303,10 +299,10 @@ suite('EventEmitter', () => {
|
||||
});
|
||||
|
||||
|
||||
emitter.addListener('foo', function() {
|
||||
emitter.addListener2('foo', function() {
|
||||
actualCallOrder.push('listener2-foo');
|
||||
});
|
||||
emitter.addListener('bar', function() {
|
||||
emitter.addListener2('bar', function() {
|
||||
actualCallOrder.push('listener2-bar');
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { SyntaxKind, createScanner, parse } from 'vs/base/common/json';
|
||||
import { SyntaxKind, createScanner, parse, getLocation, Node, ParseError, parseTree, ParseErrorCode,
|
||||
getParseErrorMessage, ParseOptions, Segment, findNodeAtLocation, getNodeValue } from 'vs/base/common/json';
|
||||
|
||||
function assertKinds(text:string, ...kinds:SyntaxKind[]):void {
|
||||
var _json = createScanner(text);
|
||||
@@ -17,24 +18,60 @@ function assertKinds(text:string, ...kinds:SyntaxKind[]):void {
|
||||
}
|
||||
|
||||
|
||||
function assertValidParse(input:string, expected:any) : void {
|
||||
var errors : string[] = [];
|
||||
var actual = parse(input, errors);
|
||||
function assertValidParse(input:string, expected:any, options?: ParseOptions) : void {
|
||||
var errors : {error: ParseErrorCode}[] = [];
|
||||
var actual = parse(input, errors, options);
|
||||
|
||||
if (errors.length !== 0) {
|
||||
assert(false, errors[0]);
|
||||
assert(false, getParseErrorMessage(errors[0].error));
|
||||
}
|
||||
assert.deepEqual(actual, expected);
|
||||
}
|
||||
|
||||
function assertInvalidParse(input:string, expected:any) : void {
|
||||
var errors : string[] = [];
|
||||
var actual = parse(input, errors);
|
||||
function assertInvalidParse(input:string, expected:any, options?: ParseOptions) : void {
|
||||
var errors : {error: ParseErrorCode}[] = [];
|
||||
var actual = parse(input, errors, options);
|
||||
|
||||
assert(errors.length > 0);
|
||||
assert.deepEqual(actual, expected);
|
||||
}
|
||||
|
||||
function assertTree(input:string, expected:any) : void {
|
||||
var errors : ParseError[] = [];
|
||||
var actual = parseTree(input, errors);
|
||||
|
||||
assert.equal(errors.length, 0);
|
||||
let checkParent = (node: Node) => {
|
||||
if (node.children) {
|
||||
for (let child of node.children) {
|
||||
assert.equal(node, child.parent);
|
||||
delete child.parent; // delete to avoid recursion in deep equal
|
||||
checkParent(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkParent(actual);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
}
|
||||
|
||||
function assertNodeAtLocation(input:Node, segments: Segment[], expected: any) {
|
||||
let actual = findNodeAtLocation(input, segments);
|
||||
assert.deepEqual(actual ? getNodeValue(actual) : void 0, expected);
|
||||
}
|
||||
|
||||
|
||||
function assertLocation(input:string, expectedSegments: Segment[], expectedNodeType: string, expectedCompleteProperty: boolean) : void {
|
||||
var errors : {error: ParseErrorCode}[] = [];
|
||||
var offset = input.indexOf('|');
|
||||
input = input.substring(0, offset) + input.substring(offset+1, input.length);
|
||||
var actual = getLocation(input, offset);
|
||||
assert(actual);
|
||||
assert.deepEqual(actual.path, expectedSegments, input);
|
||||
assert.equal(actual.previousNode && actual.previousNode.type, expectedNodeType, input);
|
||||
assert.equal(actual.isAtPropertyKey, expectedCompleteProperty, input);
|
||||
}
|
||||
|
||||
suite('JSON', () => {
|
||||
test('tokens', () => {
|
||||
assertKinds('{', SyntaxKind.OpenBraceToken);
|
||||
@@ -147,7 +184,7 @@ suite('JSON', () => {
|
||||
assertValidParse('23e3', 23e3);
|
||||
assertValidParse('1.2E+3', 1.2E+3);
|
||||
assertValidParse('1.2E-3', 1.2E-3);
|
||||
|
||||
assertValidParse('1.2E-3 // comment', 1.2E-3);
|
||||
});
|
||||
|
||||
test('parse: objects', () => {
|
||||
@@ -157,6 +194,9 @@ suite('JSON', () => {
|
||||
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} });
|
||||
assertValidParse('{ "a": false, "b": true, "c": [ 7.4 ] }', { a: false, b: true, c: [ 7.4 ]});
|
||||
assertValidParse('{ "lineComment": "//", "blockComment": ["/*", "*/"], "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ] }', { lineComment: '//', blockComment: ["/*", "*/"], brackets: [ ["{", "}"], ["[", "]"], ["(", ")"] ] });
|
||||
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} });
|
||||
assertValidParse('{ "hello": { "again": { "inside": 5 }, "world": 1 }}', { hello: { again: { inside: 5 }, world: 1 }});
|
||||
assertValidParse('{ "foo": /*hello*/true }', { foo: true });
|
||||
});
|
||||
|
||||
test('parse: arrays', () => {
|
||||
@@ -183,4 +223,105 @@ suite('JSON', () => {
|
||||
assertInvalidParse('[ ,1, 2, 3 ]', [ 1, 2, 3 ]);
|
||||
assertInvalidParse('[ ,1, 2, 3, ]', [ 1, 2, 3 ]);
|
||||
});
|
||||
|
||||
test('parse: disallow commments', () => {
|
||||
let options = { disallowComments: true };
|
||||
|
||||
assertValidParse('[ 1, 2, null, "foo" ]', [ 1, 2, null, "foo"], options);
|
||||
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} }, options);
|
||||
|
||||
assertInvalidParse('{ "foo": /*comment*/ true }', { foo: true }, options);
|
||||
});
|
||||
|
||||
test('location: properties', () => {
|
||||
assertLocation('|{ "foo": "bar" }', [], void 0, false);
|
||||
assertLocation('{| "foo": "bar" }', [], void 0, true);
|
||||
assertLocation('{ |"foo": "bar" }', ["foo" ], "property", true);
|
||||
assertLocation('{ "foo|": "bar" }', [ "foo" ], "property", true);
|
||||
assertLocation('{ "foo"|: "bar" }', ["foo" ], "property", true);
|
||||
assertLocation('{ "foo": "bar"| }', ["foo" ], "string", false);
|
||||
assertLocation('{ "foo":| "bar" }', ["foo" ], void 0, false);
|
||||
assertLocation('{ "foo": {"bar|": 1, "car": 2 } }', ["foo", "bar" ], "property", true);
|
||||
assertLocation('{ "foo": {"bar": 1|, "car": 3 } }', ["foo", "bar" ], "number", false);
|
||||
assertLocation('{ "foo": {"bar": 1,| "car": 4 } }', ["foo"], void 0, true);
|
||||
assertLocation('{ "foo": {"bar": 1, "ca|r": 5 } }', ["foo", "car" ], "property", true);
|
||||
assertLocation('{ "foo": {"bar": 1, "car": 6| } }', ["foo", "car" ], "number", false);
|
||||
assertLocation('{ "foo": {"bar": 1, "car": 7 }| }', ["foo"], void 0, false);
|
||||
assertLocation('{ "foo": {"bar": 1, "car": 8 },| "goo": {} }', [], void 0, true);
|
||||
assertLocation('{ "foo": {"bar": 1, "car": 9 }, "go|o": {} }', ["goo" ], "property", true);
|
||||
assertLocation('{ "dep": {"bar": 1, "car": |', ["dep", "car" ], void 0, false);
|
||||
assertLocation('{ "dep": {"bar": 1,, "car": |', ["dep", "car" ], void 0, false);
|
||||
assertLocation('{ "dep": {"bar": "na", "dar": "ma", "car": | } }', ["dep", "car" ], void 0, false);
|
||||
});
|
||||
|
||||
test('location: arrays', () => {
|
||||
assertLocation('|["foo", null ]', [], void 0, false);
|
||||
assertLocation('[|"foo", null ]', [0], "string", false);
|
||||
assertLocation('["foo"|, null ]', [0], "string", false);
|
||||
assertLocation('["foo",| null ]', [1], void 0, false);
|
||||
assertLocation('["foo", |null ]', [1], "null", false);
|
||||
assertLocation('["foo", null,| ]', [2], void 0, false);
|
||||
assertLocation('["foo", null,,| ]', [3], void 0, false);
|
||||
assertLocation('[["foo", null,, ],|', [1], void 0, false);
|
||||
});
|
||||
|
||||
test('tree: literals', () => {
|
||||
assertTree('true', { type: 'boolean', offset: 0, length: 4, value: true });
|
||||
assertTree('false', { type: 'boolean', offset: 0, length: 5, value: false });
|
||||
assertTree('null', { type: 'null', offset: 0, length: 4, value: null });
|
||||
assertTree('23', { type: 'number', offset: 0, length: 2, value: 23 });
|
||||
assertTree('-1.93e-19', { type: 'number', offset: 0, length: 9, value: -1.93e-19 });
|
||||
assertTree('"hello"', { type: 'string', offset: 0, length: 7, value: 'hello' });
|
||||
});
|
||||
|
||||
test('tree: arrays', () => {
|
||||
assertTree('[]', { type: 'array', offset: 0, length: 2, children: [] });
|
||||
assertTree('[ 1 ]', { type: 'array', offset: 0, length: 5, children: [{ type: 'number', offset: 2, length: 1, value: 1 }] });
|
||||
assertTree('[ 1,"x"]', { type: 'array', offset: 0, length: 8, children: [
|
||||
{ type: 'number', offset: 2, length: 1, value: 1 },
|
||||
{ type: 'string', offset: 4, length: 3, value: 'x' }
|
||||
]});
|
||||
assertTree('[[]]', { type: 'array', offset: 0, length: 4, children: [
|
||||
{ type: 'array', offset: 1, length: 2, children: []}
|
||||
]});
|
||||
});
|
||||
|
||||
test('tree: objects', () => {
|
||||
assertTree('{ }', { type: 'object', offset: 0, length: 3, children: [] });
|
||||
assertTree('{ "val": 1 }', { type: 'object', offset: 0, length: 12, children: [
|
||||
{ type: 'property', offset: 2, length: 8, columnOffset: 7, children: [
|
||||
{ type: 'string', offset: 2, length: 5, value: 'val' },
|
||||
{ type: 'number', offset: 9, length: 1, value: 1 }
|
||||
]}
|
||||
]});
|
||||
assertTree('{"id": "$", "v": [ null, null] }',
|
||||
{ type: 'object', offset: 0, length: 32, children: [
|
||||
{ type: 'property', offset: 1, length: 9, columnOffset: 5, children: [
|
||||
{ type: 'string', offset: 1, length: 4, value: 'id' },
|
||||
{ type: 'string', offset: 7, length: 3, value: '$' }
|
||||
]},
|
||||
{ type: 'property', offset: 12, length: 19, columnOffset: 15, children: [
|
||||
{ type: 'string', offset: 12, length: 3, value: 'v' },
|
||||
{ type: 'array', offset: 17, length: 13, children: [
|
||||
{ type: 'null', offset: 19, length: 4, value: null },
|
||||
{ type: 'null', offset: 25, length: 4, value: null }
|
||||
]}
|
||||
]}
|
||||
]}
|
||||
);
|
||||
});
|
||||
|
||||
test('tree: find location', () => {
|
||||
let root = parseTree('{ "key1": { "key11": [ "val111", "val112" ] }, "key2": [ { "key21": false, "key22": 221 }, null, [{}] ] }');
|
||||
assertNodeAtLocation(root, [ "key1"], { key11: [ 'val111', 'val112' ]});
|
||||
assertNodeAtLocation(root, [ "key1", "key11"], [ 'val111', 'val112' ]);
|
||||
assertNodeAtLocation(root, [ "key1", "key11", 0], 'val111');
|
||||
assertNodeAtLocation(root, [ "key1", "key11", 1], 'val112');
|
||||
assertNodeAtLocation(root, [ "key1", "key11", 2], void 0);
|
||||
assertNodeAtLocation(root, [ "key2", 0, "key21"], false);
|
||||
assertNodeAtLocation(root, [ "key2", 0, "key22"], 221);
|
||||
assertNodeAtLocation(root, [ "key2", 1], null);
|
||||
assertNodeAtLocation(root, [ "key2", 2], [{}]);
|
||||
assertNodeAtLocation(root, [ "key2", 2, 0], {});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 json = require('vs/base/common/json');
|
||||
import {FormattingOptions, Edit} from 'vs/base/common/jsonFormatter';
|
||||
import {setProperty, removeProperty} from 'vs/base/common/jsonEdit';
|
||||
import assert = require('assert');
|
||||
|
||||
suite('JSON - edits', () => {
|
||||
|
||||
function assertEdit(content: string, edits: Edit[], expected: string) {
|
||||
assert(edits);
|
||||
let lastEditOffset = content.length;
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
let edit = edits[i];
|
||||
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length)
|
||||
assert(typeof edit.content === 'string');
|
||||
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
|
||||
lastEditOffset = edit.offset;
|
||||
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
|
||||
}
|
||||
assert.equal(content, expected);
|
||||
}
|
||||
|
||||
let formatterOptions : FormattingOptions = {
|
||||
insertSpaces: true,
|
||||
tabSize: 2,
|
||||
eol: '\n'
|
||||
}
|
||||
|
||||
test('set property', () => {
|
||||
let content = '{\n "x": "y"\n}';
|
||||
let edits = setProperty(content, ['x'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": "bar"\n}');
|
||||
|
||||
content = 'true';
|
||||
edits = setProperty(content, [], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '"bar"');
|
||||
});
|
||||
|
||||
test('insert property', () => {
|
||||
let content = "{}";
|
||||
let edits = setProperty(content, ['foo'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "foo": "bar"\n}');
|
||||
|
||||
edits = setProperty(content, ['foo', 'foo2'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "foo": {\n "foo2": "bar"\n }\n}');
|
||||
|
||||
content = "{\n}";
|
||||
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "foo": "bar"\n}');
|
||||
|
||||
content = " {\n }";
|
||||
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, ' {\n "foo": "bar"\n }');
|
||||
|
||||
content = '{\n "x": "y"\n}';
|
||||
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": "y",\n "foo": "bar"\n}');
|
||||
|
||||
edits = setProperty(content, ['x'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": "bar"\n}');
|
||||
|
||||
content = '{\n "x": {\n "a": 1,\n "b": true\n }\n}\n';
|
||||
edits = setProperty(content, ['x'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": "bar"\n}\n');
|
||||
|
||||
edits = setProperty(content, ['x', 'b'], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "b": "bar"\n }\n}\n');
|
||||
|
||||
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 0);
|
||||
assertEdit(content, edits, '{\n "x": {\n "c": "bar",\n "a": 1,\n "b": true\n }\n}\n');
|
||||
|
||||
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 1);
|
||||
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "c": "bar",\n "b": true\n }\n}\n');
|
||||
|
||||
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 2);
|
||||
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "b": true,\n "c": "bar"\n }\n}\n');
|
||||
|
||||
content = '';
|
||||
edits = setProperty(content, ['foo', 0], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n}');
|
||||
|
||||
content = '//comment';
|
||||
edits = setProperty(content, ['foo', 0], 'bar', formatterOptions);
|
||||
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n} //comment\n');
|
||||
});
|
||||
|
||||
test('remove property', () => {
|
||||
let content = '{\n "x": "y"\n}';
|
||||
let edits = removeProperty(content, ['x'], formatterOptions);
|
||||
assertEdit(content, edits, '{}');
|
||||
|
||||
content = '{\n "x": "y", "a": []\n}';
|
||||
edits = removeProperty(content, ['x'], formatterOptions);
|
||||
assertEdit(content, edits, '{\n "a": []\n}');
|
||||
|
||||
content = '{\n "x": "y", "a": []\n}';
|
||||
edits = removeProperty(content, ['a'], formatterOptions);
|
||||
assertEdit(content, edits, '{\n "x": "y"\n}');
|
||||
});
|
||||
});
|
||||
+19
-32
@@ -4,46 +4,33 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import EditorCommon = require('vs/editor/common/editorCommon');
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
import {Model} from 'vs/editor/common/model/model';
|
||||
import ModesTestUtils = require('vs/editor/test/common/modesTestUtils');
|
||||
import Formatter = require('vs/languages/json/common/features/jsonFormatter');
|
||||
import MirrorModel = require('vs/editor/common/model/mirrorModel');
|
||||
import Formatter = require('vs/base/common/jsonFormatter');
|
||||
import assert = require('assert');
|
||||
|
||||
suite('JSON - formatter', () => {
|
||||
|
||||
function format(unformatted: string, expected: string, insertSpaces = true) {
|
||||
var range : EditorCommon.IRange = null;
|
||||
|
||||
var mirrorModel = MirrorModel.createTestMirrorModelFromString(unformatted);
|
||||
|
||||
var rangeStart = unformatted.indexOf('|');
|
||||
var rangeEnd = unformatted.lastIndexOf('|');
|
||||
function format(content: string, expected: string, insertSpaces = true) {
|
||||
let range = void 0;
|
||||
var rangeStart = content.indexOf('|');
|
||||
var rangeEnd = content.lastIndexOf('|');
|
||||
if (rangeStart !== -1 && rangeEnd !== -1) {
|
||||
unformatted = unformatted.substring(0, rangeStart) + unformatted.substring(rangeStart + 1, rangeEnd) + unformatted.substring(rangeEnd + 1);
|
||||
|
||||
var startPos = mirrorModel.getPositionFromOffset(rangeStart);
|
||||
var endPos = mirrorModel.getPositionFromOffset(rangeEnd);
|
||||
range = { startLineNumber: startPos.lineNumber, startColumn: startPos.column, endLineNumber: endPos.lineNumber, endColumn: endPos.column };
|
||||
mirrorModel = MirrorModel.createTestMirrorModelFromString(unformatted);
|
||||
content = content.substring(0, rangeStart) + content.substring(rangeStart + 1, rangeEnd) + content.substring(rangeEnd + 1);
|
||||
range = { offset: rangeStart, length: rangeEnd - rangeStart };
|
||||
}
|
||||
|
||||
var operations = Formatter.format(mirrorModel, range, { tabSize: 2, insertSpaces: insertSpaces });
|
||||
var edits = Formatter.format(content, range, { tabSize: 2, insertSpaces: insertSpaces, eol: '\n' });
|
||||
|
||||
var model = new Model(unformatted, Model.DEFAULT_CREATION_OPTIONS, null);
|
||||
model.pushEditOperations([], operations.map(o => {
|
||||
return {
|
||||
range: Range.lift(o.range),
|
||||
text: o.text,
|
||||
identifier: null,
|
||||
forceMoveMarkers: false
|
||||
};
|
||||
}), () => []);
|
||||
var newContent = model.getValue(EditorCommon.EndOfLinePreference.LF);
|
||||
assert.equal(newContent, expected);
|
||||
model.dispose();
|
||||
let lastEditOffset = content.length;
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
let edit = edits[i];
|
||||
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length)
|
||||
assert(typeof edit.content === 'string');
|
||||
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
|
||||
lastEditOffset = edit.offset;
|
||||
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
|
||||
}
|
||||
|
||||
assert.equal(content, expected);
|
||||
}
|
||||
|
||||
test('object - single property', () => {
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
function createModuleDescription(name, exclude) {
|
||||
var result= {};
|
||||
var excludes = ['vs/css', 'vs/nls', 'vs/text'];
|
||||
var excludes = ['vs/css', 'vs/nls'];
|
||||
result.name= name;
|
||||
if (Array.isArray(exclude) && exclude.length > 0) {
|
||||
excludes = excludes.concat(exclude);
|
||||
|
||||
@@ -409,10 +409,6 @@ export class VSCodeMenu {
|
||||
|
||||
// Files
|
||||
let files = recentList.files;
|
||||
if (platform.isMacintosh && recentList.files.length > 0) {
|
||||
files = recentList.files.filter(f => recentList.folders.indexOf(f) < 0); // TODO@Ben migration (remove in the future)
|
||||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
openRecentMenu.append(__separator__());
|
||||
|
||||
@@ -793,7 +789,7 @@ function __separator__(): Electron.MenuItem {
|
||||
|
||||
function mnemonicLabel(label: string): string {
|
||||
if (platform.isMacintosh) {
|
||||
return label.replace(/&&/g, ''); // no mnemonic support on mac
|
||||
return label.replace(/\(&&\w\)|&&/g, ''); // no mnemonic support on mac/linux
|
||||
}
|
||||
|
||||
return label.replace(/&&/g, '&');
|
||||
|
||||
@@ -112,7 +112,6 @@ export interface IWindowConfiguration extends ICommandLineArguments {
|
||||
crashReporter: Electron.CrashReporterStartOptions;
|
||||
extensionsGallery: {
|
||||
serviceUrl: string;
|
||||
cacheUrl: string;
|
||||
itemUrl: string;
|
||||
};
|
||||
extensionTips: { [id: string]: string; };
|
||||
|
||||
@@ -789,10 +789,6 @@ export class WindowsManager implements IWindowsService {
|
||||
files = arrays.distinct(files);
|
||||
folders = arrays.distinct(folders);
|
||||
|
||||
if (platform.isMacintosh && files.length > 0) {
|
||||
files = files.filter(f => folders.indexOf(f) < 0); // TODO@Ben migration (remove in the future)
|
||||
}
|
||||
|
||||
// Make sure it is bounded
|
||||
files = files.slice(0, 10);
|
||||
folders = folders.slice(0, 10);
|
||||
|
||||
@@ -94,6 +94,7 @@ ${ indent }-r, --reuse-window Force opening a file or folder in the last acti
|
||||
${ indent } window.
|
||||
${ indent }--user-data-dir <dir> Specifies the directory that user data is kept in,
|
||||
${ indent } useful when running as root.
|
||||
${ indent }--verbose Print verbose output (implies --wait).
|
||||
${ indent }-v, --version Print version.
|
||||
${ indent }-w, --wait Wait for the window to be closed before returning.
|
||||
${ indent }--list-extensions List the installed extensions.
|
||||
|
||||
+16
-7
@@ -35,14 +35,23 @@ export function main(args: string[]): TPromise<void> {
|
||||
});
|
||||
delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
||||
|
||||
const child = spawn(process.execPath, args, {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
env
|
||||
});
|
||||
let options = {
|
||||
detacted: true,
|
||||
env,
|
||||
};
|
||||
if (!argv.verbose) {
|
||||
options['stdio'] = 'ignore';
|
||||
}
|
||||
|
||||
if (argv.wait) {
|
||||
return new TPromise<void>(c => child.once('exit', ()=> c(null)));
|
||||
const child = spawn(process.execPath, args, options);
|
||||
|
||||
if (argv.verbose) {
|
||||
child.stdout.on('data', (data) => console.log(data.toString('utf8').trim()));
|
||||
child.stderr.on('data', (data) => console.log(data.toString('utf8').trim()));
|
||||
}
|
||||
|
||||
if (argv.wait || argv.verbose) {
|
||||
return new TPromise<void>(c => child.once('exit', () => c(null)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-8
@@ -13,8 +13,6 @@
|
||||
*---------------------------------------------------------------------------------------------
|
||||
*---------------------------------------------------------------------------------------------
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/// <reference path="declares.ts" />
|
||||
/// <reference path="loader.ts" />
|
||||
'use strict';
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
@@ -100,7 +98,7 @@ var CSSLoaderPlugin;
|
||||
this._insertLinkNode(linkNode);
|
||||
};
|
||||
return BrowserCSSLoader;
|
||||
})();
|
||||
}());
|
||||
/**
|
||||
* Prior to IE10, IE could not go above 31 stylesheets in a page
|
||||
* http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/internet-explorer-stylesheet-rule-selector-import-sheet-limit-maximum.aspx
|
||||
@@ -201,7 +199,7 @@ var CSSLoaderPlugin;
|
||||
}
|
||||
};
|
||||
return IE9CSSLoader;
|
||||
})(BrowserCSSLoader);
|
||||
}(BrowserCSSLoader));
|
||||
var IE8CSSLoader = (function (_super) {
|
||||
__extends(IE8CSSLoader, _super);
|
||||
function IE8CSSLoader() {
|
||||
@@ -214,7 +212,7 @@ var CSSLoaderPlugin;
|
||||
};
|
||||
};
|
||||
return IE8CSSLoader;
|
||||
})(IE9CSSLoader);
|
||||
}(IE9CSSLoader));
|
||||
var NodeCSSLoader = (function () {
|
||||
function NodeCSSLoader() {
|
||||
this.fs = require.nodeRequire('fs');
|
||||
@@ -229,7 +227,7 @@ var CSSLoaderPlugin;
|
||||
};
|
||||
NodeCSSLoader.BOM_CHAR_CODE = 65279;
|
||||
return NodeCSSLoader;
|
||||
})();
|
||||
}());
|
||||
// ------------------------------ Finally, the plugin
|
||||
var CSSPlugin = (function () {
|
||||
function CSSPlugin(cssLoader) {
|
||||
@@ -279,7 +277,7 @@ var CSSLoaderPlugin;
|
||||
};
|
||||
CSSPlugin.BUILD_MAP = {};
|
||||
return CSSPlugin;
|
||||
})();
|
||||
}());
|
||||
CSSLoaderPlugin.CSSPlugin = CSSPlugin;
|
||||
var Utilities = (function () {
|
||||
function Utilities() {
|
||||
@@ -411,7 +409,7 @@ var CSSLoaderPlugin;
|
||||
});
|
||||
};
|
||||
return Utilities;
|
||||
})();
|
||||
}());
|
||||
CSSLoaderPlugin.Utilities = Utilities;
|
||||
(function () {
|
||||
var cssLoader = null;
|
||||
|
||||
@@ -77,10 +77,10 @@ class EventGateKeeper<T> extends Disposable {
|
||||
}
|
||||
|
||||
class MousePosition {
|
||||
public position: editorCommon.IEditorPosition;
|
||||
public position: Position;
|
||||
public mouseColumn: number;
|
||||
|
||||
constructor(position:editorCommon.IEditorPosition, mouseColumn:number) {
|
||||
constructor(position:Position, mouseColumn:number) {
|
||||
this.position = position;
|
||||
this.mouseColumn = mouseColumn;
|
||||
}
|
||||
@@ -316,7 +316,7 @@ class MouseDownOperation extends Disposable {
|
||||
private _mouseMoveMonitor:GlobalMouseMoveMonitor<IMouseEvent>;
|
||||
private _mouseDownThenMoveEventHandler: EventGateKeeper<IMouseEvent>;
|
||||
|
||||
private _currentSelection: editorCommon.IEditorSelection;
|
||||
private _currentSelection: Selection;
|
||||
private _mouseState: MouseDownState;
|
||||
|
||||
private _onScrollTimeout: TimeoutTimer;
|
||||
@@ -523,7 +523,7 @@ class MouseDownState {
|
||||
private _startedOnLineNumbers: boolean;
|
||||
public get startedOnLineNumbers(): boolean { return this._startedOnLineNumbers; }
|
||||
|
||||
private _lastMouseDownPosition: editorCommon.IEditorPosition;
|
||||
private _lastMouseDownPosition: Position;
|
||||
private _lastMouseDownPositionEqualCount: number;
|
||||
private _lastMouseDownCount: number;
|
||||
private _lastSetMouseDownCountTime: number;
|
||||
@@ -555,7 +555,7 @@ class MouseDownState {
|
||||
this._startedOnLineNumbers = startedOnLineNumbers;
|
||||
}
|
||||
|
||||
public trySetCount(setMouseDownCount:number, newMouseDownPosition:editorCommon.IEditorPosition): void {
|
||||
public trySetCount(setMouseDownCount:number, newMouseDownPosition:Position): void {
|
||||
// a. Invalidate multiple clicking if too much time has passed (will be hit by IE because the detail field of mouse events contains garbage in IE10)
|
||||
let currentTime = (new Date()).getTime();
|
||||
if (currentTime - this._lastSetMouseDownCountTime > MouseDownState.CLEAR_MOUSE_DOWN_COUNT_TIME) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
import {Range as EditorRange} from 'vs/editor/common/core/range';
|
||||
import {EditorLayoutInfo, IEditorPosition, IEditorRange, IPosition, MouseTargetType} from 'vs/editor/common/editorCommon';
|
||||
import {EditorLayoutInfo, IPosition, MouseTargetType} from 'vs/editor/common/editorCommon';
|
||||
import {ClassNames, IMouseTarget, IViewZoneData} from 'vs/editor/browser/editorBrowser';
|
||||
import {IDomNodePosition} from 'vs/base/browser/dom';
|
||||
import {ViewContext} from 'vs/editor/common/view/viewContext';
|
||||
@@ -28,11 +28,11 @@ class MouseTarget implements IMouseTarget {
|
||||
public element: Element;
|
||||
public type: MouseTargetType;
|
||||
public mouseColumn: number;
|
||||
public position: IEditorPosition;
|
||||
public range: IEditorRange;
|
||||
public position: Position;
|
||||
public range: EditorRange;
|
||||
public detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn:number = 0, position:IEditorPosition = null, range: IEditorRange = null, detail: any = null) {
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn:number = 0, position:Position = null, range: EditorRange = null, detail: any = null) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
@@ -194,13 +194,6 @@ export class MouseTargetFactory {
|
||||
var t = <Element>e.target;
|
||||
var path = this.getClassNamePathTo(t, this._viewHelper.viewDomNode);
|
||||
|
||||
// Is it a cursor ?
|
||||
var lineNumberAttribute = t.hasAttribute && t.hasAttribute('lineNumber') ? t.getAttribute('lineNumber') : null;
|
||||
var columnAttribute = t.hasAttribute && t.hasAttribute('column') ? t.getAttribute('column') : null;
|
||||
if (lineNumberAttribute && columnAttribute) {
|
||||
return this.createMouseTargetFromViewCursor(t, parseInt(lineNumberAttribute, 10), parseInt(columnAttribute, 10), mouseColumn);
|
||||
}
|
||||
|
||||
// Is it a content widget?
|
||||
if (REGEX.IS_CHILD_OF_CONTENT_WIDGETS.test(path) || REGEX.IS_CHILD_OF_OVERFLOWING_CONTENT_WIDGETS.test(path)) {
|
||||
return this.createMouseTargetFromContentWidgetsChild(t, mouseColumn);
|
||||
@@ -211,6 +204,13 @@ export class MouseTargetFactory {
|
||||
return this.createMouseTargetFromOverlayWidgetsChild(t, mouseColumn);
|
||||
}
|
||||
|
||||
// Is it a cursor ?
|
||||
var lineNumberAttribute = t.hasAttribute && t.hasAttribute('lineNumber') ? t.getAttribute('lineNumber') : null;
|
||||
var columnAttribute = t.hasAttribute && t.hasAttribute('column') ? t.getAttribute('column') : null;
|
||||
if (lineNumberAttribute && columnAttribute) {
|
||||
return this.createMouseTargetFromViewCursor(t, parseInt(lineNumberAttribute, 10), parseInt(columnAttribute, 10), mouseColumn);
|
||||
}
|
||||
|
||||
// Is it the textarea cover?
|
||||
if (REGEX.IS_TEXTAREA_COVER.test(path)) {
|
||||
if (this._context.configuration.editor.viewInfo.glyphMargin) {
|
||||
@@ -541,9 +541,9 @@ export class MouseTargetFactory {
|
||||
if (viewZoneWhitespace) {
|
||||
var viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
|
||||
lineCount = this._context.model.getLineCount(),
|
||||
positionBefore: IEditorPosition = null,
|
||||
position: IEditorPosition,
|
||||
positionAfter: IEditorPosition = null;
|
||||
positionBefore: Position = null,
|
||||
position: Position,
|
||||
positionAfter: Position = null;
|
||||
|
||||
if (viewZoneWhitespace.afterLineNumber !== lineCount) {
|
||||
// There are more lines after this view zone
|
||||
@@ -575,7 +575,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private _getFullLineRangeAtCoord(mouseVerticalOffset: number): { range: IEditorRange; isAfterLines: boolean; } {
|
||||
private _getFullLineRangeAtCoord(mouseVerticalOffset: number): { range: EditorRange; isAfterLines: boolean; } {
|
||||
if (this._viewHelper.isAfterLines(mouseVerticalOffset)) {
|
||||
// Below the last line
|
||||
var lineNumber = this._context.model.getLineCount();
|
||||
|
||||
@@ -10,17 +10,28 @@ import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
|
||||
import {IMouseEvent} from 'vs/base/browser/mouseEvent';
|
||||
import {IInstantiationService, IConstructorSignature1} from 'vs/platform/instantiation/common/instantiation';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IContentWidgetData {
|
||||
widget: IContentWidget;
|
||||
position: IContentWidgetPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IOverlayWidgetData {
|
||||
widget: IOverlayWidget;
|
||||
position: IOverlayWidgetPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface ICodeEditorHelper {
|
||||
getScrollWidth(): number;
|
||||
getScrollLeft(): number;
|
||||
@@ -35,6 +46,9 @@ export interface ICodeEditorHelper {
|
||||
getOffsetForColumn(lineNumber:number, column:number): number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IView extends IDisposable {
|
||||
domNode: HTMLElement;
|
||||
|
||||
@@ -43,7 +57,7 @@ export interface IView extends IDisposable {
|
||||
createOverviewRuler(cssClassName:string, minimumHeight:number, maximumHeight:number): IOverviewRuler;
|
||||
getCodeEditorHelper(): ICodeEditorHelper;
|
||||
|
||||
getCenteredRangeInViewport(): editorCommon.IEditorRange;
|
||||
getCenteredRangeInViewport(): Range;
|
||||
|
||||
change(callback:(changeAccessor:IViewZoneChangeAccessor) => any): boolean;
|
||||
getWhitespaces(): editorCommon.IEditorWhitespace[];
|
||||
@@ -67,16 +81,22 @@ export interface IView extends IDisposable {
|
||||
removeOverlayWidget(widgetData: IOverlayWidgetData): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IViewZoneData {
|
||||
viewZoneId: number;
|
||||
positionBefore:editorCommon.IEditorPosition;
|
||||
positionAfter:editorCommon.IEditorPosition;
|
||||
position: editorCommon.IEditorPosition;
|
||||
positionBefore:Position;
|
||||
positionAfter:Position;
|
||||
position: Position;
|
||||
afterLineNumber: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IMouseDispatchData {
|
||||
position: editorCommon.IEditorPosition;
|
||||
position: Position;
|
||||
/**
|
||||
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
|
||||
*/
|
||||
@@ -91,10 +111,13 @@ export interface IMouseDispatchData {
|
||||
shiftKey: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IViewController {
|
||||
dispatchMouse(data:IMouseDispatchData);
|
||||
|
||||
moveTo(source:string, position:editorCommon.IEditorPosition): void;
|
||||
moveTo(source:string, position:Position): void;
|
||||
|
||||
paste(source:string, text:string, pasteOnNewLine:boolean): void;
|
||||
type(source: string, text: string): void;
|
||||
@@ -110,6 +133,9 @@ export interface IViewController {
|
||||
emitMouseDown(e:IEditorMouseEvent): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export var ClassNames = {
|
||||
TEXTAREA_COVER: 'textAreaCover',
|
||||
TEXTAREA: 'inputarea',
|
||||
@@ -129,8 +155,11 @@ export var ClassNames = {
|
||||
VIEW_ZONES: 'view-zones'
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IViewportInfo {
|
||||
visibleRange: editorCommon.IEditorRange;
|
||||
visibleRange: Range;
|
||||
width:number;
|
||||
height:number;
|
||||
deltaTop:number;
|
||||
@@ -323,7 +352,7 @@ export interface IMouseTarget {
|
||||
/**
|
||||
* The 'approximate' editor position
|
||||
*/
|
||||
position: editorCommon.IEditorPosition;
|
||||
position: Position;
|
||||
/**
|
||||
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
|
||||
*/
|
||||
@@ -331,7 +360,7 @@ export interface IMouseTarget {
|
||||
/**
|
||||
* The 'approximate' editor range
|
||||
*/
|
||||
range: editorCommon.IEditorRange;
|
||||
range: Range;
|
||||
/**
|
||||
* Some extra detail.
|
||||
*/
|
||||
@@ -345,10 +374,14 @@ export interface IEditorMouseEvent {
|
||||
target: IMouseTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type ISimpleEditorContributionCtor = IConstructorSignature1<ICodeEditor, editorCommon.IEditorContribution>;
|
||||
|
||||
/**
|
||||
* An editor contribution descriptor that will be used to construct editor contributions
|
||||
* @internal
|
||||
*/
|
||||
export interface IEditorContributionDescriptor {
|
||||
/**
|
||||
@@ -357,108 +390,15 @@ export interface IEditorContributionDescriptor {
|
||||
createInstance(instantiationService:IInstantiationService, editor:ICodeEditor): editorCommon.IEditorContribution;
|
||||
}
|
||||
|
||||
export class ColorZone {
|
||||
_colorZoneBrand: void;
|
||||
|
||||
from: number;
|
||||
to: number;
|
||||
colorId: number;
|
||||
position: editorCommon.OverviewRulerLane;
|
||||
|
||||
constructor(from:number, to:number, colorId:number, position: editorCommon.OverviewRulerLane) {
|
||||
this.from = from|0;
|
||||
this.to = to|0;
|
||||
this.colorId = colorId|0;
|
||||
this.position = position|0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A zone in the overview ruler
|
||||
*/
|
||||
export class OverviewRulerZone {
|
||||
_overviewRulerZoneBrand: void;
|
||||
|
||||
startLineNumber: number;
|
||||
endLineNumber: number;
|
||||
position: editorCommon.OverviewRulerLane;
|
||||
forceHeight: number;
|
||||
|
||||
private _color: string;
|
||||
private _darkColor: string;
|
||||
|
||||
private _colorZones: ColorZone[];
|
||||
|
||||
constructor(
|
||||
startLineNumber: number, endLineNumber: number,
|
||||
position: editorCommon.OverviewRulerLane,
|
||||
forceHeight: number,
|
||||
color: string, darkColor: string
|
||||
) {
|
||||
this.startLineNumber = startLineNumber;
|
||||
this.endLineNumber = endLineNumber;
|
||||
this.position = position;
|
||||
this.forceHeight = forceHeight;
|
||||
this._color = color;
|
||||
this._darkColor = darkColor;
|
||||
this._colorZones = null;
|
||||
}
|
||||
|
||||
public getColor(useDarkColor:boolean): string {
|
||||
if (useDarkColor) {
|
||||
return this._darkColor;
|
||||
}
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public equals(other:OverviewRulerZone): boolean {
|
||||
return (
|
||||
this.startLineNumber === other.startLineNumber
|
||||
&& this.endLineNumber === other.endLineNumber
|
||||
&& this.position === other.position
|
||||
&& this.forceHeight === other.forceHeight
|
||||
&& this._color === other._color
|
||||
&& this._darkColor === other._darkColor
|
||||
);
|
||||
}
|
||||
|
||||
public compareTo(other:OverviewRulerZone): number {
|
||||
if (this.startLineNumber === other.startLineNumber) {
|
||||
if (this.endLineNumber === other.endLineNumber) {
|
||||
if (this.forceHeight === other.forceHeight) {
|
||||
if (this.position === other.position) {
|
||||
if (this._darkColor === other._darkColor) {
|
||||
if (this._color === other._color) {
|
||||
return 0;
|
||||
}
|
||||
return this._color < other._color ? -1 : 1;
|
||||
}
|
||||
return this._darkColor < other._darkColor ? -1 : 1;
|
||||
}
|
||||
return this.position - other.position;
|
||||
}
|
||||
return this.forceHeight - other.forceHeight;
|
||||
}
|
||||
return this.endLineNumber - other.endLineNumber;
|
||||
}
|
||||
return this.startLineNumber - other.startLineNumber;
|
||||
}
|
||||
|
||||
public setColorZones(colorZones:ColorZone[]): void {
|
||||
this._colorZones = colorZones;
|
||||
}
|
||||
|
||||
public getColorZones(): ColorZone[] {
|
||||
return this._colorZones;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An overview ruler
|
||||
* @internal
|
||||
*/
|
||||
export interface IOverviewRuler {
|
||||
getDomNode(): HTMLElement;
|
||||
dispose(): void;
|
||||
setZones(zones:OverviewRulerZone[]): void;
|
||||
setZones(zones:editorCommon.OverviewRulerZone[]): void;
|
||||
setLayout(position:editorCommon.OverviewRulerPosition): void;
|
||||
}
|
||||
/**
|
||||
@@ -466,6 +406,16 @@ export interface IOverviewRuler {
|
||||
*/
|
||||
export interface ICodeEditor extends editorCommon.ICommonCodeEditor {
|
||||
|
||||
onMouseUp(listener: (e:IEditorMouseEvent)=>void): IDisposable;
|
||||
onMouseDown(listener: (e:IEditorMouseEvent)=>void): IDisposable;
|
||||
onContextMenu(listener: (e:IEditorMouseEvent)=>void): IDisposable;
|
||||
onMouseMove(listener: (e:IEditorMouseEvent)=>void): IDisposable;
|
||||
onMouseLeave(listener: (e:IEditorMouseEvent)=>void): IDisposable;
|
||||
onKeyUp(listener: (e:IKeyboardEvent)=>void): IDisposable;
|
||||
onKeyDown(listener: (e:IKeyboardEvent)=>void): IDisposable;
|
||||
onDidLayoutChange(listener: (e:editorCommon.EditorLayoutInfo)=>void): IDisposable;
|
||||
onDidScrollChange(listener: (e:editorCommon.IScrollEvent)=>void): IDisposable;
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
@@ -507,10 +457,11 @@ export interface ICodeEditor extends editorCommon.ICommonCodeEditor {
|
||||
/**
|
||||
* Returns the range that is currently centered in the view port.
|
||||
*/
|
||||
getCenteredRangeInViewport(): editorCommon.IEditorRange;
|
||||
getCenteredRangeInViewport(): Range;
|
||||
|
||||
/**
|
||||
* Get the view zones.
|
||||
* @internal
|
||||
*/
|
||||
getWhitespaces(): editorCommon.IEditorWhitespace[];
|
||||
|
||||
@@ -547,9 +498,13 @@ export interface ICodeEditor extends editorCommon.ICommonCodeEditor {
|
||||
|
||||
/**
|
||||
* Set the model ranges that will be hidden in the view.
|
||||
* @internal
|
||||
*/
|
||||
setHiddenAreas(ranges:editorCommon.IRange[]): void;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setAriaActiveDescendant(id:string): void;
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {ICodeEditor, IDiffEditor} from 'vs/editor/browser/editorBrowser';
|
||||
import {Selection} from 'vs/editor/common/core/selection';
|
||||
|
||||
export class SimpleEditor implements IEditor {
|
||||
|
||||
@@ -39,7 +40,7 @@ export class SimpleEditor implements IEditor {
|
||||
|
||||
public getId():string { return 'editor'; }
|
||||
public getControl():editorCommon.IEditor { return this._widget; }
|
||||
public getSelection():editorCommon.IEditorSelection { return this._widget.getSelection(); }
|
||||
public getSelection():Selection { return this._widget.getSelection(); }
|
||||
public focus():void { this._widget.focus(); }
|
||||
|
||||
public withTypedEditor<T>(codeEditorCallback:(editor:ICodeEditor)=>T, diffEditorCallback:(editor:IDiffEditor)=>T): T {
|
||||
@@ -139,7 +140,7 @@ export class SimpleEditorService implements IEditorService {
|
||||
|
||||
private findModel(editor:editorCommon.ICommonCodeEditor, data:IResourceInput): editorCommon.IModel {
|
||||
var model = editor.getModel();
|
||||
if(model.getAssociatedResource().toString() !== data.resource.toString()) {
|
||||
if(model.uri.toString() !== data.resource.toString()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -303,4 +304,8 @@ export class SimpleConfigurationService extends ConfigurationService {
|
||||
});
|
||||
}
|
||||
|
||||
setUserConfiguration(key: any, value: any) : Thenable<void> {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import {RemoteTelemetryServiceHelper} from 'vs/platform/telemetry/common/remoteT
|
||||
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {DefaultConfig} from 'vs/editor/common/config/defaultConfig';
|
||||
import {IActionDescriptor, ICodeEditorWidgetCreationOptions, IDiffEditorOptions, IModel, IModelChangedEvent, EventType} from 'vs/editor/common/editorCommon';
|
||||
import {IMode} from 'vs/editor/common/modes';
|
||||
import {HoverProvider, IMode} from 'vs/editor/common/modes';
|
||||
import {ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
|
||||
import {ILanguage} from 'vs/editor/common/modes/monarch/monarchTypes';
|
||||
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
|
||||
@@ -38,6 +38,11 @@ import {SimpleEditorService, StandaloneKeybindingService} from 'vs/editor/browse
|
||||
import {IEditorContextViewService, IEditorOverrideServices, ensureDynamicPlatformServices, ensureStaticPlatformServices, getOrCreateStaticServices} from 'vs/editor/browser/standalone/standaloneServices';
|
||||
import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import {DiffEditorWidget} from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import {EditorModelManager} from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||
import {SimpleWorkerClient} from 'vs/base/common/worker/simpleWorker';
|
||||
import {DefaultWorkerFactory} from 'vs/base/worker/defaultWorkerFactory';
|
||||
import {StandaloneWorker} from 'vs/editor/browser/standalone/standaloneWorker';
|
||||
|
||||
// Set defaults for standalone editor
|
||||
DefaultConfig.editor.wrappingIndent = 'none';
|
||||
@@ -101,7 +106,7 @@ class StandaloneEditor extends CodeEditorWidget {
|
||||
if (model) {
|
||||
let e: IModelChangedEvent = {
|
||||
oldModelUrl: null,
|
||||
newModelUrl: model.getAssociatedResource().toString()
|
||||
newModelUrl: model.uri.toString()
|
||||
};
|
||||
this.emit(EventType.ModelChanged, e);
|
||||
}
|
||||
@@ -457,6 +462,87 @@ export function createCustomMode(language:ILanguage): TPromise<IMode> {
|
||||
return modeService.getOrCreateMode(modeId);
|
||||
}
|
||||
|
||||
export function registerTokensProvider(languageId:string, support:modes.ITokenizationSupport2): IDisposable {
|
||||
startup.initStaticServicesIfNecessary();
|
||||
let staticPlatformServices = ensureStaticPlatformServices(null);
|
||||
|
||||
return staticPlatformServices.modeService.registerTokenizationSupport2(languageId, support);
|
||||
}
|
||||
|
||||
export function registerHoverProvider(languageId:string, support:HoverProvider): IDisposable {
|
||||
return modes.HoverProviderRegistry.register(languageId, support);
|
||||
}
|
||||
|
||||
interface IMonacoWebWorkerState<T> {
|
||||
myProxy:StandaloneWorker;
|
||||
foreignProxy:T;
|
||||
modelMananger: EditorModelManager;
|
||||
}
|
||||
|
||||
export class MonacoWebWorker<T> {
|
||||
|
||||
private _loaded: TPromise<IMonacoWebWorkerState<T>>;
|
||||
private _client: SimpleWorkerClient<StandaloneWorker>;
|
||||
|
||||
constructor(modelService: IModelService, opts:IWebWorkerOptions) {
|
||||
this._client = new SimpleWorkerClient<StandaloneWorker>(new DefaultWorkerFactory(), 'vs/editor/browser/standalone/standaloneWorker', null);
|
||||
|
||||
this._loaded = this._client.getProxyObject().then((proxy) => {
|
||||
|
||||
let proxyMethodRequest = (method:string, args:any[]): TPromise<any> => {
|
||||
return proxy.fmr(method, args);
|
||||
};
|
||||
|
||||
let createProxyMethod = (method:string, proxyMethodRequest:(method:string, args:any[])=>TPromise<any>): Function => {
|
||||
return function () {
|
||||
let args = Array.prototype.slice.call(arguments, 0);
|
||||
return proxyMethodRequest(method, args);
|
||||
};
|
||||
};
|
||||
|
||||
const manager = new EditorModelManager(proxy, modelService, true);
|
||||
|
||||
return proxy.loadModule(opts.moduleId).then((foreignMethods): IMonacoWebWorkerState<T> => {
|
||||
|
||||
let foreignProxy = <T><any>{};
|
||||
for (let i = 0; i < foreignMethods.length; i++) {
|
||||
foreignProxy[foreignMethods[i]] = createProxyMethod(foreignMethods[i], proxyMethodRequest);
|
||||
}
|
||||
|
||||
return {
|
||||
myProxy: proxy,
|
||||
foreignProxy: foreignProxy,
|
||||
modelMananger: manager
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
console.log('TODO: I should dispose now');
|
||||
}
|
||||
|
||||
public getProxy(): TPromise<T> {
|
||||
return this._loaded.then(data => data.foreignProxy);
|
||||
}
|
||||
|
||||
public withSyncedResources(resources: URI[]): TPromise<void> {
|
||||
return this._loaded.then(data => data.modelMananger.withSyncedResources(resources));
|
||||
}
|
||||
}
|
||||
|
||||
export interface IWebWorkerOptions {
|
||||
moduleId: string;
|
||||
}
|
||||
|
||||
export function createWebWorker<T>(opts:IWebWorkerOptions): MonacoWebWorker<T> {
|
||||
startup.initStaticServicesIfNecessary();
|
||||
let staticPlatformServices = ensureStaticPlatformServices(null);
|
||||
let modelService = staticPlatformServices.modelService;
|
||||
|
||||
return new MonacoWebWorker(modelService, opts);
|
||||
}
|
||||
|
||||
export function registerMonarchStandaloneLanguage(language:ILanguageExtensionPoint, defModule:string): void {
|
||||
ModesRegistry.registerLanguage(language);
|
||||
|
||||
@@ -501,6 +587,10 @@ export function registerStandaloneLanguage(language:ILanguageExtensionPoint, def
|
||||
});
|
||||
}
|
||||
|
||||
export function registerStandaloneLanguage2(language:ILanguageExtensionPoint, defModule:string): void {
|
||||
ModesRegistry.registerLanguage(language);
|
||||
}
|
||||
|
||||
export function registerStandaloneSchema(uri:string, schema:IJSONSchema) {
|
||||
let schemaRegistry = <IJSONContributionRegistry>Registry.as(Extensions.JSONContribution);
|
||||
schemaRegistry.registerSchema(uri, schema);
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
import 'vs/editor/standalone-languages/all';
|
||||
import './standaloneSchemas';
|
||||
import 'vs/css!./media/standalone-tokens';
|
||||
import {Emitter} from 'vs/base/common/event';
|
||||
import {IJSONSchema} from 'vs/base/common/jsonSchema';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {ClassNames, ContentWidgetPositionPreference, OverlayWidgetPositionPreference} from 'vs/editor/browser/editorBrowser';
|
||||
import {Colorizer} from 'vs/editor/browser/standalone/colorizer';
|
||||
import * as standaloneCodeEditor from 'vs/editor/browser/standalone/standaloneCodeEditor';
|
||||
import {ILanguageDef} from 'vs/editor/standalone-languages/types';
|
||||
// import {ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
|
||||
import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
|
||||
|
||||
var global:any = self;
|
||||
if (!global.Monaco) {
|
||||
@@ -77,3 +80,34 @@ if (!Monaco.Languages) {
|
||||
Monaco.Languages = {};
|
||||
}
|
||||
Monaco.Languages.register = standaloneCodeEditor.registerStandaloneLanguage;
|
||||
Monaco.Languages.register2 = standaloneCodeEditor.registerStandaloneLanguage2;
|
||||
Monaco.Languages.onLanguage = (languageId:string, callback:()=>void) => {
|
||||
let isDisposed = false;
|
||||
ExtensionsRegistry.registerOneTimeActivationEventListener('onLanguage:' + languageId, () => {
|
||||
if (!isDisposed) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
return {
|
||||
dispose: () => { isDisposed = true; }
|
||||
};
|
||||
};
|
||||
Monaco.createWebWorker = standaloneCodeEditor.createWebWorker;
|
||||
Monaco.Languages.registerTokensProvider = standaloneCodeEditor.registerTokensProvider;
|
||||
Monaco.Languages.registerHoverProvider = standaloneCodeEditor.registerHoverProvider;
|
||||
Monaco.Emitter = Emitter;
|
||||
// let handlePlugin = (plugin) => {
|
||||
// if (Array.isArray(plugin.languages)) {
|
||||
// ModesRegistry.registerLanguages(plugin.languages);
|
||||
// }
|
||||
// if (plugin.activate) {
|
||||
// try {
|
||||
// plugin.activate();
|
||||
// } catch(err) {
|
||||
// console.error(err);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// let MonacoPlugins = this.MonacoPlugins || [];
|
||||
// MonacoPlugins.forEach(handlePlugin);
|
||||
// this.MonacoPlugins = { push: handlePlugin };
|
||||
@@ -26,7 +26,7 @@ import {IMessageService} from 'vs/platform/message/common/message';
|
||||
import {IProgressService} from 'vs/platform/progress/common/progress';
|
||||
import {IRequestService} from 'vs/platform/request/common/request';
|
||||
import {ISearchService} from 'vs/platform/search/common/search';
|
||||
import {IStorageService} from 'vs/platform/storage/common/storage';
|
||||
import {IStorageService, NullStorageService} from 'vs/platform/storage/common/storage';
|
||||
import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {MainThreadService} from 'vs/platform/thread/common/mainThreadService';
|
||||
import {IThreadService} from 'vs/platform/thread/common/thread';
|
||||
@@ -86,6 +86,7 @@ export interface IStaticServices {
|
||||
codeEditorService: ICodeEditorService;
|
||||
editorWorkerService: IEditorWorkerService;
|
||||
eventService: IEventService;
|
||||
storageService: IStorageService;
|
||||
instantiationService: IInstantiationService;
|
||||
}
|
||||
|
||||
@@ -197,6 +198,7 @@ export function getOrCreateStaticServices(services?: IEditorOverrideServices): I
|
||||
codeEditorService: codeEditorService,
|
||||
editorWorkerService: editorWorkerService,
|
||||
eventService: eventService,
|
||||
storageService: services.storageService || NullStorageService,
|
||||
instantiationService: void 0
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 URI from 'vs/base/common/uri';
|
||||
import {ErrorCallback, TPromise, ValueCallback} from 'vs/base/common/winjs.base';
|
||||
import {IRequestHandler} from 'vs/base/common/worker/simpleWorker';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {MirrorModel2} from 'vs/editor/common/model/mirrorModel2';
|
||||
import {WordHelper} from 'vs/editor/common/model/textModelWithTokensHelpers';
|
||||
import {IRawModelData} from 'vs/editor/common/services/editorSimpleWorkerCommon';
|
||||
import {Emitter} from 'vs/base/common/event';
|
||||
|
||||
class MirrorModel extends MirrorModel2 {
|
||||
|
||||
public get uri(): URI {
|
||||
return this._uri;
|
||||
}
|
||||
|
||||
public get version(): number {
|
||||
return this._versionId;
|
||||
}
|
||||
|
||||
public getLinesContent(): string[] {
|
||||
return this._lines.slice(0);
|
||||
}
|
||||
|
||||
public getLineCount(): number {
|
||||
return this._lines.length;
|
||||
}
|
||||
|
||||
public getLineContent(lineNumber:number): string {
|
||||
return this._lines[lineNumber - 1];
|
||||
}
|
||||
|
||||
public getWordAtPosition(position:editorCommon.IPosition, wordDefinition:RegExp): Range {
|
||||
|
||||
let wordAtText = WordHelper._getWordAtText(
|
||||
position.column,
|
||||
WordHelper.ensureValidWordDefinition(wordDefinition),
|
||||
this._lines[position.lineNumber - 1],
|
||||
0
|
||||
);
|
||||
|
||||
if (wordAtText) {
|
||||
return new Range(position.lineNumber, wordAtText.startColumn, position.lineNumber, wordAtText.endColumn);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getWordUntilPosition(position: editorCommon.IPosition, wordDefinition:RegExp): editorCommon.IWordAtPosition {
|
||||
var wordAtPosition = this.getWordAtPosition(position, wordDefinition);
|
||||
if (!wordAtPosition) {
|
||||
return {
|
||||
word: '',
|
||||
startColumn: position.column,
|
||||
endColumn: position.column
|
||||
};
|
||||
}
|
||||
return {
|
||||
word: this._lines[position.lineNumber - 1].substring(wordAtPosition.startColumn - 1, position.column - 1),
|
||||
startColumn: wordAtPosition.startColumn,
|
||||
endColumn: position.column
|
||||
};
|
||||
}
|
||||
|
||||
private _getAllWords(wordDefinition:RegExp): string[] {
|
||||
var result:string[] = [];
|
||||
this._lines.forEach((line) => {
|
||||
this._wordenize(line, wordDefinition).forEach((info) => {
|
||||
result.push(line.substring(info.start, info.end));
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public getAllUniqueWords(wordDefinition:RegExp, skipWordOnce?:string) : string[] {
|
||||
var foundSkipWord = false;
|
||||
var uniqueWords = {};
|
||||
return this._getAllWords(wordDefinition).filter((word) => {
|
||||
if (skipWordOnce && !foundSkipWord && skipWordOnce === word) {
|
||||
foundSkipWord = true;
|
||||
return false;
|
||||
} else if (uniqueWords[word]) {
|
||||
return false;
|
||||
} else {
|
||||
uniqueWords[word] = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// // TODO@Joh, TODO@Alex - remove these and make sure the super-things work
|
||||
private _wordenize(content:string, wordDefinition:RegExp): editorCommon.IWordRange[] {
|
||||
var result:editorCommon.IWordRange[] = [];
|
||||
var match:RegExpExecArray;
|
||||
while (match = wordDefinition.exec(content)) {
|
||||
if (match[0].length === 0) {
|
||||
// it did match the empty string
|
||||
break;
|
||||
}
|
||||
result.push({ start: match.index, end: match.index + match[0].length });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public getValueInRange(range:editorCommon.IRange): string {
|
||||
if (range.startLineNumber === range.endLineNumber) {
|
||||
return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1);
|
||||
}
|
||||
|
||||
var lineEnding = this._eol,
|
||||
startLineIndex = range.startLineNumber - 1,
|
||||
endLineIndex = range.endLineNumber - 1,
|
||||
resultLines:string[] = [];
|
||||
|
||||
resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1));
|
||||
for (var i = startLineIndex + 1; i < endLineIndex; i++) {
|
||||
resultLines.push(this._lines[i]);
|
||||
}
|
||||
resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1));
|
||||
|
||||
return resultLines.join(lineEnding);
|
||||
}
|
||||
}
|
||||
|
||||
this.Monaco = this.Monaco || {};
|
||||
var Monaco = this.Monaco;
|
||||
|
||||
this.monaco = this.monaco || {};
|
||||
var monaco = this.monaco;
|
||||
|
||||
export class StandaloneWorker /*extends EditorSimpleWorker*/ implements IRequestHandler {
|
||||
_requestHandlerTrait: any;
|
||||
|
||||
private _models:{[uri:string]:MirrorModel;};
|
||||
private _foreignModule: any;
|
||||
|
||||
constructor() {
|
||||
// super();
|
||||
this._models = Object.create(null);
|
||||
this._foreignModule = null;
|
||||
|
||||
|
||||
Monaco.TPromise = TPromise;
|
||||
Monaco.Emitter = Emitter;
|
||||
|
||||
let that = this;
|
||||
monaco.worker = {
|
||||
get mirrorModels () {
|
||||
let all: MirrorModel[] = [];
|
||||
Object.keys(that._models).forEach((key) => all.push(that._models[key]));
|
||||
return all;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public acceptNewModel(data:IRawModelData): void {
|
||||
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.value.lines, data.value.EOL, data.versionId);
|
||||
}
|
||||
|
||||
public acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
let model = this._models[strURL];
|
||||
model.onEvents(events);
|
||||
}
|
||||
|
||||
public acceptRemovedModel(strURL: string): void {
|
||||
if (!this._models[strURL]) {
|
||||
return;
|
||||
}
|
||||
delete this._models[strURL];
|
||||
}
|
||||
|
||||
public loadModule(moduleId:string): TPromise<string[]> {
|
||||
let cc: ValueCallback;
|
||||
let ee: ErrorCallback;
|
||||
let r = new TPromise<any>((c, e, p) => {
|
||||
cc = c;
|
||||
ee = e;
|
||||
});
|
||||
|
||||
require([moduleId], (foreignModule) => {
|
||||
this._foreignModule = foreignModule.create();
|
||||
|
||||
let methods: string[] = [];
|
||||
for (let prop in this._foreignModule) {
|
||||
if (typeof this._foreignModule[prop] === 'function') {
|
||||
methods.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
cc(methods);
|
||||
|
||||
}, ee);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// foreign method request
|
||||
public fmr(method:string, args:any[]): TPromise<any> {
|
||||
if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') {
|
||||
return TPromise.wrapError(new Error('Missing requestHandler or method: ' + method));
|
||||
}
|
||||
|
||||
try {
|
||||
return TPromise.as(this._foreignModule[method].apply(this._foreignModule, args));
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on the worker side
|
||||
*/
|
||||
export function create(): IRequestHandler {
|
||||
return new StandaloneWorker();
|
||||
}
|
||||
@@ -4,13 +4,14 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {IEventEmitter} from 'vs/base/common/eventEmitter';
|
||||
import {EventEmitter} from 'vs/base/common/eventEmitter';
|
||||
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {IEditorMouseEvent, IViewController, IMouseDispatchData} from 'vs/editor/browser/editorBrowser';
|
||||
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
|
||||
import {IViewModel} from 'vs/editor/common/viewModel/viewModel';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
|
||||
export interface TriggerCursorHandler {
|
||||
(source:string, handlerId:string, payload:any): void;
|
||||
@@ -20,13 +21,13 @@ export class ViewController implements IViewController {
|
||||
|
||||
private viewModel:IViewModel;
|
||||
private triggerCursorHandler:TriggerCursorHandler;
|
||||
private outgoingEventBus:IEventEmitter;
|
||||
private outgoingEventBus:EventEmitter;
|
||||
private keybindingService:IKeybindingService;
|
||||
|
||||
constructor(
|
||||
viewModel:IViewModel,
|
||||
triggerCursorHandler:TriggerCursorHandler,
|
||||
outgoingEventBus:IEventEmitter,
|
||||
outgoingEventBus:EventEmitter,
|
||||
keybindingService:IKeybindingService
|
||||
) {
|
||||
this.viewModel = viewModel;
|
||||
@@ -59,7 +60,7 @@ export class ViewController implements IViewController {
|
||||
this.keybindingService.executeCommand(editorCommon.Handler.Cut, {});
|
||||
}
|
||||
|
||||
private _validateViewColumn(viewPosition:editorCommon.IEditorPosition): editorCommon.IEditorPosition {
|
||||
private _validateViewColumn(viewPosition:Position): Position {
|
||||
var minColumn = this.viewModel.getLineMinColumn(viewPosition.lineNumber);
|
||||
if (viewPosition.column < minColumn) {
|
||||
return new Position(viewPosition.lineNumber, minColumn);
|
||||
@@ -133,7 +134,7 @@ export class ViewController implements IViewController {
|
||||
}
|
||||
}
|
||||
|
||||
public moveTo(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
public moveTo(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.MoveTo, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -141,7 +142,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private moveToSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private moveToSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.MoveToSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -149,7 +150,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private columnSelect(source:string, viewPosition:editorCommon.IEditorPosition, mouseColumn:number): void {
|
||||
private columnSelect(source:string, viewPosition:Position, mouseColumn:number): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.ColumnSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -158,7 +159,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private createCursor(source:string, viewPosition:editorCommon.IEditorPosition, wholeLine:boolean): void {
|
||||
private createCursor(source:string, viewPosition:Position, wholeLine:boolean): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.CreateCursor, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -167,7 +168,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private lastCursorMoveToSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lastCursorMoveToSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LastCursorMoveToSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -175,28 +176,28 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private wordSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private wordSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.WordSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition)
|
||||
});
|
||||
}
|
||||
|
||||
private wordSelectDrag(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private wordSelectDrag(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.WordSelectDrag, {
|
||||
position: this.convertViewToModelPosition(viewPosition)
|
||||
});
|
||||
}
|
||||
|
||||
private lastCursorWordSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lastCursorWordSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LastCursorWordSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition)
|
||||
});
|
||||
}
|
||||
|
||||
private lineSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lineSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LineSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -204,7 +205,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private lineSelectDrag(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lineSelectDrag(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LineSelectDrag, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -212,7 +213,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private lastCursorLineSelect(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lastCursorLineSelect(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LastCursorLineSelect, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -220,7 +221,7 @@ export class ViewController implements IViewController {
|
||||
});
|
||||
}
|
||||
|
||||
private lastCursorLineSelectDrag(source:string, viewPosition:editorCommon.IEditorPosition): void {
|
||||
private lastCursorLineSelectDrag(source:string, viewPosition:Position): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this.triggerCursorHandler(source, editorCommon.Handler.LastCursorLineSelectDrag, {
|
||||
position: this.convertViewToModelPosition(viewPosition),
|
||||
@@ -234,11 +235,11 @@ export class ViewController implements IViewController {
|
||||
|
||||
// ----------------------
|
||||
|
||||
private convertViewToModelPosition(viewPosition:editorCommon.IEditorPosition): editorCommon.IEditorPosition {
|
||||
private convertViewToModelPosition(viewPosition:Position): Position {
|
||||
return this.viewModel.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column);
|
||||
}
|
||||
|
||||
private convertViewToModelRange(viewRange:editorCommon.IRange): editorCommon.IEditorRange {
|
||||
private convertViewToModelRange(viewRange:editorCommon.IRange): Range {
|
||||
return this.viewModel.convertViewRangeToModelRange(viewRange);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {EmitterEvent, IEmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {EmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {IViewEventBus, IViewEventHandler} from 'vs/editor/common/view/viewContext';
|
||||
|
||||
export class ViewEventDispatcher implements IViewEventBus {
|
||||
|
||||
private _eventHandlerGateKeeper:(callback:()=>void)=>void;
|
||||
private _eventHandlers:IViewEventHandler[];
|
||||
private _eventQueue:IEmitterEvent[];
|
||||
private _eventQueue:EmitterEvent[];
|
||||
private _isConsumingQueue:boolean;
|
||||
|
||||
constructor(eventHandlerGateKeeper:(callback:()=>void)=>void) {
|
||||
@@ -53,7 +53,7 @@ export class ViewEventDispatcher implements IViewEventBus {
|
||||
}
|
||||
}
|
||||
|
||||
public emitMany(events:IEmitterEvent[]): void {
|
||||
public emitMany(events:EmitterEvent[]): void {
|
||||
if (this._eventQueue) {
|
||||
this._eventQueue = this._eventQueue.concat(events);
|
||||
} else {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import {onUnexpectedError} from 'vs/base/common/errors';
|
||||
import {EventEmitter, IEmitterEvent, IEventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter';
|
||||
import {EventEmitter, EmitterEvent, IEventEmitter} from 'vs/base/common/eventEmitter';
|
||||
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
|
||||
import * as timer from 'vs/base/common/timer';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
@@ -49,7 +49,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
|
||||
private eventDispatcher:ViewEventDispatcher;
|
||||
|
||||
private listenersToRemove:ListenerUnbind[];
|
||||
private listenersToRemove:IDisposable[];
|
||||
private listenersToDispose:IDisposable[];
|
||||
|
||||
private layoutProvider: LayoutProvider;
|
||||
@@ -82,7 +82,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
private _isDisposed: boolean;
|
||||
|
||||
private handleAccumulatedModelEventsTimeout:number;
|
||||
private accumulatedModelEvents: IEmitterEvent[];
|
||||
private accumulatedModelEvents: EmitterEvent[];
|
||||
private _renderAnimationFrame: IDisposable;
|
||||
|
||||
private _keybindingService: IKeybindingService;
|
||||
@@ -148,7 +148,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
// This delayed processing of incoming model events acts as a guard against undesired/unexpected recursion.
|
||||
this.handleAccumulatedModelEventsTimeout = -1;
|
||||
this.accumulatedModelEvents = [];
|
||||
this.listenersToRemove.push(model.addBulkListener((events:IEmitterEvent[]) => {
|
||||
this.listenersToRemove.push(model.addBulkListener2((events:EmitterEvent[]) => {
|
||||
this.accumulatedModelEvents = this.accumulatedModelEvents.concat(events);
|
||||
if (this.handleAccumulatedModelEventsTimeout === -1) {
|
||||
this.handleAccumulatedModelEventsTimeout = setTimeout(() => {
|
||||
@@ -457,14 +457,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
return false;
|
||||
}
|
||||
public onScrollChanged(e:editorCommon.IScrollEvent): boolean {
|
||||
this.outgoingEventBus.emit('scroll', {
|
||||
scrollTop: this.layoutProvider.getScrollTop(),
|
||||
scrollLeft: this.layoutProvider.getScrollLeft()
|
||||
});
|
||||
this.outgoingEventBus.emit('scrollSize', {
|
||||
scrollWidth: this.layoutProvider.getScrollWidth(),
|
||||
scrollHeight: this.layoutProvider.getScrollHeight()
|
||||
});
|
||||
this.outgoingEventBus.emit('scroll', e);
|
||||
return false;
|
||||
}
|
||||
public onViewFocusChanged(isFocused:boolean): boolean {
|
||||
@@ -494,11 +487,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
|
||||
this.eventDispatcher.removeEventHandler(this);
|
||||
this.outgoingEventBus.dispose();
|
||||
this.listenersToRemove.forEach((element) => {
|
||||
element();
|
||||
});
|
||||
this.listenersToRemove = [];
|
||||
|
||||
this.listenersToRemove = dispose(this.listenersToRemove);
|
||||
this.listenersToDispose = dispose(this.listenersToDispose);
|
||||
|
||||
this.keyboardHandler.dispose();
|
||||
@@ -593,7 +582,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
||||
return this.codeEditorHelper;
|
||||
}
|
||||
|
||||
public getCenteredRangeInViewport(): editorCommon.IEditorRange {
|
||||
public getCenteredRangeInViewport(): Range {
|
||||
if (this._isDisposed) {
|
||||
throw new Error('ViewImpl.getCenteredRangeInViewport: View is disposed');
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {ClassNames, ContentWidgetPositionPreference, IContentWidget} from 'vs/ed
|
||||
import {ViewPart} from 'vs/editor/browser/view/viewPart';
|
||||
import {ViewContext} from 'vs/editor/common/view/viewContext';
|
||||
import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/view/renderingContext';
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
|
||||
interface IWidgetData {
|
||||
allowEditorOverflow: boolean;
|
||||
@@ -184,7 +185,7 @@ export class ViewContentWidgets extends ViewPart {
|
||||
}
|
||||
}
|
||||
|
||||
private _layoutBoxInViewport(position:editorCommon.IEditorPosition, domNode:HTMLElement, ctx:IRenderingContext): IBoxLayoutResult {
|
||||
private _layoutBoxInViewport(position:Position, domNode:HTMLElement, ctx:IRenderingContext): IBoxLayoutResult {
|
||||
|
||||
let visibleRange = ctx.visibleRangeForPosition(position);
|
||||
|
||||
@@ -228,7 +229,7 @@ export class ViewContentWidgets extends ViewPart {
|
||||
};
|
||||
}
|
||||
|
||||
private _layoutBoxInPage(position: editorCommon.IEditorPosition, domNode: HTMLElement, ctx: IRenderingContext): IBoxLayoutResult {
|
||||
private _layoutBoxInPage(position: Position, domNode: HTMLElement, ctx: IRenderingContext): IBoxLayoutResult {
|
||||
let visibleRange = ctx.visibleRangeForPosition(position);
|
||||
|
||||
if (!visibleRange) {
|
||||
@@ -282,7 +283,7 @@ export class ViewContentWidgets extends ViewPart {
|
||||
};
|
||||
}
|
||||
|
||||
private _prepareRenderWidgetAtExactPosition(position:editorCommon.IEditorPosition, ctx:IRenderingContext): IMyWidgetRenderData {
|
||||
private _prepareRenderWidgetAtExactPosition(position:Position, ctx:IRenderingContext): IMyWidgetRenderData {
|
||||
let visibleRange = ctx.visibleRangeForPosition(position);
|
||||
|
||||
if (!visibleRange) {
|
||||
|
||||
@@ -436,7 +436,7 @@ export class ViewLines extends ViewLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private _computeScrollTopToRevealRange(viewport:editorCommon.Viewport, range: editorCommon.IEditorRange, verticalType: editorCommon.VerticalRevealType): number {
|
||||
private _computeScrollTopToRevealRange(viewport:editorCommon.Viewport, range: Range, verticalType: editorCommon.VerticalRevealType): number {
|
||||
var viewportStartY = viewport.top,
|
||||
viewportHeight = viewport.height,
|
||||
viewportEndY = viewportStartY + viewportHeight,
|
||||
@@ -469,7 +469,7 @@ export class ViewLines extends ViewLayer {
|
||||
return newScrollTop;
|
||||
}
|
||||
|
||||
private _computeScrollLeftToRevealRange(range: editorCommon.IEditorRange): { scrollLeft: number; maxHorizontalOffset: number; } {
|
||||
private _computeScrollLeftToRevealRange(range: Range): { scrollLeft: number; maxHorizontalOffset: number; } {
|
||||
|
||||
var maxHorizontalOffset = 0;
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
import * as themes from 'vs/platform/theme/common/themes';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {OverviewRulerZone} from 'vs/editor/browser/editorBrowser';
|
||||
import {ViewPart} from 'vs/editor/browser/view/viewPart';
|
||||
import {OverviewRulerImpl} from 'vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl';
|
||||
import {ViewContext} from 'vs/editor/common/view/viewContext';
|
||||
import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/view/renderingContext';
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
|
||||
export class DecorationsOverviewRuler extends ViewPart {
|
||||
|
||||
@@ -25,10 +25,10 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
private _shouldUpdateCursorPosition:boolean;
|
||||
|
||||
private _hideCursor:boolean;
|
||||
private _cursorPositions: editorCommon.IEditorPosition[];
|
||||
private _cursorPositions: Position[];
|
||||
|
||||
private _zonesFromDecorations: OverviewRulerZone[];
|
||||
private _zonesFromCursors: OverviewRulerZone[];
|
||||
private _zonesFromDecorations: editorCommon.OverviewRulerZone[];
|
||||
private _zonesFromCursors: editorCommon.OverviewRulerZone[];
|
||||
|
||||
constructor(context:ViewContext, scrollHeight:number, getVerticalOffsetForLine:(lineNumber:number)=>number) {
|
||||
super(context);
|
||||
@@ -137,14 +137,14 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
return this._overviewRuler.getDomNode();
|
||||
}
|
||||
|
||||
private _createZonesFromDecorations(): OverviewRulerZone[] {
|
||||
private _createZonesFromDecorations(): editorCommon.OverviewRulerZone[] {
|
||||
let decorations = this._context.model.getAllDecorations();
|
||||
let zones:OverviewRulerZone[] = [];
|
||||
let zones:editorCommon.OverviewRulerZone[] = [];
|
||||
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
let dec = decorations[i];
|
||||
if (dec.options.overviewRuler.color) {
|
||||
zones.push(new OverviewRulerZone(
|
||||
zones.push(new editorCommon.OverviewRulerZone(
|
||||
dec.range.startLineNumber,
|
||||
dec.range.endLineNumber,
|
||||
dec.options.overviewRuler.position,
|
||||
@@ -158,13 +158,13 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
return zones;
|
||||
}
|
||||
|
||||
private _createZonesFromCursors(): OverviewRulerZone[] {
|
||||
let zones:OverviewRulerZone[] = [];
|
||||
private _createZonesFromCursors(): editorCommon.OverviewRulerZone[] {
|
||||
let zones:editorCommon.OverviewRulerZone[] = [];
|
||||
|
||||
for (let i = 0, len = this._cursorPositions.length; i < len; i++) {
|
||||
let cursor = this._cursorPositions[i];
|
||||
|
||||
zones.push(new OverviewRulerZone(
|
||||
zones.push(new editorCommon.OverviewRulerZone(
|
||||
cursor.lineNumber,
|
||||
cursor.lineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
@@ -201,7 +201,7 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
}
|
||||
}
|
||||
|
||||
var allZones:OverviewRulerZone[] = [];
|
||||
var allZones:editorCommon.OverviewRulerZone[] = [];
|
||||
allZones = allZones.concat(this._zonesFromCursors);
|
||||
allZones = allZones.concat(this._zonesFromDecorations);
|
||||
|
||||
@@ -216,11 +216,11 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
ctx2.lineWidth = 1;
|
||||
ctx2.strokeStyle = 'rgba(197,197,197,0.8)';
|
||||
ctx2.moveTo(0, 0);
|
||||
ctx2.lineTo(0, this._overviewRuler.getHeight());
|
||||
ctx2.lineTo(0, this._overviewRuler.getPixelHeight());
|
||||
ctx2.stroke();
|
||||
|
||||
ctx2.moveTo(0, 0);
|
||||
ctx2.lineTo(this._overviewRuler.getWidth(), 0);
|
||||
ctx2.lineTo(this._overviewRuler.getPixelWidth(), 0);
|
||||
ctx2.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {IConfigurationChangedEvent, OverviewRulerPosition, IScrollEvent} from 'vs/editor/common/editorCommon';
|
||||
import {IConfigurationChangedEvent, OverviewRulerPosition, OverviewRulerZone, IScrollEvent} from 'vs/editor/common/editorCommon';
|
||||
import {ViewEventHandler} from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import {IOverviewRuler, OverviewRulerZone} from 'vs/editor/browser/editorBrowser';
|
||||
import {IOverviewRuler} from 'vs/editor/browser/editorBrowser';
|
||||
import {OverviewRulerImpl} from 'vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl';
|
||||
import {ViewContext} from 'vs/editor/common/view/viewContext';
|
||||
|
||||
|
||||
@@ -5,269 +5,10 @@
|
||||
'use strict';
|
||||
|
||||
import {StyleMutator} from 'vs/base/browser/styleMutator';
|
||||
import {OverviewRulerPosition, OverviewRulerLane} from 'vs/editor/common/editorCommon';
|
||||
import {OverviewRulerZone, ColorZone} from 'vs/editor/browser/editorBrowser';
|
||||
|
||||
class ZoneManager {
|
||||
|
||||
private _getVerticalOffsetForLine:(lineNumber:number)=>number;
|
||||
private _zones: OverviewRulerZone[];
|
||||
private _colorZonesInvalid: boolean;
|
||||
private _lineHeight: number;
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
private _outerHeight: number;
|
||||
private _maximumHeight: number;
|
||||
private _minimumHeight: number;
|
||||
private _useDarkColor: boolean;
|
||||
|
||||
private _lastAssignedId;
|
||||
private _color2Id: { [color:string]: number; };
|
||||
private _id2Color: string[];
|
||||
|
||||
constructor(getVerticalOffsetForLine:(lineNumber:number)=>number) {
|
||||
this._getVerticalOffsetForLine = getVerticalOffsetForLine;
|
||||
this._zones = [];
|
||||
this._colorZonesInvalid = false;
|
||||
this._lineHeight = 0;
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this._outerHeight = 0;
|
||||
this._maximumHeight = 0;
|
||||
this._minimumHeight = 0;
|
||||
this._useDarkColor = false;
|
||||
|
||||
this._lastAssignedId = 0;
|
||||
this._color2Id = Object.create(null);
|
||||
this._id2Color = [];
|
||||
}
|
||||
|
||||
public getId2Color(): string[] {
|
||||
return this._id2Color;
|
||||
}
|
||||
|
||||
public setZones(newZones: OverviewRulerZone[]): void {
|
||||
newZones.sort((a, b) => a.compareTo(b));
|
||||
|
||||
let oldZones = this._zones;
|
||||
let oldIndex = 0;
|
||||
let oldLength = this._zones.length;
|
||||
let newIndex = 0;
|
||||
let newLength = newZones.length;
|
||||
|
||||
let result: OverviewRulerZone[] = [];
|
||||
while (newIndex < newLength) {
|
||||
let newZone = newZones[newIndex];
|
||||
|
||||
if (oldIndex >= oldLength) {
|
||||
result.push(newZone);
|
||||
newIndex++;
|
||||
} else {
|
||||
let oldZone = oldZones[oldIndex];
|
||||
let cmp = oldZone.compareTo(newZone);
|
||||
if (cmp < 0) {
|
||||
oldIndex++;
|
||||
} else if (cmp > 0) {
|
||||
result.push(newZone);
|
||||
newIndex++;
|
||||
} else {
|
||||
// cmp === 0
|
||||
result.push(oldZone);
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._zones = result;
|
||||
}
|
||||
|
||||
public setLineHeight(lineHeight:number): boolean {
|
||||
if (this._lineHeight === lineHeight) {
|
||||
return false;
|
||||
}
|
||||
this._lineHeight = lineHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public getWidth(): number {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
public setWidth(width:number): boolean {
|
||||
if (this._width === width) {
|
||||
return false;
|
||||
}
|
||||
this._width = width;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public getHeight(): number {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
public setHeight(height:number): boolean {
|
||||
if (this._height === height) {
|
||||
return false;
|
||||
}
|
||||
this._height = height;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public getOuterHeight(): number {
|
||||
return this._outerHeight;
|
||||
}
|
||||
|
||||
public setOuterHeight(outerHeight:number): boolean {
|
||||
if (this._outerHeight === outerHeight) {
|
||||
return false;
|
||||
}
|
||||
this._outerHeight = outerHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public setMaximumHeight(maximumHeight:number): boolean {
|
||||
if (this._maximumHeight === maximumHeight) {
|
||||
return false;
|
||||
}
|
||||
this._maximumHeight = maximumHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public setMinimumHeight(minimumHeight:number): boolean {
|
||||
if (this._minimumHeight === minimumHeight) {
|
||||
return false;
|
||||
}
|
||||
this._minimumHeight = minimumHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public setUseDarkColor(useDarkColor:boolean): boolean {
|
||||
if (this._useDarkColor === useDarkColor) {
|
||||
return false;
|
||||
}
|
||||
this._useDarkColor = useDarkColor;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public resolveColorZones(): ColorZone[] {
|
||||
const colorZonesInvalid = this._colorZonesInvalid;
|
||||
const lineHeight = Math.floor(this._lineHeight); // @perf
|
||||
const totalHeight = Math.floor(this._height); // @perf
|
||||
const maximumHeight = Math.floor(this._maximumHeight); // @perf
|
||||
const minimumHeight = Math.floor(this._minimumHeight); // @perf
|
||||
const useDarkColor = this._useDarkColor; // @perf
|
||||
const outerHeight = Math.floor(this._outerHeight); // @perf
|
||||
const heightRatio = totalHeight / outerHeight;
|
||||
|
||||
let allColorZones: ColorZone[] = [];
|
||||
for (let i = 0, len = this._zones.length; i < len; i++) {
|
||||
let zone = this._zones[i];
|
||||
|
||||
if (!colorZonesInvalid) {
|
||||
let colorZones = zone.getColorZones();
|
||||
if (colorZones) {
|
||||
for (let j = 0, lenJ = colorZones.length; j < lenJ; j++) {
|
||||
allColorZones.push(colorZones[j]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let y1 = Math.floor(this._getVerticalOffsetForLine(zone.startLineNumber));
|
||||
let y2 = Math.floor(this._getVerticalOffsetForLine(zone.endLineNumber)) + lineHeight;
|
||||
|
||||
y1 = Math.floor(y1 * heightRatio);
|
||||
y2 = Math.floor(y2 * heightRatio);
|
||||
|
||||
let colorZones: ColorZone[] = [];
|
||||
if (zone.forceHeight) {
|
||||
y2 = y1 + zone.forceHeight;
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, zone.forceHeight, zone.forceHeight, zone.getColor(useDarkColor), zone.position));
|
||||
} else {
|
||||
// Figure out if we can render this in one continuous zone
|
||||
let zoneLineNumbers = zone.endLineNumber - zone.startLineNumber + 1;
|
||||
let zoneMaximumHeight = zoneLineNumbers * maximumHeight;
|
||||
|
||||
if (y2 - y1 > zoneMaximumHeight) {
|
||||
// We need to draw one zone per line
|
||||
for (let lineNumber = zone.startLineNumber; lineNumber <= zone.endLineNumber; lineNumber++) {
|
||||
y1 = Math.floor(this._getVerticalOffsetForLine(lineNumber));
|
||||
y2 = y1 + lineHeight;
|
||||
|
||||
y1 = Math.floor(y1 * heightRatio);
|
||||
y2 = Math.floor(y2 * heightRatio);
|
||||
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, minimumHeight, maximumHeight, zone.getColor(useDarkColor), zone.position));
|
||||
}
|
||||
} else {
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, minimumHeight, zoneMaximumHeight, zone.getColor(useDarkColor), zone.position));
|
||||
}
|
||||
}
|
||||
|
||||
zone.setColorZones(colorZones);
|
||||
for (let j = 0, lenJ = colorZones.length; j < lenJ; j++) {
|
||||
allColorZones.push(colorZones[j]);
|
||||
}
|
||||
}
|
||||
|
||||
this._colorZonesInvalid = false;
|
||||
|
||||
let sortFunc = (a:ColorZone, b:ColorZone) => {
|
||||
if (a.colorId === b.colorId) {
|
||||
if (a.from === b.from) {
|
||||
return a.to - b.to;
|
||||
}
|
||||
return a.from - b.from;
|
||||
}
|
||||
return a.colorId - b.colorId;
|
||||
};
|
||||
|
||||
allColorZones.sort(sortFunc);
|
||||
return allColorZones;
|
||||
}
|
||||
|
||||
public createZone(totalHeight:number, y1:number, y2:number, minimumHeight:number, maximumHeight:number, color:string, position:OverviewRulerLane): ColorZone {
|
||||
totalHeight = Math.floor(totalHeight); // @perf
|
||||
y1 = Math.floor(y1); // @perf
|
||||
y2 = Math.floor(y2); // @perf
|
||||
minimumHeight = Math.floor(minimumHeight); // @perf
|
||||
maximumHeight = Math.floor(maximumHeight); // @perf
|
||||
|
||||
let ycenter = Math.floor((y1 + y2) / 2);
|
||||
let halfHeight = (y2 - ycenter);
|
||||
|
||||
|
||||
if (halfHeight > maximumHeight / 2) {
|
||||
halfHeight = maximumHeight / 2;
|
||||
}
|
||||
if (halfHeight < minimumHeight / 2) {
|
||||
halfHeight = minimumHeight / 2;
|
||||
}
|
||||
|
||||
if (ycenter - halfHeight < 0) {
|
||||
ycenter = halfHeight;
|
||||
}
|
||||
if (ycenter + halfHeight > totalHeight) {
|
||||
ycenter = totalHeight - halfHeight;
|
||||
}
|
||||
|
||||
let colorId = this._color2Id[color];
|
||||
if (!colorId) {
|
||||
colorId = (++this._lastAssignedId);
|
||||
this._color2Id[color] = colorId;
|
||||
this._id2Color[colorId] = color;
|
||||
}
|
||||
return new ColorZone(ycenter - halfHeight, ycenter + halfHeight, colorId, position);
|
||||
}
|
||||
}
|
||||
import {OverviewRulerPosition, OverviewRulerLane, OverviewRulerZone, ColorZone} from 'vs/editor/common/editorCommon';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import {OverviewZoneManager} from 'vs/editor/common/view/overviewZoneManager';
|
||||
|
||||
export class OverviewRulerImpl {
|
||||
|
||||
@@ -276,9 +17,11 @@ export class OverviewRulerImpl {
|
||||
private _canvasLeftOffset: number;
|
||||
private _domNode: HTMLCanvasElement;
|
||||
private _lanesCount:number;
|
||||
private _zoneManager: ZoneManager;
|
||||
private _zoneManager: OverviewZoneManager;
|
||||
private _canUseTranslate3d: boolean;
|
||||
|
||||
private _zoomListener: IDisposable;
|
||||
|
||||
constructor(canvasLeftOffset:number, cssClassName:string, scrollHeight:number, lineHeight:number, canUseTranslate3d:boolean, minimumHeight:number, maximumHeight:number, getVerticalOffsetForLine:(lineNumber:number)=>number) {
|
||||
this._canvasLeftOffset = canvasLeftOffset;
|
||||
|
||||
@@ -290,17 +33,28 @@ export class OverviewRulerImpl {
|
||||
|
||||
this._canUseTranslate3d = canUseTranslate3d;
|
||||
|
||||
this._zoneManager = new ZoneManager(getVerticalOffsetForLine);
|
||||
this._zoneManager = new OverviewZoneManager(getVerticalOffsetForLine);
|
||||
this._zoneManager.setMinimumHeight(minimumHeight);
|
||||
this._zoneManager.setMaximumHeight(maximumHeight);
|
||||
this._zoneManager.setUseDarkColor(false);
|
||||
this._zoneManager.setWidth(0);
|
||||
this._zoneManager.setHeight(0);
|
||||
this._zoneManager.setDOMWidth(0);
|
||||
this._zoneManager.setDOMHeight(0);
|
||||
this._zoneManager.setOuterHeight(scrollHeight);
|
||||
this._zoneManager.setLineHeight(lineHeight);
|
||||
|
||||
this._zoomListener = browser.onDidChangeZoomLevel(() => {
|
||||
this._zoneManager.setPixelRatio(browser.getPixelRatio());
|
||||
this._domNode.style.width = this._zoneManager.getDOMWidth() + 'px';
|
||||
this._domNode.style.height = this._zoneManager.getDOMHeight() + 'px';
|
||||
this._domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.height = this._zoneManager.getCanvasHeight();
|
||||
this.render(true);
|
||||
});
|
||||
this._zoneManager.setPixelRatio(browser.getPixelRatio());
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._zoomListener.dispose();
|
||||
this._zoneManager = null;
|
||||
}
|
||||
|
||||
@@ -309,12 +63,14 @@ export class OverviewRulerImpl {
|
||||
StyleMutator.setRight(this._domNode, position.right);
|
||||
|
||||
let hasChanged = false;
|
||||
hasChanged = this._zoneManager.setWidth(position.width) || hasChanged;
|
||||
hasChanged = this._zoneManager.setHeight(position.height) || hasChanged;
|
||||
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
|
||||
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
|
||||
|
||||
if (hasChanged) {
|
||||
this._domNode.width = this._zoneManager.getWidth();
|
||||
this._domNode.height = this._zoneManager.getHeight();
|
||||
this._domNode.style.width = this._zoneManager.getDOMWidth() + 'px';
|
||||
this._domNode.style.height = this._zoneManager.getDOMHeight() + 'px';
|
||||
this._domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
if (render) {
|
||||
this.render(true);
|
||||
@@ -346,12 +102,12 @@ export class OverviewRulerImpl {
|
||||
return this._domNode;
|
||||
}
|
||||
|
||||
public getWidth(): number {
|
||||
return this._zoneManager.getWidth();
|
||||
public getPixelWidth(): number {
|
||||
return this._zoneManager.getCanvasWidth();
|
||||
}
|
||||
|
||||
public getHeight(): number {
|
||||
return this._zoneManager.getHeight();
|
||||
public getPixelHeight(): number {
|
||||
return this._zoneManager.getCanvasHeight();
|
||||
}
|
||||
|
||||
public setScrollHeight(scrollHeight:number, render:boolean): void {
|
||||
@@ -395,8 +151,8 @@ export class OverviewRulerImpl {
|
||||
StyleMutator.setTransform(this._domNode, '');
|
||||
}
|
||||
|
||||
const width = this._zoneManager.getWidth();
|
||||
const height = this._zoneManager.getHeight();
|
||||
const width = this._zoneManager.getCanvasWidth();
|
||||
const height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
let colorZones = this._zoneManager.resolveColorZones();
|
||||
let id2Color = this._zoneManager.getId2Color();
|
||||
|
||||
@@ -11,6 +11,7 @@ import {DynamicViewOverlay} from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import {ViewContext} from 'vs/editor/common/view/viewContext';
|
||||
import {HorizontalRange, LineVisibleRanges} from 'vs/editor/common/view/renderingContext';
|
||||
import {IRenderingContext} from 'vs/editor/common/view/renderingContext';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
|
||||
enum CornerStyle {
|
||||
EXTERN,
|
||||
@@ -78,7 +79,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
private _context:ViewContext;
|
||||
private _lineHeight:number;
|
||||
private _roundedSelection:boolean;
|
||||
private _selections:editorCommon.IEditorRange[];
|
||||
private _selections:Range[];
|
||||
private _renderResult:string[];
|
||||
|
||||
constructor(context:ViewContext) {
|
||||
@@ -271,7 +272,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
}
|
||||
|
||||
private _getVisibleRangesWithStyle(selection: editorCommon.IEditorRange, ctx: IRenderingContext, previousFrame:LineVisibleRangesWithStyle[]): LineVisibleRangesWithStyle[] {
|
||||
private _getVisibleRangesWithStyle(selection: Range, ctx: IRenderingContext, previousFrame:LineVisibleRangesWithStyle[]): LineVisibleRangesWithStyle[] {
|
||||
let _linesVisibleRanges = ctx.linesVisibleRangesForRange(selection, true) || [];
|
||||
let linesVisibleRanges = _linesVisibleRanges.map(toStyled);
|
||||
let visibleRangesHaveGaps = this._visibleRangesHaveGaps(linesVisibleRanges);
|
||||
|
||||
@@ -25,11 +25,40 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
|
||||
import {Colorizer} from 'vs/editor/browser/standalone/colorizer';
|
||||
import {View} from 'vs/editor/browser/view/viewImpl';
|
||||
import {Disposable} from 'vs/base/common/lifecycle';
|
||||
import {Disposable, IDisposable} from 'vs/base/common/lifecycle';
|
||||
import Event, {Emitter} from 'vs/base/common/event';
|
||||
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
|
||||
|
||||
export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.ICodeEditor {
|
||||
|
||||
public onMouseUp(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.MouseUp, listener);
|
||||
}
|
||||
public onMouseDown(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.MouseDown, listener);
|
||||
}
|
||||
public onContextMenu(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ContextMenu, listener);
|
||||
}
|
||||
public onMouseMove(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.MouseMove, listener);
|
||||
}
|
||||
public onMouseLeave(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.MouseLeave, listener);
|
||||
}
|
||||
public onKeyUp(listener: (e:IKeyboardEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.KeyUp, listener);
|
||||
}
|
||||
public onKeyDown(listener: (e:IKeyboardEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.KeyDown, listener);
|
||||
}
|
||||
public onDidLayoutChange(listener: (e:editorCommon.EditorLayoutInfo)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.EditorLayout, listener);
|
||||
}
|
||||
public onDidScrollChange(listener: (e:editorCommon.IScrollEvent)=>void): IDisposable {
|
||||
return this.addListener2('scroll', listener);
|
||||
}
|
||||
|
||||
protected domElement:HTMLElement;
|
||||
private _focusTracker: CodeEditorWidgetFocusTracker;
|
||||
|
||||
@@ -121,7 +150,7 @@ export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.
|
||||
return this._view.domNode;
|
||||
}
|
||||
|
||||
public getCenteredRangeInViewport(): editorCommon.IEditorRange {
|
||||
public getCenteredRangeInViewport(): Range {
|
||||
if (!this.hasView) {
|
||||
return null;
|
||||
}
|
||||
@@ -584,7 +613,7 @@ export enum EditCursorState {
|
||||
|
||||
class SingleEditOperation {
|
||||
|
||||
range: editorCommon.IEditorRange;
|
||||
range: Range;
|
||||
text: string;
|
||||
forceMoveMarkers: boolean;
|
||||
|
||||
@@ -636,7 +665,7 @@ export class CommandRunner implements editorCommon.ICommand {
|
||||
}
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): editorCommon.IEditorSelection {
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
var inverseEditOperations = helper.getInverseEditOperations();
|
||||
var srcRange = inverseEditOperations[inverseEditOperations.length - 1].range;
|
||||
return Selection.createSelection(
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import 'vs/css!./media/diffEditor';
|
||||
import {IAction} from 'vs/base/common/actions';
|
||||
import {RunOnceScheduler} from 'vs/base/common/async';
|
||||
import {EventEmitter, IEmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {EventEmitter, EmitterEvent} from 'vs/base/common/eventEmitter';
|
||||
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
@@ -25,15 +25,12 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken';
|
||||
import {Configuration} from 'vs/editor/browser/config/configuration';
|
||||
|
||||
interface IEditorScrollEvent {
|
||||
scrollLeft: number;
|
||||
scrollTop: number;
|
||||
}
|
||||
import {Position} from 'vs/editor/common/core/position';
|
||||
import {Selection} from 'vs/editor/common/core/selection';
|
||||
|
||||
interface IEditorDiffDecorations {
|
||||
decorations:editorCommon.IModelDeltaDecoration[];
|
||||
overviewZones:editorBrowser.OverviewRulerZone[];
|
||||
overviewZones:editorCommon.OverviewRulerZone[];
|
||||
}
|
||||
|
||||
interface IEditorDiffDecorationsWithZones extends IEditorDiffDecorations {
|
||||
@@ -129,6 +126,34 @@ var DIFF_EDITOR_ID = 0;
|
||||
|
||||
export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDiffEditor {
|
||||
|
||||
public onDidChangeModelRawContent(listener: (e:editorCommon.IModelContentChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ModelRawContentChanged, listener);
|
||||
}
|
||||
public onDidChangeModelContent(listener: (e:editorCommon.IModelContentChangedEvent2)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ModelContentChanged2, listener);
|
||||
}
|
||||
public onDidChangeModelMode(listener: (e:editorCommon.IModelModeChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ModelModeChanged, listener);
|
||||
}
|
||||
public onDidChangeModelOptions(listener: (e:editorCommon.IModelOptionsChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ModelOptionsChanged, listener);
|
||||
}
|
||||
public onDidChangeConfiguration(listener: (e:editorCommon.IConfigurationChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.ConfigurationChanged, listener);
|
||||
}
|
||||
public onDidChangeCursorPosition(listener: (e:editorCommon.ICursorPositionChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.CursorPositionChanged, listener);
|
||||
}
|
||||
public onDidChangeCursorSelection(listener: (e:editorCommon.ICursorSelectionChangedEvent)=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.CursorSelectionChanged, listener);
|
||||
}
|
||||
public onDidDispose(listener: ()=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.Disposed, listener);
|
||||
}
|
||||
public onDidUpdateDiff(listener: ()=>void): IDisposable {
|
||||
return this.addListener2(editorCommon.EventType.DiffUpdated, listener);
|
||||
}
|
||||
|
||||
private static ONE_OVERVIEW_WIDTH = 15;
|
||||
public static ENTIRE_DIFF_OVERVIEW_WIDTH = 30;
|
||||
private static UPDATE_DIFF_DECORATIONS_DELAY = 200; // ms
|
||||
@@ -327,13 +352,13 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
private _createLeftHandSideEditor(options:editorCommon.IDiffEditorOptions, instantiationService:IInstantiationService): void {
|
||||
this.originalEditor = instantiationService.createInstance(CodeEditorWidget, this._originalDomNode, this._adjustOptionsForLeftHandSide(options, this._originalIsEditable));
|
||||
this._toDispose.push(this.originalEditor.addBulkListener2((events: any) => this._onOriginalEditorEvents(events)));
|
||||
this._toDispose.push(this.addEmitter2(this.originalEditor, 'leftHandSide'));
|
||||
this._toDispose.push(this.addEmitter2(this.originalEditor));
|
||||
}
|
||||
|
||||
private _createRightHandSideEditor(options:editorCommon.IDiffEditorOptions, instantiationService:IInstantiationService): void {
|
||||
this.modifiedEditor = instantiationService.createInstance(CodeEditorWidget, this._modifiedDomNode, this._adjustOptionsForRightHandSide(options));
|
||||
this._toDispose.push(this.modifiedEditor.addBulkListener2((events: any) => this._onModifiedEditorEvents(events)));
|
||||
this._toDispose.push(this.addEmitter2(this.modifiedEditor, 'rightHandSide'));
|
||||
this._toDispose.push(this.addEmitter2(this.modifiedEditor));
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
@@ -355,6 +380,8 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
|
||||
this._strategy.dispose();
|
||||
|
||||
this.emit(editorCommon.EventType.Disposed);
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -481,7 +508,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
return this.modifiedEditor.getVisibleColumnFromPosition(position);
|
||||
}
|
||||
|
||||
public getPosition(): editorCommon.IEditorPosition {
|
||||
public getPosition(): Position {
|
||||
return this.modifiedEditor.getPosition();
|
||||
}
|
||||
|
||||
@@ -513,18 +540,18 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
this.modifiedEditor.revealPositionInCenterIfOutsideViewport(position);
|
||||
}
|
||||
|
||||
public getSelection(): editorCommon.IEditorSelection {
|
||||
public getSelection(): Selection {
|
||||
return this.modifiedEditor.getSelection();
|
||||
}
|
||||
|
||||
public getSelections(): editorCommon.IEditorSelection[] {
|
||||
public getSelections(): Selection[] {
|
||||
return this.modifiedEditor.getSelections();
|
||||
}
|
||||
|
||||
public setSelection(range:editorCommon.IRange, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(editorRange:editorCommon.IEditorRange, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(editorRange:Range, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(selection:editorCommon.ISelection, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(editorSelection:editorCommon.IEditorSelection, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(editorSelection:Selection, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void;
|
||||
public setSelection(something:any, reveal?:boolean, revealVerticalInCenter?:boolean, revealHorizontal?:boolean): void {
|
||||
this.modifiedEditor.setSelection(something, reveal, revealVerticalInCenter, revealHorizontal);
|
||||
}
|
||||
@@ -670,11 +697,11 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
|
||||
//------------ end layouting methods
|
||||
|
||||
private _recomputeIfNecessary(events:IEmitterEvent[]): void {
|
||||
private _recomputeIfNecessary(events:EmitterEvent[]): void {
|
||||
var changed = false;
|
||||
for (var i = 0; !changed && i < events.length; i++) {
|
||||
var type = events[i].getType();
|
||||
changed = changed || type === 'change' || type === editorCommon.EventType.ModelModeChanged;
|
||||
changed = changed || type === editorCommon.EventType.ModelRawContentChanged || type === editorCommon.EventType.ModelModeChanged;
|
||||
}
|
||||
if (changed && this._isVisible) {
|
||||
// Clear previous timeout if necessary
|
||||
@@ -686,7 +713,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
}
|
||||
}
|
||||
|
||||
private _onOriginalEditorEvents(events:IEmitterEvent[]): void {
|
||||
private _onOriginalEditorEvents(events:EmitterEvent[]): void {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
if (events[i].getType() === 'scroll') {
|
||||
this._onOriginalEditorScroll(events[i].getData());
|
||||
@@ -698,15 +725,12 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
this._recomputeIfNecessary(events);
|
||||
}
|
||||
|
||||
private _onModifiedEditorEvents(events:IEmitterEvent[]): void {
|
||||
private _onModifiedEditorEvents(events:EmitterEvent[]): void {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
if (events[i].getType() === 'scroll') {
|
||||
this._onModifiedEditorScroll(events[i].getData());
|
||||
this._layoutOverviewViewport();
|
||||
}
|
||||
if (events[i].getType() === 'scrollSize') {
|
||||
this._layoutOverviewViewport();
|
||||
}
|
||||
if (events[i].getType() === 'viewLayoutChanged') {
|
||||
this._layoutOverviewViewport();
|
||||
}
|
||||
@@ -739,7 +763,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
var currentOriginalModel = this.originalEditor.getModel();
|
||||
var currentModifiedModel = this.modifiedEditor.getModel();
|
||||
|
||||
this._editorWorkerService.computeDiff(currentOriginalModel.getAssociatedResource(), currentModifiedModel.getAssociatedResource(), this._ignoreTrimWhitespace).then((result) => {
|
||||
this._editorWorkerService.computeDiff(currentOriginalModel.uri, currentModifiedModel.uri, this._ignoreTrimWhitespace).then((result) => {
|
||||
if (currentToken === this._diffComputationToken
|
||||
&& currentOriginalModel === this.originalEditor.getModel()
|
||||
&& currentModifiedModel === this.modifiedEditor.getModel()
|
||||
@@ -747,7 +771,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
{
|
||||
this._lineChanges = result;
|
||||
this._updateDecorationsRunner.schedule();
|
||||
this.emit(editorCommon.EventType.DiffUpdated, { editor: this, lineChanges: result });
|
||||
this.emit(editorCommon.EventType.DiffUpdated, { });
|
||||
}
|
||||
}, (error) => {
|
||||
if (currentToken === this._diffComputationToken
|
||||
@@ -810,7 +834,10 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
return result;
|
||||
}
|
||||
|
||||
private _onOriginalEditorScroll(e:IEditorScrollEvent): void {
|
||||
private _onOriginalEditorScroll(e:editorCommon.IScrollEvent): void {
|
||||
if (!e.scrollTopChanged && !e.scrollLeftChanged) {
|
||||
return;
|
||||
}
|
||||
if (this._isHandlingScrollEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -822,7 +849,10 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif
|
||||
this._isHandlingScrollEvent = false;
|
||||
}
|
||||
|
||||
private _onModifiedEditorScroll(e:IEditorScrollEvent): void {
|
||||
private _onModifiedEditorScroll(e:editorCommon.IScrollEvent): void {
|
||||
if (!e.scrollTopChanged && !e.scrollLeftChanged) {
|
||||
return;
|
||||
}
|
||||
if(this._isHandlingScrollEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -1329,10 +1359,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
this._sash.disable();
|
||||
}
|
||||
|
||||
this._sash.on('start', () => this.onSashDragStart());
|
||||
this._sash.on('change', (e: ISashEvent) => this.onSashDrag(e));
|
||||
this._sash.on('end', () => this.onSashDragEnd());
|
||||
this._sash.on('reset', () => this.onSashReset());
|
||||
this._sash.addListener2('start', () => this.onSashDragStart());
|
||||
this._sash.addListener2('change', (e: ISashEvent) => this.onSashDrag(e));
|
||||
this._sash.addListener2('end', () => this.onSashDragEnd());
|
||||
this._sash.addListener2('reset', () => this.onSashReset());
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -1449,7 +1479,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
result.decorations.push(createDecoration(lineChange.originalStartLineNumber, 1, lineChange.originalEndLineNumber, Number.MAX_VALUE, 'char-delete', true));
|
||||
}
|
||||
|
||||
result.overviewZones.push(new editorBrowser.OverviewRulerZone(
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
@@ -1514,7 +1544,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
if (!isChangeOrDelete(lineChange) || !lineChange.charChanges) {
|
||||
result.decorations.push(createDecoration(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber, Number.MAX_VALUE, 'char-insert', true));
|
||||
}
|
||||
result.overviewZones.push(new editorBrowser.OverviewRulerZone(
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
@@ -1594,7 +1624,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
this.decorationsLeft = dataSource.getOriginalEditor().getLayoutInfo().decorationsLeft;
|
||||
|
||||
this.toDispose = [];
|
||||
this.toDispose.push(dataSource.getOriginalEditor().addListener2(editorCommon.EventType.EditorLayout, (layoutInfo:editorCommon.EditorLayoutInfo) => {
|
||||
this.toDispose.push(dataSource.getOriginalEditor().onDidLayoutChange((layoutInfo:editorCommon.EditorLayoutInfo) => {
|
||||
if (this.decorationsLeft !== layoutInfo.decorationsLeft) {
|
||||
this.decorationsLeft = layoutInfo.decorationsLeft;
|
||||
dataSource.relayoutEditors();
|
||||
@@ -1629,7 +1659,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
|
||||
// Add overview zones in the overview ruler
|
||||
if (isChangeOrDelete(lineChange)) {
|
||||
result.overviewZones.push(new editorBrowser.OverviewRulerZone(
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
@@ -1667,7 +1697,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
if (isChangeOrInsert(lineChange)) {
|
||||
result.decorations.push(createDecoration(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber, Number.MAX_VALUE, 'line-insert', true));
|
||||
|
||||
result.overviewZones.push(new editorBrowser.OverviewRulerZone(
|
||||
result.overviewZones.push(new editorCommon.OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
|
||||
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {EventType, ICodeEditorWidgetCreationOptions, IConfigurationChangedEvent, IEditorOptions} from 'vs/editor/common/editorCommon';
|
||||
import {ICodeEditorWidgetCreationOptions, IConfigurationChangedEvent, IEditorOptions} from 'vs/editor/common/editorCommon';
|
||||
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
|
||||
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
|
||||
import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
@@ -35,7 +35,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
|
||||
// Overwrite parent's options
|
||||
super.updateOptions(this._overwriteOptions);
|
||||
|
||||
this._lifetimeDispose.push(parentEditor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => this._onParentConfigurationChanged(e)));
|
||||
this._lifetimeDispose.push(parentEditor.onDidChangeConfiguration((e:IConfigurationChangedEvent) => this._onParentConfigurationChanged(e)));
|
||||
}
|
||||
|
||||
public getParentEditor(): ICodeEditor {
|
||||
|
||||
@@ -9,9 +9,9 @@ exports.collectModules = function() {
|
||||
return [{
|
||||
name: 'vs/editor/common/worker/editorWorkerServer',
|
||||
include: [ 'vs/base/common/severity' ],
|
||||
exclude: [ 'vs/base/common/worker/workerServer', 'vs/css', 'vs/nls', 'vs/text' ]
|
||||
exclude: [ 'vs/base/common/worker/workerServer', 'vs/css', 'vs/nls' ]
|
||||
}, {
|
||||
name: 'vs/editor/common/services/editorSimpleWorker',
|
||||
exclude: [ 'vs/base/common/worker/simpleWorker', 'vs/css', 'vs/nls', 'vs/text' ]
|
||||
exclude: [ 'vs/base/common/worker/simpleWorker', 'vs/css', 'vs/nls' ]
|
||||
}];
|
||||
};
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
|
||||
import {Selection} from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
|
||||
export class ReplaceCommand implements editorCommon.ICommand {
|
||||
|
||||
private _range: editorCommon.IEditorRange;
|
||||
private _range: Range;
|
||||
private _text: string;
|
||||
|
||||
constructor(range: editorCommon.IEditorRange, text: string) {
|
||||
constructor(range: Range, text: string) {
|
||||
this._range = range;
|
||||
this._text = text;
|
||||
}
|
||||
@@ -21,11 +22,11 @@ export class ReplaceCommand implements editorCommon.ICommand {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
public getRange():editorCommon.IEditorRange {
|
||||
public getRange():Range {
|
||||
return this._range;
|
||||
}
|
||||
|
||||
public setRange(newRange:editorCommon.IEditorRange): void {
|
||||
public setRange(newRange:Range): void {
|
||||
this._range = newRange;
|
||||
}
|
||||
|
||||
@@ -33,7 +34,7 @@ export class ReplaceCommand implements editorCommon.ICommand {
|
||||
builder.addEditOperation(this._range, this._text);
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): editorCommon.IEditorSelection {
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
var inverseEditOperations = helper.getInverseEditOperations();
|
||||
var srcRange = inverseEditOperations[0].range;
|
||||
return new Selection(
|
||||
@@ -47,11 +48,11 @@ export class ReplaceCommand implements editorCommon.ICommand {
|
||||
|
||||
export class ReplaceCommandWithoutChangingPosition extends ReplaceCommand {
|
||||
|
||||
constructor(range: editorCommon.IEditorRange, text: string) {
|
||||
constructor(range: Range, text: string) {
|
||||
super(range, text);
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): editorCommon.IEditorSelection {
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
var inverseEditOperations = helper.getInverseEditOperations();
|
||||
var srcRange = inverseEditOperations[0].range;
|
||||
return new Selection(
|
||||
@@ -68,13 +69,13 @@ export class ReplaceCommandWithOffsetCursorState extends ReplaceCommand {
|
||||
private _columnDeltaOffset: number;
|
||||
private _lineNumberDeltaOffset: number;
|
||||
|
||||
constructor(range: editorCommon.IEditorRange, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number) {
|
||||
constructor(range: Range, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number) {
|
||||
super(range, text);
|
||||
this._columnDeltaOffset = columnDeltaOffset;
|
||||
this._lineNumberDeltaOffset = lineNumberDeltaOffset;
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): editorCommon.IEditorSelection {
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
var inverseEditOperations = helper.getInverseEditOperations();
|
||||
var srcRange = inverseEditOperations[0].range;
|
||||
return new Selection(
|
||||
@@ -88,10 +89,10 @@ export class ReplaceCommandWithOffsetCursorState extends ReplaceCommand {
|
||||
|
||||
export class ReplaceCommandThatPreservesSelection extends ReplaceCommand {
|
||||
|
||||
private _initialSelection: editorCommon.IEditorSelection;
|
||||
private _initialSelection: Selection;
|
||||
private _selectionId: string;
|
||||
|
||||
constructor(editRange: editorCommon.IEditorRange, text: string, initialSelection: editorCommon.IEditorSelection) {
|
||||
constructor(editRange: Range, text: string, initialSelection: Selection) {
|
||||
super(editRange, text);
|
||||
this._initialSelection = initialSelection;
|
||||
}
|
||||
@@ -102,7 +103,7 @@ export class ReplaceCommandThatPreservesSelection extends ReplaceCommand {
|
||||
this._selectionId = builder.trackSelection(this._initialSelection);
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): editorCommon.IEditorSelection {
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
return helper.getTrackedSelection(this._selectionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as strings from 'vs/base/common/strings';
|
||||
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, IEditorSelection, ITokenizedModel} from 'vs/editor/common/editorCommon';
|
||||
import {ICommand, ICursorStateComputerData, IEditOperationBuilder, ITokenizedModel} from 'vs/editor/common/editorCommon';
|
||||
import {getRawEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
|
||||
|
||||
export interface IShiftCommandOpts {
|
||||
@@ -40,11 +40,11 @@ export class ShiftCommand implements ICommand {
|
||||
}
|
||||
|
||||
private _opts: IShiftCommandOpts;
|
||||
private _selection: IEditorSelection;
|
||||
private _selection: Selection;
|
||||
private _selectionId: string;
|
||||
private _useLastEditRangeForCursorEndPosition: boolean;
|
||||
|
||||
constructor(range: IEditorSelection, opts:IShiftCommandOpts) {
|
||||
constructor(range: Selection, opts:IShiftCommandOpts) {
|
||||
this._opts = opts;
|
||||
this._selection = range;
|
||||
this._useLastEditRangeForCursorEndPosition = false;
|
||||
@@ -152,7 +152,7 @@ export class ShiftCommand implements ICommand {
|
||||
this._selectionId = builder.trackSelection(this._selection);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITokenizedModel, helper: ICursorStateComputerData): IEditorSelection {
|
||||
public computeCursorState(model: ITokenizedModel, helper: ICursorStateComputerData): Selection {
|
||||
if (this._useLastEditRangeForCursorEndPosition) {
|
||||
var lastOp = helper.getInverseEditOperations()[0];
|
||||
return new Selection(lastOp.range.endLineNumber, lastOp.range.endColumn, lastOp.range.endLineNumber, lastOp.range.endColumn);
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
import {Range} from 'vs/editor/common/core/range';
|
||||
import {Selection} from 'vs/editor/common/core/selection';
|
||||
import {ICommand, ICursorStateComputerData, IEditOperationBuilder, IEditorSelection, ITokenizedModel} from 'vs/editor/common/editorCommon';
|
||||
import {ICommand, ICursorStateComputerData, IEditOperationBuilder, ITokenizedModel} from 'vs/editor/common/editorCommon';
|
||||
|
||||
export class SurroundSelectionCommand implements ICommand {
|
||||
private _range: IEditorSelection;
|
||||
private _range: Selection;
|
||||
private _charBeforeSelection: string;
|
||||
private _charAfterSelection: string;
|
||||
|
||||
constructor(range:IEditorSelection, charBeforeSelection:string, charAfterSelection:string) {
|
||||
constructor(range:Selection, charBeforeSelection:string, charAfterSelection:string) {
|
||||
this._range = range;
|
||||
this._charBeforeSelection = charBeforeSelection;
|
||||
this._charAfterSelection = charAfterSelection;
|
||||
@@ -35,7 +35,7 @@ export class SurroundSelectionCommand implements ICommand {
|
||||
), this._charAfterSelection);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITokenizedModel, helper: ICursorStateComputerData): IEditorSelection {
|
||||
public computeCursorState(model: ITokenizedModel, helper: ICursorStateComputerData): Selection {
|
||||
var inverseEditOperations = helper.getInverseEditOperations();
|
||||
var firstOperationRange = inverseEditOperations[0].range;
|
||||
var secondOperationRange = inverseEditOperations[1].range;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user