mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Merge branch 'master' into ben/electron
This commit is contained in:
commit
1c4656f045
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -12,5 +12,6 @@
|
|||
".build/**": true,
|
||||
"out*/**": true,
|
||||
"extensions/**/out/**": true
|
||||
}
|
||||
},
|
||||
"filePicker.alternateFileNameMatching": true
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
|
@ -462,7 +462,11 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#mixins</string>
|
||||
<string>#mixin_definition</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#mixin_call</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
|
@ -592,26 +596,6 @@
|
|||
<key>name</key>
|
||||
<string>meta.first-class.jade</string>
|
||||
</dict>
|
||||
<key>brackets_js</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\[</string>
|
||||
<key>end</key>
|
||||
<string>\]</string>
|
||||
<key>name</key>
|
||||
<string>js.value.attribute.tag.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#brackets_js</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>case_conds</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
|
@ -712,7 +696,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#mixins</string>
|
||||
<string>#mixin_call</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
|
@ -946,7 +930,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#mixins</string>
|
||||
<string>#mixin_call</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
|
@ -1081,60 +1065,155 @@
|
|||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>mixins</key>
|
||||
<key>js_braces</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(((mixin\s+)|\+)([\w-]+))\s*</string>
|
||||
<string>\{</string>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>js_brackets</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\[</string>
|
||||
<key>end</key>
|
||||
<string>\]</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>js_parens</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\(</string>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_parens</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>mixin_call</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>((?:mixin\s+)|\+)([\w-]+)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>2</key>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.function.jade</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.jade</string>
|
||||
<string>meta.tag.other entity.name.function.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>comment</key>
|
||||
<string>Mixin declaration and use, including the new '+' syntax.</string>
|
||||
<key>end</key>
|
||||
<string>(?=\])|$</string>
|
||||
<key>name</key>
|
||||
<string>source.meta.function</string>
|
||||
<string>(?!\()|$</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string></string>
|
||||
<string>(?<!\))\(</string>
|
||||
<key>end</key>
|
||||
<string>(?=\])|$</string>
|
||||
<string>\)</string>
|
||||
<key>name</key>
|
||||
<string>args.mixin.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_paren</string>
|
||||
<string>#js_parens</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_brackets</string>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>meta.tag.other entity.other.attribute-name.tag.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>([^\s(),=/]+)\s*=\s*</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#complete_tag</string>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attributes</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>mixin_definition</key>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.function.jade</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>meta.tag.other entity.name.function.jade</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.begin.js</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>variable.parameter.function.js</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.begin.js</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(mixin\s+)([\w-]+)(?:(\()((?:[a-zA-Z_]\w*(?:,\s*)?)*)(\)))?$</string>
|
||||
</dict>
|
||||
<key>printed_expression</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
|
@ -1155,7 +1234,7 @@
|
|||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#brackets_js</string>
|
||||
<string>#js_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
|
@ -1189,106 +1268,43 @@
|
|||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>tag_attribute_value_braces</key>
|
||||
<key>tag_attribute_name</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>name</key>
|
||||
<string>js.value.attribute.tag.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_paren</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.tag.jade</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>([^\s(),=/!]+)\s*</string>
|
||||
</dict>
|
||||
<key>tag_attribute_value_brackets</key>
|
||||
<key>tag_attribute_name_paren</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\[</string>
|
||||
<key>end</key>
|
||||
<string>\]</string>
|
||||
<key>name</key>
|
||||
<string>js.value.attribute.tag.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_paren</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>tag_attribute_value_paren</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\(</string>
|
||||
<string>\(\s*</string>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>name</key>
|
||||
<string>js.value.attribute.tag.jade</string>
|
||||
<string>entity.other.attribute-name.tag.jade</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_paren</string>
|
||||
<string>#tag_attribute_name_paren</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
<string>#tag_attribute_name</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>tag_attributes</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(\()</string>
|
||||
<string>(\(\s*)</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
|
@ -1304,53 +1320,75 @@
|
|||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.tag.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_name_paren</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_name</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>([^\s(),=/]+)\s*((?=\))|,|\s+|$)(?!\!?\=)</string>
|
||||
<string>!</string>
|
||||
<key>name</key>
|
||||
<string>invalid.illegal.tag.jade</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>([^\s(),=/]*[^\s(),=!/])\s*(!?\=)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.tag.jade</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.separator.key-value.jade</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<string>=\s*</string>
|
||||
<key>end</key>
|
||||
<string>(,|$|(?=\)|((?<![+/*|&=:^~!?<>%-])\s+[^+/*|&=:^~!?<>%-])))</string>
|
||||
<string>$|(?=,|(?:\s+[^!%&*-+~|<>:?/])|\))</string>
|
||||
<key>name</key>
|
||||
<string>attribute_value</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_paren</string>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_brackets</string>
|
||||
<string>#js_parens</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#tag_attribute_value_braces</string>
|
||||
<string>#js_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?<=[%&*-+~|<>:?/])\s+</string>
|
||||
<key>end</key>
|
||||
<string>$|(?=,|(?:\s+[^!%&*-+~|<>:?/])|\))</string>
|
||||
<key>name</key>
|
||||
<string>attribute_value2</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_parens</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#js_braces</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.js</string>
|
||||
|
@ -1496,7 +1534,7 @@
|
|||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#brackets_js</string>
|
||||
<string>#js_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "package.json",
|
||||
"url": "http://json.schemastore.org/project"
|
||||
"url": "http://json.schemastore.org/package"
|
||||
},
|
||||
{
|
||||
"fileMatch": "bower.json",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"account": "monacobuild",
|
||||
"container": "debuggers",
|
||||
"zip": "f1ea61a/node-debug.zip",
|
||||
"zip": "d98733b/node-debug.zip",
|
||||
"output": ""
|
||||
}
|
||||
|
|
6
npm-shrinkwrap.json
generated
6
npm-shrinkwrap.json
generated
|
@ -416,9 +416,9 @@
|
|||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
|
||||
},
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.0.1",
|
||||
"from": "vscode-debugprotocol@>=1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.0.1.tgz"
|
||||
"version": "1.1.1",
|
||||
"from": "vscode-debugprotocol@>=1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.1.1.tgz"
|
||||
},
|
||||
"vscode-textmate": {
|
||||
"version": "1.0.9",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Code",
|
||||
"version": "0.10.5",
|
||||
"version": "0.10.6",
|
||||
"electronVersion": "0.35.5",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
|
@ -26,7 +26,7 @@
|
|||
"iconv-lite": "^0.4.13",
|
||||
"sax": "^1.1.1",
|
||||
"semver": "^4.2.0",
|
||||
"vscode-debugprotocol": "^1.0.0",
|
||||
"vscode-debugprotocol": "^1.1.1",
|
||||
"vscode-textmate": "^1.0.9",
|
||||
"native-keymap": "^0.1.2",
|
||||
"winreg": "0.0.12",
|
||||
|
|
|
@ -277,7 +277,7 @@ export function isEqualOrParent(path: string, candidate: string): boolean {
|
|||
|
||||
// Reference: https://en.wikipedia.org/wiki/Filename
|
||||
const INVALID_FILE_CHARS = isWindows ? /[\\/:\*\?"<>\|]/g : /[\\/]/g;
|
||||
const WINDOWS_FORBIDDEN_NAMES = /con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9]/i;
|
||||
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i;
|
||||
export function isValidBasename(name: string): boolean {
|
||||
if (!name || name.length === 0 || /^\s+$/.test(name)) {
|
||||
return false; // require a name that is not just whitespace
|
||||
|
|
|
@ -333,7 +333,7 @@ let showReferencesCommand: ICommandHandler = (accessor, args:[URI, EditorCommon.
|
|||
|
||||
let controller = FindReferencesController.getController(control);
|
||||
let range = Position.asEmptyRange(args[1]);
|
||||
return TPromise.as(controller.processRequest(Range.lift(range), TPromise.as(args[2])));
|
||||
return TPromise.as(controller.processRequest(Range.lift(range), TPromise.as(args[2]))).then(() => true);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -523,10 +523,6 @@ export class SuggestWidget implements EditorBrowser.IContentWidget, IDisposable
|
|||
this.suggestionSupportsAutoAccept.set(!(<CompletionItem>focus).suggestion.noAutoAccept);
|
||||
}
|
||||
|
||||
if (focus === this.oldFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elementsToRefresh: any[] = [];
|
||||
|
||||
if (this.oldFocus) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This document includes material copied
|
||||
* Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes includes material copied
|
||||
* from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.)"
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -280,7 +280,10 @@ export class JSONSchemaService implements IJSONSchemaService {
|
|||
this.contributionAssociations[pattern] = associations;
|
||||
|
||||
var fpa = this.getOrAddFilePatternAssociation(pattern);
|
||||
associations.forEach(schemaId => fpa.addSchema(schemaId));
|
||||
associations.forEach(schemaId => {
|
||||
var id = this.normalizeId(schemaId);
|
||||
fpa.addSchema(id)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +330,10 @@ export class JSONSchemaService implements IJSONSchemaService {
|
|||
for (var pattern in this.contributionAssociations) {
|
||||
var fpa = this.getOrAddFilePatternAssociation(pattern);
|
||||
|
||||
this.contributionAssociations[pattern].forEach(schemaId => fpa.addSchema(schemaId));
|
||||
this.contributionAssociations[pattern].forEach(schemaId => {
|
||||
var id = this.normalizeId(schemaId);
|
||||
fpa.addSchema(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
|
||||
// Return true if the given text is composed entirely of whitespace.
|
||||
this.is_whitespace = function(text) {
|
||||
for (var n = 0; n < text.length; text++) {
|
||||
for (var n = 0; n < text.length; n++) {
|
||||
if (!this.Utils.in_array(text.charAt(n), this.Utils.whitespace)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -467,7 +467,7 @@
|
|||
} else if (tag_check === 'script' &&
|
||||
(tag_complete.search('type') === -1 ||
|
||||
(tag_complete.search('type') > -1 &&
|
||||
tag_complete.search(/\b(text|application)\/(x-)?(javascript|ecmascript|jscript|livescript)/) > -1))) {
|
||||
tag_complete.search(/\b(text|application)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json)/) > -1))) {
|
||||
if (!peek) {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'SCRIPT';
|
||||
|
@ -525,7 +525,7 @@
|
|||
matched = false;
|
||||
|
||||
this.pos = start_pos;
|
||||
input_char = this.input.charAt(this.pos);
|
||||
var input_char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
|
||||
while (this.pos <= this.input.length) {
|
||||
|
@ -570,15 +570,34 @@
|
|||
return comment;
|
||||
};
|
||||
|
||||
this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety
|
||||
function tokenMatcher(delimiter) {
|
||||
var token = '';
|
||||
|
||||
var add = function (str) {
|
||||
var newToken = token + str.toLowerCase();
|
||||
token = newToken.length <= delimiter.length ? newToken : newToken.substr(newToken.length - delimiter.length, delimiter.length);
|
||||
};
|
||||
|
||||
var doesNotMatch = function () {
|
||||
return token.indexOf(delimiter) === -1;
|
||||
};
|
||||
|
||||
return {
|
||||
add: add,
|
||||
doesNotMatch: doesNotMatch
|
||||
};
|
||||
}
|
||||
|
||||
this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety
|
||||
if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
|
||||
return '';
|
||||
}
|
||||
var input_char = '';
|
||||
var content = '';
|
||||
var min_index = 0;
|
||||
var space = true;
|
||||
|
||||
var delimiterMatcher = tokenMatcher(delimiter);
|
||||
|
||||
do {
|
||||
|
||||
if (this.pos >= this.input.length) {
|
||||
|
@ -606,16 +625,17 @@
|
|||
}
|
||||
}
|
||||
content += input_char;
|
||||
delimiterMatcher.add(input_char);
|
||||
this.line_char_count++;
|
||||
space = true;
|
||||
|
||||
if (indent_handlebars && input_char === '{' && content.length && content.charAt(content.length - 2) === '{') {
|
||||
// Handlebars expressions in strings should also be unformatted.
|
||||
content += this.get_unformatted('}}');
|
||||
// These expressions are opaque. Ignore delimiters found in them.
|
||||
min_index = content.length;
|
||||
// Don't consider when stopping for delimiters.
|
||||
}
|
||||
} while (content.toLowerCase().indexOf(delimiter, min_index) === -1);
|
||||
} while (delimiterMatcher.doesNotMatch());
|
||||
|
||||
return content;
|
||||
};
|
||||
|
||||
|
@ -832,6 +852,21 @@
|
|||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_HANDLEBARS_ELSE':
|
||||
// Don't add a newline if opening {{#if}} tag is on the current line
|
||||
var foundIfOnCurrentLine = false;
|
||||
for (var lastCheckedOutput=multi_parser.output.length-1; lastCheckedOutput>=0; lastCheckedOutput--) {
|
||||
if (multi_parser.output[lastCheckedOutput] === '\n') {
|
||||
break;
|
||||
} else {
|
||||
if (multi_parser.output[lastCheckedOutput].match(/{{#if/)) {
|
||||
foundIfOnCurrentLine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundIfOnCurrentLine) {
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
}
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
if (multi_parser.indent_content) {
|
||||
multi_parser.indent();
|
||||
|
|
|
@ -298,6 +298,17 @@ jsonContributionRegistry.registerSchema('http://json-schema.org/draft-04/schema#
|
|||
],
|
||||
'description': nls.localize('schema.json.type', 'Either a string of one of the basic schema types (number, integer, null, array, object, boolean, string) or an array of strings specifying a subset of those types.')
|
||||
},
|
||||
'format': {
|
||||
'anyOf': [
|
||||
{
|
||||
'type': 'string',
|
||||
'description': nls.localize('schema.json.format', 'Describes the format expected for the value.'),
|
||||
'enum': [ 'date-time', 'uri', 'email', 'hostname', 'ipv4', 'ipv6', 'regex']
|
||||
},{
|
||||
'type': 'string'
|
||||
}
|
||||
]
|
||||
},
|
||||
'allOf': {
|
||||
'allOf': [
|
||||
{ '$ref': '#/definitions/schemaArray' }
|
||||
|
|
2
src/vs/vscode.d.ts
vendored
2
src/vs/vscode.d.ts
vendored
|
@ -3319,7 +3319,6 @@ declare namespace vscode {
|
|||
*
|
||||
* ```javascript
|
||||
* export function activate(context: vscode.ExtensionContext) {
|
||||
*
|
||||
* let api = {
|
||||
* sum(a, b) {
|
||||
* return a + b;
|
||||
|
@ -3328,7 +3327,6 @@ declare namespace vscode {
|
|||
* return a * b;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* // 'export' public api-surface
|
||||
* return api;
|
||||
* }
|
||||
|
|
|
@ -23,7 +23,6 @@ import {ExtHostLanguages} from 'vs/workbench/api/common/extHostLanguages';
|
|||
import {ExtHostLanguageFeatures} from 'vs/workbench/api/common/extHostLanguageFeatures';
|
||||
import {registerApiCommands} from 'vs/workbench/api/common/extHostApiCommands';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import 'vs/workbench/api/common/extHostTypes.marshalling';
|
||||
import Modes = require('vs/editor/common/modes');
|
||||
import {IModeService} from 'vs/editor/common/services/modeService';
|
||||
import {ICommentsSupportContribution, ITokenTypeClassificationSupportContribution} from 'vs/editor/common/modes/supports';
|
||||
|
@ -133,12 +132,36 @@ export class ExtHostAPIImplementation {
|
|||
});
|
||||
|
||||
const pluginHostCommands = this._threadService.getRemotable(ExtHostCommands);
|
||||
const pluginHostEditors = this._threadService.getRemotable(ExtHostEditors);
|
||||
const pluginHostMessageService = new ExtHostMessageService(this._threadService, this.commands);
|
||||
const pluginHostQuickOpen = new ExtHostQuickOpen(this._threadService);
|
||||
const pluginHostStatusBar = new ExtHostStatusBar(this._threadService);
|
||||
const extHostOutputService = new ExtHostOutputService(this._threadService);
|
||||
|
||||
// commands namespace
|
||||
this.commands = {
|
||||
registerCommand<T>(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
|
||||
return pluginHostCommands.registerCommand(id, command, thisArgs);
|
||||
},
|
||||
registerTextEditorCommand(commandId: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => void, thisArg?: any): vscode.Disposable {
|
||||
return pluginHostCommands.registerTextEditorCommand(commandId, callback, thisArg);
|
||||
registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => void, thisArg?: any): vscode.Disposable {
|
||||
let actualCallback: typeof callback = thisArg ? callback.bind(thisArg) : callback;
|
||||
return pluginHostCommands.registerCommand(id, () => {
|
||||
let activeTextEditor = pluginHostEditors.getActiveTextEditor();
|
||||
if (!activeTextEditor) {
|
||||
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
return;
|
||||
}
|
||||
|
||||
activeTextEditor.edit((edit: vscode.TextEditorEdit) => {
|
||||
actualCallback(activeTextEditor, edit);
|
||||
}).then((result) => {
|
||||
if (!result) {
|
||||
console.warn('Edits from command ' + id + ' were not applied.');
|
||||
}
|
||||
}, (err) => {
|
||||
console.warn('An error occured while running command ' + id, err);
|
||||
});
|
||||
});
|
||||
},
|
||||
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
return pluginHostCommands.executeCommand(id, args);
|
||||
|
@ -148,11 +171,6 @@ export class ExtHostAPIImplementation {
|
|||
}
|
||||
};
|
||||
|
||||
const pluginHostEditors = this._threadService.getRemotable(ExtHostEditors);
|
||||
const pluginHostMessageService = new ExtHostMessageService(this._threadService, this.commands);
|
||||
const pluginHostQuickOpen = new ExtHostQuickOpen(this._threadService);
|
||||
const pluginHostStatusBar = new ExtHostStatusBar(this._threadService);
|
||||
const extHostOutputService = new ExtHostOutputService(this._threadService);
|
||||
this.window = {
|
||||
get activeTextEditor() {
|
||||
return pluginHostEditors.getActiveTextEditor();
|
||||
|
|
|
@ -175,7 +175,7 @@ class ExtHostApiCommands {
|
|||
};
|
||||
return this._commands.executeCommand<modes.IReference[]>('_executeDefinitionProvider', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toLocation);
|
||||
return value.map(typeConverters.location.to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ class ExtHostApiCommands {
|
|||
};
|
||||
return this._commands.executeCommand<modes.IReference[]>('_executeDocumentHighlights', args).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConverters.toLocation);
|
||||
return value.map(typeConverters.location.to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegi
|
|||
import {IKeybindingService, ICommandHandlerDescription} from 'vs/platform/keybinding/common/keybindingService';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {ExtHostEditors} from 'vs/workbench/api/common/extHostEditors';
|
||||
import * as vscode from 'vscode';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import {cloneAndChange} from 'vs/base/common/objects';
|
||||
|
||||
interface CommandHandler {
|
||||
callback: Function;
|
||||
|
@ -30,7 +32,7 @@ export class ExtHostCommands {
|
|||
this._proxy = threadService.getRemotable(MainThreadCommands);
|
||||
}
|
||||
|
||||
registerCommand(id: string, callback: <T>(...args: any[]) => T | Thenable<T>, thisArg?: any, description?: ICommandHandlerDescription): vscode.Disposable {
|
||||
registerCommand(id: string, callback: <T>(...args: any[]) => T | Thenable<T>, thisArg?: any, description?: ICommandHandlerDescription): extHostTypes.Disposable {
|
||||
|
||||
if (!id.trim().length) {
|
||||
throw new Error('invalid id');
|
||||
|
@ -43,32 +45,7 @@ export class ExtHostCommands {
|
|||
this._commands[id] = { callback, thisArg, description };
|
||||
this._proxy.$registerCommand(id);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
delete this._commands[id];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => void, thisArg?: any): vscode.Disposable {
|
||||
let actualCallback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => void = thisArg ? callback.bind(thisArg) : callback;
|
||||
return this.registerCommand(id, () => {
|
||||
let activeTextEditor = this._pluginHostEditors.getActiveTextEditor();
|
||||
if (!activeTextEditor) {
|
||||
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
return;
|
||||
}
|
||||
|
||||
activeTextEditor.edit((edit: vscode.TextEditorEdit) => {
|
||||
actualCallback(activeTextEditor, edit);
|
||||
}).then((result) => {
|
||||
if (!result) {
|
||||
console.warn('Edits from command ' + id + ' were not applied.');
|
||||
}
|
||||
}, (err) => {
|
||||
console.warn('An error occured while running command ' + id, err);
|
||||
});
|
||||
});
|
||||
return new extHostTypes.Disposable(() => delete this._commands[id]);
|
||||
}
|
||||
|
||||
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
|
@ -79,13 +56,22 @@ export class ExtHostCommands {
|
|||
return this.$executeContributedCommand(id, ...args);
|
||||
|
||||
} else {
|
||||
// // check that we can get all parameters over to
|
||||
// // the other side
|
||||
// for (let i = 0; i < args.length; i++) {
|
||||
// if (args[i] !== null && typeof args[i] === 'object' && !canSerialize(args[i])) {
|
||||
// throw new Error('illegal argument - can not serialize argument number: ' + i)
|
||||
// }
|
||||
// }
|
||||
// automagically convert some argument types
|
||||
|
||||
args = cloneAndChange(args, function(value) {
|
||||
if (value instanceof extHostTypes.Position) {
|
||||
return extHostTypeConverter.fromPosition(value);
|
||||
}
|
||||
if (value instanceof extHostTypes.Range) {
|
||||
return extHostTypeConverter.fromRange(value);
|
||||
}
|
||||
if (value instanceof extHostTypes.Location) {
|
||||
return extHostTypeConverter.location.from(value);
|
||||
}
|
||||
if (!Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
return this._proxy.$executeCommand(id, args);
|
||||
}
|
||||
|
@ -95,7 +81,7 @@ export class ExtHostCommands {
|
|||
$executeContributedCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
let command = this._commands[id];
|
||||
if (!command) {
|
||||
return Promise.reject<T>(id);
|
||||
return Promise.reject<T>(`Contributed command '${id}' does not exist.`);
|
||||
}
|
||||
try {
|
||||
let {callback, thisArg, description} = command;
|
||||
|
@ -156,7 +142,7 @@ export class MainThreadCommands {
|
|||
KeybindingsRegistry.registerCommandDesc({
|
||||
id,
|
||||
handler: (serviceAccessor, ...args: any[]) => {
|
||||
return this._proxy.$executeContributedCommand(id, ...args); //TODO@Joh - we cannot serialize the args
|
||||
return this._proxy.$executeContributedCommand(id, ...args);
|
||||
},
|
||||
weight: undefined,
|
||||
context: undefined,
|
||||
|
@ -177,19 +163,6 @@ export class MainThreadCommands {
|
|||
$getCommands(): Thenable<string[]> {
|
||||
return TPromise.as(Object.keys(KeybindingsRegistry.getCommands()));
|
||||
}
|
||||
|
||||
$getCommandHandlerDescriptions(): TPromise<{ [id: string]: string | ICommandHandlerDescription }> {
|
||||
return this._proxy.$getContributedCommandHandlerDescriptions().then(result => {
|
||||
const commands = KeybindingsRegistry.getCommands();
|
||||
for (let id in commands) {
|
||||
let {description} = commands[id];
|
||||
if (description) {
|
||||
result[id] = description;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,7 +171,18 @@ export class MainThreadCommands {
|
|||
KeybindingsRegistry.registerCommandDesc({
|
||||
id: '_generateCommandsDocumentation',
|
||||
handler: function(accessor) {
|
||||
return accessor.get(IThreadService).getRemotable(MainThreadCommands).$getCommandHandlerDescriptions().then(result => {
|
||||
return accessor.get(IThreadService).getRemotable(ExtHostCommands).$getContributedCommandHandlerDescriptions().then(result => {
|
||||
|
||||
// add local commands
|
||||
const commands = KeybindingsRegistry.getCommands();
|
||||
for (let id in commands) {
|
||||
let {description} = commands[id];
|
||||
if (description) {
|
||||
result[id] = description;
|
||||
}
|
||||
}
|
||||
|
||||
// print all as markdown
|
||||
const all: string[] = [];
|
||||
for (let id in result) {
|
||||
all.push('`' + id + '` - ' + _generateMarkdown(result[id]));
|
||||
|
@ -228,4 +212,4 @@ function _generateMarkdown(description: string | ICommandHandlerDescription): st
|
|||
parts.push('\n\n');
|
||||
return parts.join('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import URI from 'vs/base/common/uri';
|
||||
import {DefaultFilter} from 'vs/editor/common/modes/modesFilters';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
|
||||
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
|
||||
import {Range as EditorRange} from 'vs/editor/common/core/range';
|
||||
import * as vscode from 'vscode';
|
||||
|
@ -33,7 +33,7 @@ import {ParameterHintsRegistry} from 'vs/editor/contrib/parameterHints/common/pa
|
|||
import {SuggestRegistry} from 'vs/editor/contrib/suggest/common/suggest';
|
||||
|
||||
function isThenable<T>(obj: any): obj is Thenable<T> {
|
||||
return obj && typeof obj['then'] === 'function';
|
||||
return obj && typeof (<Thenable<any>>obj).then === 'function';
|
||||
}
|
||||
|
||||
function asWinJsPromise<T>(callback: (token: vscode.CancellationToken) => T | Thenable<T>): TPromise<T> {
|
||||
|
@ -72,72 +72,112 @@ class OutlineAdapter implements IOutlineSupport {
|
|||
}
|
||||
}
|
||||
|
||||
interface CachedCodeLens {
|
||||
symbols: modes.ICodeLensSymbol[];
|
||||
lenses: vscode.CodeLens[];
|
||||
disposables: IDisposable[];
|
||||
};
|
||||
|
||||
class CodeLensAdapter implements modes.ICodeLensSupport {
|
||||
|
||||
private _documents: ExtHostModelService;
|
||||
private _commands: ExtHostCommands;
|
||||
private _provider: vscode.CodeLensProvider;
|
||||
|
||||
private _cache: { [uri: string]: vscode.CodeLens[] } = Object.create(null);
|
||||
private _cache: { [uri: string]: { version: number; data: TPromise<CachedCodeLens>; } } = Object.create(null);
|
||||
|
||||
constructor(documents: ExtHostModelService, provider: vscode.CodeLensProvider) {
|
||||
constructor(documents: ExtHostModelService, commands: ExtHostCommands, provider: vscode.CodeLensProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
findCodeLensSymbols(resource: URI): TPromise<modes.ICodeLensSymbol[]> {
|
||||
let doc = this._documents.getDocument(resource);
|
||||
let key = resource.toString();
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const version = doc.version;
|
||||
const key = resource.toString();
|
||||
|
||||
delete this._cache[key];
|
||||
// from cache
|
||||
let entry = this._cache[key];
|
||||
if (entry && entry.version === version) {
|
||||
return entry.data.then(cached => cached.symbols);
|
||||
}
|
||||
|
||||
return asWinJsPromise(token => this._provider.provideCodeLenses(doc, token)).then(value => {
|
||||
if (!Array.isArray(value)) {
|
||||
const newCodeLensData = asWinJsPromise(token => this._provider.provideCodeLenses(doc, token)).then(lenses => {
|
||||
if (!Array.isArray(lenses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._cache[key] = value;
|
||||
const data: CachedCodeLens = {
|
||||
lenses,
|
||||
symbols: [],
|
||||
disposables: [],
|
||||
}
|
||||
|
||||
return value.map((lens, i) => {
|
||||
return <modes.ICodeLensSymbol>{
|
||||
lenses.forEach((lens, i) => {
|
||||
data.symbols.push(<modes.ICodeLensSymbol>{
|
||||
id: String(i),
|
||||
range: TypeConverters.fromRange(lens.range),
|
||||
command: TypeConverters.Command.from(lens.command)
|
||||
};
|
||||
command: TypeConverters.Command.from(lens.command, { commands: this._commands, disposables: data.disposables })
|
||||
});
|
||||
});
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
this._cache[key] = {
|
||||
version,
|
||||
data: newCodeLensData
|
||||
};
|
||||
|
||||
return newCodeLensData.then(newCached => {
|
||||
if (entry) {
|
||||
// only now dispose old commands et al
|
||||
entry.data.then(oldCached => disposeAll(oldCached.disposables));
|
||||
}
|
||||
return newCached && newCached.symbols;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
resolveCodeLensSymbol(resource: URI, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol> {
|
||||
|
||||
let lenses = this._cache[resource.toString()];
|
||||
if (!lenses) {
|
||||
const entry = this._cache[resource.toString()];
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
let lens = lenses[Number(symbol.id)];
|
||||
if (!lens) {
|
||||
return;
|
||||
}
|
||||
return entry.data.then(cachedData => {
|
||||
|
||||
let resolve: TPromise<vscode.CodeLens>;
|
||||
if (typeof this._provider.resolveCodeLens !== 'function' || lens.isResolved) {
|
||||
resolve = TPromise.as(lens);
|
||||
} else {
|
||||
resolve = asWinJsPromise(token => this._provider.resolveCodeLens(lens, token));
|
||||
}
|
||||
|
||||
return resolve.then(newLens => {
|
||||
lens = newLens || lens;
|
||||
let command = lens.command;
|
||||
if (!command) {
|
||||
command = {
|
||||
title: '<<MISSING COMMAND>>',
|
||||
command: 'missing',
|
||||
};
|
||||
if (!cachedData) {
|
||||
return;
|
||||
}
|
||||
|
||||
symbol.command = TypeConverters.Command.from(command);
|
||||
return symbol;
|
||||
let lens = cachedData.lenses[Number(symbol.id)];
|
||||
if (!lens) {
|
||||
return;
|
||||
}
|
||||
|
||||
let resolve: TPromise<vscode.CodeLens>;
|
||||
if (typeof this._provider.resolveCodeLens !== 'function' || lens.isResolved) {
|
||||
resolve = TPromise.as(lens);
|
||||
} else {
|
||||
resolve = asWinJsPromise(token => this._provider.resolveCodeLens(lens, token));
|
||||
}
|
||||
|
||||
return resolve.then(newLens => {
|
||||
lens = newLens || lens;
|
||||
let command = lens.command;
|
||||
if (!command) {
|
||||
command = {
|
||||
title: '<<MISSING COMMAND>>',
|
||||
command: 'missing',
|
||||
};
|
||||
}
|
||||
|
||||
symbol.command = TypeConverters.Command.from(command, { commands: this._commands, disposables: cachedData.disposables });
|
||||
return symbol;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -279,30 +319,35 @@ class QuickFixAdapter implements modes.IQuickFixSupport {
|
|||
private _commands: ExtHostCommands;
|
||||
private _provider: vscode.CodeActionProvider;
|
||||
|
||||
private _cachedCommands: IDisposable[] = [];
|
||||
|
||||
constructor(documents: ExtHostModelService, commands: ExtHostCommands, provider: vscode.CodeActionProvider) {
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
getQuickFixes(resource: URI, range: IRange, marker?: IMarker[]): TPromise<modes.IQuickFix[]> {
|
||||
getQuickFixes(resource: URI, range: IRange, markers?: IMarker[]): TPromise<modes.IQuickFix[]> {
|
||||
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const ran = TypeConverters.toRange(range);
|
||||
const diagnostics = marker.map(marker => {
|
||||
const diagnostics = markers.map(marker => {
|
||||
const diag = new Diagnostic(TypeConverters.toRange(marker), marker.message);
|
||||
diag.code = marker.code;
|
||||
diag.severity = TypeConverters.toDiagnosticSeverty(marker.severity);
|
||||
return diag;
|
||||
});
|
||||
|
||||
this._cachedCommands = disposeAll(this._cachedCommands);
|
||||
const ctx = { commands: this._commands, disposables: this._cachedCommands };
|
||||
|
||||
return asWinJsPromise(token => this._provider.provideCodeActions(doc, ran, { diagnostics: <any>diagnostics }, token)).then(commands => {
|
||||
if (!Array.isArray(commands)) {
|
||||
return;
|
||||
}
|
||||
return commands.map((command, i) => {
|
||||
return <modes.IQuickFix> {
|
||||
command: TypeConverters.Command.from(command),
|
||||
command: TypeConverters.Command.from(command, ctx),
|
||||
score: i
|
||||
};
|
||||
});
|
||||
|
@ -310,8 +355,8 @@ class QuickFixAdapter implements modes.IQuickFixSupport {
|
|||
}
|
||||
|
||||
runQuickFixAction(resource: URI, range: IRange, quickFix: modes.IQuickFix): any {
|
||||
let {command} = quickFix;
|
||||
return this._commands.executeCommand(command.id, ...command.arguments);
|
||||
let command = TypeConverters.Command.to(quickFix.command);
|
||||
return this._commands.executeCommand(command.command, ...command.arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,7 +689,7 @@ export class ExtHostLanguageFeatures {
|
|||
|
||||
registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter[handle] = new CodeLensAdapter(this._documents, provider);
|
||||
this._adapter[handle] = new CodeLensAdapter(this._documents, this._commands, provider);
|
||||
this._proxy.$registerCodeLensSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {ExtHostCommands} from 'vs/workbench/api/common/extHostCommands';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
|
||||
import {IDisposable} from 'vs/base/common/lifecycle';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as types from './extHostTypes';
|
||||
import {Position as EditorPosition} from 'vs/platform/editor/common/editor';
|
||||
|
@ -295,11 +298,18 @@ export function toSymbolInformation(bearing: ITypeBearing): types.SymbolInformat
|
|||
}
|
||||
|
||||
|
||||
export function toLocation(reference: modes.IReference): types.Location {
|
||||
return new types.Location(reference.resource, toRange(reference.range));
|
||||
export const location = {
|
||||
from(value: types.Location): modes.IReference {
|
||||
return {
|
||||
range: fromRange(value.range),
|
||||
resource: value.uri
|
||||
}
|
||||
},
|
||||
to(value: modes.IReference): types.Location {
|
||||
return new types.Location(value.resource, toRange(value.range));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function fromHover(hover: vscode.Hover): modes.IComputeExtraInfoResult {
|
||||
return <modes.IComputeExtraInfoResult>{
|
||||
range: fromRange(hover.range),
|
||||
|
@ -419,24 +429,47 @@ export namespace SignatureHelp {
|
|||
}
|
||||
}
|
||||
|
||||
export const Command = {
|
||||
from(command: vscode.Command): modes.ICommand {
|
||||
if (command) {
|
||||
return <modes.ICommand>{
|
||||
id: command.command,
|
||||
title: command.title,
|
||||
arguments: command.arguments
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
to(command: modes.ICommand): vscode.Command {
|
||||
if (command) {
|
||||
return <vscode.Command>{
|
||||
command: command.id,
|
||||
title: command.title,
|
||||
arguments: command.arguments
|
||||
};
|
||||
export namespace Command {
|
||||
|
||||
const _cache: { [id: string]: vscode.Command } = Object.create(null);
|
||||
let _idPool = 1;
|
||||
|
||||
export function from(command: vscode.Command, context: { commands: ExtHostCommands; disposables: IDisposable[]; }): modes.ICommand {
|
||||
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = <modes.ICommand>{
|
||||
id: command.command,
|
||||
title: command.title
|
||||
};
|
||||
|
||||
if (!isFalsyOrEmpty(command.arguments)) {
|
||||
|
||||
// keep command around
|
||||
const id = `${command.command}-no-args-wrapper-${_idPool++}`;
|
||||
result.id = id;
|
||||
_cache[id] = command;
|
||||
|
||||
const disposable1 = context.commands.registerCommand(id, () => context.commands.executeCommand(command.command, ..._cache[id].arguments));
|
||||
const disposable2 = { dispose() { delete _cache[id] } };
|
||||
context.disposables.push(disposable1, disposable2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
export function to(command: modes.ICommand): vscode.Command {
|
||||
|
||||
let result = _cache[command.id];
|
||||
if (!result) {
|
||||
result = {
|
||||
command: command.id,
|
||||
title: command.title
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {registerMarshallingContribution, IMarshallingContribution} from 'vs/base/common/marshalling';
|
||||
import * as types from './extHostTypes';
|
||||
import {fromPosition, fromRange} from './extHostTypeConverters';
|
||||
import {IReference} from 'vs/editor/common/modes';
|
||||
|
||||
abstract class OneWayMarshalling<T> implements IMarshallingContribution {
|
||||
|
||||
canDeserialize() {
|
||||
return false;
|
||||
}
|
||||
|
||||
deserialize() {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
abstract canSerialize(obj: any): boolean;
|
||||
|
||||
abstract serialize(obj: T, serialize: (obj: any) => any): any;
|
||||
}
|
||||
|
||||
class RangeMarshalling extends OneWayMarshalling<types.Range> {
|
||||
|
||||
canSerialize(obj: any): boolean {
|
||||
return obj instanceof types.Range;
|
||||
}
|
||||
|
||||
serialize(obj: types.Range, serialize: (obj: any) => any): any {
|
||||
return fromRange(obj);
|
||||
}
|
||||
}
|
||||
|
||||
class PositionMarshalling extends OneWayMarshalling<types.Position> {
|
||||
|
||||
canSerialize(obj: any): boolean {
|
||||
return obj instanceof types.Position;
|
||||
}
|
||||
|
||||
serialize(obj: types.Position, serialize: (obj: any) => any): any {
|
||||
return fromPosition(obj);
|
||||
}
|
||||
}
|
||||
|
||||
class LocationMarshalling extends OneWayMarshalling<types.Location> {
|
||||
|
||||
canSerialize(obj: any): boolean {
|
||||
return obj instanceof types.Location;
|
||||
}
|
||||
|
||||
serialize(obj: types.Location, serialize: (obj: any) => any): any {
|
||||
return <IReference>{
|
||||
resource: serialize(obj.uri),
|
||||
range: serialize(obj.range)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registerMarshallingContribution(new RangeMarshalling());
|
||||
registerMarshallingContribution(new PositionMarshalling());
|
||||
registerMarshallingContribution(new LocationMarshalling());
|
|
@ -22,7 +22,7 @@ function getAgent(rawRequestURL: string, proxyURL: string, strictSSL: boolean =
|
|||
}
|
||||
|
||||
return new HttpsProxyAgent({
|
||||
host: proxyEndpoint.host,
|
||||
host: proxyEndpoint.hostname,
|
||||
port: Number(proxyEndpoint.port),
|
||||
rejectUnauthorized: strictSSL
|
||||
});
|
||||
|
|
|
@ -40,8 +40,8 @@ export class BreakpointWidget extends ZoneWidget {
|
|||
});
|
||||
dom.addClass(this.inputBox.inputElement, platform.isWindows ? 'windows' : platform.isMacintosh ? 'mac' : 'linux');
|
||||
this.inputBox.value = (breakpoint && breakpoint.condition) ? breakpoint.condition : '';
|
||||
// TODO@Isidor check with Alex why does the editor steal focus
|
||||
setTimeout(() => this.inputBox.focus(), 150);
|
||||
// Due to an electron bug we have to do the timeout, otherwise we do not get focus
|
||||
setTimeout(() => this.inputBox.focus(), 0);
|
||||
|
||||
let disposed = false;
|
||||
const toDispose: [lifecycle.IDisposable] = [this.inputBox, this];
|
||||
|
|
|
@ -13,7 +13,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
|||
import keyboard = require('vs/base/browser/keyboardEvent');
|
||||
import editorbrowser = require('vs/editor/browser/editorBrowser');
|
||||
import editorcommon = require('vs/editor/common/editorCommon');
|
||||
import { DebugHoverWidget } from 'vs/workbench/parts/debug/browser/debugHoverWidget';
|
||||
import { DebugHoverWidget } from 'vs/workbench/parts/debug/browser/debugHover';
|
||||
import debugactions = require('vs/workbench/parts/debug/electron-browser/debugActions');
|
||||
import debug = require('vs/workbench/parts/debug/common/debug');
|
||||
import { IWorkspaceContextService } from 'vs/workbench/services/workspace/common/contextService';
|
||||
|
@ -37,7 +37,7 @@ export class DebugEditorContribution implements editorcommon.IEditorContribution
|
|||
) {
|
||||
this.breakpointHintDecoration = [];
|
||||
this.toDispose = [];
|
||||
this.hoverWidget = new DebugHoverWidget(this.editor, this.debugService);
|
||||
this.hoverWidget = new DebugHoverWidget(this.editor, this.debugService, this.instantiationService);
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ export class DebugEditorContribution implements editorcommon.IEditorContribution
|
|||
// hover business
|
||||
|
||||
private onEditorMouseDown(mouseEvent: editorbrowser.IMouseEvent): void {
|
||||
if (mouseEvent.target.type === editorcommon.MouseTargetType.CONTENT_WIDGET && mouseEvent.target.detail === DebugHoverWidget.ID) {
|
||||
if (mouseEvent.target.type === editorcommon.MouseTargetType.OVERLAY_WIDGET && mouseEvent.target.detail === DebugHoverWidget.ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -163,8 +163,8 @@ export class DebugEditorContribution implements editorcommon.IEditorContribution
|
|||
const targetType = mouseEvent.target.type;
|
||||
const stopKey = env.isMacintosh ? 'metaKey' : 'ctrlKey';
|
||||
|
||||
if (targetType === editorcommon.MouseTargetType.CONTENT_WIDGET && mouseEvent.target.detail === DebugHoverWidget.ID && !(<any>mouseEvent.event)[stopKey]) {
|
||||
// mouse moved on top of content hover widget
|
||||
if (targetType === editorcommon.MouseTargetType.OVERLAY_WIDGET && mouseEvent.target.detail === DebugHoverWidget.ID && !(<any>mouseEvent.event)[stopKey]) {
|
||||
// mouse moved on top of debug hover widget
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
|
|||
range: createRange(sf.lineNumber, sf.column, sf.lineNumber, sf.column + 1)
|
||||
});
|
||||
|
||||
if (thread.exception) {
|
||||
if (thread.stoppedReason === 'exception') {
|
||||
result.push({
|
||||
options: DebugEditorModelManager.TOP_STACK_FRAME_EXCEPTION_DECORATION,
|
||||
range: wholeLineRange
|
||||
|
|
|
@ -3,16 +3,22 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import htmlcontentrenderer = require('vs/base/browser/htmlContentRenderer');
|
||||
import errors = require('vs/base/common/errors');
|
||||
import dom = require('vs/base/browser/dom');
|
||||
import { ITree } from 'vs/base/parts/tree/common/tree';
|
||||
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
|
||||
import { DefaultController, ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import editorbrowser = require('vs/editor/browser/editorBrowser');
|
||||
import editorcommon = require('vs/editor/common/editorCommon');
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import debug = require('vs/workbench/parts/debug/common/debug');
|
||||
import { tokenizeToHtmlContent } from 'vs/editor/common/modes/textToHtmlTokenizer';
|
||||
import viewer = require('vs/workbench/parts/debug/browser/debugViewer');
|
||||
|
||||
const $ = dom.emmet;
|
||||
const stringRegex = /^(['"]).*\1$/;
|
||||
const debugTreeOptions = {
|
||||
indentPixels: 8,
|
||||
twistiePixels: 20
|
||||
};
|
||||
|
||||
export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
||||
|
||||
|
@ -22,12 +28,23 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
|||
|
||||
private domNode: HTMLElement;
|
||||
private isVisible: boolean;
|
||||
private tree: ITree;
|
||||
private showAtPosition: editorcommon.IPosition;
|
||||
private lastHoveringOver: string;
|
||||
private highlightDecorations: string[];
|
||||
private treeContainer: HTMLElement;
|
||||
private valueContainer: HTMLElement;
|
||||
|
||||
constructor(private editor: editorbrowser.ICodeEditor, private debugService: debug.IDebugService) {
|
||||
constructor(private editor: editorbrowser.ICodeEditor, private debugService: debug.IDebugService, private instantiationService: IInstantiationService) {
|
||||
this.domNode = $('.debug-hover-widget monaco-editor-background');
|
||||
this.treeContainer = dom.append(this.domNode, $('.debug-hover-tree'));
|
||||
this.tree = new Tree(this.treeContainer, {
|
||||
dataSource: new viewer.VariablesDataSource(this.debugService),
|
||||
renderer: this.instantiationService.createInstance(viewer.VariablesRenderer),
|
||||
controller: new DebugHoverController()
|
||||
}, debugTreeOptions);
|
||||
this.valueContainer = dom.append(this.domNode, $('.debug-hover-value'));
|
||||
|
||||
this.isVisible = false;
|
||||
this.showAtPosition = null;
|
||||
this.lastHoveringOver = null;
|
||||
|
@ -95,8 +112,6 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
|||
return;
|
||||
}
|
||||
|
||||
const variable = variables[0];
|
||||
|
||||
// show it
|
||||
this.highlightDecorations = this.editor.deltaDecorations(this.highlightDecorations, [{
|
||||
range: {
|
||||
|
@ -110,54 +125,21 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
|||
}
|
||||
}]);
|
||||
this.lastHoveringOver = hoveringOver;
|
||||
|
||||
if (variable.reference > 0 && variable.value.indexOf('function') === -1) {
|
||||
let objectToString = '{\n';
|
||||
variable.getChildren(this.debugService).then(children => {
|
||||
if (!children) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const nameAndValue = ` ${ children[i].name }: ${ children[i].value }`;
|
||||
objectToString += nameAndValue.substr(0, 80);
|
||||
// add a quote to the end of the string if cropped
|
||||
if (nameAndValue.length > 80 && stringRegex.test(children[i].value)) {
|
||||
objectToString += children[i].value[0];
|
||||
}
|
||||
|
||||
if (i < children.length - 1) {
|
||||
objectToString += ',\n';
|
||||
}
|
||||
}
|
||||
objectToString += '\n}';
|
||||
return objectToString;
|
||||
}).done(value => this.doShow(pos, value), () => this.hide());
|
||||
} else {
|
||||
this.doShow(pos, variable.value);
|
||||
}
|
||||
this.doShow(pos, variables[0]);
|
||||
}
|
||||
|
||||
private doShow(position: editorcommon.IEditorPosition, value: string): void {
|
||||
const model = this.editor.getModel();
|
||||
if (!value || !model) {
|
||||
return;
|
||||
private doShow(position: editorcommon.IEditorPosition, expression: debug.IExpression): void {
|
||||
if (expression.reference > 0) {
|
||||
this.valueContainer.hidden = true;
|
||||
this.treeContainer.hidden = false;
|
||||
this.tree.setInput(expression).done(null, errors.onUnexpectedError);
|
||||
this.tree.layout(this.treeContainer.clientHeight);
|
||||
} else {
|
||||
this.treeContainer.hidden = true;
|
||||
this.valueContainer.hidden = false;
|
||||
viewer.renderExpressionValue(expression, false, this.valueContainer);
|
||||
}
|
||||
|
||||
let crlfCount = 0;
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value[i] === '\n') {
|
||||
crlfCount++;
|
||||
}
|
||||
if (crlfCount > 12) {
|
||||
value = value.substr(0, i + 1) + ' ...\n}';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.domNode.innerHTML = '';
|
||||
this.domNode.appendChild(htmlcontentrenderer.renderHtml(tokenizeToHtmlContent(value, model.getMode())));
|
||||
this.showAtPosition = position;
|
||||
this.isVisible = true;
|
||||
this.editor.layoutContentWidget(this);
|
||||
|
@ -184,3 +166,16 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget {
|
|||
} : null;
|
||||
}
|
||||
}
|
||||
|
||||
class DebugHoverController extends DefaultController {
|
||||
|
||||
/* protected */ public onLeftClick(tree: ITree, element: any, eventish: ICancelableEvent, origin: string = 'mouse'): boolean {
|
||||
if (element.reference > 0) {
|
||||
super.onLeftClick(tree, element, eventish, origin);
|
||||
tree.clearFocus();
|
||||
tree.deselect(element);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ const $ = dom.emmet;
|
|||
const booleanRegex = /^true|false$/i;
|
||||
const stringRegex = /^(['"]).*\1$/;
|
||||
|
||||
export function renderExpressionValue(tree: tree.ITree, arg2: debug.IExpression|string, debugInactive: boolean, container: HTMLElement): void {
|
||||
export function renderExpressionValue(arg2: debug.IExpression|string, debugInactive: boolean, container: HTMLElement): void {
|
||||
let value = typeof arg2 === 'string' ? arg2 : arg2.value;
|
||||
|
||||
// remove stale classes
|
||||
|
@ -62,7 +62,7 @@ export function renderVariable(tree: tree.ITree, variable: model.Variable, data:
|
|||
}
|
||||
|
||||
if (variable.value) {
|
||||
renderExpressionValue(tree, variable, debugInactive, data.value);
|
||||
renderExpressionValue(variable, debugInactive, data.value);
|
||||
if (variable.valueChanged && showChanged) {
|
||||
// value changed color has priority over other colors.
|
||||
data.value.className = 'value changed';
|
||||
|
@ -190,11 +190,9 @@ export class CallStackDataSource implements tree.IDataSource {
|
|||
|
||||
const threads = (<model.Model> element).getThreads();
|
||||
const threadsArray: debug.IThread[] = [];
|
||||
for (let reference in threads) {
|
||||
if (threads.hasOwnProperty(reference)) {
|
||||
threadsArray.push(threads[reference]);
|
||||
}
|
||||
}
|
||||
Object.keys(threads).forEach(threadId => {
|
||||
threadsArray.push(threads[threadId]);
|
||||
});
|
||||
|
||||
if (threadsArray.length === 1) {
|
||||
return Promise.as(threadsArray[0].callStack);
|
||||
|
@ -589,7 +587,7 @@ export class WatchExpressionsRenderer implements tree.IRenderer {
|
|||
private renderExpression(tree: tree.ITree, expression: debug.IExpression, data: IVariableTemplateData): void {
|
||||
data.name.textContent = `${expression.name}:`;
|
||||
if (expression.value) {
|
||||
renderExpressionValue(tree, expression, this.debugService.getState() === debug.State.Inactive, data.value);
|
||||
renderExpressionValue(expression, this.debugService.getState() === debug.State.Inactive, data.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -246,10 +246,11 @@ class CallStackView extends viewlet.CollapsibleViewletView {
|
|||
this.toDispose.push(debugModel.addListener2(debug.ModelEvents.CALLSTACK_UPDATED, () => {
|
||||
this.tree.refresh().done(null, errors.onUnexpectedError);
|
||||
}));
|
||||
this.toDispose.push(this.debugService.addListener2(debug.ServiceEvents.STATE_CHANGED, (reason: string) => {
|
||||
if (this.debugService.getState() === debug.State.Stopped && reason !== 'step') {
|
||||
this.messageBox.textContent = nls.localize('debugStopped', "Paused on {0}.", reason);
|
||||
reason === 'exception' ? this.messageBox.classList.add('exception') : this.messageBox.classList.remove('exception');
|
||||
this.toDispose.push(this.debugService.getViewModel().addListener2(debug.ViewModelEvents.FOCUSED_STACK_FRAME_UPDATED, () => {
|
||||
const focussedThread = this.debugService.getModel().getThreads()[this.debugService.getViewModel().getFocusedThreadId()];
|
||||
if (focussedThread && focussedThread.stoppedReason && focussedThread.stoppedReason !== 'step') {
|
||||
this.messageBox.textContent = nls.localize('debugStopped', "Paused on {0}.", focussedThread.stoppedReason);
|
||||
focussedThread.stoppedReason === 'exception' ? this.messageBox.classList.add('exception') : this.messageBox.classList.remove('exception');
|
||||
|
||||
this.messageBox.hidden = false;
|
||||
return;
|
||||
|
|
|
@ -138,44 +138,6 @@
|
|||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* Hover */
|
||||
.monaco-editor .debug-hover-widget {
|
||||
padding: 0 3px 0 3px;
|
||||
border: 1px solid #CCC;
|
||||
position: absolute;
|
||||
margin-top: -1px;
|
||||
cursor: default;
|
||||
z-index: 50;
|
||||
-webkit-animation-duration: 0.15s;
|
||||
-webkit-animation-name: fadeIn;
|
||||
-moz-animation-duration: 0.15s;
|
||||
-moz-animation-name: fadeIn;
|
||||
-ms-animation-duration: 0.15s;
|
||||
-ms-animation-name: fadeIn;
|
||||
animation-duration: 0.15s;
|
||||
animation-name: fadeIn;
|
||||
|
||||
white-space: pre;
|
||||
min-width: 50px;
|
||||
|
||||
-webkit-user-select: text;
|
||||
-ms-user-select: text;
|
||||
-khtml-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-o-user-select: text;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.monaco-editor .debugHoverHighlight {
|
||||
background-color: rgba(173, 214, 255, 0.15);
|
||||
}
|
||||
|
||||
/* Expressions */
|
||||
|
||||
.monaco-workbench .monaco-tree-row .expression {
|
||||
|
@ -352,14 +314,6 @@
|
|||
box-shadow: 0 2px 8px #000;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget {
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debugHoverHighlight {
|
||||
background-color: rgba(38, 79, 120, 0.25);
|
||||
}
|
||||
|
||||
/* High Contrast Theming */
|
||||
|
||||
.monaco-workbench.hc-black .monaco-tree-row:not(.selected) .expression .name {
|
||||
|
|
109
src/vs/workbench/parts/debug/browser/media/debugHover.css
Normal file
109
src/vs/workbench/parts/debug/browser/media/debugHover.css
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-editor .debug-hover-widget {
|
||||
padding: 0 3px 0 3px;
|
||||
border: 1px solid #CCC;
|
||||
position: absolute;
|
||||
margin-top: -1px;
|
||||
cursor: default;
|
||||
z-index: 50;
|
||||
-webkit-animation-duration: 0.15s;
|
||||
-webkit-animation-name: fadeIn;
|
||||
-moz-animation-duration: 0.15s;
|
||||
-moz-animation-name: fadeIn;
|
||||
-ms-animation-duration: 0.15s;
|
||||
-ms-animation-name: fadeIn;
|
||||
animation-duration: 0.15s;
|
||||
animation-name: fadeIn;
|
||||
|
||||
white-space: pre;
|
||||
|
||||
-webkit-user-select: text;
|
||||
-ms-user-select: text;
|
||||
-khtml-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-o-user-select: text;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .debug-hover-tree {
|
||||
line-height: 24px;
|
||||
width: 350px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
/* Disable tree hover highlight in debug hover tree. */
|
||||
.monaco-editor .debug-hover-widget .debug-hover-tree .monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .debug-hover-tree .monaco-tree .monaco-tree-rows > .monaco-tree-row {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .debug-hover-tree .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.monaco-editor .debugHoverHighlight {
|
||||
background-color: rgba(173, 214, 255, 0.15);
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .value {
|
||||
color: rgba(108, 108, 108, 0.8);
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .error {
|
||||
color: #E51400;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .value.number {
|
||||
color: #09885A;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .value.boolean {
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.monaco-editor .debug-hover-widget .value.string {
|
||||
color: #A31515;
|
||||
}
|
||||
|
||||
/* Dark theme */
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget .value {
|
||||
color: rgba(204, 204, 204, 0.6);
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget .error {
|
||||
color: #F48771;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget .value.number {
|
||||
color: #B5CEA8;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget .value.boolean {
|
||||
color: #4E94CE;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget .value.string {
|
||||
color: #CE9178;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debug-hover-widget {
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
.monaco-editor.vs-dark .debugHoverHighlight {
|
||||
background-color: rgba(38, 79, 120, 0.25);
|
||||
}
|
|
@ -208,7 +208,7 @@ export class ReplExpressionsRenderer implements tree.IRenderer {
|
|||
|
||||
private renderInputOutputPair(tree: tree.ITree, expression: debug.IExpression, templateData: IInputOutputPairTemplateData): void {
|
||||
templateData.input.textContent = expression.name;
|
||||
debugviewer.renderExpressionValue(tree, expression, this.debugService.getState() === debug.State.Inactive, templateData.value);
|
||||
debugviewer.renderExpressionValue(expression, this.debugService.getState() === debug.State.Inactive, templateData.value);
|
||||
if (expression.reference > 0) {
|
||||
templateData.annotation.className = 'annotation octicon octicon-info';
|
||||
templateData.annotation.title = nls.localize('stateCapture', "Object state is captured from first evaluation");
|
||||
|
@ -401,7 +401,7 @@ export class ReplExpressionsRenderer implements tree.IRenderer {
|
|||
}
|
||||
|
||||
// value
|
||||
debugviewer.renderExpressionValue(tree, output.value, false, templateData.value);
|
||||
debugviewer.renderExpressionValue(output.value, false, templateData.value);
|
||||
|
||||
// annotation if any
|
||||
if (output.annotation) {
|
||||
|
|
|
@ -22,7 +22,7 @@ export interface IRawModelUpdate {
|
|||
threadId: number;
|
||||
thread?: DebugProtocol.Thread;
|
||||
callStack?: DebugProtocol.StackFrame[];
|
||||
exception?: boolean;
|
||||
stoppedReason?: string;
|
||||
}
|
||||
|
||||
// model
|
||||
|
@ -45,7 +45,7 @@ export interface IThread extends ITreeElement {
|
|||
threadId: number;
|
||||
name: string;
|
||||
callStack: IStackFrame[];
|
||||
exception: boolean;
|
||||
stoppedReason: string;
|
||||
}
|
||||
|
||||
export interface IScope extends IExpressionContainer {
|
||||
|
@ -128,7 +128,7 @@ export interface IViewModel extends ee.EventEmitter {
|
|||
}
|
||||
|
||||
export interface IModel extends ee.IEventEmitter, ITreeElement {
|
||||
getThreads(): { [reference: number]: IThread; };
|
||||
getThreads(): { [threadId: number]: IThread; };
|
||||
getBreakpoints(): IBreakpoint[];
|
||||
areBreakpointsActivated(): boolean;
|
||||
getFunctionBreakpoints(): IFunctionBreakpoint[];
|
||||
|
|
|
@ -64,10 +64,10 @@ export function getFullExpressionName(expression: debug.IExpression, sessionType
|
|||
|
||||
export class Thread implements debug.IThread {
|
||||
|
||||
public exception: boolean;
|
||||
public stoppedReason: string;
|
||||
|
||||
constructor(public name: string, public threadId, public callStack: debug.IStackFrame[]) {
|
||||
this.exception = false;
|
||||
this.stoppedReason = undefined;
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
|
@ -335,7 +335,7 @@ export class Model extends ee.EventEmitter implements debug.IModel {
|
|||
delete this.threads[reference];
|
||||
} else {
|
||||
this.threads[reference].callStack = [];
|
||||
this.threads[reference].exception = false;
|
||||
this.threads[reference].stoppedReason = undefined;
|
||||
}
|
||||
} else {
|
||||
if (removeThreads) {
|
||||
|
@ -345,7 +345,7 @@ export class Model extends ee.EventEmitter implements debug.IModel {
|
|||
for (let ref in this.threads) {
|
||||
if (this.threads.hasOwnProperty(ref)) {
|
||||
this.threads[ref].callStack = [];
|
||||
this.threads[ref].exception = false;
|
||||
this.threads[ref].stoppedReason = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -613,10 +613,10 @@ export class Model extends ee.EventEmitter implements debug.IModel {
|
|||
return new StackFrame(data.threadId, 0, Source.fromUri(uri.parse('unknown')), nls.localize('unknownStack', "Unknown stack location"), undefined, undefined);
|
||||
}
|
||||
|
||||
return new StackFrame(data.threadId, rsf.id, rsf.source ? Source.fromRawSource(rsf.source) : Source.fromUri(uri.parse('unknown')), rsf.name, rsf.line, rsf.column);
|
||||
return new StackFrame(data.threadId, rsf.id, rsf.source ? new Source(rsf.source) : Source.fromUri(uri.parse('unknown')), rsf.name, rsf.line, rsf.column);
|
||||
});
|
||||
|
||||
this.threads[data.threadId].exception = data.exception;
|
||||
this.threads[data.threadId].stoppedReason = data.stoppedReason;
|
||||
}
|
||||
|
||||
this.emit(debug.ModelEvents.CALLSTACK_UPDATED);
|
||||
|
|
|
@ -444,7 +444,7 @@ declare module DebugProtocol {
|
|||
name: string;
|
||||
}
|
||||
|
||||
/** A Source .*/
|
||||
/** A Source is a descriptor for source code. It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying breakpoints. */
|
||||
export interface Source {
|
||||
/** The short name of the source. Every source returned from the debug adapter has a name. When specifying a source to the debug adapter this name is optional. */
|
||||
name?: string;
|
||||
|
@ -452,8 +452,10 @@ declare module DebugProtocol {
|
|||
path?: string;
|
||||
/** If sourceReference > 0 the contents of the source can be retrieved through the SourceRequest. A sourceReference is only valid for a session, so it must not be used to persist a source. */
|
||||
sourceReference?: number;
|
||||
/** The (optional) origin of this source: possible values "internal module", "inlined content from source map" */
|
||||
origin?: string;
|
||||
/** The (optional) origin of this source: possible values "internal module", "inlined content from source map", etc. */
|
||||
origin?: string;
|
||||
/** Optional data that a debug adapter might want to loop through the client. The client should leave the data intact and persist it across sessions. The client should not interpret the data. */
|
||||
adapterData?: any;
|
||||
}
|
||||
|
||||
/** A Stackframe contains the source location. */
|
||||
|
|
|
@ -14,11 +14,23 @@ export class Source {
|
|||
|
||||
private static INTERNAL_URI_PREFIX = 'debug://internal/';
|
||||
|
||||
constructor(public name: string, uriStr: string, public origin: string, public reference = 0) {
|
||||
this.uri = uri.parse(uriStr);
|
||||
constructor(private raw: DebugProtocol.Source) {
|
||||
this.uri = raw.path ? uri.file(raw.path) : uri.parse(Source.INTERNAL_URI_PREFIX + raw.name);
|
||||
this.available = true;
|
||||
}
|
||||
|
||||
public get name() {
|
||||
return this.raw.name;
|
||||
}
|
||||
|
||||
public get origin() {
|
||||
return this.raw.origin;
|
||||
}
|
||||
|
||||
public get reference() {
|
||||
return this.raw.sourceReference;
|
||||
}
|
||||
|
||||
public get inMemory() {
|
||||
return Source.isInMemory(this.uri);
|
||||
}
|
||||
|
@ -29,13 +41,8 @@ export class Source {
|
|||
for (let threadId in threads) {
|
||||
if (threads.hasOwnProperty(threadId) && threads[threadId].callStack) {
|
||||
const found = threads[threadId].callStack.filter(sf => sf.source.uri.toString() === uri.toString()).pop();
|
||||
|
||||
if (found) {
|
||||
return {
|
||||
name: found.source.name,
|
||||
path: found.source.inMemory ? null : found.source.uri.fsPath,
|
||||
sourceReference: found.source.reference
|
||||
}
|
||||
return found.source.raw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,13 +52,11 @@ export class Source {
|
|||
{ path: paths.normalize(uri.fsPath, true) };
|
||||
}
|
||||
|
||||
public static fromRawSource(rawSource: DebugProtocol.Source): Source {
|
||||
const uriStr = rawSource.path ? uri.file(rawSource.path).toString() : Source.INTERNAL_URI_PREFIX + rawSource.name;
|
||||
return new Source(rawSource.name, uriStr, rawSource.origin, rawSource.sourceReference);
|
||||
}
|
||||
|
||||
public static fromUri(uri: uri): Source {
|
||||
return new Source(Source.getName(uri), uri.toString(), '');
|
||||
return new Source({
|
||||
name: Source.getName(uri),
|
||||
path: uri.fsPath,
|
||||
});
|
||||
}
|
||||
|
||||
private static getName(uri: uri): string {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!../browser/media/debug.contribution';
|
||||
import 'vs/css!../browser/media/debugHover';
|
||||
import nls = require('vs/nls');
|
||||
import { CommonEditorRegistry, ContextKey, EditorActionDescriptor } from 'vs/editor/common/editorCommonExtensions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
|
|
@ -228,13 +228,13 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService
|
|||
}));
|
||||
|
||||
this.toDispose.push(this.session.addListener2(debug.SessionEvents.STOPPED, (event: DebugProtocol.StoppedEvent) => {
|
||||
this.setStateAndEmit(debug.State.Stopped, event.body.reason);
|
||||
this.setStateAndEmit(debug.State.Stopped);
|
||||
const threadId = event.body.threadId;
|
||||
|
||||
this.getThreadData(threadId).then(() => {
|
||||
this.session.stackTrace({ threadId: threadId, levels: 20 }).done((result) => {
|
||||
|
||||
this.model.rawUpdate({ threadId: threadId, callStack: result.body.stackFrames, exception: event.body && event.body.reason === 'exception' });
|
||||
this.model.rawUpdate({ threadId: threadId, callStack: result.body.stackFrames, stoppedReason: event.body.reason });
|
||||
this.windowService.getWindow().focus();
|
||||
const callStack = this.model.getThreads()[threadId].callStack;
|
||||
if (callStack.length > 0) {
|
||||
|
@ -312,7 +312,8 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService
|
|||
private loadBreakpoints(): debug.IBreakpoint[] {
|
||||
try {
|
||||
return JSON.parse(this.storageService.get(DEBUG_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((breakpoint: any) => {
|
||||
return new model.Breakpoint(new Source(breakpoint.source.name, breakpoint.source.uri, breakpoint.source.reference), breakpoint.desiredLineNumber || breakpoint.lineNumber, breakpoint.enabled, breakpoint.condition);
|
||||
return new model.Breakpoint(breakpoint.source.raw ? new Source(breakpoint.source.raw) : Source.fromUri(uri.parse(breakpoint.source.uri)),
|
||||
breakpoint.desiredLineNumber || breakpoint.lineNumber, breakpoint.enabled, breakpoint.condition);
|
||||
});
|
||||
} catch (e) {
|
||||
return [];
|
||||
|
@ -356,9 +357,9 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService
|
|||
return this.state;
|
||||
}
|
||||
|
||||
private setStateAndEmit(newState: debug.State, data?: any): void {
|
||||
private setStateAndEmit(newState: debug.State): void {
|
||||
this.state = newState;
|
||||
this.emit(debug.ServiceEvents.STATE_CHANGED, data);
|
||||
this.emit(debug.ServiceEvents.STATE_CHANGED);
|
||||
}
|
||||
|
||||
public get enabled(): boolean {
|
||||
|
|
|
@ -15,7 +15,6 @@ suite('Debug - Source', () => {
|
|||
|
||||
assert.equal(source.available, true);
|
||||
assert.equal(source.inMemory, false);
|
||||
assert.equal(source.reference, 0);
|
||||
assert.equal(source.uri.toString(), u.toString());
|
||||
assert.equal(source.name, 'd');
|
||||
});
|
||||
|
@ -26,7 +25,7 @@ suite('Debug - Source', () => {
|
|||
path: '/xx/yy/zz',
|
||||
sourceReference: 0
|
||||
};
|
||||
const source = Source.fromRawSource(rawSource);
|
||||
const source = new Source(rawSource);
|
||||
|
||||
assert.equal(source.available, true);
|
||||
assert.equal(source.name, rawSource.name);
|
||||
|
@ -40,7 +39,7 @@ suite('Debug - Source', () => {
|
|||
name: 'internalModule.js',
|
||||
sourceReference: 11
|
||||
};
|
||||
const source = Source.fromRawSource(rawSource);
|
||||
const source = new Source(rawSource);
|
||||
|
||||
assert.equal(source.available, true);
|
||||
assert.equal(source.name, rawSource.name);
|
||||
|
|
|
@ -245,11 +245,11 @@
|
|||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
to { transform: rotate(1080deg); }
|
||||
}
|
||||
|
||||
.monaco-shell .git-statusbar-group > .git-statusbar-sync-item.syncing > .octicon {
|
||||
animation: 1.5s linear infinite spin;
|
||||
animation: 2s ease-in-out infinite spin;
|
||||
}
|
||||
|
||||
.monaco-shell .git-statusbar-group > .git-statusbar-sync-item.disabled > .ahead-behind,
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
#!/bin/sh
|
||||
AMD_ENTRYPOINT="$VSCODE_GIT_ASKPASS_MODULE_ID" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_BOOTSTRAP" $*
|
||||
VSCODE_GIT_ASKPASS_PIPE=`mktemp`
|
||||
AMD_ENTRYPOINT="$VSCODE_GIT_ASKPASS_MODULE_ID" VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_BOOTSTRAP" $*
|
||||
cat $VSCODE_GIT_ASKPASS_PIPE
|
||||
rm $VSCODE_GIT_ASKPASS_PIPE
|
|
@ -8,6 +8,7 @@
|
|||
import events = require('vs/base/common/eventEmitter');
|
||||
import { connect } from 'vs/base/node/service.net';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as fs from 'fs';
|
||||
|
||||
export interface ICredentials {
|
||||
username: string;
|
||||
|
@ -42,7 +43,12 @@ function main(argv: string[]): void {
|
|||
return fatal('Missing git id');
|
||||
}
|
||||
|
||||
if (!process.env['VSCODE_GIT_ASKPASS_PIPE']) {
|
||||
return fatal('Missing pipe');
|
||||
}
|
||||
|
||||
var id = process.env['VSCODE_GIT_REQUEST_ID'];
|
||||
var output = process.env['VSCODE_GIT_ASKPASS_PIPE'];
|
||||
var request = argv[2];
|
||||
var host = argv[4].substring(1, argv[4].length - 2);
|
||||
|
||||
|
@ -52,7 +58,7 @@ function main(argv: string[]): void {
|
|||
|
||||
return service.askpass(id, host, process.env['MONACO_GIT_COMMAND']).then(result => {
|
||||
if (result) {
|
||||
console.log(/^Username$/i.test(request) ? result.username : result.password);
|
||||
fs.writeFileSync(output, (/^Username$/i.test(request) ? result.username : result.password) + '\n');
|
||||
}
|
||||
|
||||
return client;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import ipc = require('ipc');
|
||||
import platform = require('vs/base/common/platform');
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
@ -51,7 +52,8 @@ export class GitAskpassService {
|
|||
resizable: false,
|
||||
width: 450,
|
||||
height: platform.isWindows ? 280 : 260,
|
||||
show: true
|
||||
show: true,
|
||||
title: nls.localize('git', "Git")
|
||||
});
|
||||
|
||||
win.setMenuBarVisibility(false);
|
||||
|
|
|
@ -44,12 +44,12 @@ function exec(child: ChildProcess, encoding = 'utf8'): TPromise<IExecutionResult
|
|||
new TPromise<string>(c => {
|
||||
let buffers: Buffer[] = [];
|
||||
on(child.stdout, 'data', b => buffers.push(b));
|
||||
once(child.stdout, 'close', () => c(Buffer.concat(buffers).toString(encoding)));
|
||||
once(child.stdout, 'close', () => c(iconv.decode(Buffer.concat(buffers), encoding)));
|
||||
}),
|
||||
new TPromise<string>(c => {
|
||||
let buffers: Buffer[] = [];
|
||||
on(child.stderr, 'data', b => buffers.push(b));
|
||||
once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString(encoding)));
|
||||
once(child.stderr, 'close', () => c(iconv.decode(Buffer.concat(buffers), encoding)));
|
||||
})
|
||||
]).then(values => {
|
||||
disposeAll(disposables);
|
||||
|
|
|
@ -180,7 +180,10 @@ export class MarkersHandler extends QuickOpenHandler {
|
|||
|
||||
// 2nd viewstate
|
||||
const editor = this._editorService.getActiveEditor();
|
||||
const viewState = (<ICommonCodeEditor>editor.getControl()).saveViewState();
|
||||
let viewState: IEditorViewState;
|
||||
if (editor) {
|
||||
viewState = (<ICommonCodeEditor>editor.getControl()).saveViewState();
|
||||
}
|
||||
|
||||
this._activeSession = [model, viewState];
|
||||
}
|
||||
|
@ -199,8 +202,10 @@ export class MarkersHandler extends QuickOpenHandler {
|
|||
if (this._activeSession) {
|
||||
if (canceled) {
|
||||
const [, viewState] = this._activeSession;
|
||||
const editor = this._editorService.getActiveEditor();
|
||||
(<ICommonCodeEditor>editor.getControl()).restoreViewState(viewState);
|
||||
if (viewState) {
|
||||
const editor = this._editorService.getActiveEditor();
|
||||
(<ICommonCodeEditor>editor.getControl()).restoreViewState(viewState);
|
||||
}
|
||||
}
|
||||
this._activeSession = undefined;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,6 @@ import flow = require('vs/base/node/flow');
|
|||
import {ISerializedFileMatch, IRawSearch, ISearchEngine} from 'vs/workbench/services/search/node/rawSearchService';
|
||||
|
||||
export class FileWalker {
|
||||
|
||||
private static ENOTDIR = 'ENOTDIR';
|
||||
|
||||
private config: IRawSearch;
|
||||
private filePattern: string;
|
||||
private excludePattern: glob.IExpression;
|
||||
|
@ -43,6 +40,8 @@ export class FileWalker {
|
|||
this.includePattern = config.includePattern;
|
||||
this.maxResults = config.maxResults || null;
|
||||
this.walkedPaths = Object.create(null);
|
||||
this.resultCount = 0;
|
||||
this.isLimitHit = false;
|
||||
|
||||
// Normalize file patterns to forward slashes
|
||||
if (this.filePattern && this.filePattern.indexOf(paths.sep) >= 0) {
|
||||
|
@ -51,23 +50,17 @@ export class FileWalker {
|
|||
}
|
||||
}
|
||||
|
||||
private resetState(): void {
|
||||
this.walkedPaths = Object.create(null);
|
||||
this.resultCount = 0;
|
||||
this.isLimitHit = false;
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.isCanceled = true;
|
||||
}
|
||||
|
||||
public walk(rootFolders: string[], extraFiles: string[], onResult: (result: ISerializedFileMatch) => void, done: (error: Error, isLimitHit: boolean) => void): void {
|
||||
|
||||
// Reset state
|
||||
this.resetState();
|
||||
|
||||
// Support that the file pattern is a full path to a file that exists
|
||||
this.checkFilePatternAbsoluteMatch((exists) => {
|
||||
if (this.isCanceled) {
|
||||
return done(null, this.isLimitHit);
|
||||
}
|
||||
|
||||
// Report result from file pattern if matching
|
||||
if (exists) {
|
||||
|
@ -76,7 +69,7 @@ export class FileWalker {
|
|||
// Optimization: a match on an absolute path is a good result and we do not
|
||||
// continue walking the entire root paths array for other matches because
|
||||
// it is very unlikely that another file would match on the full absolute path
|
||||
return done(null, false);
|
||||
return done(null, this.isLimitHit);
|
||||
}
|
||||
|
||||
// For each extra file
|
||||
|
|
|
@ -17,6 +17,11 @@ import {FileWalker} from 'vs/workbench/services/search/node/fileSearch';
|
|||
import {UTF16le, UTF16be, UTF8} from 'vs/base/node/encoding';
|
||||
import {ISerializedFileMatch, IRawSearch, ISearchEngine} from 'vs/workbench/services/search/node/rawSearchService';
|
||||
|
||||
interface ReadLinesOptions {
|
||||
bufferLength: number;
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export class Engine implements ISearchEngine {
|
||||
private rootFolders: string[];
|
||||
private extraFiles: string[];
|
||||
|
@ -30,6 +35,7 @@ export class Engine implements ISearchEngine {
|
|||
private walkerError: Error;
|
||||
private walkerIsDone: boolean;
|
||||
private fileEncoding: string;
|
||||
private limitReached: boolean;
|
||||
|
||||
constructor(config: IRawSearch, walker: FileWalker) {
|
||||
this.rootFolders = config.rootFolders;
|
||||
|
@ -37,6 +43,7 @@ export class Engine implements ISearchEngine {
|
|||
this.walker = walker;
|
||||
this.contentPattern = strings.createRegExp(config.contentPattern.pattern, config.contentPattern.isRegExp, config.contentPattern.isCaseSensitive, config.contentPattern.isWordMatch);
|
||||
this.isCanceled = false;
|
||||
this.limitReached = false;
|
||||
this.maxResults = config.maxResults;
|
||||
this.worked = 0;
|
||||
this.total = 0;
|
||||
|
@ -50,53 +57,46 @@ export class Engine implements ISearchEngine {
|
|||
|
||||
public search(onResult: (match: ISerializedFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, isLimitHit: boolean) => void): void {
|
||||
let resultCounter = 0;
|
||||
let limitReached = false;
|
||||
|
||||
let unwind = (processed: number) => {
|
||||
this.worked += processed;
|
||||
|
||||
// Emit progress()
|
||||
if (processed && !this.isDone) {
|
||||
// Emit progress() unless we got canceled or hit the limit
|
||||
if (processed && !this.isDone && !this.isCanceled && !this.limitReached) {
|
||||
onProgress({ total: this.total, worked: this.worked });
|
||||
}
|
||||
|
||||
// Emit done()
|
||||
if (this.worked === this.total && this.walkerIsDone && !this.isDone) {
|
||||
this.isDone = true;
|
||||
done(this.walkerError, limitReached);
|
||||
done(this.walkerError, this.limitReached);
|
||||
}
|
||||
};
|
||||
|
||||
// Walk over the file system
|
||||
this.walker.walk(this.rootFolders, this.extraFiles, (result) => {
|
||||
|
||||
// Indicate progress to the outside
|
||||
this.total++;
|
||||
onProgress({ total: this.total, worked: this.worked });
|
||||
|
||||
// If the result is empty or we have reached the limit or we are canceled, ignore it
|
||||
if (limitReached || this.isCanceled) {
|
||||
if (this.limitReached || this.isCanceled) {
|
||||
return unwind(1);
|
||||
}
|
||||
|
||||
// Indicate progress to the outside
|
||||
onProgress({ total: this.total, worked: this.worked });
|
||||
|
||||
let fileMatch: FileMatch = null;
|
||||
|
||||
let doneCallback = (error?: Error) => {
|
||||
|
||||
// If the result is empty or we have reached the limit or we are canceled, ignore it
|
||||
if (error || !fileMatch || fileMatch.isEmpty() || this.isCanceled) {
|
||||
return unwind(1);
|
||||
}
|
||||
|
||||
// Otherwise send it back as result
|
||||
else {
|
||||
if (!error && !this.isCanceled && fileMatch && !fileMatch.isEmpty()) {
|
||||
onResult(fileMatch.serialize());
|
||||
|
||||
return unwind(1);
|
||||
}
|
||||
|
||||
return unwind(1);
|
||||
};
|
||||
|
||||
let perLineCallback = (line: string, lineNumber: number) => {
|
||||
if (limitReached || this.isCanceled) {
|
||||
if (this.limitReached || this.isCanceled) {
|
||||
return; // return early if canceled or limit reached
|
||||
}
|
||||
|
||||
|
@ -104,10 +104,10 @@ export class Engine implements ISearchEngine {
|
|||
let match = this.contentPattern.exec(line);
|
||||
|
||||
// Record all matches into file result
|
||||
while (match !== null && match[0].length > 0 && !limitReached && !this.isCanceled) {
|
||||
while (match !== null && match[0].length > 0 && !this.limitReached && !this.isCanceled) {
|
||||
resultCounter++;
|
||||
if (this.maxResults && resultCounter >= this.maxResults) {
|
||||
limitReached = true;
|
||||
this.limitReached = true;
|
||||
}
|
||||
|
||||
if (fileMatch === null) {
|
||||
|
@ -126,132 +126,129 @@ export class Engine implements ISearchEngine {
|
|||
};
|
||||
|
||||
// Read lines buffered to support large files
|
||||
readlinesAsync(result.path, perLineCallback, { bufferLength: 8096, encoding: this.fileEncoding }, doneCallback);
|
||||
this.readlinesAsync(result.path, perLineCallback, { bufferLength: 8096, encoding: this.fileEncoding }, doneCallback);
|
||||
}, (error, isLimitHit) => {
|
||||
this.walkerIsDone = true;
|
||||
this.walkerError = error;
|
||||
unwind(0 /* walker is done, indicate this back to our handler to be able to unwind */);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface ReadLinesOptions {
|
||||
bufferLength: number;
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
function readlinesAsync(filename: string, perLineCallback: (line: string, lineNumber: number) => void, options: ReadLinesOptions, callback: (error: Error) => void): void {
|
||||
fs.open(filename, 'r', null, (error: Error, fd: number) => {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
let buffer = new Buffer(options.bufferLength);
|
||||
let pos: number;
|
||||
let i: number;
|
||||
let line = '';
|
||||
let lineNumber = 0;
|
||||
let lastBufferHadTraillingCR = false;
|
||||
|
||||
function decode(buffer: NodeBuffer): string {
|
||||
if (options.encoding === UTF8) {
|
||||
return buffer.toString(); // much faster to use built in toString() when encoding is default
|
||||
}
|
||||
|
||||
return iconv.decode(buffer, options.encoding);
|
||||
}
|
||||
|
||||
function lineFinished(offset: number): void {
|
||||
line += decode(buffer.slice(pos, i + offset));
|
||||
perLineCallback(line, lineNumber);
|
||||
line = '';
|
||||
lineNumber++;
|
||||
pos = i + offset;
|
||||
}
|
||||
|
||||
function readFile(isFirstRead: boolean, clb: (error: Error) => void): void {
|
||||
fs.read(fd, buffer, 0, buffer.length, null, (error: Error, bytesRead: number, buffer: NodeBuffer) => {
|
||||
if (error) {
|
||||
return clb(error);
|
||||
}
|
||||
|
||||
if (bytesRead === 0) {
|
||||
return clb(null);
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
i = 0;
|
||||
|
||||
// Detect encoding and mime when this is the beginning of the file
|
||||
if (isFirstRead) {
|
||||
let mimeAndEncoding = detectMimeAndEncodingFromBuffer(buffer, bytesRead);
|
||||
if (mimeAndEncoding.mimes[mimeAndEncoding.mimes.length - 1] !== baseMime.MIME_TEXT) {
|
||||
return clb(null); // skip files that seem binary
|
||||
}
|
||||
|
||||
// Check for BOM offset
|
||||
switch (mimeAndEncoding.encoding) {
|
||||
case UTF8:
|
||||
pos = i = 3;
|
||||
options.encoding = UTF8;
|
||||
break;
|
||||
case UTF16be:
|
||||
pos = i = 2;
|
||||
options.encoding = UTF16be;
|
||||
break;
|
||||
case UTF16le:
|
||||
pos = i = 2;
|
||||
options.encoding = UTF16le;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBufferHadTraillingCR) {
|
||||
if (buffer[i] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(1);
|
||||
i++;
|
||||
} else {
|
||||
lineFinished(0);
|
||||
}
|
||||
|
||||
lastBufferHadTraillingCR = false;
|
||||
}
|
||||
|
||||
for (; i < bytesRead; ++i) {
|
||||
if (buffer[i] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(1);
|
||||
} else if (buffer[i] === 0x0d) { // CR (Carriage Return)
|
||||
if (i + 1 === bytesRead) {
|
||||
lastBufferHadTraillingCR = true;
|
||||
} else if (buffer[i + 1] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(2);
|
||||
i++;
|
||||
} else {
|
||||
lineFinished(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line += decode(buffer.slice(pos, bytesRead));
|
||||
|
||||
readFile(false /* isFirstRead */, clb); // Continue reading
|
||||
});
|
||||
}
|
||||
|
||||
readFile(true /* isFirstRead */, (error: Error) => {
|
||||
private readlinesAsync(filename: string, perLineCallback: (line: string, lineNumber: number) => void, options: ReadLinesOptions, callback: (error: Error) => void): void {
|
||||
fs.open(filename, 'r', null, (error: Error, fd: number) => {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
if (line.length) {
|
||||
perLineCallback(line, lineNumber); // handle last line
|
||||
let buffer = new Buffer(options.bufferLength);
|
||||
let pos: number;
|
||||
let i: number;
|
||||
let line = '';
|
||||
let lineNumber = 0;
|
||||
let lastBufferHadTraillingCR = false;
|
||||
|
||||
const outer = this;
|
||||
|
||||
function decode(buffer: NodeBuffer): string {
|
||||
if (options.encoding === UTF8) {
|
||||
return buffer.toString(); // much faster to use built in toString() when encoding is default
|
||||
}
|
||||
|
||||
return iconv.decode(buffer, options.encoding);
|
||||
}
|
||||
|
||||
fs.close(fd, (error: Error) => {
|
||||
callback(error);
|
||||
function lineFinished(offset: number): void {
|
||||
line += decode(buffer.slice(pos, i + offset));
|
||||
perLineCallback(line, lineNumber);
|
||||
line = '';
|
||||
lineNumber++;
|
||||
pos = i + offset;
|
||||
}
|
||||
|
||||
function readFile(isFirstRead: boolean, clb: (error: Error) => void): void {
|
||||
if (outer.limitReached || outer.isCanceled) {
|
||||
return clb(null); // return early if canceled or limit reached
|
||||
}
|
||||
|
||||
fs.read(fd, buffer, 0, buffer.length, null, (error: Error, bytesRead: number, buffer: NodeBuffer) => {
|
||||
if (error || bytesRead === 0 || outer.limitReached || outer.isCanceled) {
|
||||
return clb(error); // return early if canceled or limit reached or no more bytes to read
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
i = 0;
|
||||
|
||||
// Detect encoding and mime when this is the beginning of the file
|
||||
if (isFirstRead) {
|
||||
let mimeAndEncoding = detectMimeAndEncodingFromBuffer(buffer, bytesRead);
|
||||
if (mimeAndEncoding.mimes[mimeAndEncoding.mimes.length - 1] !== baseMime.MIME_TEXT) {
|
||||
return clb(null); // skip files that seem binary
|
||||
}
|
||||
|
||||
// Check for BOM offset
|
||||
switch (mimeAndEncoding.encoding) {
|
||||
case UTF8:
|
||||
pos = i = 3;
|
||||
options.encoding = UTF8;
|
||||
break;
|
||||
case UTF16be:
|
||||
pos = i = 2;
|
||||
options.encoding = UTF16be;
|
||||
break;
|
||||
case UTF16le:
|
||||
pos = i = 2;
|
||||
options.encoding = UTF16le;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBufferHadTraillingCR) {
|
||||
if (buffer[i] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(1);
|
||||
i++;
|
||||
} else {
|
||||
lineFinished(0);
|
||||
}
|
||||
|
||||
lastBufferHadTraillingCR = false;
|
||||
}
|
||||
|
||||
for (; i < bytesRead; ++i) {
|
||||
if (buffer[i] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(1);
|
||||
} else if (buffer[i] === 0x0d) { // CR (Carriage Return)
|
||||
if (i + 1 === bytesRead) {
|
||||
lastBufferHadTraillingCR = true;
|
||||
} else if (buffer[i + 1] === 0x0a) { // LF (Line Feed)
|
||||
lineFinished(2);
|
||||
i++;
|
||||
} else {
|
||||
lineFinished(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line += decode(buffer.slice(pos, bytesRead));
|
||||
|
||||
readFile(false /* isFirstRead */, clb); // Continue reading
|
||||
});
|
||||
}
|
||||
|
||||
readFile(true /* isFirstRead */, (error: Error) => {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
if (line.length) {
|
||||
perLineCallback(line, lineNumber); // handle last line
|
||||
}
|
||||
|
||||
fs.close(fd, (error: Error) => {
|
||||
callback(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class FileMatch implements ISerializedFileMatch {
|
||||
|
|
|
@ -14,7 +14,7 @@ import * as types from 'vs/workbench/api/common/extHostTypes';
|
|||
import {Range as CodeEditorRange} from 'vs/editor/common/core/range';
|
||||
import * as EditorCommon from 'vs/editor/common/editorCommon';
|
||||
import {Model as EditorModel} from 'vs/editor/common/model/model';
|
||||
import threadService from './testThreadService'
|
||||
import {TestThreadService} from './testThreadService'
|
||||
import {create as createInstantiationService} from 'vs/platform/instantiation/common/instantiationService';
|
||||
import {MarkerService} from 'vs/platform/markers/common/markerService';
|
||||
import {IMarkerService} from 'vs/platform/markers/common/markers';
|
||||
|
@ -27,6 +27,7 @@ import {registerApiCommands} from 'vs/workbench/api/common/extHostApiCommands';
|
|||
import {ExtHostCommands, MainThreadCommands} from 'vs/workbench/api/common/extHostCommands';
|
||||
import {ExtHostModelService} from 'vs/workbench/api/common/extHostDocuments';
|
||||
|
||||
const defaultSelector = { scheme: 'far' };
|
||||
const model: EditorCommon.IModel = new EditorModel(
|
||||
[
|
||||
'This is the first line',
|
||||
|
@ -36,6 +37,7 @@ const model: EditorCommon.IModel = new EditorModel(
|
|||
undefined,
|
||||
URI.parse('far://testing/file.b'));
|
||||
|
||||
let threadService: TestThreadService;
|
||||
let extHost: ExtHostLanguageFeatures;
|
||||
let mainThread: MainThreadLanguageFeatures;
|
||||
let commands: ExtHostCommands;
|
||||
|
@ -44,13 +46,20 @@ let originalErrorHandler: (e: any) => any;
|
|||
|
||||
suite('ExtHostLanguageFeatureCommands', function() {
|
||||
|
||||
suiteSetup(() => {
|
||||
suiteSetup((done) => {
|
||||
|
||||
originalErrorHandler = errorHandler.getUnexpectedErrorHandler();
|
||||
setUnexpectedErrorHandler(() => { });
|
||||
|
||||
let instantiationService = createInstantiationService();
|
||||
threadService.setInstantiationService(instantiationService);
|
||||
threadService = new TestThreadService(instantiationService);
|
||||
|
||||
instantiationService.addSingleton(IKeybindingService, <IKeybindingService>{
|
||||
executeCommand(id, args): any {
|
||||
let handler = KeybindingsRegistry.getCommands()[id];
|
||||
return TPromise.as(instantiationService.invokeFunction(handler, args));
|
||||
}
|
||||
});
|
||||
instantiationService.addSingleton(IMarkerService, new MarkerService(threadService));
|
||||
instantiationService.addSingleton(IThreadService, threadService);
|
||||
instantiationService.addSingleton(IModelService, <IModelService>{
|
||||
|
@ -63,12 +72,6 @@ suite('ExtHostLanguageFeatureCommands', function() {
|
|||
onModelModeChanged: undefined,
|
||||
onModelRemoved: undefined
|
||||
});
|
||||
instantiationService.addSingleton(IKeybindingService, <IKeybindingService>{
|
||||
executeCommand(id, args): any {
|
||||
let handler = KeybindingsRegistry.getCommands()[id];
|
||||
return TPromise.as(instantiationService.invokeFunction(handler, args));
|
||||
}
|
||||
})
|
||||
|
||||
threadService.getRemotable(ExtHostModelService)._acceptModelAdd({
|
||||
isDirty: false,
|
||||
|
@ -88,6 +91,8 @@ suite('ExtHostLanguageFeatureCommands', function() {
|
|||
registerApiCommands(threadService);
|
||||
mainThread = threadService.getRemotable(MainThreadLanguageFeatures);
|
||||
extHost = threadService.getRemotable(ExtHostLanguageFeatures);
|
||||
|
||||
threadService.sync().then(done, done)
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
|
@ -122,38 +127,38 @@ suite('ExtHostLanguageFeatureCommands', function() {
|
|||
// });
|
||||
});
|
||||
|
||||
// test('WorkspaceSymbols, back and forth', function(done) {
|
||||
test('WorkspaceSymbols, back and forth', function(done) {
|
||||
|
||||
// disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
// provideWorkspaceSymbols(query): any {
|
||||
// return [
|
||||
// new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first')),
|
||||
// new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/second'))
|
||||
// ]
|
||||
// }
|
||||
// }));
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first')),
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/second'))
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
// disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
// provideWorkspaceSymbols(query): any {
|
||||
// return [
|
||||
// new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first'))
|
||||
// ]
|
||||
// }
|
||||
// }));
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first'))
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeWorkspaceSymbolProvider', 'testing').then(value => {
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeWorkspaceSymbolProvider', 'testing').then(value => {
|
||||
|
||||
// for (let info of value) {
|
||||
// assert.ok(info instanceof types.SymbolInformation);
|
||||
// assert.equal(info.name, 'testing');
|
||||
// assert.equal(info.kind, types.SymbolKind.Array);
|
||||
// }
|
||||
// assert.equal(value.length, 3);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
for (let info of value) {
|
||||
assert.ok(info instanceof types.SymbolInformation);
|
||||
assert.equal(info.name, 'testing');
|
||||
assert.equal(info.kind, types.SymbolKind.Array);
|
||||
}
|
||||
assert.equal(value.length, 3);
|
||||
done();
|
||||
}, done);
|
||||
}, done);
|
||||
});
|
||||
|
||||
|
||||
// --- definition
|
||||
|
@ -175,150 +180,159 @@ suite('ExtHostLanguageFeatureCommands', function() {
|
|||
// });
|
||||
});
|
||||
|
||||
// test('Definition, back and forth', function(done) {
|
||||
test('Definition, back and forth', function(done) {
|
||||
|
||||
// disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
// provideDefinition(doc: any): any {
|
||||
// return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
// }
|
||||
// }));
|
||||
// disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
// provideDefinition(doc: any): any {
|
||||
// return [
|
||||
// new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
// new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
// new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
// ]
|
||||
// }
|
||||
// }));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return [
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.Location[]>('vscode.executeDefinitionProvider', model.getAssociatedResource(), new types.Position(0, 0)).then(values => {
|
||||
// assert.equal(values.length, 4);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.Location[]>('vscode.executeDefinitionProvider', model.getAssociatedResource(), new types.Position(0, 0)).then(values => {
|
||||
assert.equal(values.length, 4);
|
||||
done();
|
||||
}, done);
|
||||
}, done);
|
||||
});
|
||||
|
||||
// --- outline
|
||||
|
||||
// test('Outline, back and forth', function(done) {
|
||||
// disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
// provideDocumentSymbols(): any {
|
||||
// return [
|
||||
// new types.SymbolInformation('testing1', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0)),
|
||||
// new types.SymbolInformation('testing2', types.SymbolKind.Enum, new types.Range(0, 1, 0, 3)),
|
||||
// ]
|
||||
// }
|
||||
// }));
|
||||
test('Outline, back and forth', function(done) {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [
|
||||
new types.SymbolInformation('testing1', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0)),
|
||||
new types.SymbolInformation('testing2', types.SymbolKind.Enum, new types.Range(0, 1, 0, 3)),
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeDocumentSymbolProvider', model.getAssociatedResource()).then(values => {
|
||||
// assert.equal(values.length, 2);
|
||||
// let [first, second] = values;
|
||||
// assert.equal(first.name, 'testing2');
|
||||
// assert.equal(second.name, 'testing1');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.SymbolInformation[]>('vscode.executeDocumentSymbolProvider', model.getAssociatedResource()).then(values => {
|
||||
assert.equal(values.length, 2);
|
||||
let [first, second] = values;
|
||||
assert.equal(first.name, 'testing2');
|
||||
assert.equal(second.name, 'testing1');
|
||||
done();
|
||||
}, done);
|
||||
}, done);
|
||||
});
|
||||
|
||||
// --- suggest
|
||||
|
||||
// test('Suggest, back and forth', function(done) {
|
||||
// disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
// provideCompletionItems(doc, pos): any {
|
||||
// let a = new types.CompletionItem('item1');
|
||||
// let b = new types.CompletionItem('item2');
|
||||
// b.textEdit = types.TextEdit.replace(new types.Range(0, 4, 0, 8), 'foo'); // overwite after
|
||||
// let c = new types.CompletionItem('item3');
|
||||
// c.textEdit = types.TextEdit.replace(new types.Range(0, 1, 0, 6), 'foobar'); // overwite before & after
|
||||
// let d = new types.CompletionItem('item4');
|
||||
// d.textEdit = types.TextEdit.replace(new types.Range(0, 1, 0, 4), ''); // overwite before
|
||||
// return [a, b, c, d];
|
||||
// }
|
||||
// }, []));
|
||||
test('Suggest, back and forth', function(done) {
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(doc, pos): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
let b = new types.CompletionItem('item2');
|
||||
b.textEdit = types.TextEdit.replace(new types.Range(0, 4, 0, 8), 'foo'); // overwite after
|
||||
let c = new types.CompletionItem('item3');
|
||||
c.textEdit = types.TextEdit.replace(new types.Range(0, 1, 0, 6), 'foobar'); // overwite before & after
|
||||
let d = new types.CompletionItem('item4');
|
||||
d.textEdit = types.TextEdit.replace(new types.Range(0, 1, 0, 4), ''); // overwite before
|
||||
return [a, b, c, d];
|
||||
}
|
||||
}, []));
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.CompletionItem[]>('vscode.executeCompletionItemProvider', model.getAssociatedResource(), new types.Position(0, 4)).then(values => {
|
||||
// try {
|
||||
// assert.equal(values.length, 4);
|
||||
// let [first, second, third, forth] = values;
|
||||
// assert.equal(first.label, 'item1');
|
||||
// assert.equal(first.textEdit.newText, 'item1');
|
||||
// assert.equal(first.textEdit.range.start.line, 0);
|
||||
// assert.equal(first.textEdit.range.start.character, 0);
|
||||
// assert.equal(first.textEdit.range.end.line, 0);
|
||||
// assert.equal(first.textEdit.range.end.character, 4);
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.CompletionItem[]>('vscode.executeCompletionItemProvider', model.getAssociatedResource(), new types.Position(0, 4)).then(values => {
|
||||
try {
|
||||
assert.equal(values.length, 4);
|
||||
let [first, second, third, forth] = values;
|
||||
assert.equal(first.label, 'item1');
|
||||
assert.equal(first.textEdit.newText, 'item1');
|
||||
assert.equal(first.textEdit.range.start.line, 0);
|
||||
assert.equal(first.textEdit.range.start.character, 0);
|
||||
assert.equal(first.textEdit.range.end.line, 0);
|
||||
assert.equal(first.textEdit.range.end.character, 4);
|
||||
|
||||
// assert.equal(second.label, 'item2');
|
||||
// assert.equal(second.textEdit.newText, 'foo');
|
||||
// assert.equal(second.textEdit.range.start.line, 0);
|
||||
// assert.equal(second.textEdit.range.start.character, 4);
|
||||
// assert.equal(second.textEdit.range.end.line, 0);
|
||||
// assert.equal(second.textEdit.range.end.character, 8);
|
||||
assert.equal(second.label, 'item2');
|
||||
assert.equal(second.textEdit.newText, 'foo');
|
||||
assert.equal(second.textEdit.range.start.line, 0);
|
||||
assert.equal(second.textEdit.range.start.character, 4);
|
||||
assert.equal(second.textEdit.range.end.line, 0);
|
||||
assert.equal(second.textEdit.range.end.character, 8);
|
||||
|
||||
// assert.equal(third.label, 'item3');
|
||||
// assert.equal(third.textEdit.newText, 'foobar');
|
||||
// assert.equal(third.textEdit.range.start.line, 0);
|
||||
// assert.equal(third.textEdit.range.start.character, 1);
|
||||
// assert.equal(third.textEdit.range.end.line, 0);
|
||||
// assert.equal(third.textEdit.range.end.character, 6);
|
||||
assert.equal(third.label, 'item3');
|
||||
assert.equal(third.textEdit.newText, 'foobar');
|
||||
assert.equal(third.textEdit.range.start.line, 0);
|
||||
assert.equal(third.textEdit.range.start.character, 1);
|
||||
assert.equal(third.textEdit.range.end.line, 0);
|
||||
assert.equal(third.textEdit.range.end.character, 6);
|
||||
|
||||
// assert.equal(forth.label, 'item4');
|
||||
// assert.equal(forth.textEdit.newText, '');
|
||||
// assert.equal(forth.textEdit.range.start.line, 0);
|
||||
// assert.equal(forth.textEdit.range.start.character, 1);
|
||||
// assert.equal(forth.textEdit.range.end.line, 0);
|
||||
// assert.equal(forth.textEdit.range.end.character, 4);
|
||||
// done();
|
||||
// } catch (e) {
|
||||
// done(e);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
assert.equal(forth.label, 'item4');
|
||||
assert.equal(forth.textEdit.newText, '');
|
||||
assert.equal(forth.textEdit.range.start.line, 0);
|
||||
assert.equal(forth.textEdit.range.start.character, 1);
|
||||
assert.equal(forth.textEdit.range.end.line, 0);
|
||||
assert.equal(forth.textEdit.range.end.character, 4);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}, done);
|
||||
}, done);
|
||||
});
|
||||
|
||||
// --- quickfix
|
||||
|
||||
// test('QuickFix, back and forth', function(done) {
|
||||
// disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
// provideCodeActions(): any {
|
||||
// return [{ command: 'testing', title: 'Title', arguments: [1, 2, true] }];
|
||||
// }
|
||||
// }));
|
||||
test('QuickFix, back and forth', function(done) {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
provideCodeActions(): any {
|
||||
return [{ command: 'testing', title: 'Title', arguments: [1, 2, true] }];
|
||||
}
|
||||
}));
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.Command[]>('vscode.executeCodeActionProvider', model.getAssociatedResource(), new types.Range(0, 0, 1, 1)).then(value => {
|
||||
// assert.equal(value.length, 1);
|
||||
// let [first] = value;
|
||||
// assert.equal(first.title, 'Title');
|
||||
// assert.equal(first.command, 'testing');
|
||||
// assert.deepEqual(first.arguments, [1, 2, true]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.Command[]>('vscode.executeCodeActionProvider', model.getAssociatedResource(), new types.Range(0, 0, 1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
assert.equal(first.title, 'Title');
|
||||
assert.equal(first.command, 'testing');
|
||||
assert.deepEqual(first.arguments, [1, 2, true]);
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
|
||||
// --- code lens
|
||||
|
||||
// test('CodeLens, back and forth', function(done) {
|
||||
// disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
// provideCodeLenses(): any {
|
||||
// return [new types.CodeLens(new types.Range(0, 0, 1, 1), { title: 'Title', command: 'cmd', arguments: [1, 2, true] })];
|
||||
// }
|
||||
// }));
|
||||
test('CodeLens, back and forth', function(done) {
|
||||
|
||||
// threadService.sync().then(() => {
|
||||
// commands.executeCommand<vscode.CodeLens[]>('vscode.executeCodeLensProvider', model.getAssociatedResource()).then(value => {
|
||||
// assert.equal(value.length, 1);
|
||||
// let [first] = value;
|
||||
const complexArg = {
|
||||
foo() { },
|
||||
bar() { },
|
||||
big: extHost
|
||||
}
|
||||
|
||||
// assert.equal(first.command.title, 'Title');
|
||||
// assert.equal(first.command.command, 'cmd');
|
||||
// assert.deepEqual(first.command.arguments, [1, 2, true]);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
return [new types.CodeLens(new types.Range(0, 0, 1, 1), { title: 'Title', command: 'cmd', arguments: [1, true, complexArg] })];
|
||||
}
|
||||
}));
|
||||
|
||||
threadService.sync().then(() => {
|
||||
commands.executeCommand<vscode.CodeLens[]>('vscode.executeCodeLensProvider', model.getAssociatedResource()).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
|
||||
assert.equal(first.command.title, 'Title');
|
||||
assert.equal(first.command.command, 'cmd');
|
||||
assert.equal(first.command.arguments[0], 1);
|
||||
assert.equal(first.command.arguments[1], true);
|
||||
assert.equal(first.command.arguments[2], complexArg);
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import * as types from 'vs/workbench/api/common/extHostTypes';
|
|||
import {Range as CodeEditorRange} from 'vs/editor/common/core/range';
|
||||
import * as EditorCommon from 'vs/editor/common/editorCommon';
|
||||
import {Model as EditorModel} from 'vs/editor/common/model/model';
|
||||
import threadService from './testThreadService'
|
||||
import {TestThreadService} from './testThreadService'
|
||||
import {create as createInstantiationService} from 'vs/platform/instantiation/common/instantiationService';
|
||||
import {MarkerService} from 'vs/platform/markers/common/markerService';
|
||||
import {IMarkerService} from 'vs/platform/markers/common/markers';
|
||||
|
@ -47,6 +47,7 @@ const model: EditorCommon.IModel = new EditorModel(
|
|||
let extHost: ExtHostLanguageFeatures;
|
||||
let mainThread: MainThreadLanguageFeatures;
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
let threadService: TestThreadService;
|
||||
let originalErrorHandler: (e: any) => any;
|
||||
|
||||
suite('ExtHostLanguageFeatures', function() {
|
||||
|
@ -54,7 +55,7 @@ suite('ExtHostLanguageFeatures', function() {
|
|||
suiteSetup(() => {
|
||||
|
||||
let instantiationService = createInstantiationService();
|
||||
threadService.setInstantiationService(instantiationService);
|
||||
threadService = new TestThreadService(instantiationService);
|
||||
instantiationService.addSingleton(IMarkerService, new MarkerService(threadService));
|
||||
instantiationService.addSingleton(IThreadService, threadService);
|
||||
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
|
||||
import {NullThreadService} from 'vs/platform/test/common/nullThreadService';
|
||||
import {SyncDescriptor0} from 'vs/platform/instantiation/common/descriptors';
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
|
||||
export class TestThreadService extends NullThreadService {
|
||||
|
||||
constructor(instantiationService: IInstantiationService) {
|
||||
super();
|
||||
this.setInstantiationService(instantiationService);
|
||||
}
|
||||
|
||||
private _callCountValue: number = 0;
|
||||
private _idle: TPromise<any>;
|
||||
private _completeIdle: Function;
|
||||
|
@ -90,6 +96,3 @@ export class TestThreadService extends NullThreadService {
|
|||
return this._getOrCreateLocalInstance(id, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
const Instance = new TestThreadService();
|
||||
export default Instance;
|
||||
|
|
Loading…
Reference in a new issue