Merge branch 'master' into joh/commandsAsApi

This commit is contained in:
Johannes Rieken 2015-12-09 17:10:04 +01:00
commit 9408e3bb74
74 changed files with 2642 additions and 2040 deletions

View file

@ -1,7 +1,6 @@
{
"comments": {
"lineComment": ";",
"blockComment": [ "(comment", ")" ]
"lineComment": ";"
},
"brackets": [
["{", "}"],

View file

@ -1,6 +1,6 @@
{
"account": "monacobuild",
"container": "debuggers",
"zip": "32575e3/node-debug.zip",
"zip": "3efab9b/node-debug.zip",
"output": ""
}

View file

@ -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"

View file

@ -1,7 +1,6 @@
{
"comments": {
"lineComment": "'",
"blockComment": [ "/*", "*/" ]
"lineComment": "'"
},
"brackets": [
["{", "}"],

View file

@ -8,6 +8,7 @@
"id": "xml",
"extensions": [
".ascx",
".atom",
".axml",
".bpmn",
".config",

5
npm-shrinkwrap.json generated
View file

@ -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.0",
"from": "vscode-debugprotocol@1.0.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.0.0.tgz"
},
"vscode-textmate": {
"version": "1.0.9",

View file

@ -26,6 +26,7 @@
"iconv-lite": "^0.4.13",
"sax": "^1.1.1",
"semver": "^4.2.0",
"vscode-debugprotocol": "^1.0.0",
"vscode-textmate": "^1.0.9",
"native-keymap": "^0.0.2",
"winreg": "0.0.12",

View file

@ -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()); }
}

View file

@ -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)) {

View file

@ -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();

View file

@ -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
*/

View file

@ -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);

View file

@ -272,4 +272,8 @@ export class SimplePluginService extends AbstractPluginService {
console.log(msg);
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}

View file

@ -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;

View file

@ -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);
});
});
// Register all built-in standalone JSON schemas
let MonacoEditorSchemas: { [url:string]: IJSONSchema } = this.MonacoEditorSchemas || {};
for (var uri in MonacoEditorSchemas) {
standaloneCodeEditor.registerStandaloneSchema(uri, MonacoEditorSchemas[uri]);
};

File diff suppressed because it is too large Load diff

View 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;
}

View file

@ -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') {

View file

@ -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

View file

@ -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;
@ -950,64 +951,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 +960,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 +1251,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) {

View file

@ -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;
/**

View file

@ -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
};
}

View file

@ -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;

View file

@ -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);

View 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);

View file

@ -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
};
}

View file

@ -73,6 +73,10 @@ class WorkerPluginService extends AbstractPluginService {
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}
export class EditorWorkerServer {

View file

@ -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,

View file

@ -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;
}

View file

@ -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();
}
}
}

View file

@ -7,164 +7,64 @@
import { TPromise } from 'vs/base/common/winjs.base';
import {sequence} from 'vs/base/common/async';
import { assign } from 'vs/base/common/objects';
import { EventEmitter, ListenerUnbind } from 'vs/base/common/eventEmitter';
import {onUnexpectedError, isPromiseCanceledError} from 'vs/base/common/errors';
import Event, { Emitter } from 'vs/base/common/event';
import { onUnexpectedError } from 'vs/base/common/errors';
import strings = require('vs/base/common/strings');
import URI from 'vs/base/common/uri';
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
import timer = require('vs/base/common/timer');
import { getSnippets } from 'vs/editor/common/modes/modesRegistry';
import EditorCommon = require('vs/editor/common/editorCommon');
import { ISuggestSupport, ISuggestResult, ISuggestion, ISuggestionSorter } from 'vs/editor/common/modes';
import {DefaultFilter, IMatch} from 'vs/editor/common/modes/modesFilters';
import { ISuggestSupport, ISuggestResult, ISuggestion, ISuggestionCompare, ISuggestionFilter } from 'vs/editor/common/modes';
import { CodeSnippet } from 'vs/editor/contrib/snippet/common/snippet';
import { IDisposable, disposeAll } from 'vs/base/common/lifecycle';
import {SuggestRegistry, ISuggestResult2, suggest} from '../common/suggest';
import { SuggestRegistry, ISuggestResult2, suggest } from '../common/suggest';
enum SuggestState {
NOT_ACTIVE = 0,
MANUAL_TRIGGER = 1,
AUTO_TRIGGER = 2
export interface ICancelEvent {
retrigger: boolean;
}
export interface SuggestDataEvent {
suggestions: { completionItems: CompletionItem[]; currentWord: string; };
export interface ITriggerEvent {
auto: boolean;
characterTriggered: boolean;
retrigger: boolean;
}
export interface ISuggestEvent {
suggestions: ISuggestResult2[][];
currentWord: string;
auto: boolean;
}
export class CompletionItem {
private static _idPool = 0;
public id: string;
public suggestion: ISuggestion;
public highlights: IMatch[];
public support: ISuggestSupport;
public container: ISuggestResult;
private _resolveDetails:TPromise<CompletionItem>
constructor(support: ISuggestSupport, suggestion: ISuggestion, container:ISuggestResult) {
this.id = '_completion_item_#' + CompletionItem._idPool++;
this.support = support;
this.suggestion = suggestion;
this.container = container;
}
resolveDetails(resource:URI, position:EditorCommon.IPosition): TPromise<CompletionItem> {
if (!this._resolveDetails) {
if (!this.support || typeof this.support.getSuggestionDetails !== 'function') {
this._resolveDetails = TPromise.as(this);
} else {
this._resolveDetails = this.support.getSuggestionDetails(<any>resource, position, this.suggestion).then(value => {
this.suggestion = assign(this.suggestion, value);
return this;
}, err => {
if (isPromiseCanceledError(err)) {
this._resolveDetails = undefined;
} else {
onUnexpectedError(err);
}
return this;
});
}
}
return this._resolveDetails;
}
export interface IAcceptEvent {
snippet: CodeSnippet;
overwriteBefore: number;
overwriteAfter: number;
}
class RawModel {
private _items: CompletionItem[][] = [];
public size: number = 0;
public incomplete: boolean = false;
insertSuggestions(rank: number, suggestions: ISuggestResult2[]): boolean {
if (suggestions) {
let items: CompletionItem[] = [];
for (let _suggestions of suggestions) {
for (let suggestionItem of _suggestions.suggestions) {
items.push(new CompletionItem(_suggestions.support, suggestionItem, _suggestions));
}
this.size += _suggestions.suggestions.length;
this.incomplete = this.incomplete || _suggestions.incomplete;
}
this._items[rank] = items;
return true;
}
}
select(ctx: SuggestionContext): CompletionItem[] {
let result: CompletionItem[] = [];
for (let item of this._items) {
RawModel._sortAndFilter(item, ctx, result);
}
return result;
}
private static _sortAndFilter(items: CompletionItem[], ctx: SuggestionContext, bucket: CompletionItem[]): void {
if (isFalsyOrEmpty(items)) {
return;
}
// all items have the same (origin) support. derive sorter and filter
// from first
const [first] = items;
let compare = RawModel._compare;
let filter = DefaultFilter;
if (first.support) {
compare = first.support.getSorter && first.support.getSorter() || compare;
filter = first.support.getFilter && first.support.getFilter() || filter;
}
items = items.filter(item => {
// set hightlight and filter those that have none
item.highlights = filter(ctx.wordBefore, item.suggestion);
return !isFalsyOrEmpty(item.highlights);
}).sort((a, b) => {
// sort suggestions by custom strategy
return compare(a.suggestion, b.suggestion)
});
bucket.push(...items);
}
private static _compare(a: ISuggestion, b: ISuggestion):number {
return a.label.localeCompare(b.label);
}
}
class SuggestionContext {
class Context {
public lineNumber:number;
public column:number;
public isInEditableRange:boolean;
private auto: boolean;
private shouldAuto: boolean;
private isAutoTriggerEnabled: boolean;
private lineContentBefore:string;
private lineContentAfter:string;
public wordBefore:string;
public wordAfter:string;
constructor(editor:EditorCommon.ICommonCodeEditor, auto: boolean) {
this.auto = auto;
var model = editor.getModel();
var position = editor.getPosition();
var lineContent = model.getLineContent(position.lineNumber);
this.wordBefore = '';
this.wordAfter = '';
var wordUnderCursor = model.getWordAtPosition(position);
constructor(editor:EditorCommon.ICommonCodeEditor, private auto: boolean) {
const model = editor.getModel();
const position = editor.getPosition();
const lineContent = model.getLineContent(position.lineNumber);
const wordUnderCursor = model.getWordAtPosition(position);
if (wordUnderCursor) {
this.wordBefore = lineContent.substring(wordUnderCursor.startColumn - 1, position.column - 1);
this.wordAfter = lineContent.substring(position.column - 1, wordUnderCursor.endColumn - 1);
} else {
this.wordBefore = '';
this.wordAfter = '';
}
this.lineNumber = position.lineNumber;
@ -173,69 +73,77 @@ class SuggestionContext {
this.lineContentAfter = lineContent.substr(position.column - 1);
this.isInEditableRange = true;
if (model.hasEditableRange()) {
var editableRange = model.getEditableRange();
const editableRange = model.getEditableRange();
if (!editableRange.containsPosition(position)) {
this.isInEditableRange = false;
}
}
var lineContext = model.getLineContext(position.lineNumber);
var character = model.getLineContent(position.lineNumber).charAt(position.column - 1);
this.shouldAuto = SuggestRegistry.all(model)
.some(support => support.shouldAutotriggerSuggest(lineContext, position.column - 1, character));
const lineContext = model.getLineContext(position.lineNumber);
const character = model.getLineContent(position.lineNumber).charAt(position.column - 1);
const supports = SuggestRegistry.all(model);
this.isAutoTriggerEnabled = supports.some(s => s.shouldAutotriggerSuggest(lineContext, position.column - 1, character));
}
public isValidForAutoSuggest(): boolean {
public shouldAutoTrigger(): boolean {
if (!this.isAutoTriggerEnabled) {
// Support disallows it
return false;
}
if (this.wordBefore.length === 0) {
// Word before position is empty
return false;
}
if (this.wordAfter.length > 0) {
// Word after position is non empty
return false;
}
if (!this.shouldAuto) {
// ISuggestSupport#shouldAutotriggerSuggest is againt this
return false;
}
return true;
}
public isValidForNewContext(newCtx:SuggestionContext):boolean {
if (this.lineNumber !== newCtx.lineNumber) {
public isDifferentContext(context: Context):boolean {
if (this.lineNumber !== context.lineNumber) {
// Line number has changed
return false;
return true;
}
if (newCtx.column < this.column - this.wordBefore.length) {
if (context.column < this.column - this.wordBefore.length) {
// column went before word start
return false;
return true;
}
if (!strings.startsWith(newCtx.lineContentBefore, this.lineContentBefore) || this.lineContentAfter !== newCtx.lineContentAfter) {
if (!strings.startsWith(context.lineContentBefore, this.lineContentBefore) || this.lineContentAfter !== context.lineContentAfter) {
// Line has changed before position
return false;
return true;
}
if (newCtx.wordBefore === '' && newCtx.lineContentBefore !== this.lineContentBefore) {
if (context.wordBefore === '' && context.lineContentBefore !== this.lineContentBefore) {
// Most likely a space has been typed
return false;
return true;
}
return true;
return false;
}
public isValidForRetrigger(newCtx:SuggestionContext):boolean {
if (!strings.startsWith(this.lineContentBefore, newCtx.lineContentBefore) || this.lineContentAfter !== newCtx.lineContentAfter) {
public shouldRetrigger(context: Context):boolean {
if (!strings.startsWith(this.lineContentBefore, context.lineContentBefore) || this.lineContentAfter !== context.lineContentAfter) {
// Doesn't look like the same line
return false;
}
if (this.lineContentBefore.length > newCtx.lineContentBefore.length && this.wordBefore.length === 0) {
if (this.lineContentBefore.length > context.lineContentBefore.length && this.wordBefore.length === 0) {
// Text was deleted and previous current word was empty
return false;
}
if (this.auto && newCtx.wordBefore.length === 0) {
if (this.auto && context.wordBefore.length === 0) {
// Currently in auto mode and new current word is empty
return false;
}
@ -243,57 +151,55 @@ class SuggestionContext {
}
}
export class SuggestModel extends EventEmitter {
enum State {
Idle = 0,
Manual = 1,
Auto = 2
}
export class SuggestModel implements IDisposable {
private editor: EditorCommon.ICommonCodeEditor;
private onAccept:(snippet: CodeSnippet, overwriteBefore:number, overwriteAfter:number)=>void;
private toDispose: IDisposable[];
private autoSuggestDelay:number;
private triggerAutoSuggestPromise:TPromise<void>;
private state:SuggestState;
private state:State;
// Members which make sense when state is active
private requestPromise:TPromise<void>;
private requestContext:SuggestionContext;
private raw:RawModel;
private context:Context;
constructor(editor:EditorCommon.ICommonCodeEditor, onAccept:(snippet: CodeSnippet, overwriteBefore:number, overwriteAfter:number)=>void) {
super();
this.editor = editor;
this.onAccept = onAccept;
this.toDispose = [];
private raw: ISuggestResult2[][];
private incomplete: boolean;
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.ConfigurationChanged, () => this.onEditorConfigurationChange()));
this.onEditorConfigurationChange();
private _onDidCancel: Emitter<ICancelEvent> = new Emitter();
public get onDidCancel(): Event<ICancelEvent> { return this._onDidCancel.event; }
private _onDidTrigger: Emitter<ITriggerEvent> = new Emitter();
public get onDidTrigger(): Event<ITriggerEvent> { return this._onDidTrigger.event; }
private _onDidSuggest: Emitter<ISuggestEvent> = new Emitter();
public get onDidSuggest(): Event<ISuggestEvent> { return this._onDidSuggest.event; }
private _onDidAccept: Emitter<IAcceptEvent> = new Emitter();
public get onDidAccept(): Event<IAcceptEvent> { return this._onDidAccept.event; }
constructor(private editor: EditorCommon.ICommonCodeEditor) {
this.state = State.Idle;
this.triggerAutoSuggestPromise = null;
this.state = SuggestState.NOT_ACTIVE;
this.requestPromise = null;
this.raw = null;
this.requestContext = null;
this.incomplete = false;
this.context = null;
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.CursorSelectionChanged, (e: EditorCommon.ICursorSelectionChangedEvent) => {
if (!e.selection.isEmpty()) {
this.cancel();
return;
}
if (e.source !== 'keyboard' || e.reason !== '') {
this.cancel();
return;
}
this.onCursorChange();
}));
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.ModelChanged, (e) => {
this.cancel();
}));
this.toDispose = [];
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.ConfigurationChanged, () => this.onEditorConfigurationChange()));
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.CursorSelectionChanged, e => this.onCursorChange(e)));
this.toDispose.push(this.editor.addListener2(EditorCommon.EventType.ModelChanged, () => this.cancel()));
this.onEditorConfigurationChange();
}
public cancel(silent:boolean = false, retrigger:boolean = false):boolean {
var actuallyCanceled = (this.state !== SuggestState.NOT_ACTIVE);
const actuallyCanceled = this.state !== State.Idle;
if (this.triggerAutoSuggestPromise) {
this.triggerAutoSuggestPromise.cancel();
@ -305,49 +211,61 @@ export class SuggestModel extends EventEmitter {
this.requestPromise = null;
}
this.state = SuggestState.NOT_ACTIVE;
this.state = State.Idle;
this.raw = null;
this.requestContext = null;
this.incomplete = false;
this.context = null;
if (!silent) {
this.emit('cancel', { retrigger: retrigger });
this._onDidCancel.fire({ retrigger });
}
return actuallyCanceled;
}
public getRequestPosition():EditorCommon.IPosition {
if(!this.requestContext) {
if(!this.context) {
return null;
}
return {
lineNumber: this.requestContext.lineNumber,
column: this.requestContext.column
lineNumber: this.context.lineNumber,
column: this.context.column
};
}
private isAutoSuggest():boolean {
return this.state === SuggestState.AUTO_TRIGGER;
return this.state === State.Auto;
}
private onCursorChange():void {
private onCursorChange(e: EditorCommon.ICursorSelectionChangedEvent):void {
if (!e.selection.isEmpty()) {
this.cancel();
return;
}
if (e.source !== 'keyboard' || e.reason !== '') {
this.cancel();
return;
}
if (!SuggestRegistry.has(this.editor.getModel())) {
return;
}
var isInactive = this.state === SuggestState.NOT_ACTIVE;
const isInactive = this.state === State.Idle;
if (isInactive && !this.editor.getConfiguration().quickSuggestions) {
return;
}
var ctx = new SuggestionContext(this.editor, false);
const ctx = new Context(this.editor, false);
if (isInactive) {
// trigger was not called or it was canceled
this.cancel();
if (ctx.isValidForAutoSuggest()) {
if (ctx.shouldAutoTrigger()) {
this.triggerAutoSuggestPromise = TPromise.timeout(this.autoSuggestDelay);
this.triggerAutoSuggestPromise.then(() => {
this.triggerAutoSuggestPromise = null;
@ -355,79 +273,56 @@ export class SuggestModel extends EventEmitter {
});
}
} else if (this.raw && this.raw.incomplete) {
this.trigger(this.state === SuggestState.AUTO_TRIGGER, undefined, true);
} else if (this.raw && this.incomplete) {
this.trigger(this.state === State.Auto, undefined, true);
} else {
this.onNewContext(ctx);
}
}
public trigger(auto: boolean, triggerCharacter?: string, retrigger: boolean = false, groups?: ISuggestSupport[][]): void {
var model = this.editor.getModel();
var characterTriggered = !!triggerCharacter;
if (!groups) {
groups = SuggestRegistry.orderedGroups(model);
}
const model = this.editor.getModel();
const characterTriggered = !!triggerCharacter;
groups = groups || SuggestRegistry.orderedGroups(model);
if (groups.length === 0) {
return;
}
var ctx = new SuggestionContext(this.editor, auto);
const ctx = new Context(this.editor, auto);
if (!ctx.isInEditableRange) {
return;
}
var $tTrigger = timer.start(timer.Topic.EDITOR, 'suggest/TRIGGER');
// Cancel previous requests, change state & update UI
this.cancel(false, retrigger);
this.state = (auto || characterTriggered) ? SuggestState.AUTO_TRIGGER : SuggestState.MANUAL_TRIGGER;
this.emit('loading', { auto: this.isAutoSuggest(), characterTriggered: characterTriggered, retrigger: retrigger });
this.state = (auto || characterTriggered) ? State.Auto : State.Manual;
this._onDidTrigger.fire({ auto: this.isAutoSuggest(), characterTriggered, retrigger });
// Capture context when request was sent
this.requestContext = ctx;
this.context = ctx;
// Send mode request
var $tRequest = timer.start(timer.Topic.EDITOR, 'suggest/REQUEST');
var position = this.editor.getPosition();
const position = this.editor.getPosition();
let raw = new RawModel();
let rank = 0;
this.requestPromise = suggest(model, position, triggerCharacter, groups).then(all => {
for (let suggestions of all) {
if (raw.insertSuggestions(rank, suggestions)) {
rank++;
}
}
});
this.requestPromise.then(() => {
$tRequest.stop();
this.requestPromise = null;
if (this.state === SuggestState.NOT_ACTIVE) {
if (this.state === State.Idle) {
return;
}
var snippets = getSnippets(model, position);
if (snippets && snippets.suggestions && snippets.suggestions.length > 0) {
raw.insertSuggestions(rank, [snippets]);
}
this.raw = all.concat([[getSnippets(model, position)]]);
this.incomplete = all.reduce((r, s) => r || s.reduce((r, s) => r || s.incomplete, false), false);
if(raw.size > 0) {
this.raw = raw;
this.onNewContext(new SuggestionContext(this.editor, auto));
} else {
this.emit('empty', { auto: this.isAutoSuggest() });
}
}, () => {
$tRequest.stop();
}).done(() => $tTrigger.stop());
this.onNewContext(new Context(this.editor, auto));
}).then(null, onUnexpectedError);
}
private onNewContext(ctx:SuggestionContext):void {
if (this.requestContext && !this.requestContext.isValidForNewContext(ctx)) {
if (this.requestContext.isValidForRetrigger(ctx)) {
this.trigger(this.state === SuggestState.AUTO_TRIGGER, undefined, true);
private onNewContext(ctx: Context):void {
if (this.context && this.context.isDifferentContext(ctx)) {
if (this.context.shouldRetrigger(ctx)) {
this.trigger(this.state === State.Auto, undefined, true);
} else {
this.cancel();
}
@ -436,42 +331,22 @@ export class SuggestModel extends EventEmitter {
}
if (this.raw) {
let completionItems = this.raw.select(ctx);
if (completionItems.length > 0) {
this.emit('suggest', <SuggestDataEvent> {
suggestions: {
completionItems,
currentWord: ctx.wordBefore
},
auto: this.isAutoSuggest()
});
} else {
this.emit('empty', { auto: this.isAutoSuggest() });
}
this._onDidSuggest.fire({ suggestions: this.raw, currentWord: ctx.wordBefore, auto: this.isAutoSuggest() });
}
}
public accept(item: CompletionItem): boolean {
public accept(suggestion: ISuggestion, overwriteBefore: number, overwriteAfter: number): boolean {
if (this.raw === null) {
return false;
}
var parentSuggestions = item.container;
var offsetFromInvocation = this.editor.getPosition().column - this.requestContext.column;
var overwriteBefore = ((typeof parentSuggestions.overwriteBefore === 'undefined')
? parentSuggestions.currentWord.length
: parentSuggestions.overwriteBefore) + offsetFromInvocation;
var overwriteAfter = (typeof parentSuggestions.overwriteAfter === 'undefined')
? 0
: Math.max(0, parentSuggestions.overwriteAfter);
this._onDidAccept.fire({
snippet: new CodeSnippet(suggestion.codeSnippet),
overwriteBefore: overwriteBefore + (this.editor.getPosition().column - this.context.column),
overwriteAfter
});
this.cancel();
this.onAccept(new CodeSnippet(item.suggestion.codeSnippet), overwriteBefore, overwriteAfter);
return true;
}
@ -483,9 +358,8 @@ export class SuggestModel extends EventEmitter {
}
}
public destroy():void {
public dispose():void {
this.cancel(true);
this.toDispose = disposeAll(this.toDispose);
this.emit('destroy', null);
}
}

File diff suppressed because it is too large Load diff

View file

@ -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 => {

View file

@ -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');

View file

@ -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, [
'',
' ',
' ',

View file

@ -123,6 +123,10 @@ class MockPluginService extends AbstractPluginService {
console.log(msg);
}
}
public deactivate(pluginId:string): void {
// nothing to do
}
}
class MockModelService extends ModelServiceImpl {}

View file

@ -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' }
]
}
}
}
});

View 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> {

File diff suppressed because it is too large Load diff

View file

@ -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';

View file

@ -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);
}
}

View file

@ -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 = {

View file

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------------------------
* 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;
}
schemaRegistry.addSchemaFileAssociation(extension.fileMatch, uri);
});
}
});
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View 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');

View file

@ -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);

View file

@ -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;

View file

@ -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));
});

View 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);
}

View file

@ -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
};

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 198 B

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 198 B

View file

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 198 B

View file

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 219 B

View file

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 219 B

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 179 B

View file

@ -1 +1 @@
<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>
<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>

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 179 B

View file

@ -26,15 +26,15 @@
}
.monaco-editor .debug-breakpoint-glyph-hint {
background: url('breakpoint.svg') center center no-repeat;
background: url('breakpoint-hint.svg') center center no-repeat;
}
.monaco-editor .debug-breakpoint-glyph-disabled {
background: url('breakpoint-disabled.svg') center center no-repeat;
}
.monaco-editor .debug-breakpoint-glyph-verified {
background: url('breakpoint-verified.svg') center center no-repeat;
.monaco-editor .debug-breakpoint-glyph-unverified {
background: url('breakpoint-unverified.svg') center center no-repeat;
}
.monaco-editor .debug-top-stack-frame-glyph {
@ -49,11 +49,11 @@
background: url('breakpoint.svg') center center no-repeat;
}
.monaco-editor .debug-top-stack-frame-glyph.debug-breakpoint-glyph-verified {
.monaco-editor .debug-top-stack-frame-glyph.debug-breakpoint-glyph {
background: url('current-and-breakpoint.svg') center center no-repeat;
}
.monaco-editor .debug-focused-stack-frame-glyph.debug-breakpoint-glyph-verified {
.monaco-editor .debug-focused-stack-frame-glyph.debug-breakpoint-glyph {
background: url('stackframe-and-breakpoint.svg') center center no-repeat;
}
@ -271,6 +271,10 @@
background: url('breakpoint-disabled-dark.svg') center center no-repeat;
}
.monaco-editor.vs-dark .debug-breakpoint-glyph-unverified {
background: url('breakpoint-unverified-dark.svg') center center no-repeat;
}
.monaco-editor.vs-dark .debug-top-stack-frame-glyph {
background: url('current-arrow-dark.svg') center center no-repeat;
}
@ -279,11 +283,11 @@
background: url('stackframe-arrow-dark.svg') center center no-repeat;
}
.monaco-editor.vs-dark .debug-top-stack-frame-glyph.debug-breakpoint-glyph-verified {
.monaco-editor.vs-dark .debug-top-stack-frame-glyph.debug-breakpoint-glyph {
background: url('current-and-breakpoint-dark.svg') center center no-repeat;
}
.monaco-editor.vs-dark .debug-focused-stack-frame-glyph.debug-breakpoint-glyph-verified {
.monaco-editor.vs-dark .debug-focused-stack-frame-glyph.debug-breakpoint-glyph {
background: url('stackframe-and-breakpoint-dark.svg') center center no-repeat;
}

View file

@ -290,7 +290,7 @@ export class RemoveAllBreakpointsAction extends AbstractDebugAction {
export class ToggleEnablementAction extends AbstractDebugAction {
static ID = 'workbench.debug.viewlet.action.toggleBreakpointEnablement';
static LABEL = nls.localize('toggleEnablement', "Toggle Enablement");
static LABEL = nls.localize('toggleEnablement', "Enable/Disable Breakpoint");
constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) {
super(id, label, 'debug-action toggle-enablement', debugService, keybindingService);

View file

@ -601,19 +601,17 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService
}
this.session = null;
this.partService.removeClass('debugging');
this.contextService.updateOptions('editor', {
hover: true
});
this.editorService.focusEditor();
this.model.clearThreads(true);
this.setFocusedStackFrameAndEvaluate(null);
this.setStateAndEmit(debug.State.Inactive);
// Set breakpoints back to unverified since the session ended.
const data: {[id: string]: { line: number, verified: boolean } } = { };
this.model.getBreakpoints().forEach(bp => data[bp.getId()] = { line: bp.lineNumber, verified: false });
this.model.updateBreakpoints(data);
this.model.clearThreads(true);
this.setFocusedStackFrameAndEvaluate(null);
this.setStateAndEmit(debug.State.Inactive);
this.inDebugMode.reset();
}

View file

@ -13,7 +13,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
import platform = require('vs/platform/platform');
import pluginsRegistry = require('vs/platform/plugins/common/pluginsRegistry');
import editor = require('vs/editor/common/editorCommon');
import jsonContributionRegistry = require('vs/languages/json/common/jsonContributionRegistry');
import jsonContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
import debug = require('vs/workbench/parts/debug/common/debug');
import { SystemVariables } from 'vs/workbench/parts/lib/node/systemVariables';
import { Adapter } from 'vs/workbench/parts/debug/node/debugAdapter';
@ -179,7 +179,7 @@ export class ConfigurationManager {
} else if (duplicate[attribute] && attribute !== 'type') {
// Give priority to the later registered extension.
duplicate[attribute] = adapter[attribute];
extension.collector.warn(nls.localize('duplicateDebuggerType', "Debug type '{0}' is already registered and has attribute '{1}', ignoring attribute '{1}'.", adapter.type, attribute));
extension.collector.error(nls.localize('duplicateDebuggerType', "Debug type '{0}' is already registered and has attribute '{1}', ignoring attribute '{1}'.", adapter.type, attribute));
} else {
duplicate[attribute] = adapter[attribute];
}

View file

@ -5,6 +5,8 @@
import platform = require('vs/platform/platform');
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar');
import { ExtensionsStatusbarItem } from 'vs/workbench/parts/extensions/electron-browser/extensionsWidgets';
import { IGalleryService } from 'vs/workbench/parts/extensions/common/extensions';
import { GalleryService } from 'vs/workbench/parts/extensions/node/vsoGalleryService';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
@ -17,3 +19,10 @@ registerSingleton(IGalleryService, GalleryService);
(<IWorkbenchContributionsRegistry>platform.Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(
ExtensionsWorkbenchExtension
);
// Register Statusbar item
(<statusbar.IStatusbarRegistry>platform.Registry.as(statusbar.Extensions.Statusbar)).registerStatusbarItem(new statusbar.StatusbarItemDescriptor(
ExtensionsStatusbarItem,
statusbar.StatusbarAlignment.LEFT,
10 /* Low Priority */
));

View file

@ -119,4 +119,17 @@
-moz-transform: none;
-o-transform: none;
transform: none;
}
/* Status bar */
.monaco-shell .extensions-statusbar {
cursor: pointer;
}
.monaco-shell .extensions-statusbar.warning::before {
color: yellow;
}
.monaco-shell .extensions-statusbar.error::before {
color: #FF9D00;
}

View file

@ -6,6 +6,9 @@
import nls = require('vs/nls');
import { Promise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import Severity from 'vs/base/common/severity';
import { IPluginService, IPluginStatus } from 'vs/platform/plugins/common/plugins';
import { IMessageService } from 'vs/platform/message/common/message';
import { IExtensionsService } from 'vs/workbench/parts/extensions/common/extensions';
import { IQuickOpenService } from 'vs/workbench/services/quickopen/browser/quickOpenService';
@ -32,6 +35,43 @@ export class ListExtensionsAction extends Action {
}
}
export class ShowExtensionsStatusAction extends Action {
static ID = 'workbench.extensions.action.showExtensionsStatus';
static LABEL = nls.localize('showInstalledExtensions', "Show Extensions Status");
private status: { [id: string]: IPluginStatus };
constructor(
id: string,
label: string,
@IPluginService pluginService: IPluginService,
@IMessageService private messageService: IMessageService
) {
super(id, label, null, true);
pluginService.onReady().then(() => {
this.status = pluginService.getPluginsStatus();
});
}
public run(): Promise {
Object.keys(this.status).forEach(key => {
this.status[key].messages.forEach(m => {
if (m.type > Severity.Ignore) {
this.messageService.show(m.type, m.message);
}
});
});
return Promise.as(null);
}
protected isEnabled(): boolean {
return true;
}
}
export class InstallExtensionAction extends Action {
static ID = 'workbench.extensions.action.installExtension';

View file

@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import Severity from 'vs/base/common/severity';
import errors = require('vs/base/common/errors');
import dom = require('vs/base/browser/dom');
import lifecycle = require('vs/base/common/lifecycle');
import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar');
import { IPluginService } from 'vs/platform/plugins/common/plugins';
import { IQuickOpenService } from 'vs/workbench/services/quickopen/browser/quickOpenService';
var $ = dom.emmet;
export class ExtensionsStatusbarItem implements statusbar.IStatusbarItem {
private toDispose: lifecycle.IDisposable[];
private domNode: HTMLElement;
constructor(
@IPluginService pluginService: IPluginService,
@IQuickOpenService private quickOpenService: IQuickOpenService
) {
this.toDispose = [];
pluginService.onReady().then(() => {
const pluginsStatus = pluginService.getPluginsStatus();
Object.keys(pluginsStatus).forEach(key => {
const severity = pluginsStatus[key].messages.reduce((maxSeverity, message) => Math.max(maxSeverity, message.type), Severity.Ignore);
this.domNode.classList.add(Severity[severity].toLowerCase());
});
});
}
public render(container: HTMLElement): lifecycle.IDisposable {
this.domNode = dom.append(container, $('.extensions-statusbar octicon octicon-package'));
this.domNode.title = nls.localize('extensions', "Extensions"),
this.toDispose.push(dom.addDisposableListener(this.domNode, 'click', () => {
this.quickOpenService.show('>extensions: ').done(null, errors.onUnexpectedError);
}));
return {
dispose: () => lifecycle.disposeAll(this.toDispose)
};
}
}

View file

@ -16,7 +16,7 @@ import { IWorkspaceContextService } from 'vs/workbench/services/workspace/common
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
import wbaregistry = require('vs/workbench/browser/actionRegistry');
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { ListExtensionsAction, InstallExtensionAction, ListOutdatedExtensionsAction } from './extensionsActions';
import { ListExtensionsAction, ShowExtensionsStatusAction, InstallExtensionAction, ListOutdatedExtensionsAction } from './extensionsActions';
import { IQuickOpenRegistry, Extensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen';
import ipc = require('ipc');
@ -45,6 +45,7 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
const extensionsCategory = nls.localize('extensionsCategory', "Extensions");
const actionRegistry = (<wbaregistry.IWorkbenchActionRegistry> platform.Registry.as(wbaregistry.Extensions.WorkbenchActions));
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ListExtensionsAction, ListExtensionsAction.ID, ListExtensionsAction.LABEL), extensionsCategory);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowExtensionsStatusAction, ShowExtensionsStatusAction.ID, ShowExtensionsStatusAction.LABEL), extensionsCategory);
(<IQuickOpenRegistry>platform.Registry.as(Extensions.Quickopen)).registerQuickOpenHandler(
new QuickOpenHandlerDescriptor(

View file

@ -208,40 +208,6 @@ suite('Files - TextFileEditorModel', () => {
});
});
test("Change after auto save triggered will cause another autosave and twice the events", function(done) {
this.timeout(10000); // TODO@Ben test tends to need longer?
let eventCounter = 0;
let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource("/path/index.txt"), "utf8");
(<any>m1).autoSaveDelay = 10;
(<any>m1).autoSaveEnabled = true;
eventService.addListener(EventType.FILE_DIRTY, (e: LocalFileChangeEvent) => {
eventCounter++;
});
eventService.addListener(EventType.FILE_SAVED, (e: LocalFileChangeEvent) => {
eventCounter++;
});
m1.load().then(() => {
m1.textEditorModel.setValue("foo");
return Promise.timeout(50).then(() => {
m1.textEditorModel.setValue("bar");
return Promise.timeout(20).then(() => {
m1.dispose();
assert.ok(!m1.isDirty());
assert.equal(eventCounter, 4);
done();
});
});
});
});
test("Dirty tracking", function(done) {
let resource = toResource("/path/index_async.txt");
let i1 = baseInstantiationService.createInstance(FileEditorInput, resource, "text/plain", "utf8");

View file

@ -17,7 +17,7 @@ import modesExtensions = require('vs/editor/common/modes/modesRegistry');
import errors = require('vs/base/common/errors');
import {IQuickOpenService, IPickOpenEntry} from 'vs/workbench/services/quickopen/browser/quickOpenService';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
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 ipc = require('ipc');

View file

@ -48,7 +48,7 @@ import { IModel } from 'vs/editor/common/editorCommon';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import jsonContributionRegistry = require('vs/languages/json/common/jsonContributionRegistry');
import jsonContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';

View file

@ -13,7 +13,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IKeybindingItem, IUserFriendlyKeybinding} from 'vs/platform/keybinding/common/keybindingService';
import {IOSupport} from 'vs/platform/keybinding/common/commonKeybindingResolver';
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';
export abstract class WorkbenchKeybindingService extends KeybindingService {

View file

@ -305,7 +305,9 @@ class PluginHostProcessManager {
this.terminating = true;
if (this.pluginHostProcessHandle) {
this.pluginHostProcessHandle.kill();
this.pluginHostProcessHandle.send({
type: '__$terminate'
});
}
}
}