mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
Merge branch 'master' into joh/progress-api
This commit is contained in:
@@ -189,11 +189,12 @@ const hygiene = exports.hygiene = (some, options) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tsl = es.through(function (file) {
|
const tsl = es.through(function (file) {
|
||||||
const configuration = tslint.findConfiguration(null, '.');
|
const configuration = tslint.Configuration.findConfiguration(null, '.');
|
||||||
const options = { configuration, formatter: 'json', rulesDirectory: 'build/lib/tslint' };
|
const options = { formatter: 'json', rulesDirectory: 'build/lib/tslint' };
|
||||||
const contents = file.contents.toString('utf8');
|
const contents = file.contents.toString('utf8');
|
||||||
const linter = new tslint(file.relative, contents, options);
|
const linter = new tslint.Linter(options);
|
||||||
const result = linter.lint();
|
linter.lint(file.relative, contents, configuration.results);
|
||||||
|
const result = linter.getResult();
|
||||||
|
|
||||||
if (result.failureCount > 0) {
|
if (result.failureCount > 0) {
|
||||||
reportFailures(result.failures);
|
reportFailures(result.failures);
|
||||||
@@ -229,6 +230,11 @@ gulp.task('hygiene', () => hygiene());
|
|||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
cp.exec('git config core.autocrlf', (err, out) => {
|
cp.exec('git config core.autocrlf', (err, out) => {
|
||||||
const skipEOL = out.trim() === 'true';
|
const skipEOL = out.trim() === 'true';
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -51,8 +51,18 @@ gulp.task('mixin', function () {
|
|||||||
const build = all.pipe(filter('build/**'));
|
const build = all.pipe(filter('build/**'));
|
||||||
const productJsonFilter = filter('product.json', { restore: true });
|
const productJsonFilter = filter('product.json', { restore: true });
|
||||||
|
|
||||||
|
const vsdaFilter = (function() {
|
||||||
|
const filter = [];
|
||||||
|
if (process.platform !== 'win32') { filter.push('!**/vsda_win32.node'); }
|
||||||
|
if (process.platform !== 'darwin') { filter.push('!**/vsda_darwin.node'); }
|
||||||
|
if (process.platform !== 'linux' || process.arch !== 'x64') { filter.push('!**/vsda_linux64.node'); }
|
||||||
|
if (process.platform !== 'linux' || process.arch === 'x64') { filter.push('!**/vsda_linux32.node'); }
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
})();
|
||||||
|
|
||||||
const mixin = all
|
const mixin = all
|
||||||
.pipe(filter('quality/' + quality + '/**'))
|
.pipe(filter(['quality/' + quality + '/**'].concat(vsdaFilter)))
|
||||||
.pipe(util.rebase(2))
|
.pipe(util.rebase(2))
|
||||||
.pipe(productJsonFilter)
|
.pipe(productJsonFilter)
|
||||||
.pipe(buffer())
|
.pipe(buffer())
|
||||||
@@ -71,4 +81,4 @@ gulp.task('mixin', function () {
|
|||||||
return f;
|
return f;
|
||||||
}))
|
}))
|
||||||
.pipe(gulp.dest('.'));
|
.pipe(gulp.dest('.'));
|
||||||
});
|
});
|
||||||
@@ -30,7 +30,8 @@ const product = require('../product.json');
|
|||||||
const shrinkwrap = require('../npm-shrinkwrap.json');
|
const shrinkwrap = require('../npm-shrinkwrap.json');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
const dependencies = Object.keys(shrinkwrap.dependencies);
|
const dependencies = Object.keys(shrinkwrap.dependencies)
|
||||||
|
.concat(Array.isArray(product.extraNodeModules) ? product.extraNodeModules : []); // additional dependencies from our product configuration
|
||||||
const baseModules = Object.keys(process.binding('natives')).filter(n => !/^_|\//.test(n));
|
const baseModules = Object.keys(process.binding('natives')).filter(n => !/^_|\//.test(n));
|
||||||
const nodeModules = ['electron', 'original-fs']
|
const nodeModules = ['electron', 'original-fs']
|
||||||
.concat(dependencies)
|
.concat(dependencies)
|
||||||
@@ -39,8 +40,8 @@ const nodeModules = ['electron', 'original-fs']
|
|||||||
// Build
|
// Build
|
||||||
|
|
||||||
const builtInExtensions = [
|
const builtInExtensions = [
|
||||||
{ name: 'ms-vscode.node-debug', version: '1.9.5' },
|
{ name: 'ms-vscode.node-debug', version: '1.9.6' },
|
||||||
{ name: 'ms-vscode.node-debug2', version: '1.9.2' }
|
{ name: 'ms-vscode.node-debug2', version: '1.9.4' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const vscodeEntryPoints = _.flatten([
|
const vscodeEntryPoints = _.flatten([
|
||||||
@@ -93,11 +94,11 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
|
|||||||
|
|
||||||
|
|
||||||
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
|
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
|
||||||
const fullpath = path.join(process.cwd(), 'out-vscode/vs/workbench/electron-browser/bootstrap/index.js')
|
const fullpath = path.join(process.cwd(), 'out-vscode/vs/workbench/electron-browser/bootstrap/index.js');
|
||||||
const contents = fs.readFileSync(fullpath).toString();
|
const contents = fs.readFileSync(fullpath).toString();
|
||||||
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
|
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
|
||||||
fs.writeFileSync(fullpath, newContents);
|
fs.writeFileSync(fullpath, newContents);
|
||||||
})
|
});
|
||||||
|
|
||||||
const baseUrl = `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`;
|
const baseUrl = `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`;
|
||||||
gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min'));
|
gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min'));
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ options.verbose = false;
|
|||||||
options.sourceMap = true;
|
options.sourceMap = true;
|
||||||
options.rootDir = rootDir;
|
options.rootDir = rootDir;
|
||||||
options.sourceRoot = util.toFileUri(rootDir);
|
options.sourceRoot = util.toFileUri(rootDir);
|
||||||
var smSourceRootPath = path.resolve(path.dirname(rootDir));
|
|
||||||
var smSourceRoot = util.toFileUri(smSourceRootPath);
|
|
||||||
function createCompile(build, emitError) {
|
function createCompile(build, emitError) {
|
||||||
var opts = _.clone(options);
|
var opts = _.clone(options);
|
||||||
opts.inlineSources = !!build;
|
opts.inlineSources = !!build;
|
||||||
@@ -48,7 +46,7 @@ function createCompile(build, emitError) {
|
|||||||
.pipe(sourcemaps.write('.', {
|
.pipe(sourcemaps.write('.', {
|
||||||
addComment: false,
|
addComment: false,
|
||||||
includeContent: !!build,
|
includeContent: !!build,
|
||||||
sourceRoot: smSourceRoot
|
sourceRoot: options.sourceRoot
|
||||||
}))
|
}))
|
||||||
.pipe(tsFilter.restore)
|
.pipe(tsFilter.restore)
|
||||||
.pipe(reporter.end(emitError));
|
.pipe(reporter.end(emitError));
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ options.sourceMap = true;
|
|||||||
options.rootDir = rootDir;
|
options.rootDir = rootDir;
|
||||||
options.sourceRoot = util.toFileUri(rootDir);
|
options.sourceRoot = util.toFileUri(rootDir);
|
||||||
|
|
||||||
const smSourceRootPath = path.resolve(path.dirname(rootDir));
|
|
||||||
const smSourceRoot = util.toFileUri(smSourceRootPath);
|
|
||||||
|
|
||||||
function createCompile(build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
|
function createCompile(build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
|
||||||
const opts = _.clone(options);
|
const opts = _.clone(options);
|
||||||
opts.inlineSources = !!build;
|
opts.inlineSources = !!build;
|
||||||
@@ -57,7 +54,7 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
|
|||||||
.pipe(sourcemaps.write('.', {
|
.pipe(sourcemaps.write('.', {
|
||||||
addComment: false,
|
addComment: false,
|
||||||
includeContent: !!build,
|
includeContent: !!build,
|
||||||
sourceRoot: smSourceRoot
|
sourceRoot: options.sourceRoot
|
||||||
}))
|
}))
|
||||||
.pipe(tsFilter.restore)
|
.pipe(tsFilter.restore)
|
||||||
.pipe(reporter.end(emitError));
|
.pipe(reporter.end(emitError));
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ var NoUnexternalizedStringsRuleWalker = (function (_super) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
|
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
|
||||||
var s = node.getText();
|
var s_1 = node.getText();
|
||||||
var replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")");
|
var replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s_1.substring(1, s_1.length - 1) + "', " + s_1 + ")");
|
||||||
var fix = new Lint.Fix("Unexternalitzed string", [replacement]);
|
var fix = new Lint.Fix("Unexternalitzed string", [replacement]);
|
||||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
|
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
|
||||||
return;
|
return;
|
||||||
|
|||||||
+2
-2
@@ -195,7 +195,7 @@ function format(text:string): string {
|
|||||||
// Apply the edits on the input code
|
// Apply the edits on the input code
|
||||||
return applyEdits(text, edits);
|
return applyEdits(text, edits);
|
||||||
|
|
||||||
function getRuleProvider(options: ts.FormatCodeOptions) {
|
function getRuleProvider(options: ts.FormatCodeSettings) {
|
||||||
// Share this between multiple formatters using the same options.
|
// Share this between multiple formatters using the same options.
|
||||||
// This represents the bulk of the space the formatter uses.
|
// This represents the bulk of the space the formatter uses.
|
||||||
let ruleProvider = new (<any>ts).formatting.RulesProvider();
|
let ruleProvider = new (<any>ts).formatting.RulesProvider();
|
||||||
@@ -215,7 +215,7 @@ function format(text:string): string {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultOptions(): ts.FormatCodeOptions {
|
function getDefaultOptions(): ts.FormatCodeSettings {
|
||||||
return {
|
return {
|
||||||
indentSize: 4,
|
indentSize: 4,
|
||||||
tabSize: 4,
|
tabSize: 4,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
"sinon": "^1.17.2",
|
"sinon": "^1.17.2",
|
||||||
"source-map": "^0.4.4",
|
"source-map": "^0.4.4",
|
||||||
"tslint": "^3.3.0",
|
"tslint": "^3.3.0",
|
||||||
"typescript": "^2.0.3",
|
"typescript": "^2.1.4",
|
||||||
"typescript-formatter": "3.1.0",
|
"typescript-formatter": "3.1.0",
|
||||||
"underscore": "^1.8.2",
|
"underscore": "^1.8.2",
|
||||||
"vinyl": "^0.4.5",
|
"vinyl": "^0.4.5",
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
body {
|
body {
|
||||||
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
|
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-left: 12px;
|
padding: 0 12px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.scrollBeyondLastLine {
|
body.scrollBeyondLastLine {
|
||||||
@@ -96,6 +97,10 @@ code {
|
|||||||
line-height: 19px;
|
line-height: 19px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.wordWrap pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.mac code {
|
.mac code {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
|||||||
public provideTextDocumentContent(uri: vscode.Uri): Thenable<string> {
|
public provideTextDocumentContent(uri: vscode.Uri): Thenable<string> {
|
||||||
return vscode.workspace.openTextDocument(vscode.Uri.parse(uri.query)).then(document => {
|
return vscode.workspace.openTextDocument(vscode.Uri.parse(uri.query)).then(document => {
|
||||||
const scrollBeyondLastLine = vscode.workspace.getConfiguration('editor')['scrollBeyondLastLine'];
|
const scrollBeyondLastLine = vscode.workspace.getConfiguration('editor')['scrollBeyondLastLine'];
|
||||||
|
const wordWrap = vscode.workspace.getConfiguration('editor')['wordWrap'];
|
||||||
|
|
||||||
const head = ([] as Array<string>).concat(
|
const head = ([] as Array<string>).concat(
|
||||||
'<!DOCTYPE html>',
|
'<!DOCTYPE html>',
|
||||||
'<html>',
|
'<html>',
|
||||||
@@ -267,7 +269,7 @@ class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
|||||||
this.computeCustomStyleSheetIncludes(uri),
|
this.computeCustomStyleSheetIncludes(uri),
|
||||||
`<base href="${document.uri.toString(true)}">`,
|
`<base href="${document.uri.toString(true)}">`,
|
||||||
'</head>',
|
'</head>',
|
||||||
`<body class="${scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''}">`
|
`<body class="${scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${wordWrap ? 'wordWrap' : ''}">`
|
||||||
).join('\n');
|
).join('\n');
|
||||||
const body = this._renderer.render(this.getDocumentContentForPreview(document));
|
const body = this._renderer.render(this.getDocumentContentForPreview(document));
|
||||||
|
|
||||||
|
|||||||
@@ -256,11 +256,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keybindings": {
|
|
||||||
"key": ".",
|
|
||||||
"command": "^acceptSelectedSuggestion",
|
|
||||||
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'typescript' && suggestionSupportsAcceptOnKey"
|
|
||||||
},
|
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
"command": "typescript.reloadProjects",
|
"command": "typescript.reloadProjects",
|
||||||
|
|||||||
@@ -18,16 +18,17 @@ import * as nls from 'vscode-nls';
|
|||||||
let localize = nls.loadMessageBundle();
|
let localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
class MyCompletionItem extends CompletionItem {
|
class MyCompletionItem extends CompletionItem {
|
||||||
|
constructor(
|
||||||
document: TextDocument;
|
public position: Position,
|
||||||
position: Position;
|
public document: TextDocument,
|
||||||
|
entry: CompletionEntry,
|
||||||
constructor(position: Position, document: TextDocument, entry: CompletionEntry) {
|
enableDotCompletions: boolean
|
||||||
|
) {
|
||||||
super(entry.name);
|
super(entry.name);
|
||||||
this.sortText = entry.sortText;
|
this.sortText = entry.sortText;
|
||||||
this.kind = MyCompletionItem.convertKind(entry.kind);
|
this.kind = MyCompletionItem.convertKind(entry.kind);
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.document = document;
|
this.commitCharacters = MyCompletionItem.getCommitCharacters(enableDotCompletions, entry.kind);
|
||||||
if (entry.replacementSpan) {
|
if (entry.replacementSpan) {
|
||||||
let span: protocol.TextSpan = entry.replacementSpan;
|
let span: protocol.TextSpan = entry.replacementSpan;
|
||||||
// The indexing for the range returned by the server uses 1-based indexing.
|
// The indexing for the range returned by the server uses 1-based indexing.
|
||||||
@@ -85,6 +86,38 @@ class MyCompletionItem extends CompletionItem {
|
|||||||
|
|
||||||
return CompletionItemKind.Property;
|
return CompletionItemKind.Property;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static getCommitCharacters(enableDotCompletions: boolean, kind: string): string[] | undefined {
|
||||||
|
switch (kind) {
|
||||||
|
case PConst.Kind.externalModuleName:
|
||||||
|
return ['"', '\''];
|
||||||
|
|
||||||
|
case PConst.Kind.file:
|
||||||
|
case PConst.Kind.directory:
|
||||||
|
return ['/', '"', '\''];
|
||||||
|
|
||||||
|
case PConst.Kind.memberGetAccessor:
|
||||||
|
case PConst.Kind.memberSetAccessor:
|
||||||
|
case PConst.Kind.constructSignature:
|
||||||
|
case PConst.Kind.callSignature:
|
||||||
|
case PConst.Kind.indexSignature:
|
||||||
|
case PConst.Kind.enum:
|
||||||
|
case PConst.Kind.interface:
|
||||||
|
return enableDotCompletions ? ['.'] : undefined;
|
||||||
|
|
||||||
|
case PConst.Kind.module:
|
||||||
|
case PConst.Kind.alias:
|
||||||
|
case PConst.Kind.variable:
|
||||||
|
case PConst.Kind.localVariable:
|
||||||
|
case PConst.Kind.memberVariable:
|
||||||
|
case PConst.Kind.class:
|
||||||
|
case PConst.Kind.function:
|
||||||
|
case PConst.Kind.memberFunction:
|
||||||
|
return enableDotCompletions ? ['.', '('] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Configuration {
|
interface Configuration {
|
||||||
@@ -97,15 +130,12 @@ namespace Configuration {
|
|||||||
|
|
||||||
export default class TypeScriptCompletionItemProvider implements CompletionItemProvider {
|
export default class TypeScriptCompletionItemProvider implements CompletionItemProvider {
|
||||||
|
|
||||||
public triggerCharacters = ['.'];
|
|
||||||
public excludeTokens = ['string', 'comment', 'numeric'];
|
|
||||||
public sortBy = [{ type: 'reference', partSeparator: '/' }];
|
|
||||||
|
|
||||||
private client: ITypescriptServiceClient;
|
|
||||||
private typingsStatus: TypingsStatus;
|
|
||||||
private config: Configuration;
|
private config: Configuration;
|
||||||
|
|
||||||
constructor(client: ITypescriptServiceClient, typingsStatus: TypingsStatus) {
|
constructor(
|
||||||
|
private client: ITypescriptServiceClient,
|
||||||
|
private typingsStatus: TypingsStatus
|
||||||
|
) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.typingsStatus = typingsStatus;
|
this.typingsStatus = typingsStatus;
|
||||||
this.config = { useCodeSnippetsOnMethodSuggest: false };
|
this.config = { useCodeSnippetsOnMethodSuggest: false };
|
||||||
@@ -158,9 +188,22 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
|||||||
let completionItems: CompletionItem[] = [];
|
let completionItems: CompletionItem[] = [];
|
||||||
let body = msg.body;
|
let body = msg.body;
|
||||||
if (body) {
|
if (body) {
|
||||||
|
// Only enable dot completions in TS files for now
|
||||||
|
let enableDotCompletions = document && (document.languageId === 'typescript' || document.languageId === 'typescriptreact');
|
||||||
|
|
||||||
|
// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/13456
|
||||||
|
// Only enable dot completions when previous character is an identifier.
|
||||||
|
// Prevents incorrectly completing while typing spread operators.
|
||||||
|
if (position.character > 0) {
|
||||||
|
const preText = document.getText(new Range(
|
||||||
|
new Position(position.line, 0),
|
||||||
|
new Position(position.line, position.character - 1)));
|
||||||
|
enableDotCompletions = preText.match(/[a-z_$]\s*$/ig) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < body.length; i++) {
|
for (let i = 0; i < body.length; i++) {
|
||||||
let element = body[i];
|
let element = body[i];
|
||||||
let item = new MyCompletionItem(position, document, element);
|
let item = new MyCompletionItem(position, document, element, enableDotCompletions);
|
||||||
completionItems.push(item);
|
completionItems.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,50 +5,18 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { DefinitionProvider, TextDocument, Position, Range, CancellationToken, Definition, Location } from 'vscode';
|
import { DefinitionProvider, TextDocument, Position, CancellationToken, Definition } from 'vscode';
|
||||||
|
|
||||||
import * as Proto from '../protocol';
|
|
||||||
import { ITypescriptServiceClient } from '../typescriptService';
|
import { ITypescriptServiceClient } from '../typescriptService';
|
||||||
|
import DefinitionProviderBase from './definitionProviderBase';
|
||||||
|
|
||||||
export default class TypeScriptDefinitionProvider implements DefinitionProvider {
|
export default class TypeScriptDefinitionProvider extends DefinitionProviderBase implements DefinitionProvider {
|
||||||
|
|
||||||
private client: ITypescriptServiceClient;
|
|
||||||
|
|
||||||
public tokens: string[] = [];
|
|
||||||
|
|
||||||
constructor(client: ITypescriptServiceClient) {
|
constructor(client: ITypescriptServiceClient) {
|
||||||
this.client = client;
|
super(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise<Definition | null> {
|
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Definition | null> {
|
||||||
const filepath = this.client.asAbsolutePath(document.uri);
|
return this.getSymbolLocations('definition', document, position, token);
|
||||||
if (!filepath) {
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
let args: Proto.FileLocationRequestArgs = {
|
|
||||||
file: filepath,
|
|
||||||
line: position.line + 1,
|
|
||||||
offset: position.character + 1
|
|
||||||
};
|
|
||||||
if (!args.file) {
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
return this.client.execute('definition', args, token).then(response => {
|
|
||||||
let locations: Proto.FileSpan[] = response.body || [];
|
|
||||||
if (!locations || locations.length === 0) {
|
|
||||||
return [] as Definition;
|
|
||||||
}
|
|
||||||
return locations.map(location => {
|
|
||||||
let resource = this.client.asUrl(location.file);
|
|
||||||
if (resource === null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return new Location(resource, new Range(location.start.line - 1, location.start.offset - 1, location.end.line - 1, location.end.offset - 1));
|
|
||||||
}
|
|
||||||
}).filter(x => x !== null) as Location[];
|
|
||||||
}, (error) => {
|
|
||||||
this.client.error(`'definition' request failed with error.`, error);
|
|
||||||
return [] as Definition;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { TextDocument, Position, Range, CancellationToken, Location } from 'vscode';
|
||||||
|
|
||||||
|
import * as Proto from '../protocol';
|
||||||
|
import { ITypescriptServiceClient } from '../typescriptService';
|
||||||
|
|
||||||
|
export default class TypeScriptDefinitionProviderBase {
|
||||||
|
|
||||||
|
private client: ITypescriptServiceClient;
|
||||||
|
|
||||||
|
public tokens: string[] = [];
|
||||||
|
|
||||||
|
constructor(client: ITypescriptServiceClient) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getSymbolLocations(definitionType: 'definition' | 'implementation', document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Location[] | null> {
|
||||||
|
const filepath = this.client.asAbsolutePath(document.uri);
|
||||||
|
if (!filepath) {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
let args: Proto.FileLocationRequestArgs = {
|
||||||
|
file: filepath,
|
||||||
|
line: position.line + 1,
|
||||||
|
offset: position.character + 1
|
||||||
|
};
|
||||||
|
if (!args.file) {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
return this.client.execute(definitionType, args, token).then(response => {
|
||||||
|
let locations: Proto.FileSpan[] = (response && response.body) || [];
|
||||||
|
if (!locations || locations.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return locations.map(location => {
|
||||||
|
let resource = this.client.asUrl(location.file);
|
||||||
|
if (resource === null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new Location(resource, new Range(location.start.line - 1, location.start.offset - 1, location.end.line - 1, location.end.offset - 1));
|
||||||
|
}
|
||||||
|
}).filter(x => x !== null) as Location[];
|
||||||
|
}, (error) => {
|
||||||
|
this.client.error(`'${definitionType}' request failed with error.`, error);
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,14 +73,13 @@ export default class TypeScriptReferencesCodeLensProvider implements CodeLensPro
|
|||||||
// Exclude original definition from references
|
// Exclude original definition from references
|
||||||
const locations = response.body.refs
|
const locations = response.body.refs
|
||||||
.filter(reference =>
|
.filter(reference =>
|
||||||
reference.start.line !== codeLens.range.start.line + 1
|
!(reference.start.line === codeLens.range.start.line + 1
|
||||||
&& reference.start.offset !== codeLens.range.start.character + 1)
|
&& reference.start.offset === codeLens.range.start.character + 1))
|
||||||
.map(reference =>
|
.map(reference =>
|
||||||
new Location(Uri.file(reference.file),
|
new Location(Uri.file(reference.file),
|
||||||
new Range(
|
new Range(
|
||||||
new Position(reference.start.line - 1, reference.start.offset - 1),
|
new Position(reference.start.line - 1, reference.start.offset - 1),
|
||||||
new Position(reference.end.line - 1, reference.end.offset - 1))));
|
new Position(reference.end.line - 1, reference.end.offset - 1))));
|
||||||
|
|
||||||
codeLens.command = {
|
codeLens.command = {
|
||||||
title: locations.length + ' ' + (locations.length === 1 ? localize('oneReferenceLabel', 'reference') : localize('manyReferenceLabel', 'references')),
|
title: locations.length + ' ' + (locations.length === 1 ? localize('oneReferenceLabel', 'reference') : localize('manyReferenceLabel', 'references')),
|
||||||
command: 'editor.action.showReferences',
|
command: 'editor.action.showReferences',
|
||||||
@@ -124,12 +123,17 @@ export default class TypeScriptReferencesCodeLensProvider implements CodeLensPro
|
|||||||
}
|
}
|
||||||
// fallthrough
|
// fallthrough
|
||||||
|
|
||||||
|
case PConst.Kind.class:
|
||||||
|
if (item.text === '<class>') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fallthrough
|
||||||
|
|
||||||
case PConst.Kind.memberFunction:
|
case PConst.Kind.memberFunction:
|
||||||
case PConst.Kind.memberVariable:
|
case PConst.Kind.memberVariable:
|
||||||
case PConst.Kind.memberGetAccessor:
|
case PConst.Kind.memberGetAccessor:
|
||||||
case PConst.Kind.memberSetAccessor:
|
case PConst.Kind.memberSetAccessor:
|
||||||
case PConst.Kind.constructorImplementation:
|
case PConst.Kind.constructorImplementation:
|
||||||
case PConst.Kind.class:
|
|
||||||
case PConst.Kind.interface:
|
case PConst.Kind.interface:
|
||||||
case PConst.Kind.type:
|
case PConst.Kind.type:
|
||||||
case PConst.Kind.enum:
|
case PConst.Kind.enum:
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { TypeDefinitionProvider, TextDocument, Position, CancellationToken, Definition } from 'vscode';
|
||||||
|
|
||||||
|
import { ITypescriptServiceClient } from '../typescriptService';
|
||||||
|
import DefinitionProviderBase from './definitionProviderBase';
|
||||||
|
|
||||||
|
export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements TypeDefinitionProvider {
|
||||||
|
|
||||||
|
constructor(client: ITypescriptServiceClient) {
|
||||||
|
super(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Definition | null> {
|
||||||
|
return this.getSymbolLocations('implementation', document, position, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import { ITypescriptServiceClientHost } from './typescriptService';
|
|||||||
|
|
||||||
import HoverProvider from './features/hoverProvider';
|
import HoverProvider from './features/hoverProvider';
|
||||||
import DefinitionProvider from './features/definitionProvider';
|
import DefinitionProvider from './features/definitionProvider';
|
||||||
|
import TypeDefinitionProvider from './features/TypeDefinitionProvider';
|
||||||
import DocumentHighlightProvider from './features/documentHighlightProvider';
|
import DocumentHighlightProvider from './features/documentHighlightProvider';
|
||||||
import ReferenceProvider from './features/referenceProvider';
|
import ReferenceProvider from './features/referenceProvider';
|
||||||
import DocumentSymbolProvider from './features/documentSymbolProvider';
|
import DocumentSymbolProvider from './features/documentSymbolProvider';
|
||||||
@@ -147,6 +148,7 @@ class LanguageProvider {
|
|||||||
|
|
||||||
let hoverProvider = new HoverProvider(client);
|
let hoverProvider = new HoverProvider(client);
|
||||||
let definitionProvider = new DefinitionProvider(client);
|
let definitionProvider = new DefinitionProvider(client);
|
||||||
|
let typeDefinitionProvider = new TypeDefinitionProvider(client);
|
||||||
let documentHighlightProvider = new DocumentHighlightProvider(client);
|
let documentHighlightProvider = new DocumentHighlightProvider(client);
|
||||||
let referenceProvider = new ReferenceProvider(client);
|
let referenceProvider = new ReferenceProvider(client);
|
||||||
let documentSymbolProvider = new DocumentSymbolProvider(client);
|
let documentSymbolProvider = new DocumentSymbolProvider(client);
|
||||||
@@ -169,6 +171,7 @@ class LanguageProvider {
|
|||||||
languages.registerCompletionItemProvider(selector, this.completionItemProvider, '.');
|
languages.registerCompletionItemProvider(selector, this.completionItemProvider, '.');
|
||||||
languages.registerHoverProvider(selector, hoverProvider);
|
languages.registerHoverProvider(selector, hoverProvider);
|
||||||
languages.registerDefinitionProvider(selector, definitionProvider);
|
languages.registerDefinitionProvider(selector, definitionProvider);
|
||||||
|
languages.registerTypeDefinitionProvider(selector, typeDefinitionProvider);
|
||||||
languages.registerDocumentHighlightProvider(selector, documentHighlightProvider);
|
languages.registerDocumentHighlightProvider(selector, documentHighlightProvider);
|
||||||
languages.registerReferenceProvider(selector, referenceProvider);
|
languages.registerReferenceProvider(selector, referenceProvider);
|
||||||
languages.registerDocumentSymbolProvider(selector, documentSymbolProvider);
|
languages.registerDocumentSymbolProvider(selector, documentSymbolProvider);
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export interface ITypescriptServiceClient {
|
|||||||
execute(commant: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: CancellationToken): Promise<Proto.CompletionDetailsResponse>;
|
execute(commant: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: CancellationToken): Promise<Proto.CompletionDetailsResponse>;
|
||||||
execute(commant: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: CancellationToken): Promise<Proto.SignatureHelpResponse>;
|
execute(commant: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: CancellationToken): Promise<Proto.SignatureHelpResponse>;
|
||||||
execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.DefinitionResponse>;
|
execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.DefinitionResponse>;
|
||||||
|
execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ImplementationResponse>;
|
||||||
execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ReferencesResponse>;
|
execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ReferencesResponse>;
|
||||||
execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: CancellationToken): Promise<Proto.NavtoResponse>;
|
execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: CancellationToken): Promise<Proto.NavtoResponse>;
|
||||||
execute(command: 'navbar', args: Proto.FileRequestArgs, token?: CancellationToken): Promise<Proto.NavBarResponse>;
|
execute(command: 'navbar', args: Proto.FileRequestArgs, token?: CancellationToken): Promise<Proto.NavBarResponse>;
|
||||||
|
|||||||
@@ -58,8 +58,14 @@ var ALL_EDITOR_TASKS = [
|
|||||||
'tslint',
|
'tslint',
|
||||||
'hygiene',
|
'hygiene',
|
||||||
];
|
];
|
||||||
|
|
||||||
var runningEditorTasks = process.argv.length > 2 && process.argv.slice(2).every(function (arg) { return (ALL_EDITOR_TASKS.indexOf(arg) !== -1); });
|
var runningEditorTasks = process.argv.length > 2 && process.argv.slice(2).every(function (arg) { return (ALL_EDITOR_TASKS.indexOf(arg) !== -1); });
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
if (runningEditorTasks) {
|
if (runningEditorTasks) {
|
||||||
require(`./build/gulpfile.editor`);
|
require(`./build/gulpfile.editor`);
|
||||||
require(`./build/gulpfile.hygiene`);
|
require(`./build/gulpfile.hygiene`);
|
||||||
|
|||||||
Generated
+1
-1
@@ -432,7 +432,7 @@
|
|||||||
"xterm": {
|
"xterm": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"from": "git+https://github.com/Tyriar/xterm.js.git#vscode-release/1.9",
|
"from": "git+https://github.com/Tyriar/xterm.js.git#vscode-release/1.9",
|
||||||
"resolved": "git+https://github.com/Tyriar/xterm.js.git#8fb0947bf7d2e506b16b5425c71726c25a64475b"
|
"resolved": "git+https://github.com/Tyriar/xterm.js.git#36c63323c3f940636e799ae6e0168b2dfd7a3d21"
|
||||||
},
|
},
|
||||||
"yauzl": {
|
"yauzl": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
"name": "code-oss-dev",
|
"name": "code-oss-dev",
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"electronVersion": "1.4.6",
|
"electronVersion": "1.4.6",
|
||||||
"distro": "ef07477c3bbf2aa2f274b13093cbe0d96fa59fdd",
|
"distro": "07e460da0e2854e12c183abaa5acbcd7b8c48d7f",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Microsoft Corporation"
|
"name": "Microsoft Corporation"
|
||||||
},
|
},
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
"gulp-rename": "^1.2.0",
|
"gulp-rename": "^1.2.0",
|
||||||
"gulp-replace": "^0.5.4",
|
"gulp-replace": "^0.5.4",
|
||||||
"gulp-shell": "^0.5.2",
|
"gulp-shell": "^0.5.2",
|
||||||
"gulp-sourcemaps": "^1.6.0",
|
"gulp-sourcemaps": "^1.11.0",
|
||||||
"gulp-tsb": "^2.0.3",
|
"gulp-tsb": "^2.0.3",
|
||||||
"gulp-tslint": "^7.0.1",
|
"gulp-tslint": "^7.0.1",
|
||||||
"gulp-uglify": "^2.0.0",
|
"gulp-uglify": "^2.0.0",
|
||||||
|
|||||||
@@ -40,13 +40,14 @@ export class SelectBox extends Widget {
|
|||||||
return this._onDidSelect.event;
|
return this._onDidSelect.event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setOptions(options: string[], selected?: number): void {
|
public setOptions(options: string[], selected?: number, disabled?: number): void {
|
||||||
if (!this.options || !arrays.equals(this.options, options)) {
|
if (!this.options || !arrays.equals(this.options, options)) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
this.selectElement.options.length = 0;
|
this.selectElement.options.length = 0;
|
||||||
|
let i = 0;
|
||||||
this.options.forEach((option) => {
|
this.options.forEach((option) => {
|
||||||
this.selectElement.add(this.createOption(option));
|
this.selectElement.add(this.createOption(option, disabled === i++));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.select(selected);
|
this.select(selected);
|
||||||
@@ -91,10 +92,11 @@ export class SelectBox extends Widget {
|
|||||||
this.setOptions(this.options, this.selected);
|
this.setOptions(this.options, this.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private createOption(value: string): HTMLOptionElement {
|
private createOption(value: string, disabled?: boolean): HTMLOptionElement {
|
||||||
let option = document.createElement('option');
|
let option = document.createElement('option');
|
||||||
option.value = value;
|
option.value = value;
|
||||||
option.text = value;
|
option.text = value;
|
||||||
|
option.disabled = disabled;
|
||||||
|
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public focusTextArea(): void {
|
public focusTextArea(): void {
|
||||||
this.textAreaHandler.writePlaceholderAndSelectTextAreaSync();
|
this.textAreaHandler.focusTextArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
|
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
|||||||
import { TimeoutTimer, RunOnceScheduler } from 'vs/base/common/async';
|
import { TimeoutTimer, RunOnceScheduler } from 'vs/base/common/async';
|
||||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||||
import { VisibleRange } from 'vs/editor/common/view/renderingContext';
|
import { VisibleRange } from 'vs/editor/common/view/renderingContext';
|
||||||
import { EditorMouseEventFactory, GlobalEditorMouseMoveMonitor, EditorMouseEvent } from 'vs/editor/browser/editorDom';
|
import { EditorMouseEventFactory, GlobalEditorMouseMoveMonitor, EditorMouseEvent, createEditorPagePosition, ClientCoordinates } from 'vs/editor/browser/editorDom';
|
||||||
import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||||
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
|
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
|
||||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||||
@@ -204,9 +204,7 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- begin event handlers
|
// --- begin event handlers
|
||||||
_layoutInfo: editorCommon.EditorLayoutInfo;
|
|
||||||
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
|
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
|
||||||
this._layoutInfo = layoutInfo;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public onScrollChanged(e: editorCommon.IScrollEvent): boolean {
|
public onScrollChanged(e: editorCommon.IScrollEvent): boolean {
|
||||||
@@ -224,13 +222,26 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
|
|||||||
}
|
}
|
||||||
// --- end event handlers
|
// --- end event handlers
|
||||||
|
|
||||||
|
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||||
|
let clientPos = new ClientCoordinates(clientX, clientY);
|
||||||
|
let pos = clientPos.toPageCoordinates();
|
||||||
|
let editorPos = createEditorPagePosition(this.viewHelper.viewDomNode);
|
||||||
|
|
||||||
|
if (pos.y < editorPos.y || pos.y > editorPos.y + editorPos.height || pos.x < editorPos.x || pos.x > editorPos.x + editorPos.width) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastViewCursorsRenderData = this.viewHelper.getLastViewCursorsRenderData();
|
||||||
|
return this.mouseTargetFactory.createMouseTarget(lastViewCursorsRenderData, editorPos, pos, null);
|
||||||
|
}
|
||||||
|
|
||||||
protected _createMouseTarget(e: EditorMouseEvent, testEventTarget: boolean): editorBrowser.IMouseTarget {
|
protected _createMouseTarget(e: EditorMouseEvent, testEventTarget: boolean): editorBrowser.IMouseTarget {
|
||||||
let lastViewCursorsRenderData = this.viewHelper.getLastViewCursorsRenderData();
|
let lastViewCursorsRenderData = this.viewHelper.getLastViewCursorsRenderData();
|
||||||
return this.mouseTargetFactory.createMouseTarget(this._layoutInfo, lastViewCursorsRenderData, e, testEventTarget);
|
return this.mouseTargetFactory.createMouseTarget(lastViewCursorsRenderData, e.editorPos, e.pos, testEventTarget ? e.target : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getMouseColumn(e: EditorMouseEvent): number {
|
private _getMouseColumn(e: EditorMouseEvent): number {
|
||||||
return this.mouseTargetFactory.getMouseColumn(this._layoutInfo, e);
|
return this.mouseTargetFactory.getMouseColumn(e.editorPos, e.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _onContextMenu(e: EditorMouseEvent, testEventTarget: boolean): void {
|
protected _onContextMenu(e: EditorMouseEvent, testEventTarget: boolean): void {
|
||||||
@@ -453,23 +464,23 @@ class MouseDownOperation extends Disposable {
|
|||||||
|
|
||||||
let mouseColumn = this._getMouseColumn(e);
|
let mouseColumn = this._getMouseColumn(e);
|
||||||
|
|
||||||
if (e.posy < editorContent.top) {
|
if (e.posy < editorContent.y) {
|
||||||
let aboveLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(Math.max(this._viewHelper.getScrollTop() - (editorContent.top - e.posy), 0));
|
let aboveLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(Math.max(this._viewHelper.getScrollTop() - (editorContent.y - e.posy), 0));
|
||||||
return new MousePosition(new Position(aboveLineNumber, 1), mouseColumn);
|
return new MousePosition(new Position(aboveLineNumber, 1), mouseColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.posy > editorContent.top + editorContent.height) {
|
if (e.posy > editorContent.y + editorContent.height) {
|
||||||
let belowLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.top));
|
let belowLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.y));
|
||||||
return new MousePosition(new Position(belowLineNumber, this._context.model.getLineMaxColumn(belowLineNumber)), mouseColumn);
|
return new MousePosition(new Position(belowLineNumber, this._context.model.getLineMaxColumn(belowLineNumber)), mouseColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
let possibleLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.top));
|
let possibleLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.y));
|
||||||
|
|
||||||
if (e.posx < editorContent.left) {
|
if (e.posx < editorContent.x) {
|
||||||
return new MousePosition(new Position(possibleLineNumber, 1), mouseColumn);
|
return new MousePosition(new Position(possibleLineNumber, 1), mouseColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.posx > editorContent.left + editorContent.width) {
|
if (e.posx > editorContent.x + editorContent.width) {
|
||||||
return new MousePosition(new Position(possibleLineNumber, this._context.model.getLineMaxColumn(possibleLineNumber)), mouseColumn);
|
return new MousePosition(new Position(possibleLineNumber, this._context.model.getLineMaxColumn(possibleLineNumber)), mouseColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,8 @@
|
|||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import * as dom from 'vs/base/browser/dom';
|
import * as dom from 'vs/base/browser/dom';
|
||||||
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
|
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
|
||||||
import { IScrollEvent } from 'vs/editor/common/editorCommon';
|
|
||||||
import { MouseHandler, IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
import { MouseHandler, IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||||
import { IViewController } from 'vs/editor/browser/editorBrowser';
|
import { IViewController, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||||
import { EditorMouseEvent } from 'vs/editor/browser/editorDom';
|
import { EditorMouseEvent } from 'vs/editor/browser/editorDom';
|
||||||
|
|
||||||
@@ -247,8 +246,8 @@ export class PointerHandler implements IDisposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public onScrollChanged(e: IScrollEvent): void {
|
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget {
|
||||||
this.handler.onScrollChanged(e);
|
return this.handler.getTargetAtClientPoint(clientX, clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export interface ICodeEditorHelper {
|
|||||||
getVerticalOffsetForPosition(lineNumber: number, column: number): number;
|
getVerticalOffsetForPosition(lineNumber: number, column: number): number;
|
||||||
delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void;
|
delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void;
|
||||||
getOffsetForColumn(lineNumber: number, column: number): number;
|
getOffsetForColumn(lineNumber: number, column: number): number;
|
||||||
|
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -522,6 +523,14 @@ export interface ICodeEditor extends editorCommon.ICommonCodeEditor {
|
|||||||
*/
|
*/
|
||||||
getTopForPosition(lineNumber: number, column: number): number;
|
getTopForPosition(lineNumber: number, column: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hit test target at coordinates `clientX` and `clientY`.
|
||||||
|
* The coordinates are relative to the top-left of the viewport.
|
||||||
|
*
|
||||||
|
* @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
|
||||||
|
*/
|
||||||
|
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the visible position for `position`.
|
* Get the visible position for `position`.
|
||||||
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
||||||
|
|||||||
@@ -9,27 +9,88 @@ import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
|||||||
import * as dom from 'vs/base/browser/dom';
|
import * as dom from 'vs/base/browser/dom';
|
||||||
import { GlobalMouseMoveMonitor } from 'vs/base/browser/globalMouseMoveMonitor';
|
import { GlobalMouseMoveMonitor } from 'vs/base/browser/globalMouseMoveMonitor';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coordinates relative to the whole document (e.g. mouse event's pageX and pageY)
|
||||||
|
*/
|
||||||
|
export class PageCoordinates {
|
||||||
|
_pageCoordinatesBrand: void;
|
||||||
|
public readonly x: number;
|
||||||
|
public readonly y: number;
|
||||||
|
|
||||||
|
constructor(x: number, y: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toClientCoordinates(): ClientCoordinates {
|
||||||
|
return new ClientCoordinates(this.x - dom.StandardWindow.scrollX, this.y - dom.StandardWindow.scrollY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coordinates within the application's client area (i.e. origin is document's scroll position).
|
||||||
|
*
|
||||||
|
* For example, clicking in the top-left corner of the client area will
|
||||||
|
* always result in a mouse event with a client.x value of 0, regardless
|
||||||
|
* of whether the page is scrolled horizontally.
|
||||||
|
*/
|
||||||
|
export class ClientCoordinates {
|
||||||
|
_clientCoordinatesBrand: void;
|
||||||
|
|
||||||
|
public readonly clientX: number;
|
||||||
|
public readonly clientY: number;
|
||||||
|
|
||||||
|
constructor(clientX: number, clientY: number) {
|
||||||
|
this.clientX = clientX;
|
||||||
|
this.clientY = clientY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toPageCoordinates(): PageCoordinates {
|
||||||
|
return new PageCoordinates(this.clientX + dom.StandardWindow.scrollX, this.clientY + dom.StandardWindow.scrollY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of the editor in the page.
|
||||||
|
*/
|
||||||
|
export class EditorPagePosition {
|
||||||
|
_editorPagePositionBrand: void;
|
||||||
|
|
||||||
|
public readonly x: number;
|
||||||
|
public readonly y: number;
|
||||||
|
public readonly width: number;
|
||||||
|
public readonly height: number;
|
||||||
|
|
||||||
|
constructor(x: number, y: number, width: number, height: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createEditorPagePosition(editorViewDomNode: HTMLElement): EditorPagePosition {
|
||||||
|
let editorPos = dom.getDomNodePagePosition(editorViewDomNode);
|
||||||
|
return new EditorPagePosition(editorPos.left, editorPos.top, editorPos.width, editorPos.height);
|
||||||
|
}
|
||||||
|
|
||||||
export class EditorMouseEvent extends StandardMouseEvent {
|
export class EditorMouseEvent extends StandardMouseEvent {
|
||||||
_editorMouseEventBrand: void;
|
_editorMouseEventBrand: void;
|
||||||
|
|
||||||
editorPos: dom.IDomNodePagePosition;
|
/**
|
||||||
|
* Coordinates relative to the whole document.
|
||||||
|
*/
|
||||||
|
public readonly pos: PageCoordinates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The horizontal position of the cursor relative to the viewport (i.e. scrolled).
|
* Editor's coordinates relative to the whole document.
|
||||||
*/
|
*/
|
||||||
viewportx: number;
|
public readonly editorPos: EditorPagePosition;
|
||||||
|
|
||||||
/**
|
|
||||||
* The vertical position of the cursor relative to the viewport (i.e. scrolled).
|
|
||||||
*/
|
|
||||||
viewporty: number;
|
|
||||||
|
|
||||||
constructor(e: MouseEvent, editorViewDomNode: HTMLElement) {
|
constructor(e: MouseEvent, editorViewDomNode: HTMLElement) {
|
||||||
super(e);
|
super(e);
|
||||||
this.editorPos = dom.getDomNodePagePosition(editorViewDomNode);
|
this.pos = new PageCoordinates(this.posx, this.posy);
|
||||||
|
this.editorPos = createEditorPagePosition(editorViewDomNode);
|
||||||
this.viewportx = this.posx - dom.StandardWindow.scrollX;
|
|
||||||
this.viewporty = this.posy - dom.StandardWindow.scrollY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -276,6 +276,13 @@ export function registerDefinitionProvider(languageId: string, provider: modes.D
|
|||||||
return modes.DefinitionProviderRegistry.register(languageId, provider);
|
return modes.DefinitionProviderRegistry.register(languageId, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a type definition provider (used by e.g. go to implementation).
|
||||||
|
*/
|
||||||
|
export function registerTypeDefinitionProvider(languageId: string, provider: modes.TypeDefinitionProvider): IDisposable {
|
||||||
|
return modes.TypeDefinitionProviderRegistry.register(languageId, provider);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a code lens provider (used by e.g. inline code lenses).
|
* Register a code lens provider (used by e.g. inline code lenses).
|
||||||
*/
|
*/
|
||||||
@@ -633,6 +640,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages {
|
|||||||
registerDocumentSymbolProvider: registerDocumentSymbolProvider,
|
registerDocumentSymbolProvider: registerDocumentSymbolProvider,
|
||||||
registerDocumentHighlightProvider: registerDocumentHighlightProvider,
|
registerDocumentHighlightProvider: registerDocumentHighlightProvider,
|
||||||
registerDefinitionProvider: registerDefinitionProvider,
|
registerDefinitionProvider: registerDefinitionProvider,
|
||||||
|
registerTypeDefinitionProvider: registerTypeDefinitionProvider,
|
||||||
registerCodeLensProvider: registerCodeLensProvider,
|
registerCodeLensProvider: registerCodeLensProvider,
|
||||||
registerCodeActionProvider: registerCodeActionProvider,
|
registerCodeActionProvider: registerCodeActionProvider,
|
||||||
registerDocumentFormattingEditProvider: registerDocumentFormattingEditProvider,
|
registerDocumentFormattingEditProvider: registerDocumentFormattingEditProvider,
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
|||||||
// (there have been reports of tiny blinking cursors)
|
// (there have been reports of tiny blinking cursors)
|
||||||
// (in WebKit the textarea is 1px by 1px because it cannot handle input to a 0x0 textarea)
|
// (in WebKit the textarea is 1px by 1px because it cannot handle input to a 0x0 textarea)
|
||||||
this.textAreaCover = document.createElement('div');
|
this.textAreaCover = document.createElement('div');
|
||||||
PartFingerprints.write(this.textAreaCover, PartFingerprint.TextAreaCover);
|
|
||||||
if (this._context.configuration.editor.viewInfo.glyphMargin) {
|
if (this._context.configuration.editor.viewInfo.glyphMargin) {
|
||||||
this.textAreaCover.className = 'monaco-editor-background ' + editorBrowser.ClassNames.GLYPH_MARGIN + ' ' + editorBrowser.ClassNames.TEXTAREA_COVER;
|
this.textAreaCover.className = 'monaco-editor-background ' + editorBrowser.ClassNames.GLYPH_MARGIN + ' ' + editorBrowser.ClassNames.TEXTAREA_COVER;
|
||||||
} else {
|
} else {
|
||||||
@@ -609,7 +608,15 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return visibleRanges[0].left;
|
return visibleRanges[0].left;
|
||||||
|
},
|
||||||
|
|
||||||
|
getTargetAtClientPoint: (clientX: number, clientY: number): editorBrowser.IMouseTarget => {
|
||||||
|
if (this._isDisposed) {
|
||||||
|
throw new Error('ViewImpl.codeEditorHelper.getTargetAtClientPoint: View is disposed');
|
||||||
|
}
|
||||||
|
return this.pointerHandler.getTargetAtClientPoint(clientX, clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return this.codeEditorHelper;
|
return this.codeEditorHelper;
|
||||||
@@ -666,7 +673,9 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
|
|||||||
this.keyboardHandler.focusTextArea();
|
this.keyboardHandler.focusTextArea();
|
||||||
|
|
||||||
// IE does not trigger the focus event immediately, so we must help it a little bit
|
// IE does not trigger the focus event immediately, so we must help it a little bit
|
||||||
this._setHasFocus(true);
|
if (document.activeElement === this.textArea) {
|
||||||
|
this._setHasFocus(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public isFocused(): boolean {
|
public isFocused(): boolean {
|
||||||
|
|||||||
@@ -30,17 +30,12 @@ export abstract class ViewPart extends ViewEventHandler {
|
|||||||
export const enum PartFingerprint {
|
export const enum PartFingerprint {
|
||||||
None,
|
None,
|
||||||
ContentWidgets,
|
ContentWidgets,
|
||||||
Margin,
|
|
||||||
OverflowingContentWidgets,
|
OverflowingContentWidgets,
|
||||||
OverflowGuard,
|
OverflowGuard,
|
||||||
OverlayWidgets,
|
OverlayWidgets,
|
||||||
OverviewRuler,
|
|
||||||
ScrollableElement,
|
ScrollableElement,
|
||||||
TextArea,
|
TextArea,
|
||||||
TextAreaCover,
|
|
||||||
ViewCursorsLayer,
|
|
||||||
ViewLines,
|
ViewLines,
|
||||||
ViewZones
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PartFingerprints {
|
export class PartFingerprints {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { StyleMutator, FastDomNode, createFastDomNode } from 'vs/base/browser/styleMutator';
|
import { StyleMutator, FastDomNode, createFastDomNode } from 'vs/base/browser/styleMutator';
|
||||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||||
import { ClassNames } from 'vs/editor/browser/editorBrowser';
|
import { ClassNames } from 'vs/editor/browser/editorBrowser';
|
||||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||||
import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||||
import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider';
|
import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider';
|
||||||
@@ -39,7 +39,6 @@ export class Margin extends ViewPart {
|
|||||||
|
|
||||||
public _createDomNode(): HTMLElement {
|
public _createDomNode(): HTMLElement {
|
||||||
let domNode = document.createElement('div');
|
let domNode = document.createElement('div');
|
||||||
PartFingerprints.write(domNode, PartFingerprint.Margin);
|
|
||||||
domNode.className = ClassNames.MARGIN + ' monaco-editor-background';
|
domNode.className = ClassNames.MARGIN + ' monaco-editor-background';
|
||||||
domNode.style.position = 'absolute';
|
domNode.style.position = 'absolute';
|
||||||
domNode.setAttribute('role', 'presentation');
|
domNode.setAttribute('role', 'presentation');
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { OverviewRulerPosition, OverviewRulerLane, OverviewRulerZone, ColorZone
|
|||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import * as browser from 'vs/base/browser/browser';
|
import * as browser from 'vs/base/browser/browser';
|
||||||
import { OverviewZoneManager } from 'vs/editor/common/view/overviewZoneManager';
|
import { OverviewZoneManager } from 'vs/editor/common/view/overviewZoneManager';
|
||||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
|
||||||
|
|
||||||
export class OverviewRulerImpl {
|
export class OverviewRulerImpl {
|
||||||
|
|
||||||
@@ -25,7 +24,6 @@ export class OverviewRulerImpl {
|
|||||||
this._canvasLeftOffset = canvasLeftOffset;
|
this._canvasLeftOffset = canvasLeftOffset;
|
||||||
|
|
||||||
this._domNode = <HTMLCanvasElement>document.createElement('canvas');
|
this._domNode = <HTMLCanvasElement>document.createElement('canvas');
|
||||||
PartFingerprints.write(this._domNode, PartFingerprint.OverviewRuler);
|
|
||||||
|
|
||||||
this._domNode.className = cssClassName;
|
this._domNode.className = cssClassName;
|
||||||
this._domNode.style.position = 'absolute';
|
this._domNode.style.position = 'absolute';
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import 'vs/css!./viewCursors';
|
import 'vs/css!./viewCursors';
|
||||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||||
import { ClassNames } from 'vs/editor/browser/editorBrowser';
|
import { ClassNames } from 'vs/editor/browser/editorBrowser';
|
||||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||||
import { Position } from 'vs/editor/common/core/position';
|
import { Position } from 'vs/editor/common/core/position';
|
||||||
import { IViewCursorRenderData, ViewCursor } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
import { IViewCursorRenderData, ViewCursor } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||||
@@ -49,7 +49,6 @@ export class ViewCursors extends ViewPart {
|
|||||||
this._renderData = [];
|
this._renderData = [];
|
||||||
|
|
||||||
this._domNode = createFastDomNode(document.createElement('div'));
|
this._domNode = createFastDomNode(document.createElement('div'));
|
||||||
PartFingerprints.write(this._domNode.domNode, PartFingerprint.ViewCursorsLayer);
|
|
||||||
this._updateDomClassName();
|
this._updateDomClassName();
|
||||||
|
|
||||||
this._domNode.domNode.appendChild(this._primaryCursor.getDomNode());
|
this._domNode.domNode.appendChild(this._primaryCursor.getDomNode());
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
|||||||
import { StyleMutator } from 'vs/base/browser/styleMutator';
|
import { StyleMutator } from 'vs/base/browser/styleMutator';
|
||||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||||
import { ClassNames, IViewZone } from 'vs/editor/browser/editorBrowser';
|
import { ClassNames, IViewZone } from 'vs/editor/browser/editorBrowser';
|
||||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||||
import { Position } from 'vs/editor/common/core/position';
|
import { Position } from 'vs/editor/common/core/position';
|
||||||
import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||||
@@ -49,7 +49,6 @@ export class ViewZones extends ViewPart {
|
|||||||
this._whitespaceManager = whitespaceManager;
|
this._whitespaceManager = whitespaceManager;
|
||||||
|
|
||||||
this.domNode = document.createElement('div');
|
this.domNode = document.createElement('div');
|
||||||
PartFingerprints.write(this.domNode, PartFingerprint.ViewZones);
|
|
||||||
this.domNode.className = ClassNames.VIEW_ZONES;
|
this.domNode.className = ClassNames.VIEW_ZONES;
|
||||||
this.domNode.style.position = 'absolute';
|
this.domNode.style.position = 'absolute';
|
||||||
this.domNode.setAttribute('role', 'presentation');
|
this.domNode.setAttribute('role', 'presentation');
|
||||||
|
|||||||
@@ -404,6 +404,13 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
|||||||
return this._view.getCodeEditorHelper().getVerticalOffsetForPosition(lineNumber, column);
|
return this._view.getCodeEditorHelper().getVerticalOffsetForPosition(lineNumber, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||||
|
if (!this.hasView) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this._view.getCodeEditorHelper().getTargetAtClientPoint(clientX, clientY);
|
||||||
|
}
|
||||||
|
|
||||||
public getScrolledVisiblePosition(rawPosition: editorCommon.IPosition): { top: number; left: number; height: number; } {
|
public getScrolledVisiblePosition(rawPosition: editorCommon.IPosition): { top: number; left: number; height: number; } {
|
||||||
if (!this.hasView) {
|
if (!this.hasView) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
.monaco-editor .vs-whitespace {
|
.monaco-editor .vs-whitespace {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
font-weight: normal !important;
|
||||||
}
|
}
|
||||||
.monaco-editor.hc-black .view-line {
|
.monaco-editor.hc-black .view-line {
|
||||||
mix-blend-mode: difference;
|
mix-blend-mode: difference;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export class TextAreaHandler extends Disposable {
|
|||||||
|
|
||||||
// In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled.
|
// In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled.
|
||||||
if (!this.Browser.isEdgeOrIE) {
|
if (!this.Browser.isEdgeOrIE) {
|
||||||
this.setTextAreaState('compositionstart', this.textAreaState.toEmpty());
|
this.setTextAreaState('compositionstart', this.textAreaState.toEmpty(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._onCompositionStart.fire({
|
this._onCompositionStart.fire({
|
||||||
@@ -200,13 +200,13 @@ export class TextAreaHandler extends Disposable {
|
|||||||
} else {
|
} else {
|
||||||
if (this.textArea.getSelectionStart() !== this.textArea.getSelectionEnd()) {
|
if (this.textArea.getSelectionStart() !== this.textArea.getSelectionEnd()) {
|
||||||
// Clean up the textarea, to get a clean paste
|
// Clean up the textarea, to get a clean paste
|
||||||
this.setTextAreaState('paste', this.textAreaState.toEmpty());
|
this.setTextAreaState('paste', this.textAreaState.toEmpty(), false);
|
||||||
}
|
}
|
||||||
this._nextCommand = ReadFromTextArea.Paste;
|
this._nextCommand = ReadFromTextArea.Paste;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._writePlaceholderAndSelectTextArea('ctor');
|
this._writePlaceholderAndSelectTextArea('ctor', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
@@ -227,24 +227,24 @@ export class TextAreaHandler extends Disposable {
|
|||||||
}
|
}
|
||||||
this.hasFocus = isFocused;
|
this.hasFocus = isFocused;
|
||||||
if (this.hasFocus) {
|
if (this.hasFocus) {
|
||||||
this._writePlaceholderAndSelectTextArea('focusgain');
|
this._writePlaceholderAndSelectTextArea('focusgain', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setCursorSelections(primary: Range, secondary: Range[]): void {
|
public setCursorSelections(primary: Range, secondary: Range[]): void {
|
||||||
this.selection = primary;
|
this.selection = primary;
|
||||||
this.selections = [primary].concat(secondary);
|
this.selections = [primary].concat(secondary);
|
||||||
this._writePlaceholderAndSelectTextArea('selection changed');
|
this._writePlaceholderAndSelectTextArea('selection changed', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- end event handlers
|
// --- end event handlers
|
||||||
|
|
||||||
private setTextAreaState(reason: string, textAreaState: TextAreaState): void {
|
private setTextAreaState(reason: string, textAreaState: TextAreaState, forceFocus: boolean): void {
|
||||||
if (!this.hasFocus) {
|
if (!this.hasFocus) {
|
||||||
textAreaState = textAreaState.resetSelection();
|
textAreaState = textAreaState.resetSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
textAreaState.applyToTextArea(reason, this.textArea, this.hasFocus);
|
textAreaState.applyToTextArea(reason, this.textArea, this.hasFocus || forceFocus);
|
||||||
this.textAreaState = textAreaState;
|
this.textAreaState = textAreaState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,18 +281,18 @@ export class TextAreaHandler extends Disposable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public writePlaceholderAndSelectTextAreaSync(): void {
|
public focusTextArea(): void {
|
||||||
this._writePlaceholderAndSelectTextArea('focusTextArea');
|
this._writePlaceholderAndSelectTextArea('focusTextArea', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _writePlaceholderAndSelectTextArea(reason: string): void {
|
private _writePlaceholderAndSelectTextArea(reason: string, forceFocus: boolean): void {
|
||||||
if (!this.textareaIsShownAtCursor) {
|
if (!this.textareaIsShownAtCursor) {
|
||||||
// Do not write to the textarea if it is visible.
|
// Do not write to the textarea if it is visible.
|
||||||
if (this.Browser.isIPad) {
|
if (this.Browser.isIPad) {
|
||||||
// Do not place anything in the textarea for the iPad
|
// Do not place anything in the textarea for the iPad
|
||||||
this.setTextAreaState(reason, this.textAreaState.toEmpty());
|
this.setTextAreaState(reason, this.textAreaState.toEmpty(), forceFocus);
|
||||||
} else {
|
} else {
|
||||||
this.setTextAreaState(reason, this.textAreaState.fromEditorSelection(this.model, this.selection));
|
this.setTextAreaState(reason, this.textAreaState.fromEditorSelection(this.model, this.selection), forceFocus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ export class TextAreaHandler extends Disposable {
|
|||||||
if (e.canUseTextData()) {
|
if (e.canUseTextData()) {
|
||||||
e.setTextData(whatToCopy);
|
e.setTextData(whatToCopy);
|
||||||
} else {
|
} else {
|
||||||
this.setTextAreaState('copy or cut', this.textAreaState.fromText(whatToCopy));
|
this.setTextAreaState('copy or cut', this.textAreaState.fromText(whatToCopy), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Browser.enableEmptySelectionClipboard) {
|
if (this.Browser.enableEmptySelectionClipboard) {
|
||||||
|
|||||||
@@ -243,10 +243,9 @@ export interface IEditorOptions {
|
|||||||
*/
|
*/
|
||||||
roundedSelection?: boolean;
|
roundedSelection?: boolean;
|
||||||
/**
|
/**
|
||||||
* Theme to be used for rendering. Consists of two parts, the UI theme and the syntax theme,
|
* Theme to be used for rendering.
|
||||||
* separated by a space.
|
* The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black'.
|
||||||
* The current available UI themes are: 'vs' (default), 'vs-dark', 'hc-black'
|
* You can create custom themes via `monaco.editor.defineTheme`.
|
||||||
* The syntax themes are contributed. The default is 'default-theme'
|
|
||||||
*/
|
*/
|
||||||
theme?: string;
|
theme?: string;
|
||||||
/**
|
/**
|
||||||
@@ -3064,6 +3063,10 @@ export namespace ModeContextKeys {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', undefined);
|
export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', undefined);
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', undefined);
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -418,6 +418,7 @@ export interface Location {
|
|||||||
* defined.
|
* defined.
|
||||||
*/
|
*/
|
||||||
export type Definition = Location | Location[];
|
export type Definition = Location | Location[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The definition provider interface defines the contract between extensions and
|
* The definition provider interface defines the contract between extensions and
|
||||||
* the [go to definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition)
|
* the [go to definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition)
|
||||||
@@ -430,6 +431,16 @@ export interface DefinitionProvider {
|
|||||||
provideDefinition(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
provideDefinition(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type definition provider interface defines the contract between extensions and
|
||||||
|
* the go to implementation feature.
|
||||||
|
*/
|
||||||
|
export interface TypeDefinitionProvider {
|
||||||
|
/**
|
||||||
|
* Provide the implementation of the symbol at the given position and document.
|
||||||
|
*/
|
||||||
|
provideTypeDefinition(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A symbol kind.
|
* A symbol kind.
|
||||||
@@ -738,6 +749,11 @@ export const DocumentHighlightProviderRegistry = new LanguageFeatureRegistry<Doc
|
|||||||
*/
|
*/
|
||||||
export const DefinitionProviderRegistry = new LanguageFeatureRegistry<DefinitionProvider>();
|
export const DefinitionProviderRegistry = new LanguageFeatureRegistry<DefinitionProvider>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const TypeDefinitionProviderRegistry = new LanguageFeatureRegistry<TypeDefinitionProvider>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export class EditorModeContext {
|
|||||||
private _hasCodeActionsProvider: IContextKey<boolean>;
|
private _hasCodeActionsProvider: IContextKey<boolean>;
|
||||||
private _hasCodeLensProvider: IContextKey<boolean>;
|
private _hasCodeLensProvider: IContextKey<boolean>;
|
||||||
private _hasDefinitionProvider: IContextKey<boolean>;
|
private _hasDefinitionProvider: IContextKey<boolean>;
|
||||||
|
private _hasTypeDefinitionProvider: IContextKey<boolean>;
|
||||||
private _hasHoverProvider: IContextKey<boolean>;
|
private _hasHoverProvider: IContextKey<boolean>;
|
||||||
private _hasDocumentHighlightProvider: IContextKey<boolean>;
|
private _hasDocumentHighlightProvider: IContextKey<boolean>;
|
||||||
private _hasDocumentSymbolProvider: IContextKey<boolean>;
|
private _hasDocumentSymbolProvider: IContextKey<boolean>;
|
||||||
@@ -39,6 +40,7 @@ export class EditorModeContext {
|
|||||||
this._hasCodeActionsProvider = ModeContextKeys.hasCodeActionsProvider.bindTo(contextKeyService);
|
this._hasCodeActionsProvider = ModeContextKeys.hasCodeActionsProvider.bindTo(contextKeyService);
|
||||||
this._hasCodeLensProvider = ModeContextKeys.hasCodeLensProvider.bindTo(contextKeyService);
|
this._hasCodeLensProvider = ModeContextKeys.hasCodeLensProvider.bindTo(contextKeyService);
|
||||||
this._hasDefinitionProvider = ModeContextKeys.hasDefinitionProvider.bindTo(contextKeyService);
|
this._hasDefinitionProvider = ModeContextKeys.hasDefinitionProvider.bindTo(contextKeyService);
|
||||||
|
this._hasTypeDefinitionProvider = ModeContextKeys.hasTypeDefinitionProvider.bindTo(contextKeyService);
|
||||||
this._hasHoverProvider = ModeContextKeys.hasHoverProvider.bindTo(contextKeyService);
|
this._hasHoverProvider = ModeContextKeys.hasHoverProvider.bindTo(contextKeyService);
|
||||||
this._hasDocumentHighlightProvider = ModeContextKeys.hasDocumentHighlightProvider.bindTo(contextKeyService);
|
this._hasDocumentHighlightProvider = ModeContextKeys.hasDocumentHighlightProvider.bindTo(contextKeyService);
|
||||||
this._hasDocumentSymbolProvider = ModeContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
this._hasDocumentSymbolProvider = ModeContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
||||||
@@ -57,6 +59,7 @@ export class EditorModeContext {
|
|||||||
modes.CodeActionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.CodeActionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
modes.CodeLensProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.CodeLensProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
modes.DefinitionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.DefinitionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
|
modes.TypeDefinitionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
modes.HoverProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.HoverProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
modes.DocumentHighlightProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.DocumentHighlightProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
modes.DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables);
|
modes.DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||||
@@ -79,6 +82,7 @@ export class EditorModeContext {
|
|||||||
this._hasCodeActionsProvider.reset();
|
this._hasCodeActionsProvider.reset();
|
||||||
this._hasCodeLensProvider.reset();
|
this._hasCodeLensProvider.reset();
|
||||||
this._hasDefinitionProvider.reset();
|
this._hasDefinitionProvider.reset();
|
||||||
|
this._hasTypeDefinitionProvider.reset();
|
||||||
this._hasHoverProvider.reset();
|
this._hasHoverProvider.reset();
|
||||||
this._hasDocumentHighlightProvider.reset();
|
this._hasDocumentHighlightProvider.reset();
|
||||||
this._hasDocumentSymbolProvider.reset();
|
this._hasDocumentSymbolProvider.reset();
|
||||||
@@ -100,6 +104,7 @@ export class EditorModeContext {
|
|||||||
this._hasCodeActionsProvider.set(modes.CodeActionProviderRegistry.has(model));
|
this._hasCodeActionsProvider.set(modes.CodeActionProviderRegistry.has(model));
|
||||||
this._hasCodeLensProvider.set(modes.CodeLensProviderRegistry.has(model));
|
this._hasCodeLensProvider.set(modes.CodeLensProviderRegistry.has(model));
|
||||||
this._hasDefinitionProvider.set(modes.DefinitionProviderRegistry.has(model));
|
this._hasDefinitionProvider.set(modes.DefinitionProviderRegistry.has(model));
|
||||||
|
this._hasTypeDefinitionProvider.set(modes.TypeDefinitionProviderRegistry.has(model));
|
||||||
this._hasHoverProvider.set(modes.HoverProviderRegistry.has(model));
|
this._hasHoverProvider.set(modes.HoverProviderRegistry.has(model));
|
||||||
this._hasDocumentHighlightProvider.set(modes.DocumentHighlightProviderRegistry.has(model));
|
this._hasDocumentHighlightProvider.set(modes.DocumentHighlightProviderRegistry.has(model));
|
||||||
this._hasDocumentSymbolProvider.set(modes.DocumentSymbolProviderRegistry.has(model));
|
this._hasDocumentSymbolProvider.set(modes.DocumentSymbolProviderRegistry.has(model));
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { ReplaceAllCommand } from './replaceAllCommand';
|
|||||||
import { Selection } from 'vs/editor/common/core/selection';
|
import { Selection } from 'vs/editor/common/core/selection';
|
||||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||||
import { IKeybindings } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindings } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { SearchParams } from 'vs/editor/common/model/textModelSearch';
|
|
||||||
|
|
||||||
export const ToggleCaseSensitiveKeybinding: IKeybindings = {
|
export const ToggleCaseSensitiveKeybinding: IKeybindings = {
|
||||||
primary: KeyMod.Alt | KeyCode.KEY_C,
|
primary: KeyMod.Alt | KeyCode.KEY_C,
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as strings from 'vs/base/common/strings';
|
|
||||||
import { IPatternInfo } from 'vs/platform/search/common/search';
|
|
||||||
import { CharCode } from 'vs/base/common/charCode';
|
import { CharCode } from 'vs/base/common/charCode';
|
||||||
|
|
||||||
export class ReplacePattern {
|
export class ReplacePattern {
|
||||||
@@ -40,7 +38,7 @@ export class ReplacePattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildReplaceString(matches:string[]): string {
|
public buildReplaceString(matches: string[]): string {
|
||||||
if (this._staticValue) {
|
if (this._staticValue) {
|
||||||
return this._staticValue;
|
return this._staticValue;
|
||||||
}
|
}
|
||||||
@@ -61,7 +59,7 @@ export class ReplacePattern {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _substitute(matchIndex: number, matches:string[]): string {
|
private static _substitute(matchIndex: number, matches: string[]): string {
|
||||||
if (matchIndex === 0) {
|
if (matchIndex === 0) {
|
||||||
return matches[0];
|
return matches[0];
|
||||||
}
|
}
|
||||||
@@ -83,11 +81,11 @@ export class ReplacePattern {
|
|||||||
*/
|
*/
|
||||||
export class ReplacePiece {
|
export class ReplacePiece {
|
||||||
|
|
||||||
public static staticValue(value:string): ReplacePiece {
|
public static staticValue(value: string): ReplacePiece {
|
||||||
return new ReplacePiece(value, -1);
|
return new ReplacePiece(value, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static matchIndex(index:number): ReplacePiece {
|
public static matchIndex(index: number): ReplacePiece {
|
||||||
return new ReplacePiece(null, index);
|
return new ReplacePiece(null, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ suite('Replace Pattern test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('get replace string if given text is a complete match', () => {
|
test('get replace string if given text is a complete match', () => {
|
||||||
function assertReplace(target:string, search: RegExp, replaceString: string, expected: string): void {
|
function assertReplace(target: string, search: RegExp, replaceString: string, expected: string): void {
|
||||||
let replacePattern = parseReplaceString(replaceString);
|
let replacePattern = parseReplaceString(replaceString);
|
||||||
let m = search.exec(target);
|
let m = search.exec(target);
|
||||||
let actual = replacePattern.buildReplaceString(m);
|
let actual = replacePattern.buildReplaceString(m);
|
||||||
@@ -125,7 +125,7 @@ suite('Replace Pattern test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('get replace string if match is sub-string of the text', () => {
|
test('get replace string if match is sub-string of the text', () => {
|
||||||
function assertReplace(target:string, search: RegExp, replaceString: string, expected: string): void {
|
function assertReplace(target: string, search: RegExp, replaceString: string, expected: string): void {
|
||||||
let replacePattern = parseReplaceString(replaceString);
|
let replacePattern = parseReplaceString(replaceString);
|
||||||
let m = search.exec(target);
|
let m = search.exec(target);
|
||||||
let actual = replacePattern.buildReplaceString(m);
|
let actual = replacePattern.buildReplaceString(m);
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ import { editorAction, IActionOptions, ServicesAccessor, EditorAction } from 'vs
|
|||||||
import { Location, DefinitionProviderRegistry } from 'vs/editor/common/modes';
|
import { Location, DefinitionProviderRegistry } from 'vs/editor/common/modes';
|
||||||
import { ICodeEditor, IEditorMouseEvent, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
import { ICodeEditor, IEditorMouseEvent, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||||
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
|
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
|
||||||
import { getDeclarationsAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
import { getDeclarationsAtPosition, getTypeDefinitionAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||||
import { ReferencesController } from 'vs/editor/contrib/referenceSearch/browser/referencesController';
|
import { ReferencesController } from 'vs/editor/contrib/referenceSearch/browser/referencesController';
|
||||||
import { ReferencesModel } from 'vs/editor/contrib/referenceSearch/browser/referencesModel';
|
import { ReferencesModel } from 'vs/editor/contrib/referenceSearch/browser/referencesModel';
|
||||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
import { PeekContext } from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
|
import { PeekContext } from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
|
||||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
|
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
|
||||||
|
import * as corePosition from 'vs/editor/common/core/position';
|
||||||
|
|
||||||
import ModeContextKeys = editorCommon.ModeContextKeys;
|
import ModeContextKeys = editorCommon.ModeContextKeys;
|
||||||
import EditorContextKeys = editorCommon.EditorContextKeys;
|
import EditorContextKeys = editorCommon.EditorContextKeys;
|
||||||
@@ -64,7 +65,7 @@ export class DefinitionAction extends EditorAction {
|
|||||||
let model = editor.getModel();
|
let model = editor.getModel();
|
||||||
let pos = editor.getPosition();
|
let pos = editor.getPosition();
|
||||||
|
|
||||||
return getDeclarationsAtPosition(model, pos).then(references => {
|
return this.getDeclarationsAtPosition(model, pos).then(references => {
|
||||||
|
|
||||||
if (!references) {
|
if (!references) {
|
||||||
return;
|
return;
|
||||||
@@ -104,6 +105,10 @@ export class DefinitionAction extends EditorAction {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||||
|
return getDeclarationsAtPosition(model, position);
|
||||||
|
}
|
||||||
|
|
||||||
private _onResult(editorService: IEditorService, editor: editorCommon.ICommonCodeEditor, model: ReferencesModel) {
|
private _onResult(editorService: IEditorService, editor: editorCommon.ICommonCodeEditor, model: ReferencesModel) {
|
||||||
if (this._configuration.openInPeek) {
|
if (this._configuration.openInPeek) {
|
||||||
this._openInPeek(editorService, editor, model);
|
this._openInPeek(editorService, editor, model);
|
||||||
@@ -217,6 +222,61 @@ export class PeekDefinitionAction extends DefinitionAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@editorAction
|
||||||
|
export class GoToImplementationAction extends DefinitionAction {
|
||||||
|
|
||||||
|
public static ID = 'editor.action.goToImplementation';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(new DefinitionActionConfig(), {
|
||||||
|
id: GoToImplementationAction.ID,
|
||||||
|
label: nls.localize('actions.goToImplementation.label', "Go to Implementation"),
|
||||||
|
alias: 'Go to Implementation',
|
||||||
|
precondition: ModeContextKeys.hasTypeDefinitionProvider,
|
||||||
|
kbOpts: {
|
||||||
|
kbExpr: EditorContextKeys.TextFocus,
|
||||||
|
primary: KeyMod.CtrlCmd | KeyCode.F12
|
||||||
|
},
|
||||||
|
menuOpts: {
|
||||||
|
group: 'navigation',
|
||||||
|
order: 1.3
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||||
|
return getTypeDefinitionAtPosition(model, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@editorAction
|
||||||
|
export class PeekImplementationAction extends DefinitionAction {
|
||||||
|
|
||||||
|
public static ID = 'editor.action.peekImplementation';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(new DefinitionActionConfig(false, true, false), {
|
||||||
|
id: PeekImplementationAction.ID,
|
||||||
|
label: nls.localize('actions.peekImplementation.label', "Peek Implementation"),
|
||||||
|
alias: 'Peek Implementation',
|
||||||
|
precondition: ModeContextKeys.hasTypeDefinitionProvider,
|
||||||
|
kbOpts: {
|
||||||
|
kbExpr: EditorContextKeys.TextFocus,
|
||||||
|
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F12
|
||||||
|
},
|
||||||
|
menuOpts: {
|
||||||
|
group: 'navigation',
|
||||||
|
order: 1.3
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||||
|
return getTypeDefinitionAtPosition(model, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Editor Contribution to goto definition using the mouse and a modifier key
|
// --- Editor Contribution to goto definition using the mouse and a modifier key
|
||||||
|
|
||||||
@editorContribution
|
@editorContribution
|
||||||
|
|||||||
@@ -9,10 +9,24 @@ import { onUnexpectedExternalError } from 'vs/base/common/errors';
|
|||||||
import { TPromise } from 'vs/base/common/winjs.base';
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
import { IReadOnlyModel } from 'vs/editor/common/editorCommon';
|
import { IReadOnlyModel } from 'vs/editor/common/editorCommon';
|
||||||
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
|
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
|
||||||
import { DefinitionProviderRegistry, Location } from 'vs/editor/common/modes';
|
import { DefinitionProviderRegistry, TypeDefinitionProviderRegistry, Location } from 'vs/editor/common/modes';
|
||||||
import { asWinJsPromise } from 'vs/base/common/async';
|
import { asWinJsPromise } from 'vs/base/common/async';
|
||||||
import { Position } from 'vs/editor/common/core/position';
|
import { Position } from 'vs/editor/common/core/position';
|
||||||
|
|
||||||
|
function outputResults(promises: TPromise<Location[]>[]) {
|
||||||
|
return TPromise.join(promises).then(allReferences => {
|
||||||
|
let result: Location[] = [];
|
||||||
|
for (let references of allReferences) {
|
||||||
|
if (Array.isArray(references)) {
|
||||||
|
result.push(...references);
|
||||||
|
} else if (references) {
|
||||||
|
result.push(references);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function getDeclarationsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
export function getDeclarationsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||||
|
|
||||||
const provider = DefinitionProviderRegistry.ordered(model);
|
const provider = DefinitionProviderRegistry.ordered(model);
|
||||||
@@ -27,18 +41,25 @@ export function getDeclarationsAtPosition(model: IReadOnlyModel, position: Posit
|
|||||||
onUnexpectedExternalError(err);
|
onUnexpectedExternalError(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return outputResults(promises);
|
||||||
return TPromise.join(promises).then(allReferences => {
|
|
||||||
let result: Location[] = [];
|
|
||||||
for (let references of allReferences) {
|
|
||||||
if (Array.isArray(references)) {
|
|
||||||
result.push(...references);
|
|
||||||
} else if (references) {
|
|
||||||
result.push(references);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeDefinitionProvider', getDeclarationsAtPosition);
|
export function getTypeDefinitionAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||||
|
|
||||||
|
const provider = TypeDefinitionProviderRegistry.ordered(model);
|
||||||
|
|
||||||
|
// get results
|
||||||
|
const promises = provider.map((provider, idx) => {
|
||||||
|
return asWinJsPromise((token) => {
|
||||||
|
return provider.provideTypeDefinition(model, position, token);
|
||||||
|
}).then(result => {
|
||||||
|
return result;
|
||||||
|
}, err => {
|
||||||
|
onUnexpectedExternalError(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return outputResults(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonEditorRegistry.registerDefaultLanguageCommand('_executeDefinitionProvider', getDeclarationsAtPosition);
|
||||||
|
CommonEditorRegistry.registerDefaultLanguageCommand('_executeTypeDefinitionProvider', getTypeDefinitionAtPosition);
|
||||||
@@ -105,9 +105,14 @@ export class SuggestController implements IEditorContribution {
|
|||||||
// Wire up logic to accept a suggestion on certain characters
|
// Wire up logic to accept a suggestion on certain characters
|
||||||
const autoAcceptOracle = new AcceptOnCharacterOracle(editor, this.widget, item => this.onDidSelectItem(item));
|
const autoAcceptOracle = new AcceptOnCharacterOracle(editor, this.widget, item => this.onDidSelectItem(item));
|
||||||
this.toDispose.push(
|
this.toDispose.push(
|
||||||
|
autoAcceptOracle,
|
||||||
this.model.onDidCancel(autoAcceptOracle.reset, autoAcceptOracle),
|
this.model.onDidCancel(autoAcceptOracle.reset, autoAcceptOracle),
|
||||||
this.model.onDidTrigger(autoAcceptOracle.reset, autoAcceptOracle),
|
this.model.onDidTrigger(autoAcceptOracle.reset, autoAcceptOracle),
|
||||||
autoAcceptOracle
|
this.model.onDidSuggest(e => {
|
||||||
|
if (e.completionModel.items.length === 0) {
|
||||||
|
autoAcceptOracle.reset();
|
||||||
|
}
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ function doCreateTest(strategy: TextAreaStrategy, description: string, inputStr:
|
|||||||
cursorOffset = off;
|
cursorOffset = off;
|
||||||
cursorLength = len;
|
cursorLength = len;
|
||||||
handler.setCursorSelections(new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength), []);
|
handler.setCursorSelections(new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength), []);
|
||||||
handler.writePlaceholderAndSelectTextAreaSync();
|
handler.focusTextArea();
|
||||||
};
|
};
|
||||||
|
|
||||||
let updateModelAndPosition = (text: string, off: number, len: number) => {
|
let updateModelAndPosition = (text: string, off: number, len: number) => {
|
||||||
|
|||||||
Vendored
+26
-4
@@ -1154,10 +1154,9 @@ declare module monaco.editor {
|
|||||||
*/
|
*/
|
||||||
roundedSelection?: boolean;
|
roundedSelection?: boolean;
|
||||||
/**
|
/**
|
||||||
* Theme to be used for rendering. Consists of two parts, the UI theme and the syntax theme,
|
* Theme to be used for rendering.
|
||||||
* separated by a space.
|
* The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black'.
|
||||||
* The current available UI themes are: 'vs' (default), 'vs-dark', 'hc-black'
|
* You can create custom themes via `monaco.editor.defineTheme`.
|
||||||
* The syntax themes are contributed. The default is 'default-theme'
|
|
||||||
*/
|
*/
|
||||||
theme?: string;
|
theme?: string;
|
||||||
/**
|
/**
|
||||||
@@ -3803,6 +3802,13 @@ declare module monaco.editor {
|
|||||||
* Get the vertical position (top offset) for the position w.r.t. to the first line.
|
* Get the vertical position (top offset) for the position w.r.t. to the first line.
|
||||||
*/
|
*/
|
||||||
getTopForPosition(lineNumber: number, column: number): number;
|
getTopForPosition(lineNumber: number, column: number): number;
|
||||||
|
/**
|
||||||
|
* Get the hit test target at coordinates `clientX` and `clientY`.
|
||||||
|
* The coordinates are relative to the top-left of the viewport.
|
||||||
|
*
|
||||||
|
* @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
|
||||||
|
*/
|
||||||
|
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget;
|
||||||
/**
|
/**
|
||||||
* Get the visible position for `position`.
|
* Get the visible position for `position`.
|
||||||
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
||||||
@@ -3953,6 +3959,11 @@ declare module monaco.languages {
|
|||||||
*/
|
*/
|
||||||
export function registerDefinitionProvider(languageId: string, provider: DefinitionProvider): IDisposable;
|
export function registerDefinitionProvider(languageId: string, provider: DefinitionProvider): IDisposable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a type definition provider (used by e.g. go to implementation).
|
||||||
|
*/
|
||||||
|
export function registerTypeDefinitionProvider(languageId: string, provider: TypeDefinitionProvider): IDisposable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a code lens provider (used by e.g. inline code lenses).
|
* Register a code lens provider (used by e.g. inline code lenses).
|
||||||
*/
|
*/
|
||||||
@@ -4532,6 +4543,17 @@ declare module monaco.languages {
|
|||||||
provideDefinition(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
provideDefinition(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type definition provider interface defines the contract between extensions and
|
||||||
|
* the go to implementation feature.
|
||||||
|
*/
|
||||||
|
export interface TypeDefinitionProvider {
|
||||||
|
/**
|
||||||
|
* Provide the implementation of the symbol at the given position and document.
|
||||||
|
*/
|
||||||
|
provideTypeDefinition(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A symbol kind.
|
* A symbol kind.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export interface IProductConfiguration {
|
|||||||
npsSurveyUrl: string;
|
npsSurveyUrl: string;
|
||||||
checksums: { [path: string]: string; };
|
checksums: { [path: string]: string; };
|
||||||
checksumFailMoreInfoUrl: string;
|
checksumFailMoreInfoUrl: string;
|
||||||
|
extraNodeModules: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootPath = path.dirname(uri.parse(require.toUrl('')).fsPath);
|
const rootPath = path.dirname(uri.parse(require.toUrl('')).fsPath);
|
||||||
|
|||||||
Vendored
+42
-9
@@ -1632,6 +1632,24 @@ declare module 'vscode' {
|
|||||||
provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition>;
|
provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type definition provider interface defines the contract between extensions and
|
||||||
|
* the go to implementation feature.
|
||||||
|
*/
|
||||||
|
export interface TypeDefinitionProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide the implementations of the symbol at the given position and document.
|
||||||
|
*
|
||||||
|
* @param document The document in which the command was invoked.
|
||||||
|
* @param position The position at which the command was invoked.
|
||||||
|
* @param token A cancellation token.
|
||||||
|
* @return A definition or a thenable that resolves to such. The lack of a result can be
|
||||||
|
* signaled by returning `undefined` or `null`.
|
||||||
|
*/
|
||||||
|
provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MarkedString can be used to render human readable text. It is either a markdown string
|
* MarkedString can be used to render human readable text. It is either a markdown string
|
||||||
* or a code-block that provides a language and a code snippet. Note that
|
* or a code-block that provides a language and a code snippet. Note that
|
||||||
@@ -3628,15 +3646,6 @@ declare module 'vscode' {
|
|||||||
*/
|
*/
|
||||||
export function createOutputChannel(name: string): OutputChannel;
|
export function createOutputChannel(name: string): OutputChannel;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a message to the status bar. This is a short hand for the more powerful
|
|
||||||
* status bar [items](#window.createStatusBarItem).
|
|
||||||
*
|
|
||||||
* @param text The message to show, support icon subtitution as in status bar [items](#StatusBarItem.text).
|
|
||||||
* @return A disposable which hides the status bar message.
|
|
||||||
*/
|
|
||||||
export function setStatusBarMessage(text: string): Disposable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a message to the status bar. This is a short hand for the more powerful
|
* Set a message to the status bar. This is a short hand for the more powerful
|
||||||
* status bar [items](#window.createStatusBarItem).
|
* status bar [items](#window.createStatusBarItem).
|
||||||
@@ -3657,6 +3666,18 @@ declare module 'vscode' {
|
|||||||
*/
|
*/
|
||||||
export function setStatusBarMessage(text: string, hideWhenDone: Thenable<any>): Disposable;
|
export function setStatusBarMessage(text: string, hideWhenDone: Thenable<any>): Disposable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a message to the status bar. This is a short hand for the more powerful
|
||||||
|
* status bar [items](#window.createStatusBarItem).
|
||||||
|
*
|
||||||
|
* *Note* that status bar messages stack and that they must be disposed when no
|
||||||
|
* longer used.
|
||||||
|
*
|
||||||
|
* @param text The message to show, support icon subtitution as in status bar [items](#StatusBarItem.text).
|
||||||
|
* @return A disposable which hides the status bar message.
|
||||||
|
*/
|
||||||
|
export function setStatusBarMessage(text: string): Disposable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a status bar [item](#StatusBarItem).
|
* Creates a status bar [item](#StatusBarItem).
|
||||||
*
|
*
|
||||||
@@ -4117,6 +4138,18 @@ declare module 'vscode' {
|
|||||||
*/
|
*/
|
||||||
export function registerDefinitionProvider(selector: DocumentSelector, provider: DefinitionProvider): Disposable;
|
export function registerDefinitionProvider(selector: DocumentSelector, provider: DefinitionProvider): Disposable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an type definition provider.
|
||||||
|
*
|
||||||
|
* Multiple providers can be registered for a language. In that case providers are sorted
|
||||||
|
* by their [score](#languages.match) and the best-matching provider is used.
|
||||||
|
*
|
||||||
|
* @param selector A selector that defines the documents this provider is applicable to.
|
||||||
|
* @param provider An implementation provider.
|
||||||
|
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
|
||||||
|
*/
|
||||||
|
export function registerTypeDefinitionProvider(selector: DocumentSelector, provider: TypeDefinitionProvider): Disposable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a hover provider.
|
* Register a hover provider.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -182,6 +182,9 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
|||||||
registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
|
registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
|
||||||
return languageFeatures.registerDefinitionProvider(selector, provider);
|
return languageFeatures.registerDefinitionProvider(selector, provider);
|
||||||
},
|
},
|
||||||
|
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||||
|
return languageFeatures.registerTypeDefinitionProvider(selector, provider);
|
||||||
|
},
|
||||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||||
return languageFeatures.registerHoverProvider(selector, provider);
|
return languageFeatures.registerHoverProvider(selector, provider);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ export abstract class MainThreadLanguageFeaturesShape {
|
|||||||
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector, eventHandle: number): TPromise<any> { throw ni(); }
|
$registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector, eventHandle: number): TPromise<any> { throw ni(); }
|
||||||
$emitCodeLensEvent(eventHandle: number, event?: any): TPromise<any> { throw ni(); }
|
$emitCodeLensEvent(eventHandle: number, event?: any): TPromise<any> { throw ni(); }
|
||||||
$registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
$registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||||
|
$registerImplementationSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||||
$registerDocumentHighlightProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
$registerDocumentHighlightProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||||
$registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
$registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||||
@@ -335,6 +336,7 @@ export abstract class ExtHostLanguageFeaturesShape {
|
|||||||
$provideCodeLenses(handle: number, resource: URI): TPromise<modes.ICodeLensSymbol[]> { throw ni(); }
|
$provideCodeLenses(handle: number, resource: URI): TPromise<modes.ICodeLensSymbol[]> { throw ni(); }
|
||||||
$resolveCodeLens(handle: number, resource: URI, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol> { throw ni(); }
|
$resolveCodeLens(handle: number, resource: URI, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol> { throw ni(); }
|
||||||
$provideDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
$provideDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||||
|
$provideTypeDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||||
$provideHover(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Hover> { throw ni(); }
|
$provideHover(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Hover> { throw ni(); }
|
||||||
$provideDocumentHighlights(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.DocumentHighlight[]> { throw ni(); }
|
$provideDocumentHighlights(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.DocumentHighlight[]> { throw ni(); }
|
||||||
$provideReferences(handle: number, resource: URI, position: editorCommon.IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]> { throw ni(); }
|
$provideReferences(handle: number, resource: URI, position: editorCommon.IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]> { throw ni(); }
|
||||||
|
|||||||
@@ -46,6 +46,14 @@ export class ExtHostApiCommands {
|
|||||||
],
|
],
|
||||||
returns: 'A promise that resolves to an array of Location-instances.'
|
returns: 'A promise that resolves to an array of Location-instances.'
|
||||||
});
|
});
|
||||||
|
this._register('vscode.executeTypeDefinitionProvider', this._executeTypeDefinitionProvider, {
|
||||||
|
description: 'Execute all implementation providers.',
|
||||||
|
args: [
|
||||||
|
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
|
||||||
|
{ name: 'position', description: 'Position of a symbol', constraint: types.Position }
|
||||||
|
],
|
||||||
|
returns: 'A promise that resolves to an array of Location-instance.'
|
||||||
|
});
|
||||||
this._register('vscode.executeHoverProvider', this._executeHoverProvider, {
|
this._register('vscode.executeHoverProvider', this._executeHoverProvider, {
|
||||||
description: 'Execute all hover provider.',
|
description: 'Execute all hover provider.',
|
||||||
args: [
|
args: [
|
||||||
@@ -265,6 +273,18 @@ export class ExtHostApiCommands {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _executeTypeDefinitionProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
|
||||||
|
const args = {
|
||||||
|
resource,
|
||||||
|
position: position && typeConverters.fromPosition(position)
|
||||||
|
};
|
||||||
|
return this._commands.executeCommand<modes.Location[]>('_executeTypeDefinitionProvider', args).then(value => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map(typeConverters.location.to);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
|
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
|
||||||
const args = {
|
const args = {
|
||||||
resource,
|
resource,
|
||||||
|
|||||||
@@ -122,6 +122,29 @@ class DefinitionAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ImplementationAdapter {
|
||||||
|
|
||||||
|
private _documents: ExtHostDocuments;
|
||||||
|
private _provider: vscode.TypeDefinitionProvider;
|
||||||
|
|
||||||
|
constructor(documents: ExtHostDocuments, provider: vscode.TypeDefinitionProvider) {
|
||||||
|
this._documents = documents;
|
||||||
|
this._provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
provideTypeDefinition(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||||
|
let doc = this._documents.getDocumentData(resource).document;
|
||||||
|
let pos = TypeConverters.toPosition(position);
|
||||||
|
return asWinJsPromise(token => this._provider.provideTypeDefinition(doc, pos, token)).then(value => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map(TypeConverters.location.from);
|
||||||
|
} else if (value) {
|
||||||
|
return TypeConverters.location.from(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class HoverAdapter {
|
class HoverAdapter {
|
||||||
|
|
||||||
private _documents: ExtHostDocuments;
|
private _documents: ExtHostDocuments;
|
||||||
@@ -614,7 +637,7 @@ class LinkProviderAdapter {
|
|||||||
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||||
| DocumentHighlightAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
|
| DocumentHighlightAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
|
||||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter;
|
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter;
|
||||||
|
|
||||||
export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||||
|
|
||||||
@@ -713,6 +736,17 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
|||||||
return this._withAdapter(handle, DefinitionAdapter, adapter => adapter.provideDefinition(resource, position));
|
return this._withAdapter(handle, DefinitionAdapter, adapter => adapter.provideDefinition(resource, position));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||||
|
const handle = this._nextHandle();
|
||||||
|
this._adapter.set(handle, new ImplementationAdapter(this._documents, provider));
|
||||||
|
this._proxy.$registerImplementationSupport(handle, selector);
|
||||||
|
return this._createDisposable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
$provideTypeDefinition(handle: number, resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||||
|
return this._withAdapter(handle, ImplementationAdapter, adapter => adapter.provideTypeDefinition(resource, position));
|
||||||
|
}
|
||||||
|
|
||||||
// --- extra info
|
// --- extra info
|
||||||
|
|
||||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||||
|
|||||||
@@ -102,6 +102,15 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$registerImplementationSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||||
|
this._registrations[handle] = modes.TypeDefinitionProviderRegistry.register(selector, <modes.TypeDefinitionProvider>{
|
||||||
|
provideTypeDefinition: (model, position, token): Thenable<modes.Definition> => {
|
||||||
|
return wireCancellationToken(token, this._proxy.$provideTypeDefinition(handle, model.uri, position));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// --- extra info
|
// --- extra info
|
||||||
|
|
||||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
|
|||||||
);
|
);
|
||||||
|
|
||||||
interface ISerializedUntitledEditorInput {
|
interface ISerializedUntitledEditorInput {
|
||||||
resource: any | string; // TODO@Ben migration
|
resource: string;
|
||||||
|
resourceJSON: any;
|
||||||
modeId: string;
|
modeId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +121,11 @@ class UntitledEditorInputFactory implements IEditorInputFactory {
|
|||||||
resource = URI.file(resource.fsPath); // untitled with associated file path use the file schema
|
resource = URI.file(resource.fsPath); // untitled with associated file path use the file schema
|
||||||
}
|
}
|
||||||
|
|
||||||
const serialized: ISerializedUntitledEditorInput = { resource: resource.toJSON(), modeId: untitledEditorInput.getModeId() };
|
const serialized: ISerializedUntitledEditorInput = {
|
||||||
|
resource: resource.toString(), // Keep for backwards compatibility
|
||||||
|
resourceJSON: resource.toJSON(),
|
||||||
|
modeId: untitledEditorInput.getModeId()
|
||||||
|
};
|
||||||
|
|
||||||
return JSON.stringify(serialized);
|
return JSON.stringify(serialized);
|
||||||
}
|
}
|
||||||
@@ -128,7 +133,7 @@ class UntitledEditorInputFactory implements IEditorInputFactory {
|
|||||||
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
|
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
|
||||||
const deserialized: ISerializedUntitledEditorInput = JSON.parse(serializedEditorInput);
|
const deserialized: ISerializedUntitledEditorInput = JSON.parse(serializedEditorInput);
|
||||||
|
|
||||||
return this.untitledEditorService.createOrGet(typeof deserialized.resource === 'string' ? URI.parse(deserialized.resource) : URI.revive(deserialized.resource), deserialized.modeId);
|
return this.untitledEditorService.createOrGet(!!deserialized.resourceJSON ? URI.revive(deserialized.resourceJSON) : URI.parse(deserialized.resource), deserialized.modeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const $ = dom.$;
|
|||||||
export class StartDebugActionItem extends EventEmitter implements IActionItem {
|
export class StartDebugActionItem extends EventEmitter implements IActionItem {
|
||||||
|
|
||||||
private static ADD_CONFIGURATION = nls.localize('addConfiguration', "Add Configuration...");
|
private static ADD_CONFIGURATION = nls.localize('addConfiguration', "Add Configuration...");
|
||||||
|
private static SEPARATOR = '─────────';
|
||||||
|
|
||||||
public actionRunner: IActionRunner;
|
public actionRunner: IActionRunner;
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
@@ -132,8 +133,9 @@ export class StartDebugActionItem extends EventEmitter implements IActionItem {
|
|||||||
} else {
|
} else {
|
||||||
this.setEnabled(true);
|
this.setEnabled(true);
|
||||||
const selected = options.indexOf(this.debugService.getViewModel().selectedConfigurationName);
|
const selected = options.indexOf(this.debugService.getViewModel().selectedConfigurationName);
|
||||||
|
options.push(StartDebugActionItem.SEPARATOR);
|
||||||
options.push(StartDebugActionItem.ADD_CONFIGURATION);
|
options.push(StartDebugActionItem.ADD_CONFIGURATION);
|
||||||
this.selectBox.setOptions(options, selected);
|
this.selectBox.setOptions(options, selected, options.length - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
import * as lifecycle from 'vs/base/common/lifecycle';
|
import * as lifecycle from 'vs/base/common/lifecycle';
|
||||||
import uri from 'vs/base/common/uri';
|
import uri from 'vs/base/common/uri';
|
||||||
import { TPromise } from 'vs/base/common/winjs.base';
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
import { guessMimeTypes } from 'vs/base/common/mime';
|
import { guessMimeTypes, MIME_TEXT } from 'vs/base/common/mime';
|
||||||
import { IModel } from 'vs/editor/common/editorCommon';
|
import { IModel } from 'vs/editor/common/editorCommon';
|
||||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||||
import { ITextModelResolverService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
|
import { ITextModelResolverService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
|
||||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
import { DEBUG_SCHEME, IDebugService, State } from 'vs/workbench/parts/debug/common/debug';
|
import { DEBUG_SCHEME, IDebugService, State } from 'vs/workbench/parts/debug/common/debug';
|
||||||
import { Model } from 'vs/workbench/parts/debug/common/debugModel';
|
|
||||||
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
||||||
|
|
||||||
export class DebugContentProvider implements IWorkbenchContribution, ITextModelContentProvider {
|
export class DebugContentProvider implements IWorkbenchContribution, ITextModelContentProvider {
|
||||||
@@ -52,9 +51,12 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
|||||||
this.modelsToDispose.push(model);
|
this.modelsToDispose.push(model);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}, err => {
|
}, (err: DebugProtocol.ErrorResponse) => {
|
||||||
(<Model>this.debugService.getModel()).sourceIsUnavailable(resource);
|
this.debugService.deemphasizeSource(resource);
|
||||||
return err;
|
const modePromise = this.modeService.getOrCreateMode(MIME_TEXT);
|
||||||
|
const model = this.modelService.createModel(err.message, modePromise, resource);
|
||||||
|
|
||||||
|
return model;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,6 +476,11 @@ export interface IDebugService {
|
|||||||
*/
|
*/
|
||||||
restartProcess(process: IProcess): TPromise<any>;
|
restartProcess(process: IProcess): TPromise<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deemphasizes all sources with the passed uri. Source will appear as grayed out in callstack view.
|
||||||
|
*/
|
||||||
|
deemphasizeSource(uri: uri): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current debug model.
|
* Gets the current debug model.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ export class Thread implements debug.IThread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getId(): string {
|
public getId(): string {
|
||||||
return `thread:${this.process.getId()}:${this.name}:${this.threadId}`;
|
return `thread:${this.process.getId()}:${this.threadId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearCallStack(): void {
|
public clearCallStack(): void {
|
||||||
@@ -506,6 +506,9 @@ export class Process implements debug.IProcess {
|
|||||||
if (data.thread && !this.threads.has(data.threadId)) {
|
if (data.thread && !this.threads.has(data.threadId)) {
|
||||||
// A new thread came in, initialize it.
|
// A new thread came in, initialize it.
|
||||||
this.threads.set(data.threadId, new Thread(this, data.thread.name, data.thread.id));
|
this.threads.set(data.threadId, new Thread(this, data.thread.name, data.thread.id));
|
||||||
|
} else if (data.thread && data.thread.name) {
|
||||||
|
// Just the thread name got updated #18244
|
||||||
|
this.threads.get(data.threadId).name = data.thread.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.stoppedDetails) {
|
if (data.stoppedDetails) {
|
||||||
@@ -556,7 +559,7 @@ export class Process implements debug.IProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sourceIsUnavailable(uri: uri): void {
|
public deemphasizeSource(uri: uri): void {
|
||||||
this.threads.forEach(thread => {
|
this.threads.forEach(thread => {
|
||||||
thread.getCallStack().forEach(stackFrame => {
|
thread.getCallStack().forEach(stackFrame => {
|
||||||
if (stackFrame.source.uri.toString() === uri.toString()) {
|
if (stackFrame.source.uri.toString() === uri.toString()) {
|
||||||
@@ -926,8 +929,8 @@ export class Model implements debug.IModel {
|
|||||||
this._onDidChangeWatchExpressions.fire();
|
this._onDidChangeWatchExpressions.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
public sourceIsUnavailable(uri: uri): void {
|
public deemphasizeSource(uri: uri): void {
|
||||||
this.processes.forEach(p => p.sourceIsUnavailable(uri));
|
this.processes.forEach(p => p.deemphasizeSource(uri));
|
||||||
this._onDidChangeCallStack.fire();
|
this._onDidChangeCallStack.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export class DebugHoverWidget implements IContentWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the most specific scope containing the range #16632
|
// Find the most specific scope containing the range #16632
|
||||||
return [scopes.filter(scope => Range.containsRange(scope.range, expressionRange))
|
return [scopes.filter(scope => scope.range && Range.containsRange(scope.range, expressionRange))
|
||||||
.sort((first, second) => (first.range.endLineNumber - first.range.startLineNumber) - (second.range.endLineNumber - second.range.startLineNumber)).shift()];
|
.sort((first, second) => (first.range.endLineNumber - first.range.startLineNumber) - (second.range.endLineNumber - second.range.startLineNumber)).shift()];
|
||||||
})
|
})
|
||||||
.then(scopes => TPromise.join(scopes.map(scope => this.doFindExpression(scope, namesToFind))))
|
.then(scopes => TPromise.join(scopes.map(scope => this.doFindExpression(scope, namesToFind))))
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ export class DebugService implements debug.IDebugService {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this.toDisposeOnSessionEnd.get(session.getId()).push(session.onDidContinued(event => {
|
this.toDisposeOnSessionEnd.get(session.getId()).push(session.onDidContinued(event => {
|
||||||
const threadId = event.body.allThreadsContinued ? undefined : event.body.threadId;
|
const threadId = event.body.allThreadsContinued !== false ? undefined : event.body.threadId;
|
||||||
this.model.clearThreads(session.getId(), false, threadId);
|
this.model.clearThreads(session.getId(), false, threadId);
|
||||||
if (this.viewModel.focusedProcess.getId() === session.getId()) {
|
if (this.viewModel.focusedProcess.getId() === session.getId()) {
|
||||||
this.focusStackFrameAndEvaluate(null, this.viewModel.focusedProcess).done(null, errors.onUnexpectedError);
|
this.focusStackFrameAndEvaluate(null, this.viewModel.focusedProcess).done(null, errors.onUnexpectedError);
|
||||||
@@ -779,7 +779,7 @@ export class DebugService implements debug.IDebugService {
|
|||||||
this.lastTaskEvent = null;
|
this.lastTaskEvent = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (filteredTasks[0].isWatching) {
|
if (filteredTasks[0].isBackground) {
|
||||||
return new TPromise((c, e) => this.taskService.addOneTimeDisposableListener(TaskServiceEvents.Inactive, () => c(null)));
|
return new TPromise((c, e) => this.taskService.addOneTimeDisposableListener(TaskServiceEvents.Inactive, () => c(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,6 +801,10 @@ export class DebugService implements debug.IDebugService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public deemphasizeSource(uri: uri): void {
|
||||||
|
this.model.deemphasizeSource(uri);
|
||||||
|
}
|
||||||
|
|
||||||
public restartProcess(process: debug.IProcess): TPromise<any> {
|
public restartProcess(process: debug.IProcess): TPromise<any> {
|
||||||
if (!process) {
|
if (!process) {
|
||||||
return this.createProcess(this.viewModel.selectedConfigurationName);
|
return this.createProcess(this.viewModel.selectedConfigurationName);
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ export interface IRenderValueOptions {
|
|||||||
showHover?: boolean;
|
showHover?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceWhitespace(value: string): string {
|
||||||
|
const map = { '\n': '\\n', '\r': '\\r', '\t': '\\t' };
|
||||||
|
return value.replace(/[\n\r\t]/g, char => map[char]);
|
||||||
|
}
|
||||||
|
|
||||||
export function renderExpressionValue(expressionOrValue: debug.IExpression | string, container: HTMLElement, options: IRenderValueOptions): void {
|
export function renderExpressionValue(expressionOrValue: debug.IExpression | string, container: HTMLElement, options: IRenderValueOptions): void {
|
||||||
let value = typeof expressionOrValue === 'string' ? expressionOrValue : expressionOrValue.value;
|
let value = typeof expressionOrValue === 'string' ? expressionOrValue : expressionOrValue.value;
|
||||||
|
|
||||||
@@ -77,8 +82,7 @@ export function renderExpressionValue(expressionOrValue: debug.IExpression | str
|
|||||||
value = value.substr(0, options.maxValueLength) + '...';
|
value = value.substr(0, options.maxValueLength) + '...';
|
||||||
}
|
}
|
||||||
if (value && !options.preserveWhitespace) {
|
if (value && !options.preserveWhitespace) {
|
||||||
const map = { '\n': '\\n', '\r': '\\r', '\t': '\\t' };
|
container.textContent = replaceWhitespace(value);
|
||||||
container.textContent = value.replace(/[\n\r\t]/g, char => map[char]);
|
|
||||||
} else {
|
} else {
|
||||||
container.textContent = value;
|
container.textContent = value;
|
||||||
}
|
}
|
||||||
@@ -89,7 +93,7 @@ export function renderExpressionValue(expressionOrValue: debug.IExpression | str
|
|||||||
|
|
||||||
export function renderVariable(tree: ITree, variable: Variable, data: IVariableTemplateData, showChanged: boolean): void {
|
export function renderVariable(tree: ITree, variable: Variable, data: IVariableTemplateData, showChanged: boolean): void {
|
||||||
if (variable.available) {
|
if (variable.available) {
|
||||||
data.name.textContent = variable.name;
|
data.name.textContent = replaceWhitespace(variable.name);
|
||||||
data.name.title = variable.type ? variable.type : '';
|
data.name.title = variable.type ? variable.type : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,6 +560,9 @@ export class CallStackRenderer implements IRenderer {
|
|||||||
private renderStackFrame(stackFrame: debug.IStackFrame, data: IStackFrameTemplateData): void {
|
private renderStackFrame(stackFrame: debug.IStackFrame, data: IStackFrameTemplateData): void {
|
||||||
stackFrame.source.deemphasize ? dom.addClass(data.stackFrame, 'disabled') : dom.removeClass(data.stackFrame, 'disabled');
|
stackFrame.source.deemphasize ? dom.addClass(data.stackFrame, 'disabled') : dom.removeClass(data.stackFrame, 'disabled');
|
||||||
data.file.title = stackFrame.source.raw.path || stackFrame.source.name;
|
data.file.title = stackFrame.source.raw.path || stackFrame.source.name;
|
||||||
|
if (stackFrame.source.raw.origin) {
|
||||||
|
data.file.title += `\n${stackFrame.source.raw.origin}`;
|
||||||
|
}
|
||||||
data.label.textContent = stackFrame.name;
|
data.label.textContent = stackFrame.name;
|
||||||
data.label.title = stackFrame.name;
|
data.label.title = stackFrame.name;
|
||||||
data.fileName.textContent = getSourceName(stackFrame.source, this.contextService);
|
data.fileName.textContent = getSourceName(stackFrame.source, this.contextService);
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.ISession {
|
|||||||
public disconnected: boolean;
|
public disconnected: boolean;
|
||||||
private sentPromises: TPromise<DebugProtocol.Response>[];
|
private sentPromises: TPromise<DebugProtocol.Response>[];
|
||||||
private capabilities: DebugProtocol.Capabilities;
|
private capabilities: DebugProtocol.Capabilities;
|
||||||
|
private allThreadsContinued: boolean;
|
||||||
|
|
||||||
private _onDidInitialize: Emitter<DebugProtocol.InitializedEvent>;
|
private _onDidInitialize: Emitter<DebugProtocol.InitializedEvent>;
|
||||||
private _onDidStop: Emitter<DebugProtocol.StoppedEvent>;
|
private _onDidStop: Emitter<DebugProtocol.StoppedEvent>;
|
||||||
@@ -80,6 +81,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.ISession {
|
|||||||
super(id);
|
super(id);
|
||||||
this.emittedStopped = false;
|
this.emittedStopped = false;
|
||||||
this.readyForBreakpoints = false;
|
this.readyForBreakpoints = false;
|
||||||
|
this.allThreadsContinued = false;
|
||||||
this.sentPromises = [];
|
this.sentPromises = [];
|
||||||
|
|
||||||
this._onDidInitialize = new Emitter<DebugProtocol.InitializedEvent>();
|
this._onDidInitialize = new Emitter<DebugProtocol.InitializedEvent>();
|
||||||
@@ -202,6 +204,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.ISession {
|
|||||||
this.emittedStopped = true;
|
this.emittedStopped = true;
|
||||||
this._onDidStop.fire(<DebugProtocol.StoppedEvent>event);
|
this._onDidStop.fire(<DebugProtocol.StoppedEvent>event);
|
||||||
} else if (event.event === 'continued') {
|
} else if (event.event === 'continued') {
|
||||||
|
this.allThreadsContinued = (<DebugProtocol.ContinuedEvent>event).body.allThreadsContinued = false ? false : true;
|
||||||
this._onDidContinued.fire(<DebugProtocol.ContinuedEvent>event);
|
this._onDidContinued.fire(<DebugProtocol.ContinuedEvent>event);
|
||||||
} else if (event.event === 'thread') {
|
} else if (event.event === 'thread') {
|
||||||
this._onDidThread.fire(<DebugProtocol.ThreadEvent>event);
|
this._onDidThread.fire(<DebugProtocol.ThreadEvent>event);
|
||||||
@@ -270,7 +273,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.ISession {
|
|||||||
|
|
||||||
public continue(args: DebugProtocol.ContinueArguments): TPromise<DebugProtocol.ContinueResponse> {
|
public continue(args: DebugProtocol.ContinueArguments): TPromise<DebugProtocol.ContinueResponse> {
|
||||||
return this.send('continue', args).then(response => {
|
return this.send('continue', args).then(response => {
|
||||||
this.fireFakeContinued(args.threadId);
|
this.fireFakeContinued(args.threadId, this.allThreadsContinued);
|
||||||
return response;
|
return response;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -402,12 +405,13 @@ export class RawDebugSession extends v8.V8Protocol implements debug.ISession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fireFakeContinued(threadId: number): void {
|
private fireFakeContinued(threadId: number, allThreadsContinued = false): void {
|
||||||
this._onDidContinued.fire({
|
this._onDidContinued.fire({
|
||||||
type: 'event',
|
type: 'event',
|
||||||
event: 'continued',
|
event: 'continued',
|
||||||
body: {
|
body: {
|
||||||
threadId
|
threadId,
|
||||||
|
allThreadsContinued
|
||||||
},
|
},
|
||||||
seq: undefined
|
seq: undefined
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ export class MockDebugService implements debug.IDebugService {
|
|||||||
public getViewModel(): debug.IViewModel {
|
public getViewModel(): debug.IViewModel {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public deemphasizeSource(uri: uri): void { }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MockSession implements debug.ISession {
|
export class MockSession implements debug.ISession {
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ const descriptor = new AsyncDescriptor<IFileEditorInput>('vs/workbench/parts/fil
|
|||||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerDefaultFileInput(descriptor);
|
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerDefaultFileInput(descriptor);
|
||||||
|
|
||||||
interface ISerializedFileInput {
|
interface ISerializedFileInput {
|
||||||
resource: any | string; // TODO@Ben migration
|
resource: string;
|
||||||
|
resourceJSON: any;
|
||||||
encoding?: string;
|
encoding?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +132,10 @@ class FileEditorInputFactory implements IEditorInputFactory {
|
|||||||
|
|
||||||
public serialize(editorInput: EditorInput): string {
|
public serialize(editorInput: EditorInput): string {
|
||||||
const fileEditorInput = <FileEditorInput>editorInput;
|
const fileEditorInput = <FileEditorInput>editorInput;
|
||||||
|
const resource = fileEditorInput.getResource();
|
||||||
const fileInput: ISerializedFileInput = {
|
const fileInput: ISerializedFileInput = {
|
||||||
resource: fileEditorInput.getResource().toJSON()
|
resource: resource.toString(), // Keep for backwards compatibility
|
||||||
|
resourceJSON: resource.toJSON()
|
||||||
};
|
};
|
||||||
|
|
||||||
const encoding = fileEditorInput.getPreferredEncoding();
|
const encoding = fileEditorInput.getPreferredEncoding();
|
||||||
@@ -147,7 +149,7 @@ class FileEditorInputFactory implements IEditorInputFactory {
|
|||||||
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
|
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
|
||||||
const fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput);
|
const fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput);
|
||||||
|
|
||||||
return instantiationService.createInstance(FileEditorInput, typeof fileInput.resource === 'string' ? URI.parse(fileInput.resource) : URI.revive(fileInput.resource), fileInput.encoding);
|
return instantiationService.createInstance(FileEditorInput, !!fileInput.resourceJSON ? URI.revive(fileInput.resourceJSON) : URI.parse(fileInput.resource), fileInput.encoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export class OpenEditorsView extends AdaptiveCollapsibleViewletView {
|
|||||||
}, {
|
}, {
|
||||||
indentPixels: 0,
|
indentPixels: 0,
|
||||||
twistiePixels: 20,
|
twistiePixels: 20,
|
||||||
ariaLabel: nls.localize({ key: 'treeAriaLabel', comment: ['Open is an adjective'] }, "Open Editors")
|
ariaLabel: nls.localize({ key: 'treeAriaLabel', comment: ['Open is an adjective'] }, "Open Editors: List of Active Files")
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fullRefreshNeeded = true;
|
this.fullRefreshNeeded = true;
|
||||||
|
|||||||
@@ -71,10 +71,6 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setResource(resource: URI): void {
|
public setResource(resource: URI): void {
|
||||||
if (resource.scheme !== 'file') {
|
|
||||||
throw new Error('FileEditorInput can only handle file:// resources.');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
|
|
||||||
// Reset resource dependent properties
|
// Reset resource dependent properties
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ class OutputContentProvider implements ITextModelContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bufferedOutput = this.bufferedOutput[channel];
|
const bufferedOutput = this.bufferedOutput[channel];
|
||||||
|
this.bufferedOutput[channel] = '';
|
||||||
if (!bufferedOutput) {
|
if (!bufferedOutput) {
|
||||||
return; // return if nothing to append
|
return; // return if nothing to append
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -999,7 +999,7 @@ export class SearchViewlet extends Viewlet {
|
|||||||
|
|
||||||
// Fake progress up to 90%, or when actual progress beats it
|
// Fake progress up to 90%, or when actual progress beats it
|
||||||
const fakeMax = 900;
|
const fakeMax = 900;
|
||||||
const fakeMultiplier = 15;
|
const fakeMultiplier = 12;
|
||||||
if (fakeProgress && progressWorked < fakeMax) {
|
if (fakeProgress && progressWorked < fakeMax) {
|
||||||
// Linearly decrease the rate of fake progress.
|
// Linearly decrease the rate of fake progress.
|
||||||
// 1 is the smallest allowed amount of progress.
|
// 1 is the smallest allowed amount of progress.
|
||||||
|
|||||||
@@ -1,115 +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 { TPromise, Promise } from 'vs/base/common/winjs.base';
|
|
||||||
import { TerminateResponse } from 'vs/base/common/processes';
|
|
||||||
|
|
||||||
import { IMode } from 'vs/editor/common/modes';
|
|
||||||
import { EventEmitter } from 'vs/base/common/eventEmitter';
|
|
||||||
|
|
||||||
import { ITaskSystem, ITaskSummary, TaskDescription, TelemetryEvent, Triggers, TaskConfiguration, ITaskExecuteResult, TaskExecuteKind } from 'vs/workbench/parts/tasks/common/taskSystem';
|
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|
||||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
|
||||||
|
|
||||||
export interface LanguageServiceTaskConfiguration extends TaskConfiguration {
|
|
||||||
modes: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export class LanguageServiceTaskSystem extends EventEmitter implements ITaskSystem {
|
|
||||||
|
|
||||||
public static TelemetryEventName: string = 'taskService';
|
|
||||||
|
|
||||||
private configuration: LanguageServiceTaskConfiguration;
|
|
||||||
private telemetryService: ITelemetryService;
|
|
||||||
private modeService: IModeService;
|
|
||||||
|
|
||||||
constructor(configuration: LanguageServiceTaskConfiguration, telemetryService: ITelemetryService, modeService: IModeService) {
|
|
||||||
super();
|
|
||||||
this.configuration = configuration;
|
|
||||||
this.telemetryService = telemetryService;
|
|
||||||
this.modeService = modeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public build(): ITaskExecuteResult {
|
|
||||||
return this.processMode((mode) => {
|
|
||||||
return null;
|
|
||||||
}, 'build', Triggers.shortcut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public rebuild(): ITaskExecuteResult {
|
|
||||||
return this.processMode((mode) => {
|
|
||||||
return null;
|
|
||||||
}, 'rebuild', Triggers.shortcut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public clean(): ITaskExecuteResult {
|
|
||||||
return this.processMode((mode) => {
|
|
||||||
return null;
|
|
||||||
}, 'clean', Triggers.shortcut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public runTest(): ITaskExecuteResult {
|
|
||||||
return { kind: TaskExecuteKind.Started, promise: TPromise.wrapError<ITaskSummary>('Not implemented yet.') };
|
|
||||||
}
|
|
||||||
|
|
||||||
public run(taskIdentifier: string): ITaskExecuteResult {
|
|
||||||
return { kind: TaskExecuteKind.Started, promise: TPromise.wrapError<ITaskSummary>('Not implemented yet.') };
|
|
||||||
}
|
|
||||||
|
|
||||||
public isActive(): TPromise<boolean> {
|
|
||||||
return TPromise.as(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public isActiveSync(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public canAutoTerminate(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public terminate(): TPromise<TerminateResponse> {
|
|
||||||
return TPromise.as({ success: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
public terminateSync(): TerminateResponse {
|
|
||||||
return { success: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
public tasks(): TPromise<TaskDescription[]> {
|
|
||||||
let result: TaskDescription[] = [];
|
|
||||||
return TPromise.as(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private processMode(fn: (mode: IMode) => Promise, taskName: string, trigger: string): ITaskExecuteResult {
|
|
||||||
let telemetryEvent: TelemetryEvent = {
|
|
||||||
trigger: trigger,
|
|
||||||
command: 'languageService',
|
|
||||||
success: true
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
kind: TaskExecuteKind.Started, started: {}, promise: Promise.join(this.configuration.modes.map((mode) => {
|
|
||||||
return this.modeService.getOrCreateMode(mode);
|
|
||||||
})).then((modes: IMode[]) => {
|
|
||||||
let promises: Promise[] = [];
|
|
||||||
modes.forEach((mode) => {
|
|
||||||
let promise = fn(mode);
|
|
||||||
if (promise) {
|
|
||||||
promises.push(promise);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Promise.join(promises);
|
|
||||||
}).then((value) => {
|
|
||||||
this.telemetryService.publicLog(LanguageServiceTaskSystem.TelemetryEventName, telemetryEvent);
|
|
||||||
return value;
|
|
||||||
}, (err) => {
|
|
||||||
telemetryEvent.success = false;
|
|
||||||
this.telemetryService.publicLog(LanguageServiceTaskSystem.TelemetryEventName, telemetryEvent);
|
|
||||||
return Promise.wrapError(err);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -98,9 +98,9 @@ export interface TaskDescription {
|
|||||||
args?: string[];
|
args?: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the task is running in watching mode or not.
|
* Whether the task is a background task or not.
|
||||||
*/
|
*/
|
||||||
isWatching?: boolean;
|
isBackground?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the task should prompt on close for confirmation if running.
|
* Whether the task should prompt on close for confirmation if running.
|
||||||
@@ -201,7 +201,7 @@ export interface ITaskExecuteResult {
|
|||||||
};
|
};
|
||||||
active?: {
|
active?: {
|
||||||
same: boolean;
|
same: boolean;
|
||||||
watching: boolean;
|
background: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,5 +242,5 @@ export interface TaskConfiguration {
|
|||||||
/**
|
/**
|
||||||
* The build system to use. If omitted program is used.
|
* The build system to use. If omitted program is used.
|
||||||
*/
|
*/
|
||||||
buildSystem?: string;
|
_runner?: string;
|
||||||
}
|
}
|
||||||
@@ -59,13 +59,15 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
|||||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||||
import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output';
|
import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output';
|
||||||
|
|
||||||
|
import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal';
|
||||||
|
|
||||||
import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TaskConfiguration, TaskDescription, TaskSystemEvents } from 'vs/workbench/parts/tasks/common/taskSystem';
|
import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TaskConfiguration, TaskDescription, TaskSystemEvents } from 'vs/workbench/parts/tasks/common/taskSystem';
|
||||||
import { ITaskService, TaskServiceEvents } from 'vs/workbench/parts/tasks/common/taskService';
|
import { ITaskService, TaskServiceEvents } from 'vs/workbench/parts/tasks/common/taskService';
|
||||||
import { templates as taskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates';
|
import { templates as taskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates';
|
||||||
|
|
||||||
import { LanguageServiceTaskSystem, LanguageServiceTaskConfiguration } from 'vs/workbench/parts/tasks/common/languageServiceTaskSystem';
|
|
||||||
import * as FileConfig from 'vs/workbench/parts/tasks/node/processRunnerConfiguration';
|
import * as FileConfig from 'vs/workbench/parts/tasks/node/processRunnerConfiguration';
|
||||||
import { ProcessRunnerSystem } from 'vs/workbench/parts/tasks/node/processRunnerSystem';
|
import { ProcessRunnerSystem } from 'vs/workbench/parts/tasks/node/processRunnerSystem';
|
||||||
|
import { TerminalTaskSystem } from './terminalTaskSystem';
|
||||||
import { ProcessRunnerDetector } from 'vs/workbench/parts/tasks/node/processRunnerDetector';
|
import { ProcessRunnerDetector } from 'vs/workbench/parts/tasks/node/processRunnerDetector';
|
||||||
|
|
||||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
@@ -631,7 +633,9 @@ class TaskService extends EventEmitter implements ITaskService {
|
|||||||
@IModelService modelService: IModelService, @IExtensionService extensionService: IExtensionService,
|
@IModelService modelService: IModelService, @IExtensionService extensionService: IExtensionService,
|
||||||
@IQuickOpenService quickOpenService: IQuickOpenService,
|
@IQuickOpenService quickOpenService: IQuickOpenService,
|
||||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||||
@IConfigurationResolverService private configurationResolverService: IConfigurationResolverService) {
|
@IConfigurationResolverService private configurationResolverService: IConfigurationResolverService,
|
||||||
|
@ITerminalService private terminalService: ITerminalService
|
||||||
|
) {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
this.modeService = modeService;
|
this.modeService = modeService;
|
||||||
@@ -740,10 +744,15 @@ class TaskService extends EventEmitter implements ITaskService {
|
|||||||
throw new TaskError(Severity.Info, nls.localize('TaskSystem.noConfiguration', 'No task runner configured.'), TaskErrors.NotConfigured);
|
throw new TaskError(Severity.Info, nls.localize('TaskSystem.noConfiguration', 'No task runner configured.'), TaskErrors.NotConfigured);
|
||||||
}
|
}
|
||||||
let result: ITaskSystem = null;
|
let result: ITaskSystem = null;
|
||||||
if (config.buildSystem === 'service') {
|
if (this.isRunnerConfig(config)) {
|
||||||
result = new LanguageServiceTaskSystem(<LanguageServiceTaskConfiguration>config, this.telemetryService, this.modeService);
|
|
||||||
} else if (this.isRunnerConfig(config)) {
|
|
||||||
result = new ProcessRunnerSystem(<FileConfig.ExternalTaskRunnerConfiguration>config, this.markerService, this.modelService, this.telemetryService, this.outputService, this.configurationResolverService, TaskService.OutputChannelId, clearOutput);
|
result = new ProcessRunnerSystem(<FileConfig.ExternalTaskRunnerConfiguration>config, this.markerService, this.modelService, this.telemetryService, this.outputService, this.configurationResolverService, TaskService.OutputChannelId, clearOutput);
|
||||||
|
} else if (this.isTerminalConfig(config)) {
|
||||||
|
result = new TerminalTaskSystem(
|
||||||
|
<FileConfig.ExternalTaskRunnerConfiguration>config,
|
||||||
|
this.terminalService, this.outputService, this.markerService,
|
||||||
|
this.modelService, this.configurationResolverService, this.telemetryService,
|
||||||
|
TaskService.OutputChannelId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (result === null) {
|
if (result === null) {
|
||||||
this._taskSystemPromise = null;
|
this._taskSystemPromise = null;
|
||||||
@@ -776,7 +785,11 @@ class TaskService extends EventEmitter implements ITaskService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private isRunnerConfig(config: TaskConfiguration): boolean {
|
private isRunnerConfig(config: TaskConfiguration): boolean {
|
||||||
return !config.buildSystem || config.buildSystem === 'program';
|
return !config._runner || config._runner === 'program';
|
||||||
|
}
|
||||||
|
|
||||||
|
private isTerminalConfig(config: TaskConfiguration): boolean {
|
||||||
|
return config._runner === 'terminal';
|
||||||
}
|
}
|
||||||
|
|
||||||
private hasDetectorSupport(config: FileConfig.ExternalTaskRunnerConfiguration): boolean {
|
private hasDetectorSupport(config: FileConfig.ExternalTaskRunnerConfiguration): boolean {
|
||||||
@@ -819,14 +832,14 @@ class TaskService extends EventEmitter implements ITaskService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private executeTarget(fn: (taskSystem: ITaskSystem) => ITaskExecuteResult): TPromise<ITaskSummary> {
|
private executeTarget(fn: (taskSystem: ITaskSystem) => ITaskExecuteResult): TPromise<ITaskSummary> {
|
||||||
return this.textFileService.saveAll().then((value) => { // make sure all dirty files are saved
|
return this.textFileService.saveAll().then((value) => { // make sure all dirty files are saved
|
||||||
return this.configurationService.reloadConfiguration().then(() => { // make sure configuration is up to date
|
return this.configurationService.reloadConfiguration().then(() => { // make sure configuration is up to date
|
||||||
return this.taskSystemPromise.
|
return this.taskSystemPromise.
|
||||||
then((taskSystem) => {
|
then((taskSystem) => {
|
||||||
let executeResult = fn(taskSystem);
|
let executeResult = fn(taskSystem);
|
||||||
if (executeResult.kind === TaskExecuteKind.Active) {
|
if (executeResult.kind === TaskExecuteKind.Active) {
|
||||||
let active = executeResult.active;
|
let active = executeResult.active;
|
||||||
if (active.same && active.watching) {
|
if (active.same && active.background) {
|
||||||
this.messageService.show(Severity.Info, nls.localize('TaskSystem.activeSame', 'The task is already active and in watch mode. To terminate the task use `F1 > terminate task`'));
|
this.messageService.show(Severity.Info, nls.localize('TaskSystem.activeSame', 'The task is already active and in watch mode. To terminate the task use `F1 > terminate task`'));
|
||||||
} else {
|
} else {
|
||||||
throw new TaskError(Severity.Warning, nls.localize('TaskSystem.active', 'There is an active running task right now. Terminate it first before executing another task.'), TaskErrors.RunningTask);
|
throw new TaskError(Severity.Warning, nls.localize('TaskSystem.active', 'There is an active running task right now. Terminate it first before executing another task.'), TaskErrors.RunningTask);
|
||||||
|
|||||||
@@ -0,0 +1,440 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 path = require('path');
|
||||||
|
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
import * as Objects from 'vs/base/common/objects';
|
||||||
|
import { CharCode } from 'vs/base/common/charCode';
|
||||||
|
import * as Platform from 'vs/base/common/platform';
|
||||||
|
import * as Async from 'vs/base/common/async';
|
||||||
|
import { TPromise } from 'vs/base/common/winjs.base';
|
||||||
|
import { IStringDictionary } from 'vs/base/common/collections';
|
||||||
|
import Severity from 'vs/base/common/severity';
|
||||||
|
import { EventEmitter } from 'vs/base/common/eventEmitter';
|
||||||
|
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
|
import { TerminateResponse } from 'vs/base/common/processes';
|
||||||
|
|
||||||
|
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||||
|
import { ValidationStatus } from 'vs/base/common/parsers';
|
||||||
|
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||||
|
import { ProblemMatcher } from 'vs/platform/markers/common/problemMatcher';
|
||||||
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
|
|
||||||
|
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||||
|
import { ITerminalService, ITerminalInstance } from 'vs/workbench/parts/terminal/common/terminal';
|
||||||
|
import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
|
||||||
|
import { IOutputService, IOutputChannel } from 'vs/workbench/parts/output/common/output';
|
||||||
|
import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEvents } from 'vs/workbench/parts/tasks/common/problemCollectors';
|
||||||
|
import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TaskRunnerConfiguration, TaskDescription, ShowOutput, TelemetryEvent, Triggers, TaskSystemEvents, TaskEvent, TaskType } from 'vs/workbench/parts/tasks/common/taskSystem';
|
||||||
|
import * as FileConfig from '../node/processRunnerConfiguration';
|
||||||
|
|
||||||
|
interface TerminalData {
|
||||||
|
terminal: ITerminalInstance;
|
||||||
|
promise: TPromise<ITaskSummary>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TerminalDecoder {
|
||||||
|
// See https://en.wikipedia.org/wiki/ANSI_escape_code & http://stackoverflow.com/questions/25189651/how-to-remove-ansi-control-chars-vt100-from-a-java-string &
|
||||||
|
// https://www.npmjs.com/package/strip-ansi
|
||||||
|
private static ANSI_CONTROL_SEQUENCE: RegExp = /\x1b[[()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
||||||
|
|
||||||
|
private remaining: string;
|
||||||
|
|
||||||
|
public write(data: string): string[] {
|
||||||
|
let result: string[] = [];
|
||||||
|
let value = this.remaining
|
||||||
|
? this.remaining + data.replace(TerminalDecoder.ANSI_CONTROL_SEQUENCE, '')
|
||||||
|
: data.replace(TerminalDecoder.ANSI_CONTROL_SEQUENCE, '');
|
||||||
|
|
||||||
|
if (value.length < 1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
let start = 0;
|
||||||
|
let ch: number;
|
||||||
|
while (start < value.length && ((ch = value.charCodeAt(start)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
let idx = start;
|
||||||
|
while (idx < value.length) {
|
||||||
|
ch = value.charCodeAt(idx);
|
||||||
|
if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) {
|
||||||
|
result.push(value.substring(start, idx));
|
||||||
|
idx++;
|
||||||
|
while (idx < value.length && ((ch = value.charCodeAt(idx)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
start = idx;
|
||||||
|
} else {
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.remaining = start < value.length ? value.substr(start) : null;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public end(): string {
|
||||||
|
return this.remaining;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
|
||||||
|
|
||||||
|
public static TelemetryEventName: string = 'taskService';
|
||||||
|
|
||||||
|
private validationStatus: ValidationStatus;
|
||||||
|
private buildTaskIdentifier: string;
|
||||||
|
private testTaskIdentifier: string;
|
||||||
|
private configuration: TaskRunnerConfiguration;
|
||||||
|
|
||||||
|
private outputChannel: IOutputChannel;
|
||||||
|
private activeTasks: IStringDictionary<TerminalData>;
|
||||||
|
|
||||||
|
constructor(private fileConfig: FileConfig.ExternalTaskRunnerConfiguration, private terminalService: ITerminalService, private outputService: IOutputService,
|
||||||
|
private markerService: IMarkerService, private modelService: IModelService, private configurationResolverService: IConfigurationResolverService,
|
||||||
|
private telemetryService: ITelemetryService, outputChannelId: string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.outputChannel = this.outputService.getChannel(outputChannelId);
|
||||||
|
this.clearOutput();
|
||||||
|
this.activeTasks = Object.create(null);
|
||||||
|
|
||||||
|
let parseResult = FileConfig.parse(fileConfig, this);
|
||||||
|
this.validationStatus = parseResult.validationStatus;
|
||||||
|
this.configuration = parseResult.configuration;
|
||||||
|
this.buildTaskIdentifier = parseResult.defaultBuildTaskIdentifier;
|
||||||
|
this.testTaskIdentifier = parseResult.defaultTestTaskIdentifier;
|
||||||
|
|
||||||
|
if (!this.validationStatus.isOK()) {
|
||||||
|
this.showOutput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public log(value: string): void {
|
||||||
|
this.outputChannel.append(value + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
private showOutput(): void {
|
||||||
|
this.outputChannel.show(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private clearOutput(): void {
|
||||||
|
this.outputChannel.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public build(): ITaskExecuteResult {
|
||||||
|
if (!this.buildTaskIdentifier) {
|
||||||
|
throw new TaskError(Severity.Info, nls.localize('TerminalTaskSystem.noBuildTask', 'No build task defined in tasks.json'), TaskErrors.NoBuildTask);
|
||||||
|
}
|
||||||
|
return this.run(this.buildTaskIdentifier, Triggers.shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public rebuild(): ITaskExecuteResult {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clean(): ITaskExecuteResult {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public runTest(): ITaskExecuteResult {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public run(taskIdentifier: string, trigger: string = Triggers.command): ITaskExecuteResult {
|
||||||
|
let task = this.configuration.tasks[taskIdentifier];
|
||||||
|
if (!task) {
|
||||||
|
throw new TaskError(Severity.Info, nls.localize('TerminalTaskSystem.noTask', 'Task \'{0}\' not found', taskIdentifier), TaskErrors.TaskNotFound);
|
||||||
|
}
|
||||||
|
let telemetryEvent: TelemetryEvent = {
|
||||||
|
trigger: trigger,
|
||||||
|
command: 'other',
|
||||||
|
success: true
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
let result = this.executeTask(task, telemetryEvent);
|
||||||
|
result.promise = result.promise.then((summary) => {
|
||||||
|
this.telemetryService.publicLog(TerminalTaskSystem.TelemetryEventName, telemetryEvent);
|
||||||
|
return summary;
|
||||||
|
}, (error) => {
|
||||||
|
telemetryEvent.success = false;
|
||||||
|
this.telemetryService.publicLog(TerminalTaskSystem.TelemetryEventName, telemetryEvent);
|
||||||
|
return TPromise.wrapError<ITaskSummary>(error);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
telemetryEvent.success = false;
|
||||||
|
this.telemetryService.publicLog(TerminalTaskSystem.TelemetryEventName, telemetryEvent);
|
||||||
|
if (error instanceof TaskError) {
|
||||||
|
throw error;
|
||||||
|
} else if (error instanceof Error) {
|
||||||
|
this.log(error.message);
|
||||||
|
throw new TaskError(Severity.Error, error.message, TaskErrors.UnknownError);
|
||||||
|
} else {
|
||||||
|
this.log(error.toString());
|
||||||
|
throw new TaskError(Severity.Error, nls.localize('TerminalTaskSystem.unknownError', 'A unknown error has occurred while executing a task. See task output log for details.'), TaskErrors.UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isActive(): TPromise<boolean> {
|
||||||
|
return TPromise.as(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public isActiveSync(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public canAutoTerminate(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public terminate(): TPromise<TerminateResponse> {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tasks(): TPromise<TaskDescription[]> {
|
||||||
|
let result: TaskDescription[];
|
||||||
|
if (!this.configuration || !this.configuration.tasks) {
|
||||||
|
result = [];
|
||||||
|
} else {
|
||||||
|
result = Object.keys(this.configuration.tasks).map(key => this.configuration.tasks[key]);
|
||||||
|
}
|
||||||
|
return TPromise.as(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private executeTask(task: TaskDescription, telemetryEvent: TelemetryEvent): ITaskExecuteResult {
|
||||||
|
let terminalData = this.activeTasks[task.id];
|
||||||
|
if (terminalData && terminalData.promise) {
|
||||||
|
if (task.showOutput === ShowOutput.Always) {
|
||||||
|
terminalData.terminal.setVisible(true);
|
||||||
|
}
|
||||||
|
return { kind: TaskExecuteKind.Active, active: { same: true, background: task.isBackground }, promise: terminalData.promise };
|
||||||
|
} else {
|
||||||
|
let terminal: ITerminalInstance = undefined;
|
||||||
|
let promise: TPromise<ITaskSummary> = undefined;
|
||||||
|
if (task.isBackground) {
|
||||||
|
promise = new TPromise<ITaskSummary>((resolve, reject) => {
|
||||||
|
let watchingProblemMatcher = new WatchingProblemCollector(this.resolveMatchers(task.problemMatchers), this.markerService, this.modelService);
|
||||||
|
let toUnbind: IDisposable[] = [];
|
||||||
|
let event: TaskEvent = { taskId: task.id, taskName: task.name, type: TaskType.Watching };
|
||||||
|
let eventCounter: number = 0;
|
||||||
|
toUnbind.push(watchingProblemMatcher.addListener2(ProblemCollectorEvents.WatchingBeginDetected, () => {
|
||||||
|
eventCounter++;
|
||||||
|
this.emit(TaskSystemEvents.Active, event);
|
||||||
|
}));
|
||||||
|
toUnbind.push(watchingProblemMatcher.addListener2(ProblemCollectorEvents.WatchingEndDetected, () => {
|
||||||
|
eventCounter--;
|
||||||
|
this.emit(TaskSystemEvents.Inactive, event);
|
||||||
|
}));
|
||||||
|
watchingProblemMatcher.aboutToStart();
|
||||||
|
let delayer: Async.Delayer<any> = null;
|
||||||
|
let decoder = new TerminalDecoder();
|
||||||
|
terminal = this.createTerminal(task);
|
||||||
|
terminal.onData((data: string) => {
|
||||||
|
decoder.write(data).forEach(line => {
|
||||||
|
watchingProblemMatcher.processLine(line);
|
||||||
|
if (delayer === null) {
|
||||||
|
delayer = new Async.Delayer(3000);
|
||||||
|
}
|
||||||
|
delayer.trigger(() => {
|
||||||
|
watchingProblemMatcher.forceDelivery();
|
||||||
|
delayer = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
terminal.onExit((exitCode) => {
|
||||||
|
watchingProblemMatcher.dispose();
|
||||||
|
toUnbind = dispose(toUnbind);
|
||||||
|
toUnbind = null;
|
||||||
|
for (let i = 0; i < eventCounter; i++) {
|
||||||
|
this.emit(TaskSystemEvents.Inactive, event);
|
||||||
|
}
|
||||||
|
eventCounter = 0;
|
||||||
|
if (exitCode && exitCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && task.showOutput !== ShowOutput.Never) {
|
||||||
|
this.terminalService.setActiveInstance(terminal);
|
||||||
|
this.terminalService.showPanel(false);
|
||||||
|
}
|
||||||
|
resolve({ exitCode });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
promise = new TPromise<ITaskSummary>((resolve, reject) => {
|
||||||
|
terminal = this.createTerminal(task);
|
||||||
|
this.emit(TaskSystemEvents.Active, event);
|
||||||
|
let decoder = new TerminalDecoder();
|
||||||
|
let startStopProblemMatcher = new StartStopProblemCollector(this.resolveMatchers(task.problemMatchers), this.markerService, this.modelService);
|
||||||
|
terminal.onData((data: string) => {
|
||||||
|
decoder.write(data).forEach((line) => {
|
||||||
|
startStopProblemMatcher.processLine(line);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
terminal.onExit((exitCode) => {
|
||||||
|
startStopProblemMatcher.processLine(decoder.end());
|
||||||
|
startStopProblemMatcher.done();
|
||||||
|
startStopProblemMatcher.dispose();
|
||||||
|
this.emit(TaskSystemEvents.Inactive, event);
|
||||||
|
delete this.activeTasks[task.id];
|
||||||
|
resolve({ exitCode });
|
||||||
|
});
|
||||||
|
this.terminalService.setActiveInstance(terminal);
|
||||||
|
if (task.showOutput === ShowOutput.Always) {
|
||||||
|
this.terminalService.showPanel(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.terminalService.setActiveInstance(terminal);
|
||||||
|
if (task.showOutput === ShowOutput.Always) {
|
||||||
|
this.terminalService.showPanel(false);
|
||||||
|
}
|
||||||
|
this.activeTasks[task.id] = { terminal, promise };
|
||||||
|
return { kind: TaskExecuteKind.Started, started: {}, promise: promise };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createTerminal(task: TaskDescription): ITerminalInstance {
|
||||||
|
let { command, args } = this.resolveCommandAndArgs(task);
|
||||||
|
let terminalName = nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', task.name);
|
||||||
|
if (this.configuration.isShellCommand) {
|
||||||
|
let shellConfig = (this.terminalService.configHelper as TerminalConfigHelper).getShell();
|
||||||
|
let shellArgs = shellConfig.args.slice(0);
|
||||||
|
let toAdd: string[] = [];
|
||||||
|
let commandLine: string;
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
toAdd.push('/d', '/c');
|
||||||
|
let quotedCommand: boolean = false;
|
||||||
|
let quotedArg: boolean = false;
|
||||||
|
let quoted = this.ensureDoubleQuotes(command);
|
||||||
|
let commandPieces: string[] = [];
|
||||||
|
commandPieces.push(quoted.value);
|
||||||
|
quotedCommand = quoted.quoted;
|
||||||
|
if (args) {
|
||||||
|
args.forEach((arg) => {
|
||||||
|
quoted = this.ensureDoubleQuotes(arg);
|
||||||
|
commandPieces.push(quoted.value);
|
||||||
|
quotedArg = quotedArg && quoted.quoted;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (quotedCommand) {
|
||||||
|
if (quotedArg) {
|
||||||
|
commandLine = '"' + commandPieces.join(' ') + '"';
|
||||||
|
} else {
|
||||||
|
if (commandPieces.length > 1) {
|
||||||
|
commandLine = '"' + commandPieces[0] + '"' + ' ' + commandPieces.slice(1).join(' ');
|
||||||
|
} else {
|
||||||
|
commandLine = '"' + commandPieces[0] + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
commandLine = commandPieces.join(' ');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toAdd.push('-c');
|
||||||
|
commandLine = `${command} ${args.join(' ')}`;
|
||||||
|
}
|
||||||
|
toAdd.forEach(element => {
|
||||||
|
if (!shellArgs.some(arg => arg.toLowerCase() === element)) {
|
||||||
|
shellArgs.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
shellArgs.push(commandLine);
|
||||||
|
return this.terminalService.createInstance(terminalName, shellConfig.executable, shellArgs, true);
|
||||||
|
} else {
|
||||||
|
return this.terminalService.createInstance(terminalName, command, args, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private resolveCommandAndArgs(task: TaskDescription): { command: string, args: string[] } {
|
||||||
|
let args: string[] = this.configuration.args ? this.configuration.args.slice() : [];
|
||||||
|
// We need to first pass the task name
|
||||||
|
if (!task.suppressTaskName) {
|
||||||
|
if (this.fileConfig.taskSelector) {
|
||||||
|
args.push(this.fileConfig.taskSelector + task.name);
|
||||||
|
} else {
|
||||||
|
args.push(task.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// And then additional arguments
|
||||||
|
if (task.args) {
|
||||||
|
args = args.concat(task.args);
|
||||||
|
}
|
||||||
|
args = this.resolveVariables(args);
|
||||||
|
let command: string = this.resolveVariable(this.configuration.command);
|
||||||
|
return { command, args };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private resolveVariables(value: string[]): string[] {
|
||||||
|
return value.map(s => this.resolveVariable(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private resolveMatchers<T extends ProblemMatcher>(values: T[]): T[] {
|
||||||
|
if (values.length === 0) {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
let result: T[] = [];
|
||||||
|
values.forEach((matcher) => {
|
||||||
|
if (!matcher.filePrefix) {
|
||||||
|
result.push(matcher);
|
||||||
|
} else {
|
||||||
|
let copy = Objects.clone(matcher);
|
||||||
|
copy.filePrefix = this.resolveVariable(copy.filePrefix);
|
||||||
|
result.push(copy);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private resolveVariable(value: string): string {
|
||||||
|
return this.configurationResolverService.resolve(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static doubleQuotes = /^[^"].* .*[^"]$/;
|
||||||
|
private ensureDoubleQuotes(value: string) {
|
||||||
|
if (TerminalTaskSystem.doubleQuotes.test(value)) {
|
||||||
|
return {
|
||||||
|
value: '"' + value + '"',
|
||||||
|
quoted: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
value: value,
|
||||||
|
quoted: value.length > 0 && value[0] === '"' && value[value.length - 1] === '"'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WellKnowCommands: IStringDictionary<boolean> = {
|
||||||
|
'ant': true,
|
||||||
|
'cmake': true,
|
||||||
|
'eslint': true,
|
||||||
|
'gradle': true,
|
||||||
|
'grunt': true,
|
||||||
|
'gulp': true,
|
||||||
|
'jake': true,
|
||||||
|
'jenkins': true,
|
||||||
|
'jshint': true,
|
||||||
|
'make': true,
|
||||||
|
'maven': true,
|
||||||
|
'msbuild': true,
|
||||||
|
'msc': true,
|
||||||
|
'nmake': true,
|
||||||
|
'npm': true,
|
||||||
|
'rake': true,
|
||||||
|
'tsc': true,
|
||||||
|
'xbuild': true
|
||||||
|
};
|
||||||
|
public getSanitizedCommand(cmd: string): string {
|
||||||
|
let result = cmd.toLowerCase();
|
||||||
|
let index = result.lastIndexOf(path.sep);
|
||||||
|
if (index !== -1) {
|
||||||
|
result = result.substring(index + 1);
|
||||||
|
}
|
||||||
|
if (TerminalTaskSystem.WellKnowCommands[result]) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -451,7 +451,7 @@ class ConfigurationParser {
|
|||||||
name: globals.command,
|
name: globals.command,
|
||||||
showOutput: globals.showOutput,
|
showOutput: globals.showOutput,
|
||||||
suppressTaskName: true,
|
suppressTaskName: true,
|
||||||
isWatching: isWatching,
|
isBackground: isWatching,
|
||||||
promptOnClose: promptOnClose,
|
promptOnClose: promptOnClose,
|
||||||
echoCommand: globals.echoCommand,
|
echoCommand: globals.echoCommand,
|
||||||
};
|
};
|
||||||
@@ -539,15 +539,15 @@ class ConfigurationParser {
|
|||||||
if (Types.isStringArray(externalTask.args)) {
|
if (Types.isStringArray(externalTask.args)) {
|
||||||
task.args = externalTask.args.slice();
|
task.args = externalTask.args.slice();
|
||||||
}
|
}
|
||||||
task.isWatching = false;
|
task.isBackground = false;
|
||||||
if (!Types.isUndefined(externalTask.isWatching)) {
|
if (!Types.isUndefined(externalTask.isWatching)) {
|
||||||
task.isWatching = !!externalTask.isWatching;
|
task.isBackground = !!externalTask.isWatching;
|
||||||
}
|
}
|
||||||
task.promptOnClose = true;
|
task.promptOnClose = true;
|
||||||
if (!Types.isUndefined(externalTask.promptOnClose)) {
|
if (!Types.isUndefined(externalTask.promptOnClose)) {
|
||||||
task.promptOnClose = !!externalTask.promptOnClose;
|
task.promptOnClose = !!externalTask.promptOnClose;
|
||||||
} else {
|
} else {
|
||||||
task.promptOnClose = !task.isWatching;
|
task.promptOnClose = !task.isBackground;
|
||||||
}
|
}
|
||||||
if (Types.isString(externalTask.showOutput)) {
|
if (Types.isString(externalTask.showOutput)) {
|
||||||
task.showOutput = TaskSystem.ShowOutput.fromString(externalTask.showOutput);
|
task.showOutput = TaskSystem.ShowOutput.fromString(externalTask.showOutput);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem {
|
|||||||
public build(): ITaskExecuteResult {
|
public build(): ITaskExecuteResult {
|
||||||
if (this.activeTaskIdentifier) {
|
if (this.activeTaskIdentifier) {
|
||||||
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
||||||
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === this.defaultBuildTaskIdentifier, watching: task.isWatching }, promise: this.activeTaskPromise };
|
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === this.defaultBuildTaskIdentifier, background: task.isBackground }, promise: this.activeTaskPromise };
|
||||||
}
|
}
|
||||||
if (!this.defaultBuildTaskIdentifier) {
|
if (!this.defaultBuildTaskIdentifier) {
|
||||||
throw new TaskError(Severity.Info, nls.localize('TaskRunnerSystem.noBuildTask', 'No task is marked as a build task in the tasks.json. Mark a task with \'isBuildCommand\'.'), TaskErrors.NoBuildTask);
|
throw new TaskError(Severity.Info, nls.localize('TaskRunnerSystem.noBuildTask', 'No task is marked as a build task in the tasks.json. Mark a task with \'isBuildCommand\'.'), TaskErrors.NoBuildTask);
|
||||||
@@ -109,7 +109,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem {
|
|||||||
public runTest(): ITaskExecuteResult {
|
public runTest(): ITaskExecuteResult {
|
||||||
if (this.activeTaskIdentifier) {
|
if (this.activeTaskIdentifier) {
|
||||||
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
||||||
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === this.defaultTestTaskIdentifier, watching: task.isWatching }, promise: this.activeTaskPromise };
|
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === this.defaultTestTaskIdentifier, background: task.isBackground }, promise: this.activeTaskPromise };
|
||||||
}
|
}
|
||||||
if (!this.defaultTestTaskIdentifier) {
|
if (!this.defaultTestTaskIdentifier) {
|
||||||
throw new TaskError(Severity.Info, nls.localize('TaskRunnerSystem.noTestTask', 'No test task configured.'), TaskErrors.NoTestTask);
|
throw new TaskError(Severity.Info, nls.localize('TaskRunnerSystem.noTestTask', 'No test task configured.'), TaskErrors.NoTestTask);
|
||||||
@@ -120,7 +120,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem {
|
|||||||
public run(taskIdentifier: string): ITaskExecuteResult {
|
public run(taskIdentifier: string): ITaskExecuteResult {
|
||||||
if (this.activeTaskIdentifier) {
|
if (this.activeTaskIdentifier) {
|
||||||
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
let task = this.configuration.tasks[this.activeTaskIdentifier];
|
||||||
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === taskIdentifier, watching: task.isWatching }, promise: this.activeTaskPromise };
|
return { kind: TaskExecuteKind.Active, active: { same: this.activeTaskIdentifier === taskIdentifier, background: task.isBackground }, promise: this.activeTaskPromise };
|
||||||
}
|
}
|
||||||
return this.executeTask(taskIdentifier);
|
return this.executeTask(taskIdentifier);
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem {
|
|||||||
let prompt: string = Platform.isWindows ? '>' : '$';
|
let prompt: string = Platform.isWindows ? '>' : '$';
|
||||||
this.log(`running command${prompt} ${command} ${args.join(' ')}`);
|
this.log(`running command${prompt} ${command} ${args.join(' ')}`);
|
||||||
}
|
}
|
||||||
if (task.isWatching) {
|
if (task.isBackground) {
|
||||||
let watchingProblemMatcher = new WatchingProblemCollector(this.resolveMatchers(task.problemMatchers), this.markerService, this.modelService);
|
let watchingProblemMatcher = new WatchingProblemCollector(this.resolveMatchers(task.problemMatchers), this.markerService, this.modelService);
|
||||||
let toUnbind: IDisposable[] = [];
|
let toUnbind: IDisposable[] = [];
|
||||||
let event: TaskEvent = { taskId: task.id, taskName: task.name, type: TaskType.Watching };
|
let event: TaskEvent = { taskId: task.id, taskName: task.name, type: TaskType.Watching };
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class TaskBuilder {
|
|||||||
showOutput: TaskSystem.ShowOutput.Always,
|
showOutput: TaskSystem.ShowOutput.Always,
|
||||||
suppressTaskName: false,
|
suppressTaskName: false,
|
||||||
echoCommand: false,
|
echoCommand: false,
|
||||||
isWatching: false,
|
isBackground: false,
|
||||||
promptOnClose: true,
|
promptOnClose: true,
|
||||||
problemMatchers: []
|
problemMatchers: []
|
||||||
};
|
};
|
||||||
@@ -99,8 +99,8 @@ class TaskBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isWatching(value: boolean): TaskBuilder {
|
public isBackground(value: boolean): TaskBuilder {
|
||||||
this.result.isWatching = value;
|
this.result.isBackground = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ suite('Tasks Configuration parsing tests', () => {
|
|||||||
let builder = new ConfiguationBuilder('tsc');
|
let builder = new ConfiguationBuilder('tsc');
|
||||||
builder.task('tsc').
|
builder.task('tsc').
|
||||||
suppressTaskName(true).
|
suppressTaskName(true).
|
||||||
isWatching(true).
|
isBackground(true).
|
||||||
promptOnClose(false);
|
promptOnClose(false);
|
||||||
testGobalCommand(
|
testGobalCommand(
|
||||||
{
|
{
|
||||||
@@ -627,7 +627,7 @@ suite('Tasks Configuration parsing tests', () => {
|
|||||||
showOutput(TaskSystem.ShowOutput.Never).
|
showOutput(TaskSystem.ShowOutput.Never).
|
||||||
echoCommand(true).
|
echoCommand(true).
|
||||||
args(['--p']).
|
args(['--p']).
|
||||||
isWatching(true).
|
isBackground(true).
|
||||||
promptOnClose(false);
|
promptOnClose(false);
|
||||||
|
|
||||||
let result = testConfiguration(external, builder);
|
let result = testConfiguration(external, builder);
|
||||||
@@ -833,7 +833,7 @@ suite('Tasks Configuration parsing tests', () => {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
let builder = new ConfiguationBuilder('tsc');
|
let builder = new ConfiguationBuilder('tsc');
|
||||||
builder.task('taskName').isWatching(true).promptOnClose(false);
|
builder.task('taskName').isBackground(true).promptOnClose(false);
|
||||||
testConfiguration(external, builder);
|
testConfiguration(external, builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -943,7 +943,7 @@ suite('Tasks Configuration parsing tests', () => {
|
|||||||
assert.strictEqual(actual.showOutput, expected.showOutput, 'showOutput');
|
assert.strictEqual(actual.showOutput, expected.showOutput, 'showOutput');
|
||||||
assert.strictEqual(actual.suppressTaskName, expected.suppressTaskName, 'suppressTaskName');
|
assert.strictEqual(actual.suppressTaskName, expected.suppressTaskName, 'suppressTaskName');
|
||||||
assert.strictEqual(actual.echoCommand, expected.echoCommand, 'echoCommand');
|
assert.strictEqual(actual.echoCommand, expected.echoCommand, 'echoCommand');
|
||||||
assert.strictEqual(actual.isWatching, expected.isWatching, 'isWatching');
|
assert.strictEqual(actual.isBackground, expected.isBackground, 'isBackground');
|
||||||
assert.strictEqual(actual.promptOnClose, expected.promptOnClose, 'promptOnClose');
|
assert.strictEqual(actual.promptOnClose, expected.promptOnClose, 'promptOnClose');
|
||||||
assert.strictEqual(typeof actual.problemMatchers, typeof expected.problemMatchers);
|
assert.strictEqual(typeof actual.problemMatchers, typeof expected.problemMatchers);
|
||||||
if (actual.problemMatchers && expected.problemMatchers) {
|
if (actual.problemMatchers && expected.problemMatchers) {
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ export class EditorState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ISerializedFileHistoryEntry {
|
interface ISerializedFileHistoryEntry {
|
||||||
resource: any | string; // TODO@Ben migration
|
resource?: string;
|
||||||
|
resourceJSON: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class BaseHistoryService {
|
export abstract class BaseHistoryService {
|
||||||
@@ -708,7 +709,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
|
|||||||
return void 0; // only file resource inputs are serializable currently
|
return void 0; // only file resource inputs are serializable currently
|
||||||
}
|
}
|
||||||
|
|
||||||
return { resource: (input as IResourceInput).resource.toJSON() };
|
return { resourceJSON: (input as IResourceInput).resource.toJSON() };
|
||||||
}).filter(serialized => !!serialized);
|
}).filter(serialized => !!serialized);
|
||||||
|
|
||||||
this.storageService.store(HistoryService.STORAGE_KEY, JSON.stringify(entries), StorageScope.WORKSPACE);
|
this.storageService.store(HistoryService.STORAGE_KEY, JSON.stringify(entries), StorageScope.WORKSPACE);
|
||||||
@@ -724,8 +725,8 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
|
|||||||
|
|
||||||
this.history = entries.map(entry => {
|
this.history = entries.map(entry => {
|
||||||
const serializedFileInput = entry as ISerializedFileHistoryEntry;
|
const serializedFileInput = entry as ISerializedFileHistoryEntry;
|
||||||
if (serializedFileInput.resource) {
|
if (serializedFileInput.resource || serializedFileInput.resourceJSON) {
|
||||||
return { resource: typeof serializedFileInput.resource === 'string' ? URI.parse(serializedFileInput.resource) : URI.revive(serializedFileInput.resource) } as IResourceInput;
|
return { resource: !!serializedFileInput.resourceJSON ? URI.revive(serializedFileInput.resourceJSON) : URI.parse(serializedFileInput.resource) } as IResourceInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
return void 0;
|
return void 0;
|
||||||
|
|||||||
@@ -48,4 +48,5 @@ export interface IThemeSetting {
|
|||||||
|
|
||||||
export interface IThemeSettingStyle {
|
export interface IThemeSettingStyle {
|
||||||
foreground?: string;
|
foreground?: string;
|
||||||
|
background?: string;
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,24 @@ export class ThemeService implements IThemeService {
|
|||||||
@ITelemetryService private telemetryService: ITelemetryService) {
|
@ITelemetryService private telemetryService: ITelemetryService) {
|
||||||
|
|
||||||
this.knownColorThemes = [];
|
this.knownColorThemes = [];
|
||||||
this.currentColorThemeDocument = null;
|
|
||||||
|
// In order to avoid paint flashing for tokens, because
|
||||||
|
// themes are loaded asynchronously, we need to initialize
|
||||||
|
// a color theme document with good defaults until the theme is loaded
|
||||||
|
let isLightTheme = (Array.prototype.indexOf.call(document.body.classList, 'vs') >= 0);
|
||||||
|
let foreground = isLightTheme ? '#000000' : '#D4D4D4';
|
||||||
|
let background = isLightTheme ? '#ffffff' : '#1E1E1E';
|
||||||
|
this.currentColorThemeDocument = {
|
||||||
|
name: null,
|
||||||
|
include: null,
|
||||||
|
settings: [{
|
||||||
|
settings: {
|
||||||
|
foreground: foreground,
|
||||||
|
background: background
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
this.onColorThemeChange = new Emitter<string>();
|
this.onColorThemeChange = new Emitter<string>();
|
||||||
this.knownIconThemes = [];
|
this.knownIconThemes = [];
|
||||||
this.currentIconTheme = '';
|
this.currentIconTheme = '';
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ suite('Editor - Range decorations', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mockEditorService(editorInput: IEditorInput);
|
function mockEditorService(editorInput: IEditorInput);
|
||||||
function mockEditorService(resource: URI)
|
function mockEditorService(resource: URI);
|
||||||
function mockEditorService(arg: any) {
|
function mockEditorService(arg: any) {
|
||||||
let editorInput: IEditorInput = arg instanceof URI ? instantiationService.createInstance(FileEditorInput, arg, void 0) : arg;
|
let editorInput: IEditorInput = arg instanceof URI ? instantiationService.createInstance(FileEditorInput, arg, void 0) : arg;
|
||||||
instantiationService.stub(WorkbenchEditorService.IWorkbenchEditorService, 'getActiveEditorInput', editorInput);
|
instantiationService.stub(WorkbenchEditorService.IWorkbenchEditorService, 'getActiveEditorInput', editorInput);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
|||||||
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/common/quickOpen';
|
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/common/quickOpen';
|
||||||
import { DocumentSymbolProviderRegistry, DocumentHighlightKind } from 'vs/editor/common/modes';
|
import { DocumentSymbolProviderRegistry, DocumentHighlightKind } from 'vs/editor/common/modes';
|
||||||
import { getCodeLensData } from 'vs/editor/contrib/codelens/common/codelens';
|
import { getCodeLensData } from 'vs/editor/contrib/codelens/common/codelens';
|
||||||
import { getDeclarationsAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
import { getDeclarationsAtPosition, getTypeDefinitionAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||||
import { getHover } from 'vs/editor/contrib/hover/common/hover';
|
import { getHover } from 'vs/editor/contrib/hover/common/hover';
|
||||||
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
|
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
|
||||||
import { provideReferences } from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
|
import { provideReferences } from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
|
||||||
@@ -351,6 +351,26 @@ suite('ExtHostLanguageFeatures', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- type definition
|
||||||
|
|
||||||
|
test('TypeDefinition, data conversion', function () {
|
||||||
|
|
||||||
|
disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||||
|
provideTypeDefinition(): any {
|
||||||
|
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return threadService.sync().then(() => {
|
||||||
|
return getTypeDefinitionAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||||
|
assert.equal(value.length, 1);
|
||||||
|
let [entry] = value;
|
||||||
|
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||||
|
assert.equal(entry.uri.toString(), model.uri.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// --- extra info
|
// --- extra info
|
||||||
|
|
||||||
test('HoverProvider, word range at pos', function () {
|
test('HoverProvider, word range at pos', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user