提交 d97efc5f 编写于 作者: B Benjamin Pasero

Merge branch 'master' into ben/fuzzy-quickopen

{
"comments": {
"lineComment": ";",
"blockComment": [ "(comment", ")" ]
"lineComment": ";"
},
"brackets": [
["{", "}"],
......
......@@ -14,6 +14,10 @@
"language": "csharp",
"scopeName": "source.cs",
"path": "./syntaxes/csharp.json"
}],
"jsonValidation": [{
"fileMatch": "project.json",
"url": "http://json.schemastore.org/project"
}]
}
}
\ No newline at end of file
......@@ -2,37 +2,86 @@
"name": "javascript",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"engines": {
"vscode": "*"
},
"contributes": {
"languages": [{
"id": "javascriptreact",
"aliases": ["JavaScript React","jsx"],
"extensions": [".jsx"],
"configuration": "./javascript.configuration.json"
},{
"id": "javascript",
"aliases": ["JavaScript", "javascript", "js"],
"extensions": [".js", ".es6"],
"filenames": ["jakefile"],
"firstLine": "^#!.*\\bnode",
"mimetypes": ["text/javascript"]
}],
"grammars": [{
"language": "javascriptreact",
"scopeName": "source.jsx",
"path": "./syntaxes/JavaScriptReact.tmLanguage"
},{
"language": "javascript",
"scopeName": "source.js",
"path": "./syntaxes/JavaScript.tmLanguage"
},{
// referenced by other grammars
"scopeName": "source.js.regexp",
"path": "./syntaxes/Regular Expressions (JavaScript).tmLanguage"
}],
"snippets": [{
"language": "javascript",
"path": "./snippets/javascript.json"
}]
"languages": [
{
"id": "javascriptreact",
"aliases": [
"JavaScript React",
"jsx"
],
"extensions": [
".jsx"
],
"configuration": "./javascript.configuration.json"
},
{
"id": "javascript",
"aliases": [
"JavaScript",
"javascript",
"js"
],
"extensions": [
".js",
".es6"
],
"filenames": [
"jakefile"
],
"firstLine": "^#!.*\\bnode",
"mimetypes": [
"text/javascript"
]
}
],
"grammars": [
{
"language": "javascriptreact",
"scopeName": "source.jsx",
"path": "./syntaxes/JavaScriptReact.tmLanguage"
},
{
"language": "javascript",
"scopeName": "source.js",
"path": "./syntaxes/JavaScript.tmLanguage"
},
{
// referenced by other grammars
"scopeName": "source.js.regexp",
"path": "./syntaxes/Regular Expressions (JavaScript).tmLanguage"
}
],
"snippets": [
{
"language": "javascript",
"path": "./snippets/javascript.json"
}
],
"jsonValidation": [
{
"fileMatch": "package.json",
"url": "http://json.schemastore.org/project"
},
{
"fileMatch": "bower.json",
"url": "http://json.schemastore.org/bower"
},
{
"fileMatch": ".bower.json",
"url": "http://json.schemastore.org/bower"
},
{
"fileMatch": ".bowerrc",
"url": "http://json.schemastore.org/bowerrc"
},
{
"fileMatch": "jsconfig.json",
"url": "./schemas/jsconfig.schema.json"
}
]
}
}
\ No newline at end of file
{
"title": "JSON schema for the JavaScript configuration file",
"type": "object",
"default": {
"compilerOptions": {
"target": "ES5"
}
},
"properties": {
"compilerOptions": {
"type": "object",
"description": "Instructs the JavaScript language service how to validate .js files",
"properties": {
"charset": {
"description": "The character set of the input files",
"type": "string"
},
"diagnostics": {
"description": "Show diagnostic information.",
"type": "boolean"
},
"locale": {
"description": "The locale to use to show error messages, e.g. en-us.",
"type": "string"
},
"mapRoot": {
"description": "Specifies the location where debugger should locate map files instead of generated locations",
"type": "string",
"format": "uri"
},
"module": {
"description": "Module code generation to resolve against: 'commonjs', 'amd', 'system', or 'umd'.",
"enum": [
"commonjs",
"amd",
"system",
"umd"
]
},
"noLib": {
"description": "Do not include the default library file (lib.d.ts).",
"type": "boolean"
},
"target": {
"description": "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental).",
"enum": [
"ES3",
"ES5",
"ES6",
"es3",
"es5",
"es6"
],
"default": "ES3"
},
"experimentalDecorators": {
"description": "Enables experimental support for ES7 decorators.",
"type": "boolean"
}
}
},
"files": {
"type": "array",
"description": "If no 'files' property is present in a jsconfig.json, the language service defaults to including all files the containing directory and subdirectories. When a 'files' property is specified, only those files are included.",
"items": {
"type": "string",
"format": "uri"
}
},
"exclude": {
"type": "array",
"description": "List files and folders that should not be included. This property is not honored when the 'files' property is present.",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
\ No newline at end of file
......@@ -2,18 +2,41 @@
"name": "json",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"engines": {
"vscode": "*"
},
"contributes": {
"languages": [{
"id": "json",
"aliases": ["JSON", "json"],
"extensions": [".json", ".bowerrc", ".jshintrc", ".jscsrc", ".eslintrc"],
"mimetypes": ["application/json"]
}],
"grammars": [{
"language": "json",
"scopeName": "source.json",
"path": "./syntaxes/JSON.tmLanguage"
}]
"languages": [
{
"id": "json",
"aliases": [
"JSON",
"json"
],
"extensions": [
".json",
".bowerrc",
".jshintrc",
".jscsrc",
".eslintrc"
],
"mimetypes": [
"application/json"
]
}
],
"grammars": [
{
"language": "json",
"scopeName": "source.json",
"path": "./syntaxes/JSON.tmLanguage"
}
],
"jsonValidation": [
{
"fileMatch": "*.schema.json",
"url": "http://json-schema.org/draft-04/schema#"
}
]
}
}
\ No newline at end of file
{
"account": "monacobuild",
"container": "debuggers",
"zip": "32575e3/node-debug.zip",
"zip": "3efab9b/node-debug.zip",
"output": ""
}
......@@ -6,7 +6,7 @@
"contributes": {
"languages": [{
"id": "ruby",
"extensions": [ ".rb", ".rbx", ".rjs", ".gemspec", ".pp" ],
"extensions": [ ".rb", ".rbx", ".rjs", ".gemspec", ".pp", ".rake" ],
"filenames": [ "rakefile", "gemfile" ],
"aliases": [ "Ruby", "rb" ],
"configuration": "./ruby.configuration.json"
......
......@@ -101,6 +101,12 @@
"language": "typescriptreact",
"path": "./snippets/typescriptreact.json"
}
],
"jsonValidation": [
{
"fileMatch": "tsconfig.json",
"url": "http://json.schemastore.org/tsconfig"
}
]
}
}
\ No newline at end of file
{
"comments": {
"lineComment": "'",
"blockComment": [ "/*", "*/" ]
"lineComment": "'"
},
"brackets": [
["{", "}"],
......
......@@ -8,6 +8,7 @@
"id": "xml",
"extensions": [
".ascx",
".atom",
".axml",
".bpmn",
".config",
......
......@@ -414,6 +414,11 @@
"version": "4.3.6",
"from": "semver@>=4.2.0 <5.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
},
"vscode-debugprotocol": {
"version": "1.0.1",
"from": "vscode-debugprotocol@>=1.0.1",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.0.1.tgz"
},
"vscode-textmate": {
"version": "1.0.9",
......
......@@ -36,13 +36,11 @@ export class ArrayIterator<T> implements IIterator<T> {
export class MappedIterator<T, R> implements IIterator<R> {
constructor(private iterator: IIterator<T>, private fn: (item:T)=>R) {
constructor(protected iterator: IIterator<T>, protected fn: (item:T)=>R) {
// noop
}
public next(): R {
return this.fn(this.iterator.next());
}
next() { return this.fn(this.iterator.next()); }
}
export interface INavigator<T> extends IIterator<T> {
......@@ -52,3 +50,16 @@ export interface INavigator<T> extends IIterator<T> {
first(): T;
last(): T;
}
export class MappedNavigator<T, R> extends MappedIterator<T, R> implements INavigator<R> {
constructor(protected navigator: INavigator<T>, fn: (item:T)=>R) {
super(navigator, fn);
}
current() { return this.fn(this.navigator.current()); }
previous() { return this.fn(this.navigator.previous()); }
parent() { return this.fn(this.navigator.parent()); }
first() { return this.fn(this.navigator.first()); }
last() { return this.fn(this.navigator.last()); }
}
......@@ -131,7 +131,11 @@ export class Server {
if (!method) {
promise = Promise.wrapError(new Error(`${ request.name } is not a valid method on ${ request.serviceName }`));
} else {
promise = method.call(service, ...request.args)
try {
promise = method.call(service, ...request.args);
} catch (err) {
promise = Promise.wrapError(err);
}
}
if (!Promise.is(promise)) {
......
......@@ -11,6 +11,7 @@ import Events = require('vs/base/common/eventEmitter');
import Model = require('vs/base/parts/tree/common/treeModel');
import View = require('./treeView');
import _ = require('vs/base/parts/tree/common/tree');
import { INavigator, MappedNavigator } from 'vs/base/common/iterator';
export class TreeContext implements _.ITreeContext {
......@@ -165,6 +166,10 @@ export class Tree extends Events.EventEmitter implements _.ITree {
this.view.setScrollPosition(pos);
}
getContentHeight(): number {
return this.view.getTotalHeight();
}
public setHighlight(element?:any, eventPayload?:any):void {
this.model.setHighlight(element, eventPayload);
}
......@@ -306,6 +311,10 @@ export class Tree extends Events.EventEmitter implements _.ITree {
return this.view.withFakeRow(fn);
}
getNavigator(): INavigator<any> {
return new MappedNavigator(this.model.getNavigator(), i => i && i.getElement());
}
public dispose(): void {
if (this.model !== null) {
this.model.dispose();
......
......@@ -9,6 +9,7 @@ import Touch = require('vs/base/browser/touch');
import Events = require('vs/base/common/eventEmitter');
import Mouse = require('vs/base/browser/mouseEvent');
import Keyboard = require('vs/base/browser/keyboardEvent');
import { INavigator } from 'vs/base/common/iterator';
export interface ITree extends Events.IEventEmitter {
......@@ -132,6 +133,11 @@ export interface ITree extends Events.IEventEmitter {
*/
setScrollPosition(pos: number): void;
/**
* Returns the total height of the tree's content.
*/
getContentHeight(): number;
/**
* Sets the tree's highlight to be the given element.
* Provide no arguments and it clears the tree's highlight.
......@@ -309,6 +315,12 @@ export interface ITree extends Events.IEventEmitter {
*/
withFakeRow(fn:(container:HTMLElement)=>any):any;
/**
* Returns a navigator which allows to discover the visible and
* expanded elements in the tree.
*/
getNavigator(): INavigator<any>;
/**
* Disposes the tree
*/
......
......@@ -458,7 +458,7 @@ export class Item extends Events.EventEmitter {
public getHierarchy(): Item[] {
var result: Item[] = [];
var node = this;
var node: Item = this;
do {
result.push(node);
......
......@@ -272,4 +272,8 @@ export class SimplePluginService extends AbstractPluginService {
console.log(msg);
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}
......@@ -40,6 +40,8 @@ import {createAsyncDescriptor0} from 'vs/platform/instantiation/common/descripto
import {LanguageExtensions, ILanguageExtensionPoint} from 'vs/editor/common/modes/languageExtensionPoint';
import {AbstractKeybindingService} from 'vs/platform/keybinding/browser/keybindingServiceImpl';
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
import {IJSONSchema} from 'vs/base/common/jsonSchema';
import * as JSONContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
// Set defaults for standalone editor
DefaultConfig.editor.wrappingIndent = 'none';
......@@ -451,6 +453,11 @@ export function registerStandaloneLanguage(language:ILanguageExtensionPoint, def
});
}
export function registerStandaloneSchema(uri:string, schema:IJSONSchema) {
let schemaRegistry = <JSONContributionRegistry.IJSONContributionRegistry>Registry.as(JSONContributionRegistry.Extensions.JSONContribution);
schemaRegistry.registerSchema(uri, schema);
}
export function colorizeElement(domNode:HTMLElement, options:colorizer.IColorizerElementOptions): TPromise<void> {
startup.initStaticServicesIfNecessary();
var modeService = standaloneServices.ensureStaticPlatformServices(null).modeService;
......
......@@ -5,12 +5,14 @@
'use strict';
import 'vs/editor/standalone-languages/all';
import './standaloneSchemas';
import Colorizer = require('vs/editor/browser/standalone/colorizer');
import standaloneCodeEditor = require('vs/editor/browser/standalone/standaloneCodeEditor');
import EditorCommon = require('vs/editor/common/editorCommon');
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import {ILanguageDef} from 'vs/editor/standalone-languages/types';
import {IJSONSchema} from 'vs/base/common/jsonSchema';
var global:any = self;
if (!global.Monaco) {
......@@ -67,4 +69,10 @@ Monaco.Editor.OverlayWidgetPositionPreference = EditorBrowser.OverlayWidgetPosit
let MonacoEditorLanguages: ILanguageDef[] = this.MonacoEditorLanguages || [];
MonacoEditorLanguages.forEach((language) => {
standaloneCodeEditor.registerStandaloneLanguage(language, language.defModule);
});
\ No newline at end of file
});
// Register all built-in standalone JSON schemas
let MonacoEditorSchemas: { [url:string]: IJSONSchema } = this.MonacoEditorSchemas || {};
for (var uri in MonacoEditorSchemas) {
standaloneCodeEditor.registerStandaloneSchema(uri, MonacoEditorSchemas[uri]);
};
\ No newline at end of file
此差异已折叠。
......@@ -9,6 +9,7 @@ import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import EditorCommon = require('vs/editor/common/editorCommon');
import {CursorMoveHelper} from 'vs/editor/common/controller/cursorMoveHelper';
import {getRawEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
export interface IShiftCommandOpts {
isUnshift: boolean;
......@@ -50,19 +51,21 @@ export class ShiftCommand implements EditorCommon.ICommand {
}
public getEditOperations(model: EditorCommon.ITokenizedModel, builder: EditorCommon.IEditOperationBuilder): void {
var startLine = this._selection.startLineNumber,
endLine = this._selection.endLineNumber;
let startLine = this._selection.startLineNumber,
endLine = this._selection.endLineNumber,
_SPACE = ' '.charCodeAt(0);
if (this._selection.endColumn === 1 && startLine !== endLine) {
endLine = endLine - 1;
}
var lineNumber:number,
let lineNumber:number,
tabSize = this._opts.tabSize,
oneIndent = this._opts.oneIndent;
oneIndent = this._opts.oneIndent,
shouldIndentEmptyLines = (startLine === endLine);
// indents[i] represents i * oneIndent
var indents: string[] = ['', oneIndent];
let indents: string[] = ['', oneIndent];
// if indenting or outdenting on a whitespace only line
if (this._selection.isEmpty()) {
......@@ -71,15 +74,21 @@ export class ShiftCommand implements EditorCommon.ICommand {
}
}
for (lineNumber = startLine; lineNumber <= endLine; lineNumber++) {
var lineText = model.getLineContent(lineNumber);
var indentationEndIndex = Strings.firstNonWhitespaceIndex(lineText);
// keep track of previous line's "miss-alignment"
let previousLineExtraSpaces = 0, extraSpaces = 0;
for (lineNumber = startLine; lineNumber <= endLine; lineNumber++, previousLineExtraSpaces = extraSpaces) {
extraSpaces = 0;
let lineText = model.getLineContent(lineNumber);
let indentationEndIndex = Strings.firstNonWhitespaceIndex(lineText);
if (this._opts.isUnshift) {
if (lineText.length === 0 || indentationEndIndex === 0) {
// empty line or line with no leading whitespace => nothing to do
continue;
}
if (this._opts.isUnshift && (lineText.length === 0 || indentationEndIndex === 0)) {
// empty line or line with no leading whitespace => nothing to do
continue;
}
if (!shouldIndentEmptyLines && !this._opts.isUnshift && lineText.length === 0) {
// do not indent empty lines => nothing to do
continue;
}
if (indentationEndIndex === -1) {
......@@ -87,7 +96,45 @@ export class ShiftCommand implements EditorCommon.ICommand {
indentationEndIndex = lineText.length;
}
var desiredIndentCount: number;
if (lineNumber > 1) {
let contentStartVisibleColumn = CursorMoveHelper.visibleColumnFromColumn2(lineText, indentationEndIndex + 1, tabSize);
if (contentStartVisibleColumn % tabSize !== 0) {
// The current line is "miss-aligned", so let's see if this is expected...
// This can only happen when it has trailing commas in the indent
let enterAction = getRawEnterActionAtPosition(model, lineNumber - 1, model.getLineMaxColumn(lineNumber - 1));
if (enterAction) {
extraSpaces = previousLineExtraSpaces;
if (enterAction.appendText) {
for (let j = 0, lenJ = enterAction.appendText.length; j < lenJ && extraSpaces < tabSize; j++) {
if (enterAction.appendText.charCodeAt(j) === _SPACE) {
extraSpaces++;
} else {
break;
}
}
}
if (enterAction.removeText) {
extraSpaces = Math.max(0, extraSpaces - enterAction.removeText);
}
// Act as if `prefixSpaces` is not part of the indentation
for (let j = 0; j < extraSpaces; j++) {
if (indentationEndIndex === 0 || lineText.charCodeAt(indentationEndIndex - 1) !== _SPACE) {
break;
}
indentationEndIndex--;
}
}
}
}
if (this._opts.isUnshift && indentationEndIndex === 0) {
// line with no leading whitespace => nothing to do
continue;
}
let desiredIndentCount: number;
if (this._opts.isUnshift) {
desiredIndentCount = ShiftCommand.unshiftIndentCount(lineText, indentationEndIndex + 1, tabSize);
} else {
......@@ -95,7 +142,7 @@ export class ShiftCommand implements EditorCommon.ICommand {
}
// Fill `indents`, as needed
for (var j = indents.length; j <= desiredIndentCount; j++) {
for (let j = indents.length; j <= desiredIndentCount; j++) {
indents[j] = indents[j-1] + oneIndent;
}
......
......@@ -505,7 +505,7 @@ export class CommonEditorConfiguration extends EventEmitter implements EditorCom
tabSizeIsAuto: false,
tabSize: 4,
insertSpacesIsAuto: false,
insertSpaces: false
insertSpaces: true
};
if (opts.tabSize === 'auto') {
......
......@@ -63,8 +63,8 @@ class ConfigClass implements IConfiguration {
referenceInfos: true,
renderWhitespace: false,
tabSize: 'auto',
insertSpaces: 'auto',
tabSize: 4,
insertSpaces: true,
fontFamily: '',
fontSize: 0,
lineHeight: 0
......
......@@ -15,6 +15,7 @@ import {IEnterAction,IndentAction,IElectricAction} from 'vs/editor/common/modes'
import {CursorMoveHelper, ICursorMoveHelperModel, IMoveResult} from 'vs/editor/common/controller/cursorMoveHelper';
import EditorCommon = require('vs/editor/common/editorCommon');
import Errors = require('vs/base/common/errors');
import {getEnterActionAtPosition} from 'vs/editor/common/modes/supports/onEnter';
export interface IPostOperationRunnable {
(ctx: IOneCursorOperationContext): void;
......@@ -491,23 +492,25 @@ export class OneCursorOp {
// -------------------- START handlers that simply change cursor state
public static jumpToBracket(cursor:OneCursor, ctx: IOneCursorOperationContext): boolean {
var bracketDecorations = cursor.getBracketsDecorations();
var len = bracketDecorations.length;
let bracketDecorations = cursor.getBracketsDecorations();
if (len !== 2) {
if (bracketDecorations.length !== 2) {
return false;
}
var position = cursor.getPosition();
let firstBracket = cursor.model.getDecorationRange(bracketDecorations[0]);
let secondBracket = cursor.model.getDecorationRange(bracketDecorations[1]);
for (var i = 0; i < 2; i++) {
var range = cursor.model.getDecorationRange(bracketDecorations[i]);
var otherRange = cursor.model.getDecorationRange(bracketDecorations[1 - i]);
let position = cursor.getPosition();
if (Utils.isPositionAtRangeEdges(position, range) || Utils.isPositionInsideRange(position, range)) {
cursor.moveModelPosition(false, otherRange.startLineNumber, otherRange.startColumn, 0, false);
return true;
}
if (Utils.isPositionAtRangeEdges(position, firstBracket) || Utils.isPositionInsideRange(position, firstBracket)) {
cursor.moveModelPosition(false, secondBracket.endLineNumber, secondBracket.endColumn, 0, false);
return true;
}
if (Utils.isPositionAtRangeEdges(position, secondBracket) || Utils.isPositionInsideRange(position, secondBracket)) {
cursor.moveModelPosition(false, firstBracket.endLineNumber, firstBracket.endColumn, 0, false);
return true;
}
return false;
......@@ -950,64 +953,6 @@ export class OneCursorOp {
return this._enter(cursor, true, ctx);
}
private static _getEnterActionAtPosition(model:EditorCommon.IModel, lineNumber:number, column:number): { enterAction: IEnterAction; indentation: string; } {
var lineText = model.getLineContent(lineNumber);
var lineContext = model.getLineContext(lineNumber);
var enterAction:IEnterAction;
if (model.getMode().onEnterSupport) {
try {
enterAction = model.getMode().onEnterSupport.onEnter(model, new Position(lineNumber, column));
} catch (e) {
Errors.onUnexpectedError(e);
}
}
if (!enterAction) {
if (model.getMode().electricCharacterSupport) {
try {
enterAction = model.getMode().electricCharacterSupport.onEnter(lineContext, column - 1);
} catch(e) {
Errors.onUnexpectedError(e);
}
}
} else {
// console.log('USING NEW INDENTATION LOGIC!');
}
var indentation = Strings.getLeadingWhitespace(lineText);
if (indentation.length > column - 1) {
indentation = indentation.substring(0, column - 1);
}
if (!enterAction) {
enterAction = {
indentAction: IndentAction.None,
appendText: '',
};
} else {
if(!enterAction.appendText) {
if (
(enterAction.indentAction === IndentAction.Indent) ||
(enterAction.indentAction === IndentAction.IndentOutdent)
) {
enterAction.appendText = '\t';
} else {
enterAction.appendText = '';
}
}
}
if (enterAction.removeText) {
indentation = indentation.substring(0, indentation.length - 1);
}
return {
enterAction: enterAction,
indentation: indentation
};
}
private static _enter(cursor:OneCursor, keepPosition: boolean, ctx: IOneCursorOperationContext, position?: EditorCommon.IEditorPosition, range?: EditorCommon.IEditorRange): boolean {
if (typeof position === 'undefined') {
position = cursor.getPosition();
......@@ -1017,7 +962,7 @@ export class OneCursorOp {
}
ctx.shouldPushStackElementBefore = true;
var r = this._getEnterActionAtPosition(cursor.model, position.lineNumber, position.column);
var r = getEnterActionAtPosition(cursor.model, position.lineNumber, position.column);
var enterAction = r.enterAction;
var indentation = r.indentation;
......@@ -1308,7 +1253,7 @@ export class OneCursorOp {
return '\t';
}
var r = this._getEnterActionAtPosition(cursor.model, lastLineNumber, cursor.model.getLineMaxColumn(lastLineNumber));
var r = getEnterActionAtPosition(cursor.model, lastLineNumber, cursor.model.getLineMaxColumn(lastLineNumber));
var indentation: string;
if (r.enterAction.indentAction === IndentAction.Outdent) {
......
......@@ -490,12 +490,14 @@ export interface ICommonEditorOptions {
export interface IEditorOptions extends ICommonEditorOptions {
/**
* Tab size in spaces. This is used for rendering and for editing.
* Defaults to 'auto', meaning the model attached to the editor will be scanned and this property will be guessed.
* 'auto' means the model attached to the editor will be scanned and this property will be guessed.
* Defaults to 4.
*/
tabSize?:any;
/**
* Insert spaces instead of tabs when indenting or when auto-indenting.
* Defaults to 'auto', meaning the model attached to the editor will be scanned and this property will be guessed.
* 'auto' means the model attached to the editor will be scanned and this property will be guessed.
* Defaults to true.
*/
insertSpaces?:any;
/**
......
......@@ -486,11 +486,11 @@ export class TextModel extends OrderGuaranteeEventEmitter implements EditorCommo
linesIndentedWithSpaces += (absoluteSpaceCounts[i] || 0);
}
// Give preference to tabs over spaces (when evidence is the same)
// Give preference to spaces over tabs (when evidence is the same)
// or when there are not enough clues (too little indentation in the file)
if (linesIndentedWithTabs >= linesIndentedWithSpaces) {
return {
insertSpaces: false,
insertSpaces: true,
tabSize: defaultTabSize
};
}
......@@ -498,7 +498,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements EditorCommo
if (linesWithIndentationCount < 6 && linesIndentedWithTabs > 0) {
// Making a guess with 6 indented lines, of which tabs are used besides spaces is very difficult
return {
insertSpaces: false,
insertSpaces: true,
tabSize: defaultTabSize
};
}
......
......@@ -409,7 +409,7 @@ export interface ISuggestionFilter {
(word: string, suggestion: ISuggestion): IMatch[];
}
export interface ISuggestionSorter {
export interface ISuggestionCompare {
(one: ISuggestion, other: ISuggestion): number;
}
......@@ -429,7 +429,7 @@ export interface ISuggestSupport {
getSuggestionDetails?:(resource:URI, position:EditorCommon.IPosition, suggestion:ISuggestion)=>TPromise<ISuggestion>;
getFilter():ISuggestionFilter;
getSorter?():ISuggestionSorter;
getSorter?():ISuggestionCompare;
getTriggerCharacters():string[];
shouldShowEmptySuggestionList():boolean;
shouldAutotriggerSuggest(context:ILineContext, offset:number, triggeredByCharacter:string):boolean;
......
......@@ -25,15 +25,11 @@ export var ContiguousSubString: ISuggestionFilter = wrapBaseFilter(Filters.match
// Combined Filters
export function or(first: ISuggestionFilter, second: ISuggestionFilter): ISuggestionFilter {
return (word: string, suggestion: ISuggestion): Filters.IMatch[] => {
return first(word, suggestion) || second(word, suggestion);
};
return (word, suggestion) => first(word, suggestion) || second(word, suggestion);
}
export function and(first: ISuggestionFilter, second: ISuggestionFilter): ISuggestionFilter {
return (word: string, suggestion: ISuggestion): Filters.IMatch[] => {
return first(word, suggestion) && second(word, suggestion);
};
return (word, suggestion) => first(word, suggestion) && second(word, suggestion);
}
export var DefaultFilter = or(or(Prefix, CamelCase), ContiguousSubString);
\ No newline at end of file
......@@ -776,7 +776,7 @@ export class SuggestSupport extends AbstractSupport implements Modes.ISuggestSup
return DefaultFilter;
}
public getSorter(): Modes.ISuggestionSorter {
public getSorter(): Modes.ISuggestionCompare {
return (one, other) => {
if (this.sortByType.length > 0) {
var oneTypeIndex = this.sortByType.indexOf(one.type);
......
......@@ -9,6 +9,7 @@ import {IEnterAction, IndentAction, IOnEnterSupport, ILineContext, IMode} from '
import EditorCommon = require('vs/editor/common/editorCommon');
import Errors = require('vs/base/common/errors');
import Strings = require('vs/base/common/strings');
import {Position} from 'vs/editor/common/core/position';
export interface IBracketPair {
open: string;
......@@ -179,3 +180,66 @@ export class OnEnterSupport implements IOnEnterSupport {
}
}
}
export function getRawEnterActionAtPosition(model:EditorCommon.ITokenizedModel, lineNumber:number, column:number): IEnterAction {
let enterAction:IEnterAction;
if (model.getMode().onEnterSupport) {
try {
enterAction = model.getMode().onEnterSupport.onEnter(model, new Position(lineNumber, column));
} catch (e) {
Errors.onUnexpectedError(e);
}
}
if (!enterAction) {
if (model.getMode().electricCharacterSupport) {
let lineContext = model.getLineContext(lineNumber);
try {
enterAction = model.getMode().electricCharacterSupport.onEnter(lineContext, column - 1);
} catch(e) {
Errors.onUnexpectedError(e);
}
}
} else {
// console.log('USING NEW INDENTATION LOGIC!');
}
return enterAction;
}
export function getEnterActionAtPosition(model:EditorCommon.ITokenizedModel, lineNumber:number, column:number): { enterAction: IEnterAction; indentation: string; } {
let lineText = model.getLineContent(lineNumber);
let indentation = Strings.getLeadingWhitespace(lineText);
if (indentation.length > column - 1) {
indentation = indentation.substring(0, column - 1);
}
let enterAction = getRawEnterActionAtPosition(model, lineNumber, column);
if (!enterAction) {
enterAction = {
indentAction: IndentAction.None,
appendText: '',
};
} else {
if(!enterAction.appendText) {
if (
(enterAction.indentAction === IndentAction.Indent) ||
(enterAction.indentAction === IndentAction.IndentOutdent)
) {
enterAction.appendText = '\t';
} else {
enterAction.appendText = '';
}
}
}
if (enterAction.removeText) {
indentation = indentation.substring(0, indentation.length - 1);
}
return {
enterAction: enterAction,
indentation: indentation
};
}
......@@ -73,6 +73,10 @@ class WorkerPluginService extends AbstractPluginService {
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}
export class EditorWorkerServer {
......
......@@ -516,6 +516,16 @@ export class SelectionHighlighter implements EditorCommon.IEditorContribution {
var matches = this.editor.getModel().findMatches(r.searchText, true, r.isRegex, r.matchCase, r.wholeWord);
// do not overlap with selection (issue #64)
let editorSelection = this.editor.getSelection();
matches = matches.filter((m) => {
if (editorSelection.equalsRange(m)) {
return false;
}
return true;
});
var decorations = matches.map(r => {
return {
range: r,
......
......@@ -26,43 +26,31 @@
line-height: 1.3em;
}
.monaco-editor .suggest-widget > .message {
padding-left: 22px;
opacity: 0.7;
}
.monaco-editor .suggest-widget > .tree {
height: 100%;
width: 100%;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content {
-mox-box-sizing: border-box;
box-sizing: border-box;
line-height: 1.2em;
padding: 2px 10px 2px 2px;
padding: 2px 10px 2px 22px;
background-repeat: no-repeat;
background-position: 2px 2px;
white-space: nowrap;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content > * {
float: left;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content:after {
content:"";
clear: both;
display: block;
visibility: hidden;
height: 0;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .text {
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: -ms-calc(100% - 16px);
width: -o-calc(100% - 16px);
width: calc(100% - 16px);
overflow: hidden;
text-overflow: ellipsis;
padding-left: 6px;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
display: none;
max-height: 3.4em;
......@@ -79,15 +67,11 @@
opacity: 1;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
font-weight: bold;
color: #186B9E;
}
.monaco-editor .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
background-color: inherit;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .type-label {
display: none;
margin-left: 0.8em;
......@@ -95,17 +79,19 @@
color: #0035DD;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.fake > .content .type-label,
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.focused > .content .type-label {
display: inline;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.fake > .content .docs,
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.focused > .content .docs {
display: block;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .icon {
position: absolute;
display: block;
left: 1px;
top: 2px;
background-image: url('symbol-sprite.svg');
background-repeat: no-repeat;
height: 16px;
......@@ -150,14 +136,10 @@
border: 1px solid rgb(69, 69, 69);
}
.monaco-editor.vs-dark .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor.vs-dark .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: #219AE4;
}
.monaco-editor.vs-dark .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: inherit;
}
.monaco-editor.vs-dark .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
color: #C07A7A;
}
......@@ -195,14 +177,10 @@
border: 2px solid #6FC3DF;
}
.monaco-editor.hc-black .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor.hc-black .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: #219AE4;
}
.monaco-editor.hc-black .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: inherit;
}
.monaco-editor.hc-black .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
color: #C07A7A;
}
......
......@@ -7,22 +7,22 @@
import nls = require('vs/nls');
import Lifecycle = require('vs/base/common/lifecycle');
import Snippet = require('vs/editor/contrib/snippet/common/snippet');
import SuggestWidget = require('./suggestWidget');
import SuggestModel = require('./suggestModel');
import { SuggestWidget } from './suggestWidget';
import { SuggestModel } from './suggestModel';
import Errors = require('vs/base/common/errors');
import {TPromise} from 'vs/base/common/winjs.base';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions';
import {EditorAction, Behaviour} from 'vs/editor/common/editorAction';
import { TPromise } from 'vs/base/common/winjs.base';
import { EditorBrowserRegistry } from 'vs/editor/browser/editorBrowserExtensions';
import { CommonEditorRegistry, ContextKey, EditorActionDescriptor } from 'vs/editor/common/editorCommonExtensions';
import { EditorAction, Behaviour } from 'vs/editor/common/editorAction';
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import EventEmitter = require('vs/base/common/eventEmitter');
import {IKeybindingService, IKeybindingContextKey} from 'vs/platform/keybinding/common/keybindingService';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {SuggestRegistry, ACCEPT_SELECTED_SUGGESTION_CMD, CONTEXT_SUGGEST_WIDGET_VISIBLE} from 'vs/editor/contrib/suggest/common/suggest';
import {INullService} from 'vs/platform/instantiation/common/instantiation';
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
import { IKeybindingService, IKeybindingContextKey } from 'vs/platform/keybinding/common/keybindingService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { SuggestRegistry, ACCEPT_SELECTED_SUGGESTION_CMD, CONTEXT_SUGGEST_WIDGET_VISIBLE } from 'vs/editor/contrib/suggest/common/suggest';
import { IInstantiationService, INullService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
export class SuggestController implements EditorCommon.IEditorContribution {
static ID = 'editor.contrib.suggestController';
......@@ -31,32 +31,25 @@ export class SuggestController implements EditorCommon.IEditorContribution {
return <SuggestController>editor.getContribution(SuggestController.ID);
}
private editor:EditorBrowser.ICodeEditor;
private model:SuggestModel.SuggestModel;
private suggestWidget: SuggestWidget.SuggestWidget;
private toDispose: Lifecycle.IDisposable[];
private model: SuggestModel;
private widget: SuggestWidget;
private triggerCharacterListeners: Function[];
private suggestWidgetVisible: IKeybindingContextKey<boolean>;
private toDispose: Lifecycle.IDisposable[];
constructor(editor:EditorBrowser.ICodeEditor, @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService) {
this.editor = editor;
constructor(
private editor:EditorBrowser.ICodeEditor,
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService instantiationService: IInstantiationService
) {
this.suggestWidgetVisible = keybindingService.createKey(CONTEXT_SUGGEST_WIDGET_VISIBLE, false);
this.model = new SuggestModel.SuggestModel(this.editor, (snippet:Snippet.CodeSnippet, overwriteBefore:number, overwriteAfter:number) => {
Snippet.get(this.editor).run(snippet, overwriteBefore, overwriteAfter);
});
this.suggestWidget = new SuggestWidget.SuggestWidget(this.editor, telemetryService, keybindingService, () => {
this.suggestWidgetVisible.set(true);
}, () => {
this.suggestWidgetVisible.reset();
});
this.suggestWidget.setModel(this.model);
this.model = new SuggestModel(this.editor);
this.widget = instantiationService.createInstance(SuggestWidget, this.editor, this.model);
this.triggerCharacterListeners = [];
this.toDispose = [];
this.toDispose.push(this.widget.onDidVisibilityChange(visible => visible ? this.suggestWidgetVisible.set(true) : this.suggestWidgetVisible.reset()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ConfigurationChanged, () => this.update()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ModelChanged, () => this.update()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ModelModeChanged, () => this.update()));
......@@ -67,6 +60,9 @@ export class SuggestController implements EditorCommon.IEditorContribution {
}));
this.toDispose.push(SuggestRegistry.onDidChange(this.update, this));
// TODO@Joao: what is this?
this.toDispose.push(this.model.onDidAccept(e => Snippet.get(this.editor).run(e.snippet, e.overwriteBefore, e.overwriteAfter)));
this.update();
}
......@@ -78,12 +74,12 @@ export class SuggestController implements EditorCommon.IEditorContribution {
this.toDispose = Lifecycle.disposeAll(this.toDispose);
this.triggerCharacterListeners = Lifecycle.cAll(this.triggerCharacterListeners);
if (this.suggestWidget) {
this.suggestWidget.destroy();
this.suggestWidget = null;
if (this.widget) {
this.widget.dispose();
this.widget = null;
}
if (this.model) {
this.model.destroy();
this.model.dispose();
this.model = null;
}
}
......@@ -160,38 +156,38 @@ export class SuggestController implements EditorCommon.IEditorContribution {
}
public acceptSelectedSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.acceptSelectedSuggestion();
if (this.widget) {
this.widget.acceptSelectedSuggestion();
}
}
public hideSuggestWidget(): void {
if (this.suggestWidget) {
this.suggestWidget.cancel();
if (this.widget) {
this.widget.cancel();
}
}
public selectNextSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectNext();
if (this.widget) {
this.widget.selectNext();
}
}
public selectNextPageSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectNextPage();
if (this.widget) {
this.widget.selectNextPage();
}
}
public selectPrevSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectPrevious();
if (this.widget) {
this.widget.selectPrevious();
}
}
public selectPrevPageSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectPreviousPage();
if (this.widget) {
this.widget.selectPreviousPage();
}
}
}
......
......@@ -11,6 +11,8 @@ import EditorCommon = require('vs/editor/common/editorCommon');
import {withEditorModel} from 'vs/editor/test/common/editorTestUtils';
import {Selection} from 'vs/editor/common/core/selection';
import {Cursor} from 'vs/editor/common/controller/cursor';
import * as Modes from 'vs/editor/common/modes';
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
function testShiftCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
TU.testCommand(lines, null, selection, (sel) => new ShiftCommand(sel, {
......@@ -28,6 +30,69 @@ function testUnshiftCommand(lines: string[], selection: Selection, expectedLines
}), expectedLines, expectedSelection);
}
class DocBlockCommentMode implements Modes.IMode {
public onEnterSupport: Modes.IOnEnterSupport;
constructor() {
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '(', close: ')' },
{ open: '{', close: '}' },
{ open: '[', close: ']' }
],
regExpRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
action: { indentAction: Modes.IndentAction.IndentOutdent, appendText: ' * ' }
},
{
// e.g. /** ...|
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
action: { indentAction: Modes.IndentAction.None, appendText: ' * ' }
},
{
// e.g. * ...|
beforeText: /^(\t|(\ \ ))*\ \*\ ([^\*]|\*(?!\/))*$/,
action: { indentAction: Modes.IndentAction.None, appendText: '* ' }
},
{
// e.g. */|
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
action: { indentAction: Modes.IndentAction.None, removeText: 1 }
}
]
});
}
public getId(): string {
return 'docBlockCommentMode';
}
public toSimplifiedMode(): Modes.IMode {
return this;
}
}
function testShiftCommandInDocBlockCommentMode(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
TU.testCommand(lines, new DocBlockCommentMode(), selection, (sel) => new ShiftCommand(sel, {
isUnshift: false,
tabSize: 4,
oneIndent: '\t'
}), expectedLines, expectedSelection);
}
function testUnshiftCommandInDocBlockCommentMode(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
TU.testCommand(lines, new DocBlockCommentMode(), selection, (sel) => new ShiftCommand(sel, {
isUnshift: true,
tabSize: 4,
oneIndent: '\t'
}), expectedLines, expectedSelection);
}
suite('Editor Commands - ShiftCommand', () => {
// --------- shift
......@@ -212,10 +277,50 @@ suite('Editor Commands - ShiftCommand', () => {
'My First Line',
'\t\tMy Second Line',
' Third Line',
'\t',
'',
'\t123'
],
new Selection(4, 2, 5, 3)
new Selection(4, 1, 5, 3)
);
});
test('issue #1120 TAB should not indent empty lines in a multi-line selection', () => {
testShiftCommand(
[
'My First Line',
'\t\tMy Second Line',
' Third Line',
'',
'123'
],
new Selection(1, 1, 5, 2),
[
'\tMy First Line',
'\t\t\tMy Second Line',
'\t\tThird Line',
'',
'\t123'
],
new Selection(1, 2, 5, 3)
);
testShiftCommand(
[
'My First Line',
'\t\tMy Second Line',
' Third Line',
'',
'123'
],
new Selection(4, 1, 5, 1),
[
'My First Line',
'\t\tMy Second Line',
' Third Line',
'\t',
'123'
],
new Selection(4, 2, 5, 1)
);
});
......@@ -399,7 +504,7 @@ suite('Editor Commands - ShiftCommand', () => {
'\tMy First Line',
'\tMy Second Line',
'\tThird Line',
'\t',
'',
'\t123'
],
new Selection(1, 2, 5, 5)
......@@ -427,6 +532,65 @@ suite('Editor Commands - ShiftCommand', () => {
);
});
test('issue #348: indenting around doc block comments', () => {
testShiftCommandInDocBlockCommentMode(
[
'',
'/**',
' * a doc comment',
' */',
'function hello() {}'
],
new Selection(1,1,5,20),
[
'',
'\t/**',
'\t * a doc comment',
'\t */',
'\tfunction hello() {}'
],
new Selection(1,1,5,21)
);
testUnshiftCommandInDocBlockCommentMode(
[
'',
'/**',
' * a doc comment',
' */',
'function hello() {}'
],
new Selection(1,1,5,20),
[
'',
'/**',
' * a doc comment',
' */',
'function hello() {}'
],
new Selection(1,1,5,20)
);
testUnshiftCommandInDocBlockCommentMode(
[
'\t',
'\t/**',
'\t * a doc comment',
'\t */',
'\tfunction hello() {}'
],
new Selection(1,1,5,21),
[
'',
'/**',
' * a doc comment',
' */',
'function hello() {}'
],
new Selection(1,1,5,20)
);
});
test('bug #16815:Shift+Tab doesn\'t go back to tabstop', () => {
var repeatStr = (str:string, cnt:number): string => {
......
......@@ -756,7 +756,10 @@ suite('Editor Controller - Cursor', () => {
test('Bug 9121: Auto indent + undo + redo is funky', () => {
var model = new Model.Model('', thisHighlighter);
var cursor = new Cursor.Cursor(1, new MockConfiguration(null), model, null, false);
var cursor = new Cursor.Cursor(1, new MockConfiguration({
tabSize: 4,
insertSpaces: false
}), model, null, false);
cursorCommand(cursor, H.Type, { text: '\n' }, null, 'keyboard');
assert.equal(model.getValue(EditorCommon.EndOfLinePreference.LF), '\n', 'assert1');
......@@ -811,6 +814,31 @@ suite('Editor Controller - Cursor Configuration', () => {
var thisHighlighter = new ModelModes.CursorMode();
test('issue #183: jump to matching bracket position', () => {
let mode = new ModelModes.BracketMode();
let model = new Model.Model([
'var x = (3 + (5-7));'
].join('\n'), mode);
let cursor = new Cursor.Cursor(1, new MockConfiguration(null), model, null, false);
// ensure is tokenized
model.getLineContext(1);
moveTo(cursor, 1, 20);
cursorCommand(cursor, H.JumpToBracket, null, null, 'keyboard');
cursorEqual(cursor, 1, 10);
cursorCommand(cursor, H.JumpToBracket, null, null, 'keyboard');
cursorEqual(cursor, 1, 20);
cursorCommand(cursor, H.JumpToBracket, null, null, 'keyboard');
cursorEqual(cursor, 1, 10);
cursor.dispose();
model.dispose();
});
test('Cursor honors insertSpaces configuration on new line', () => {
var text = ' \tMy First Line\t \n' + '\tMy Second Line\n' + ' Third Line\n' + '\n' + '1';
var model = new Model.Model(text, thisHighlighter);
......
......@@ -11,14 +11,14 @@ import Position = require('vs/editor/common/core/position');
function testGuessIndentation(expectedInsertSpaces:boolean, expectedTabSize:number, text:string[], msg?:string): void {
var m = new TextModel.TextModel([], TextModel.TextModel.toRawText(text.join('\n')));
var r = m.guessIndentation(1773);
var r = m.guessIndentation(1337);
m.dispose();
assert.equal(r.insertSpaces, expectedInsertSpaces, msg);
if (expectedInsertSpaces) {
assert.equal(r.tabSize, expectedTabSize, msg);
} else {
assert.equal(r.tabSize, 1773, msg);
assert.equal(r.tabSize, 1337, msg);
}
}
......@@ -64,26 +64,26 @@ suite('Editor Model - TextModel', () => {
test('guess indentation 1', () => {
// Defaults to tabs
guessesTabs([
guessesSpaces(1337, [
'x',
'x'
]);
// Gives preference to tabs
guessesTabs([
guessesSpaces(1337, [
'\tx',
'x'
]);
guessesTabs([
guessesSpaces(1337, [
'\tx',
' x'
]);
guessesTabs([
guessesSpaces(1337, [
'\tx',
' x'
]);
guessesTabs([
guessesSpaces(1337, [
'x',
' x',
' x',
......@@ -93,7 +93,7 @@ suite('Editor Model - TextModel', () => {
' x',
' x'
], '7x1 - 1 space is never guessed as an indentation');
guessesTabs([
guessesSpaces(1337, [
'',
' ',
' ',
......
......@@ -123,6 +123,10 @@ class MockPluginService extends AbstractPluginService {
console.log(msg);
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}
class MockModelService extends ModelServiceImpl {}
......
......@@ -51,19 +51,7 @@ configurationRegistry.registerConfiguration({
'description': nls.localize('jsonConfiguration.schema', "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL."),
},
}
},
'default' : [
{ 'fileMatch': [ '/bower.json', '/.bower.json' ], 'url': 'http://json.schemastore.org/bower' },
{ 'fileMatch': [ '/package.json' ], 'url': 'http://json.schemastore.org/package' },
{ 'fileMatch': [ '/project.json' ], 'url': 'http://json.schemastore.org/project' },
{ 'fileMatch': [ '*.schema.json' ], 'url': 'http://json-schema.org/draft-04/schema#' },
{ 'fileMatch': [ '/global.json' ], 'url': 'http://json.schemastore.org/global' },
{ 'fileMatch': [ '/tsconfig.json'], 'url': 'http://json.schemastore.org/tsconfig' },
{ 'fileMatch': [ '/jsconfig.json' ], 'url': 'http://opentools.azurewebsites.net/jsconfig' },
{ 'fileMatch': [ '/.bowerrc' ], 'url': 'http://json.schemastore.org/bowerrc' },
{ 'fileMatch': [ '/.jshintrc' ], 'url': 'http://json.schemastore.org/jshintrc' },
{ 'fileMatch': [ '/.jscsrc' ], 'url': 'http://json.schemastore.org/jscsrc' }
]
}
}
}
});
\ No newline at end of file
......@@ -20,7 +20,7 @@ import {OneWorkerAttr, AllWorkersAttr} from 'vs/platform/thread/common/threadSer
import {IThreadService, IThreadSynchronizableObject} from 'vs/platform/thread/common/thread';
import {AsyncDescriptor2, createAsyncDescriptor2} from 'vs/platform/instantiation/common/descriptors';
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IJSONContributionRegistry, Extensions, ISchemaContributions} from 'vs/languages/json/common/jsonContributionRegistry';
import {IJSONContributionRegistry, Extensions, ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Modes.IExtraInfoSupport, Modes.IOutlineSupport, IThreadSynchronizableObject<ISchemaContributions> {
......
......@@ -29,7 +29,7 @@ import errors = require('vs/base/common/errors');
import {IMarkerService, IMarkerData} from 'vs/platform/markers/common/markers';
import {IRequestService} from 'vs/platform/request/common/request';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {ISchemaContributions} from 'vs/languages/json/common/jsonContributionRegistry';
import {ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IResourceService} from 'vs/editor/common/services/resourceService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
......
......@@ -50,8 +50,7 @@ suite('JSON - Worker', () => {
if (schema) {
var id = "http://myschemastore/test1";
var schemaService = <SchemaService.JSONSchemaService> (<any>worker).schemaService;
schemaService.addPreloadedFileSchema(id, schema);
schemaService.registerExternalSchema(id, [ "*.json" ]);
schemaService.registerExternalSchema(id, [ "*.json" ], schema);
}
}
......
......@@ -12,7 +12,7 @@ import objects = require('vs/base/common/objects');
import strings = require('vs/base/common/strings');
import {IPluginDescription} from 'vs/platform/plugins/common/plugins';
import {PluginsRegistry} from 'vs/platform/plugins/common/pluginsRegistry';
import JSONContributionRegistry = require('vs/languages/json/common/jsonContributionRegistry');
import JSONContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
export var Extensions = {
......
/*---------------------------------------------------------------------------------------------
* 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 nls = require('vs/nls');
import {IJSONSchema} from 'vs/base/common/jsonSchema';
import {PluginsRegistry} from 'vs/platform/plugins/common/pluginsRegistry';
import {Registry} from 'vs/platform/platform';
import JSONContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
import strings = require('vs/base/common/strings');
import paths = require('vs/base/common/paths');
import {INullService} from 'vs/platform/instantiation/common/instantiation';
interface IJSONValidationExtensionPoint {
fileMatch: string,
url: string
}
let schemaRegistry = <JSONContributionRegistry.IJSONContributionRegistry>Registry.as(JSONContributionRegistry.Extensions.JSONContribution);
let configurationExtPoint = PluginsRegistry.registerExtensionPoint<IJSONValidationExtensionPoint[]>('jsonValidation', {
description: nls.localize('contributes.jsonValidation', 'Contributes json schema configuration.'),
type: 'array',
default: [ { fileMatch: "{{file.json}}", url: "{{url}}" } ],
items: {
type: 'object',
default: { fileMatch: "{{file.json}}", url: "{{url}}" },
properties: {
fileMatch: {
type: 'string',
description: nls.localize('contributes.jsonValidation.fileMatch', 'The file pattern to match, for example "package.json" or "*.launch".'),
},
url: {
description: nls.localize('contributes.jsonValidation.url', 'A schema URL (\'http:\', \'https:\') or relative path to the extension folder (\'./\').'),
type: 'string'
}
}
}
});
export class JSONValidationExtensionPoint {
constructor(
@INullService modeService: INullService
) {
configurationExtPoint.setHandler((extensions) => {
for (var i = 0; i < extensions.length; i++) {
var extensionValue = <IJSONValidationExtensionPoint[]> extensions[i].value;
var collector = extensions[i].collector;
var extensionPath = extensions[i].description.extensionFolderPath;
if (!extensionValue || !Array.isArray(extensionValue)) {
collector.error(nls.localize('invalid.jsonValidation', "'configuration.jsonValidation' must be a array"));
return;
}
extensionValue.forEach(extension => {
if (typeof extension.fileMatch !== 'string') {
collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined"));
return;
}
var uri = extension.url;
if (typeof extension.url !== 'string') {
collector.error(nls.localize('invalid.url', "'configuration.jsonValidation.url' must be a URL or relative path"));
return;
}
if (strings.startsWith(uri, './')) {
uri = paths.normalize(paths.join(extensionPath, uri));
} else if (!strings.startsWith(uri, 'https:/') && strings.startsWith(uri, 'https:/')) {
collector.error(nls.localize('invalid.url.schema', "'configuration.jsonValidation.url' must start with 'http:', 'https:' or './' to reference schemas located in the extension"));
return;
}
var fileMatch = extension.fileMatch;
if (!strings.startsWith(extension.fileMatch, '/')) {
fileMatch = '/' + fileMatch;
}
schemaRegistry.addSchemaFileAssociation(fileMatch, uri);
});
}
});
}
}
/*---------------------------------------------------------------------------------------------
* 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 {IDisposable} from 'vs/base/common/lifecycle';
import Event, {Emitter} from 'vs/base/common/event';
export class ApiCommands {
static Instance = new ApiCommands();
private _commands: { [id: string]: [(...args: any[]) => any, any] } = Object.create(null);
private _onDidAddCommand = new Emitter<{ id: string; handler: (...args: any[]) => any; thisArg?: any }>();
add(id: string, handler: (...args: any[]) => any, thisArg?: any) {
if (this._commands[id]) {
throw new Error();
}
this._commands[id] = [handler, thisArg];
this._onDidAddCommand.fire({ id, handler, thisArg });
}
track(callback: (event: { id: string; handler: (...args: any[]) => any; thisArg?: any }) => any): IDisposable {
for (let id in this._commands) {
let [handler, thisArg] = this._commands[id];
callback({ id, handler, thisArg });
}
return this._onDidAddCommand.event(callback);
}
}
export function addApiCommand(id: string, handler: (...args: any[]) => any, thisArg?: any) {
ApiCommands.Instance.add(id, handler, thisArg);
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ import {Registry} from 'vs/platform/platform';
import {ICommandHandler, ICommandsMap, IKeybindingItem, IKeybindings, IKeybindingContextRule} from 'vs/platform/keybinding/common/keybindingService';
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import {KeyMod, KeyCode, BinaryKeybindings} from 'vs/base/common/keyCodes';
import {ApiCommands} from 'vs/platform/keybinding/common/commands';
import Platform = require('vs/base/common/platform');
export interface ICommandRule extends IKeybindings {
......@@ -68,17 +67,6 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
constructor() {
this._keybindings = [];
this._commands = Object.create(null);
ApiCommands.Instance.track(event => {
this.registerCommandDesc({
id: event.id,
handler: function(accessor, args) {
event.handler.apply(event.thisArg, args);
},
weight: this.WEIGHT.externalExtension(0),
context: undefined,
primary: undefined
});
});
}
public registerCommandRule(rule:ICommandRule): void {
......
......@@ -5,7 +5,7 @@
'use strict';
import nls = require('vs/nls');
import {IPluginDescription, IPluginService, IMessage, IPointListener, IActivationEventListener } from 'vs/platform/plugins/common/plugins';
import {IPluginDescription, IPluginService, IMessage, IPointListener, IActivationEventListener, IPluginStatus } from 'vs/platform/plugins/common/plugins';
import WinJS = require('vs/base/common/winjs.base');
import {IDisposable} from 'vs/base/common/lifecycle';
import Errors = require('vs/base/common/errors');
......@@ -21,8 +21,8 @@ export interface IPluginExports {
}
export interface IPluginModule {
activate(subscriptions: IDisposable[]): WinJS.TPromise<IPluginExports>;
deactivate(callback:(err:any, success:boolean)=>void): void;
activate(ctx: IPluginContext): WinJS.TPromise<IPluginExports>;
deactivate(): void;
}
export interface IPluginContext {
......@@ -83,6 +83,7 @@ export abstract class AbstractPluginService implements IPluginService {
this.activatedPlugins = {};
}
public abstract deactivate(pluginId:string): void;
protected abstract _showMessage(severity:Severity, message:string): void;
protected showMessage(severity:Severity, source:string, message:string): void {
......@@ -111,6 +112,10 @@ export abstract class AbstractPluginService implements IPluginService {
return this.activatedPlugins[pluginId].exports;
}
public getPluginsStatus(): { [id: string]: IPluginStatus } {
return null;
}
public isActivated(pluginId:string): boolean {
return hasOwnProperty.call(this.activatedPlugins, pluginId);
}
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {IPluginDescription, IMessage} from 'vs/platform/plugins/common/plugins';
import {IPluginDescription, IMessage, IPluginStatus} from 'vs/platform/plugins/common/plugins';
import {PluginsRegistry} from 'vs/platform/plugins/common/pluginsRegistry';
import WinJS = require('vs/base/common/winjs.base');
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
......@@ -15,6 +15,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {PluginHostStorage} from 'vs/platform/storage/common/remotable.storage';
import * as paths from 'vs/base/common/paths';
import {IWorkspaceContextService, IConfiguration} from 'vs/platform/workspace/common/workspace';
import {disposeAll} from 'vs/base/common/lifecycle';
class PluginMemento implements IPluginMemento {
......@@ -64,6 +65,7 @@ export class MainProcessPluginService extends AbstractPluginService {
private _telemetryService: ITelemetryService;
private _proxy: PluginHostPluginService;
private _isDev: boolean;
private _pluginsStatus: { [id: string]: IPluginStatus };
/**
* This class is constructed manually because it is a service, so it doesn't use any ctor injection
......@@ -83,8 +85,13 @@ export class MainProcessPluginService extends AbstractPluginService {
this._threadService = threadService;
this._telemetryService = telemetryService;
this._proxy = this._threadService.getRemotable(PluginHostPluginService);
this._pluginsStatus = {};
PluginsRegistry.handleExtensionPoints((severity, source, message) => {
if (!this._pluginsStatus[source]) {
this._pluginsStatus[source] = { messages: [] };
}
this._pluginsStatus[source].messages.push({ type: severity, source, message });
this.showMessage(severity, source, message);
});
}
......@@ -158,6 +165,14 @@ export class MainProcessPluginService extends AbstractPluginService {
}
}
public getPluginsStatus(): { [id: string]: IPluginStatus } {
return this._pluginsStatus;
}
public deactivate(pluginId:string): void {
this._proxy.deactivate(pluginId);
}
// -- overwriting AbstractPluginService
protected _actualActivatePlugin(pluginDescription: IPluginDescription): WinJS.TPromise<ActivatedPlugin> {
......@@ -222,6 +237,28 @@ export class PluginHostPluginService extends AbstractPluginService {
}
}
public deactivate(pluginId:string): void {
let plugin = this.activatedPlugins[pluginId];
if (!plugin) {
return;
}
// call deactivate if available
try {
if (typeof plugin.module.deactivate === 'function') {
plugin.module.deactivate();
}
} catch(err) {
// TODO: Do something with err if this is not the shutdown case
}
// clean up subscriptions
try {
disposeAll(plugin.subscriptions)
} catch(err) {
// TODO: Do something with err if this is not the shutdown case
}
}
// -- overwriting AbstractPluginService
......
......@@ -40,18 +40,38 @@ export interface IMessage {
source: string;
}
export interface IPluginStatus {
messages: IMessage[];
}
export interface IPluginService {
serviceId: ServiceIdentifier<any>;
activateByEvent(activationEvent:string): TPromise<any>;
activateAndGet(pluginId:string): TPromise<any>;
activateAndGet<T>(pluginId:string): TPromise<T>;
isActivated(pluginId:string): boolean;
/**
* This method should be called only on shutdown!
* More work is needed for this to be called any time!
*/
deactivate(pluginId:string): void;
/**
* To be used only by the platform once on startup.
*/
registrationDone(errors?:IMessage[]): void;
registerOneTimeActivationEventListener(activationEvent: string, listener: IActivationEventListener): void;
get(pluginId:string): any;
/**
* Block on this signal any interactions with extensions.
*/
onReady(): TPromise<boolean>;
getPluginsStatus(): { [id: string]: IPluginStatus };
}
export var INSTANCE:IPluginService = null;
\ No newline at end of file
......@@ -8,7 +8,7 @@ import {IPluginDescription, IPointListener, IActivationEventListener, IMessage}
import {Registry} from 'vs/platform/platform';
import Errors = require('vs/base/common/errors');
import env = require('vs/base/common/flags');
import * as JSONContributionRegistry from 'vs/languages/json/common/jsonContributionRegistry';
import * as JSONContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IJSONSchema} from 'vs/base/common/jsonSchema';
import nls = require('vs/nls');
import paths = require('vs/base/common/paths');
......
......@@ -35,7 +35,6 @@ import {NavigateTypesSupportRegistry, INavigateTypesSupport, ITypeBearing} from
import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename';
import {FormatRegistry, FormatOnTypeRegistry} from 'vs/editor/contrib/format/common/format';
import {ICodeLensData} from 'vs/editor/contrib/codelens/common/codelens';
import {addApiCommand} from 'vs/platform/keybinding/common/commands';
export class ExtHostLanguageFeatureCommands {
......@@ -45,24 +44,28 @@ export class ExtHostLanguageFeatureCommands {
constructor(commands: PluginHostCommands) {
this._commands = commands;
addApiCommand('vscode.executeWorkspaceSymbolProvider', this._executeWorkspaceSymbolProvider, this);
addApiCommand('vscode.executeDefinitionProvider', this._executeDefinitionProvider, this);
addApiCommand('vscode.executeHoverProvider', this._executeHoverProvider, this);
addApiCommand('vscode.executeDocumentHighlights', this._executeDocumentHighlights, this);
addApiCommand('vscode.executeReferenceProvider', this._executeReferenceProvider, this);
addApiCommand('vscode.executeDocumentRenameProvider', this._executeDocumentRenameProvider, this);
addApiCommand('vscode.executeSignatureHelpProvider', this._executeSignatureHelpProvider, this);
addApiCommand('vscode.executeDocumentSymbolProvider', this._executeDocumentSymbolProvider, this);
addApiCommand('vscode.executeCompletionItemProvider', this._executeCompletionItemProvider, this);
addApiCommand('vscode.executeCodeActionProvider', this._executeCodeActionProvider, this);
addApiCommand('vscode.executeCodeLensProvider', this._executeCodeLensProvider, this);
addApiCommand('vscode.executeFormatDocumentProvider', this._executeFormatDocumentProvider, this);
addApiCommand('vscode.executeFormatRangeProvider', this._executeFormatRangeProvider, this);
addApiCommand('vscode.executeFormatOnTypeProvider', this._executeFormatOnTypeProvider, this);
this._register('vscode.executeWorkspaceSymbolProvider', this._executeWorkspaceSymbolProvider);
this._register('vscode.executeDefinitionProvider', this._executeDefinitionProvider);
this._register('vscode.executeHoverProvider', this._executeHoverProvider);
this._register('vscode.executeDocumentHighlights', this._executeDocumentHighlights);
this._register('vscode.executeReferenceProvider', this._executeReferenceProvider);
this._register('vscode.executeDocumentRenameProvider', this._executeDocumentRenameProvider);
this._register('vscode.executeSignatureHelpProvider', this._executeSignatureHelpProvider);
this._register('vscode.executeDocumentSymbolProvider', this._executeDocumentSymbolProvider);
this._register('vscode.executeCompletionItemProvider', this._executeCompletionItemProvider);
this._register('vscode.executeCodeActionProvider', this._executeCodeActionProvider);
this._register('vscode.executeCodeLensProvider', this._executeCodeLensProvider);
this._register('vscode.executeFormatDocumentProvider', this._executeFormatDocumentProvider);
this._register('vscode.executeFormatRangeProvider', this._executeFormatRangeProvider);
this._register('vscode.executeFormatOnTypeProvider', this._executeFormatOnTypeProvider);
}
// --- command impl
private _register(id: string, handler: (...args: any[]) => any): void {
this._disposables.push(this._commands.registerCommand(id, handler, this));
}
/**
* Execute workspace symbol provider.
*
......
......@@ -15,7 +15,6 @@ import {PluginHostEditors} from 'vs/workbench/api/common/pluginHostEditors';
import {IMessageService, Severity} from 'vs/platform/message/common/message';
import {canSerialize} from 'vs/base/common/marshalling';
import {toErrorMessage} from 'vs/base/common/errors';
import {ApiCommands} from 'vs/platform/keybinding/common/commands';
import * as vscode from 'vscode';
@Remotable.PluginHostContext('PluginHostCommands')
......@@ -28,11 +27,6 @@ export class PluginHostCommands {
constructor(@IThreadService threadService: IThreadService) {
this._pluginHostEditors = threadService.getRemotable(PluginHostEditors);
this._proxy = threadService.getRemotable(MainThreadCommands);
ApiCommands.Instance.track(event => {
let {id, handler, thisArg} = event;
this.registerCommand(id, handler, thisArg);
});
}
registerCommand(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
......
......@@ -55,6 +55,7 @@ import {MainProcessPluginService} from 'vs/platform/plugins/common/nativePluginS
import {MainThreadDocuments} from 'vs/workbench/api/common/pluginHostDocuments';
import {MainProcessTextMateSyntax} from 'vs/editor/node/textMate/TMSyntax';
import {MainProcessTextMateSnippet} from 'vs/editor/node/textMate/TMSnippets';
import {JSONValidationExtensionPoint} from 'vs/platform/jsonschemas/common/jsonValidationExtensionPoint';
import {LanguageConfigurationFileHandler} from 'vs/editor/node/languageConfiguration';
import {MainThreadFileSystemEventService} from 'vs/workbench/api/common/pluginHostFileSystemEventService';
import {MainThreadQuickOpen} from 'vs/workbench/api/browser/pluginHostQuickOpen';
......@@ -355,6 +356,7 @@ export class WorkbenchShell {
this.threadService.getRemotable(RemoteTelemetryServiceHelper);
this.workbench.getInstantiationService().createInstance(MainProcessTextMateSyntax);
this.workbench.getInstantiationService().createInstance(MainProcessTextMateSnippet);
this.workbench.getInstantiationService().createInstance(JSONValidationExtensionPoint);
this.workbench.getInstantiationService().createInstance(LanguageConfigurationFileHandler);
this.threadService.getRemotable(MainThreadConfiguration);
this.threadService.getRemotable(MainThreadQuickOpen);
......
......@@ -822,8 +822,7 @@ export class WindowsManager {
if (paths && paths.length > 0) {
// Remember path in storage for next time
let pathToRemember = isFolder ? paths[0] : path.dirname(paths[0]);
storage.setItem(WindowsManager.workingDirPickerStorageKey, pathToRemember);
storage.setItem(WindowsManager.workingDirPickerStorageKey, path.dirname(paths[0]));
// Return
clb(paths);
......
......@@ -104,16 +104,45 @@ interface ITestRunner {
export class PluginHostMain {
private _isTerminating: boolean;
constructor(
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IPluginService private pluginService: IPluginService,
@IInstantiationService instantiationService: IInstantiationService
) {}
) {
this._isTerminating = false;
}
public start(): TPromise<void> {
return this.readPlugins();
}
public terminate(): void {
if (this._isTerminating) {
// we are already shutting down...
return;
}
this._isTerminating = true;
try {
let allExtensions = PluginsRegistry.getAllPluginDescriptions();
let allExtensionsIds = allExtensions.map(ext => ext.id);
let activatedExtensions = allExtensionsIds.filter(id => this.pluginService.isActivated(id));
activatedExtensions.forEach((extensionId) => {
this.pluginService.deactivate(extensionId);
});
} catch(err) {
// TODO: write to log once we have one
}
// Give extensions 1 second to wrap up any async dispose, then exit
setTimeout(() => {
exit()
}, 1000);
}
private readPlugins(): TPromise<void> {
let collector = new PluginsMessageCollector();
let env = this.contextService.getConfiguration().env;
......
......@@ -16,8 +16,14 @@ interface IRendererConnection {
initData: IInitData;
}
// This calls exit directly in case the initialization is not finished and we need to exit
// Otherwise, if initialization completed we go to pluginHostMain.terminate()
var onTerminate = function() {
exit();
};
function connectToRenderer(): TPromise<IRendererConnection> {
return new TPromise((c, e) => {
return new TPromise<IRendererConnection>((c, e) => {
const stats: number[] = [];
// Listen init data message
......@@ -28,7 +34,13 @@ function connectToRenderer(): TPromise<IRendererConnection> {
});
// Listen to all other messages
process.on('message', msg => remoteCom.handle(msg));
process.on('message', (msg) => {
if (msg.type === '__$terminate') {
onTerminate();
return;
}
remoteCom.handle(msg);
});
// Print a console message when rejection isn't handled. For details
// see https://nodejs.org/api/process.html#process_event_unhandledrejection
......@@ -50,7 +62,7 @@ function connectToRenderer(): TPromise<IRendererConnection> {
try {
process.kill(msg.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
} catch (e) {
exit();
onTerminate();
}
}, 5000);
......@@ -86,6 +98,10 @@ TPromise.join<any>([connectToRenderer(), connectToSharedProcess()])
const instantiationService = createServices(renderer.remoteCom, renderer.initData, sharedProcessClient);
const pluginHostMain = instantiationService.createInstance(PluginHostMain);
onTerminate = () => {
pluginHostMain.terminate();
};
pluginHostMain.start()
.done(null, err => console.error(err));
});
\ No newline at end of file
......@@ -55,8 +55,6 @@ export interface IOptions {
}
export function getProxyAgent(rawRequestURL: string, options: IOptions = {}): any {
console.log(rawRequestURL, options);
if (!options.proxyUrl) {
return getSystemProxyAgent(rawRequestURL);
}
......
......@@ -6,7 +6,7 @@
import lifecycle = require('vs/base/common/lifecycle');
import editorcommon = require('vs/editor/common/editorCommon');
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IDebugService, ModelEvents, ViewModelEvents, IBreakpoint, IRawBreakpoint } from 'vs/workbench/parts/debug/common/debug';
import { IDebugService, ModelEvents, ViewModelEvents, IBreakpoint, IRawBreakpoint, State } from 'vs/workbench/parts/debug/common/debug';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IModelService } from 'vs/editor/common/services/modelService';
......@@ -254,10 +254,11 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
private createBreakpointDecorations(breakpoints: IBreakpoint[]): editorcommon.IModelDeltaDecoration[] {
const activated = this.debugService.getModel().areBreakpointsActivated();
const debugActive = this.debugService.getState() === State.Running || this.debugService.getState() === State.Stopped;
return breakpoints.map((breakpoint) => {
return {
options: (!breakpoint.enabled || !activated) ? DebugEditorModelManager.BREAKPOINT_DISABLED_DECORATION :
breakpoint.verified ? DebugEditorModelManager.BREAKPOINT_VERIFIED_DECORATION : DebugEditorModelManager.BREAKPOINT_DECORATION,
debugActive && !breakpoint.verified ? DebugEditorModelManager.BREAKPOINT_UNVERIFIED_DECORATION : DebugEditorModelManager.BREAKPOINT_DECORATION,
range: createRange(breakpoint.lineNumber, 1, breakpoint.lineNumber, 2)
};
});
......@@ -275,8 +276,8 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
stickiness: editorcommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges
};
private static BREAKPOINT_VERIFIED_DECORATION: editorcommon.IModelDecorationOptions = {
glyphMarginClassName: 'debug-breakpoint-glyph-verified',
private static BREAKPOINT_UNVERIFIED_DECORATION: editorcommon.IModelDecorationOptions = {
glyphMarginClassName: 'debug-breakpoint-glyph-unverified',
stickiness: editorcommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges
};
......
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#5A5A5A" stroke-width="3" stroke-opacity="0.8"><circle cx="8" cy="8" r="4"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" fill-opacity="0.8"><g fill="#5A5A5A"><circle cx="8" cy="8" r="5"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#6C6C6C" stroke-width="3" stroke-opacity="0.6"><circle cx="8" cy="8" r="4"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" fill-opacity="0.6"><g fill="#6C6C6C"><circle cx="8" cy="8" r="5"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#007ACC"><circle cx="8" cy="8" r="5"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" fill-opacity="0.4"><g fill="#007ACC"><circle cx="8" cy="8" r="5"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#5A5A5A" stroke-width="3" stroke-opacity="0.8"><circle cx="8" cy="8" r="4"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#6C6C6C" stroke-width="3" stroke-opacity="0.6"><circle cx="8" cy="8" r="4"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#007ACC" stroke-width="3" stroke-opacity="0.8"><circle cx="8" cy="8" r="4"/></g></g></svg>
\ No newline at end of file
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#007ACC"><circle cx="8" cy="8" r="5"/></g></g></svg>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册