diff --git a/.gitignore b/.gitignore index 04a5b2ee9a..c006f31f5e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bin/ out/ node_modules/ vscode-powershell.zip -vscps-preview.zip \ No newline at end of file +vscps-preview.zip +*.vsix \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index 57ebba3e2a..d9c90f4234 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,9 +1,10 @@ .vscode/** typings/** -node_modules/vscode/** -node_modules/vscode-languageworker/** +node_modules/** **/*.ts .gitignore tsconfig.json +build/** bin/EditorServices.log +bin/DebugService.log bin/*.vshost.* \ No newline at end of file diff --git a/README.md b/README.md index e3f90430a8..478c840c7e 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,36 @@ # Windows PowerShell for Visual Studio Code -Windows PowerShell language support for Visual Studio Code. +This extension provides Windows PowerShell language support for Visual Studio Code. More details forthcoming. -## Building the code +## Features -First, install the package dependencies: +- IntelliSense for cmdlets and more +- Rule-based analysis provided by [Windows PowerShell Script Analyzer](http://github.com/PowerShell/PSScriptAnalyzer) +- Go to Definition for cmdlets and variables +- Find References of cmdlets and variables +- Local script debugging! -``` -npm install -``` - -The next two steps are required if you have Node.js 5 installed due to some change in npm: - -``` -cd node_modules\vscode -npm install -``` - -Now you can compile the code: - -``` -npm run compile -``` - -After the initial compile, the source files will be watched and recompiled -when changes are saved. +## Example Scripts -## Running the compiled code +There are some example scripts in the extension's `examples` folder that you can +use to discover PowerShell editing and debugging functionality. Please +check out the included [README.md](examples/README.md) file to learn more about +how to use them. -From a PowerShell or cmd.exe prompt, run the following command: +This folder can be found at the following path: ``` -code --extensionDevelopmentPath="c:\path\to\vscode-powershell" . +c:\Users\\.vscode\extensions\daviwil.PowerShell\examples ``` - -If you allow the compiler to continue watching for file changes, you can use -the `Reload Window` command found in the command palette `(Ctrl+Shift+P)` -so that the new source files are loaded. -## Example Scripts +## Contributing to the Code -There are some example scripts in the `examples` folder that you can -use to discover PowerShell editing and debugging functionality. Please -check out the [README.md](examples/README.md) file to learn more about -how to use them. +Check out the [development documentation](docs/development.md) for more details +on how to contribute to this extension! ## License -This project is [licensed under the MIT License](LICENSE). Please see the +This extension is [licensed under the MIT License](LICENSE). Please see the [third-party notices](Third Party Notices.txt) file for details on the third-party binaries that we include with releases of this project. diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000000..15be7089ca --- /dev/null +++ b/docs/development.md @@ -0,0 +1,30 @@ +# Working with the PowerShell extension code + +## Building the code + +First, install the package dependencies: + +``` +npm install +``` + +Now you can compile the code: + +``` +npm run compile +``` + +After the initial compile, the source files will be watched and recompiled +when changes are saved. + +## Running the compiled code + +From a PowerShell or cmd.exe prompt, run the following command: + +``` +code --extensionDevelopmentPath="c:\path\to\vscode-powershell" . +``` + +If you allow the compiler to continue watching for file changes, you can use +the `Reload Window` command found in the command palette `(Ctrl+Shift+P)` +so that the new source files are loaded. diff --git a/images/PowerShell_icon.png b/images/PowerShell_icon.png new file mode 100644 index 0000000000..b20df69b8c Binary files /dev/null and b/images/PowerShell_icon.png differ diff --git a/package.json b/package.json index dd96381d96..87d0699031 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,33 @@ { "name": "PowerShell", - "version": "0.1.0-preview", + "displayName": "Windows PowerShell Language Support", + "version": "0.1.0", "publisher": "daviwil", - "description": "Windows PowerShell for Visual Studio Code", - "engines": { "vscode": "*" }, + "description": "Develop Windows PowerShell scripts in Visual Studio Code!", + "engines": { "vscode": "0.10.x" }, + "author": { + "name": "Microsoft Corporation - Development Labs" + }, + "license":"SEE LICENSE FILE", + "homepage": "https://github.com/PowerShell/vscode-powershell/README.md", + "categories": [ + "Languages", + "Snippets", + "Linters" + ], + "icon": "images/PowerShell_icon.png", + "galleryBanner": { + "color": "#ACD1EC", + "theme": "light" + }, + "repository": { + "type": "git", + "url": "https://github.com/PowerShell/vscode-powershell.git" + }, "main": "./out/powershellMain", "activationEvents": ["onLanguage:PowerShell"], - "dependencies": { - "vscode": "0.9.6" + "devDependencies": { + "vscode": "0.10.0" }, "scripts": { "vscode:prepublish": "node ./node_modules/vscode/bin/compile", @@ -19,13 +39,31 @@ "extensions": [ ".ps1", ".psm1", ".psd1", ".pssc", ".psrc" ], "aliases": [ "PowerShell", "powershell", "ps", "ps1" ] }], + "grammars": [{ + "language": "PowerShell", + "scopeName": "source.powershell", + "path": "./syntaxes/PowerShell.tmLanguage" + }], + "snippets": [ + { + "language": "PowerShell", + "path": "./snippets/PowerShell.json" + } + ], + "debuggers": [ + { + "type": "PowerShell", + "enableBreakpointsFor": { "languageIds": ["PowerShell"] }, + "program": "bin/Microsoft.PowerShell.EditorServices.Host.exe" + } + ], "configuration": { "type": "object", "title": "PowerShell Configuration", "properties": { "PowerShell.editorServicesHostPath": { "type": "string", - "default": "bin/Microsoft.PowerShell.EditorServices.Host.exe", + "default": "../bin/Microsoft.PowerShell.EditorServices.Host.exe", "description": "Specifies the path to the PowerShell Editor Services host executable." }, "PowerShell.waitForDebugger": { @@ -39,14 +77,7 @@ "description": "Enables diagnostic logging for the extension." } } - }, - "debugAdapter": [ - { - "type": "PowerShell", - "enableBreakpointsFor": { "languageIds": ["PowerShell"] }, - "program": "bin/Microsoft.PowerShell.EditorServices.Host.exe" - } - ] + } }, "private": true } \ No newline at end of file diff --git a/src/features/bufferSyncSupport.ts b/src/features/bufferSyncSupport.ts index 0858daa056..deeba521c6 100644 --- a/src/features/bufferSyncSupport.ts +++ b/src/features/bufferSyncSupport.ts @@ -42,7 +42,7 @@ class SyncedBuffer { } onContentChanged(events: vscode.TextDocumentContentChangeEvent[]): void { - var filePath = this.client.asAbsolutePath(this.document.getUri()); + var filePath = this.client.asAbsolutePath(this.document.uri); if (!filePath) { return; } @@ -53,14 +53,10 @@ class SyncedBuffer { var text = event.text; var args:Proto.ChangeRequestArgs = { file: filePath, - //line: range.start.line + 1, - //offset: range.start.character + 1, - //endLine: range.end.line + 1, - //endOffset: range.end.character + 1, - line: range.start.line, - offset: range.start.character, - endLine: range.end.line, - endOffset: range.end.character, + line: range.start.line + 1, + offset: range.start.character + 1, + endLine: range.end.line + 1, + endOffset: range.end.character + 1, insertString: text }; this.client.execute('change', args, false); @@ -90,7 +86,7 @@ class BufferSyncSupport { vscode.workspace.onDidOpenTextDocument(this.onDidAddDocument, this, this.disposables); vscode.workspace.onDidCloseTextDocument(this.onDidRemoveDocument, this, this.disposables); vscode.workspace.onDidChangeTextDocument(this.onDidChangeDocument, this, this.disposables); - vscode.workspace.getTextDocuments().forEach(this.onDidAddDocument, this); + vscode.workspace.textDocuments.forEach(this.onDidAddDocument, this); } public dispose(): void { @@ -101,13 +97,13 @@ class BufferSyncSupport { private onDidAddDocument(document: vscode.TextDocument): void { - if (document.getLanguageId() !== this.modeId) { + if (document.languageId !== this.modeId) { return; } - if (document.isUntitled()) { + if (document.isUntitled) { return; } - var resource = document.getUri(); + var resource = document.uri; var filepath = this.client.asAbsolutePath(resource); if (!filepath) { return; @@ -117,11 +113,11 @@ class BufferSyncSupport { syncedBuffer.open(); this.requestDiagnostic(filepath); - this.client.log("Added new document: " + document.getUri()); + this.client.log("Added new document: " + document.uri); } private onDidRemoveDocument(document: vscode.TextDocument): void { - var filepath:string = this.client.asAbsolutePath(document.getUri()); + var filepath:string = this.client.asAbsolutePath(document.uri); if (!filepath) { return; } @@ -134,7 +130,7 @@ class BufferSyncSupport { } private onDidChangeDocument(e: vscode.TextDocumentChangeEvent): void { - var filepath:string = this.client.asAbsolutePath(e.document.getUri()); + var filepath:string = this.client.asAbsolutePath(e.document.uri); if (!filepath) { return; } diff --git a/src/features/commentsSupport.ts b/src/features/commentsSupport.ts deleted file mode 100644 index 7e6dbd0f5b..0000000000 --- a/src/features/commentsSupport.ts +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - -'use strict'; - -import vscode = require('vscode'); - -class CommentsSupport implements vscode.Modes.ICommentsSupport { - - commentsConfiguration: vscode.Modes.ICommentsConfiguration = { - lineCommentTokens: ['#'], - blockCommentStartToken: '<#', - blockCommentEndToken: '#>' - }; - -} - -export = CommentsSupport; \ No newline at end of file diff --git a/src/features/configuration.ts b/src/features/configuration.ts index 8b03e797af..24b3e0ff81 100644 --- a/src/features/configuration.ts +++ b/src/features/configuration.ts @@ -17,7 +17,11 @@ export var defaultConfiguration: IConfiguration = { enableLogging: false } -export function load(myPluginId: string): Thenable { - let configuration = vscode.extensions.getConfigurationMemento(myPluginId); - return configuration.getValues(defaultConfiguration); +export function load(myPluginId: string): IConfiguration { + let configuration = vscode.workspace.getConfiguration(myPluginId); + return { + editorServicesHostPath: configuration.get("editorServicesHostPath", "../bin/Microsoft.PowerShell.EditorServices.Host.exe"), + waitForDebugger: configuration.get("waitForDebugger", false), + enableLogging: configuration.get("enableLogging", false) + } } diff --git a/src/features/declarationSupport.ts b/src/features/declarationSupport.ts index 226147d33c..b9da6948fb 100644 --- a/src/features/declarationSupport.ts +++ b/src/features/declarationSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class DeclarationSupport implements vscode.Modes.IDeclarationSupport { +class DeclarationSupport implements vscode.DefinitionProvider { private client: PowershellService.IPowershellServiceClient; @@ -18,47 +18,41 @@ class DeclarationSupport implements vscode.Modes.IDeclarationSupport { this.client = client; } - public findDeclaration(document: vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideDefinition(document: vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { var args:Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve(null); + return Promise.resolve(null); } return this.client.execute('definition', args).then((response) => { var locations:Proto.FileSpan[] = response.body; if (!locations || locations.length === 0) { + vscode.window.showWarningMessage("The selected symbol's definition could not be found."); return null; } - var location = locations[0]; - var resource = this.client.asUrl(location.file); - // if (resource === null) { - // return null; - // } - // - // return locations.map(location => { - // var resource = this.client.asUrl(location.file); - // if (resource === null) { - // return null; - // } else { - // return { - // resource: resource, - // range: new vscode.Range(location.start.line, location.start.offset, location.end.line, location.end.offset) - // } - // } - // }); - if (resource === null) { - return null; - } else { - return { - resource: resource, - range: new vscode.Range(location.start.line, location.start.offset, location.end.line, location.end.offset) - }; - } + + return locations.map(location => { + var resource = this.client.asUrl(location.file); + if (resource === null) { + return null; + } else { + // TODO: Strangely, this doesn't work if I return the Location directly, + // only works if I assign to a variable first. Not sure what is going on yet. + var loc = + new vscode.Location( + resource, + new vscode.Range( + location.start.line - 1, + location.start.offset - 1, + location.end.line - 1, + location.end.offset - 1 + )); + return loc; + } + }); }, () => { return null; }); diff --git a/src/features/navigateTypesSupport.ts b/src/features/navigateTypesSupport.ts index c21b3ce71a..80e43fec06 100644 --- a/src/features/navigateTypesSupport.ts +++ b/src/features/navigateTypesSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { +class NavigateTypeSupport implements vscode.WorkspaceSymbolProvider { private client: PowershellService.IPowershellServiceClient; private modeId: string @@ -18,20 +18,20 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { this.modeId = modeId; } - public getNavigateToItems(search:string, token:vscode.CancellationToken): Promise { + public provideWorkspaceSymbols(search:string, token:vscode.CancellationToken): Promise { // Get all PowerShell files in the workspace let uri: vscode.Uri; - let documents = vscode.workspace.getTextDocuments(); + let documents = vscode.workspace.textDocuments; for (let document of documents) { - if (document.getLanguageId() === this.modeId) { - uri = document.getUri(); + if (document.languageId === this.modeId) { + uri = document.uri; break; } } if (!uri) { - return Promise.resolve([]); + return Promise.resolve([]); } var args:Proto.NavtoRequestArgs = { @@ -39,20 +39,19 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { searchValue: search }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } - return this.client.execute('navto', args, token).then((response):vscode.Modes.ITypeBearing[] => { + return this.client.execute('navto', args, token).then((response):vscode.SymbolInformation[] => { var data = response.body; if (data) { return data.map((item) => { - return { - containerName: item.containerName, - name: item.name, - parameters: (item.kind === 'method' || item.kind === 'function') ? '()' : '', - type: item.kind, - range: new vscode.Range(item.start.line, item.start.offset, item.end.line, item.end.offset), - resourceUri: this.client.asUrl(item.file) - }; + let range = new vscode.Range(item.start.line - 1, item.start.offset - 1, item.end.line - 1, item.end.offset - 1); + let label = item.name; + if (item.kind === 'method' || item.kind === 'function') { + label += '()'; + } + return new vscode.SymbolInformation(label, _kindMapping[item.kind], range, + this.client.asUrl(item.file), item.containerName); }); } else { return []; @@ -64,4 +63,12 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { } } +var _kindMapping: { [kind: string]: vscode.SymbolKind } = Object.create(null); +_kindMapping['method'] = vscode.SymbolKind.Method; +_kindMapping['enum'] = vscode.SymbolKind.Enum; +_kindMapping['function'] = vscode.SymbolKind.Function; +_kindMapping['class'] = vscode.SymbolKind.Class; +_kindMapping['interface'] = vscode.SymbolKind.Interface; +_kindMapping['var'] = vscode.SymbolKind.Variable; + export = NavigateTypeSupport; \ No newline at end of file diff --git a/src/features/occurrencesSupport.ts b/src/features/occurrencesSupport.ts index 7f4d7acc2b..a881b4d293 100644 --- a/src/features/occurrencesSupport.ts +++ b/src/features/occurrencesSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class OccurrencesSupport implements vscode.Modes.IOccurrencesSupport { +class OccurrencesSupport implements vscode.DocumentHighlightProvider { private client: PowershellService.IPowershellServiceClient; @@ -16,25 +16,22 @@ class OccurrencesSupport implements vscode.Modes.IOccurrencesSupport { this.client = client; } - public findOccurrences(resource:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideDocumentHighlights(resource:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { var args:Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(resource.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(resource.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } - return this.client.execute('occurrences', args, token).then((response):vscode.Modes.IOccurrence[] => { + return this.client.execute('occurrences', args, token).then((response):vscode.DocumentHighlight[] => { var data = response.body; if (data) { return data.map((item) => { - return { - kind: item.isWriteAccess ? 'write' : null, - range: new vscode.Range(item.start.line, item.start.offset, item.end.line, item.end.offset) - }; + return new vscode.DocumentHighlight( + new vscode.Range(item.start.line - 1, item.start.offset - 1, item.end.line - 1, item.end.offset - 1), + item.isWriteAccess ? vscode.DocumentHighlightKind.Write : vscode.DocumentHighlightKind.Read); }); } }, (err) => { diff --git a/src/features/parameterHintsSupport.ts b/src/features/parameterHintsSupport.ts index 9d3de384a5..37cdc227d8 100644 --- a/src/features/parameterHintsSupport.ts +++ b/src/features/parameterHintsSupport.ts @@ -9,7 +9,7 @@ import Proto = require('../protocol'); import PowershellService = require('../powershellService'); import Previewer = require('./previewer'); -class ParameterHintsSupport implements vscode.Modes.IParameterHintsSupport { +class ParameterHintsSupport implements vscode.SignatureHelpProvider { public triggerCharacters:string[] = ['(', ',','"','-']; public excludeTokens:string[] = ['string']; @@ -20,41 +20,32 @@ class ParameterHintsSupport implements vscode.Modes.IParameterHintsSupport { this.client = client; } - public getParameterHints(document:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideSignatureHelp(document:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken):Promise { var args:Proto.SignatureHelpRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve(null); + return Promise.resolve(null); } return this.client.execute('signatureHelp', args).then((response) => { var info = response.body; if (!info) { return null; } - var result = { - currentSignature: 0, - currentParameter: 0, - signatures: [] - }; + + var result = new vscode.SignatureHelp(); + result.activeSignature = info.selectedItemIndex; + result.activeParameter = info.argumentIndex; + info.items.forEach(item => { - var signature = { - label: info.commandName += ' ', - documentation: null, - parameters: [] - }; + var signature = new vscode.SignatureInformation(''); + signature.label += info.commandName + ' '; var paramlabel = item.signatureText; - var parameter = { - label: paramlabel, - documentation: null, - signatureLabelOffset: signature.label.length, - signatureLabelEnd: signature.label.length + paramlabel.length - }; + var parameter = new vscode.ParameterInformation(item.signatureText, ''); + signature.label += paramlabel; signature.parameters.push(parameter); diff --git a/src/features/referenceSupport.ts b/src/features/referenceSupport.ts index ba25d4bbef..09de1b2071 100644 --- a/src/features/referenceSupport.ts +++ b/src/features/referenceSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class ReferenceSupport implements vscode.Modes.IReferenceSupport { +class ReferenceSupport implements vscode.ReferenceProvider { private client: PowershellService.IPowershellServiceClient; @@ -18,27 +18,25 @@ class ReferenceSupport implements vscode.Modes.IReferenceSupport { this.client = client; } - public findReferences(document: vscode.TextDocument, position: vscode.Position, includeDeclaration:boolean, token: vscode.CancellationToken): Promise { + public provideReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Promise { var args: Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } return this.client.execute('references', args, token).then((msg) => { - var result: vscode.Modes.IReference[] = []; + var result: vscode.Location[] = []; var refs = msg.body.refs; for (var i = 0; i < refs.length; i++) { var ref = refs[i]; var url = this.client.asUrl(ref.file); - result.push({ - resource: url, - range: new vscode.Range(ref.start.line, ref.start.offset, ref.end.line, ref.end.offset) - }); + result.push( + new vscode.Location( + url, + new vscode.Range(ref.start.line - 1, ref.start.offset - 1, ref.end.line - 1, ref.end.offset - 1))); } return result; }, () => { diff --git a/src/features/suggestSupport.ts b/src/features/suggestSupport.ts index 4fdd747831..39f9b05a1f 100644 --- a/src/features/suggestSupport.ts +++ b/src/features/suggestSupport.ts @@ -9,38 +9,72 @@ import vscode = require('vscode'); import Previewer = require('./previewer'); import Proto = require('../protocol'); import PConst = require('../protocol.const'); -import Configuration = require('./configuration'); import PowershellService = require('../powershellService'); -class SuggestSupport implements vscode.Modes.ISuggestSupport { +class PowerShellCompletionItem extends vscode.CompletionItem { + + document: vscode.TextDocument; + position: vscode.Position; + + constructor(entry: Proto.CompletionEntry) { + super(entry.name); + this.sortText = entry.sortText; + this.kind = PowerShellCompletionItem.convertKind(entry.kind); + } + + private static convertKind(kind: string): vscode.CompletionItemKind { + switch (kind) { + case PConst.Kind.primitiveType: + case PConst.Kind.keyword: + return vscode.CompletionItemKind.Keyword; + case PConst.Kind.variable: + case PConst.Kind.localVariable: + return vscode.CompletionItemKind.Variable; + case PConst.Kind.memberVariable: + case PConst.Kind.memberGetAccessor: + case PConst.Kind.memberSetAccessor: + return vscode.CompletionItemKind.Field; + case PConst.Kind.function: + case PConst.Kind.memberFunction: + case PConst.Kind.constructSignature: + case PConst.Kind.callSignature: + case PConst.Kind.indexSignature: + return vscode.CompletionItemKind.Function; + case PConst.Kind.enum: + return vscode.CompletionItemKind.Enum; + case PConst.Kind.module: + return vscode.CompletionItemKind.Module; + case PConst.Kind.class: + return vscode.CompletionItemKind.Class; + case PConst.Kind.interface: + return vscode.CompletionItemKind.Interface; + } + + return vscode.CompletionItemKind.Property; + } +} + +class SuggestSupport implements vscode.CompletionItemProvider { public triggerCharacters = ['.','$','-']; public excludeTokens = ['string', 'comment', 'numeric']; public sortBy = [{ type: 'reference', partSeparator: '/' }]; private client: PowershellService.IPowershellServiceClient; - private config:Configuration.IConfiguration; constructor(client: PowershellService.IPowershellServiceClient) { this.client = client; - this.config = Configuration.defaultConfiguration; - } - - public setConfiguration(config: Configuration.IConfiguration): void { - this.config = config; } - public suggest(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { - var filepath = this.client.asAbsolutePath(document.getUri()); + public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + var filepath = this.client.asAbsolutePath(document.uri); var args: Proto.CompletionsRequestArgs = { file: filepath, - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } // Need to capture the word at position before we send the request. @@ -62,100 +96,68 @@ class SuggestSupport implements vscode.Modes.ISuggestSupport { // }); // isMemberCompletion = value === '.'; // } - - var suggests:vscode.Modes.ISuggestion[] = []; + + var completionItems: vscode.CompletionItem[] = []; var body = msg.body; - // sort by CompletionEntry#sortText - // TODO: Uncomment this? - //msg.body.sort(SuggestSupport.bySortText); - for (var i = 0; i < body.length; i++) { var element = body[i]; - suggests.push({ - label: element.name, - codeSnippet: element.name, - type: this.monacoTypeFromEntryKind(element.kind) - }); + var item = new PowerShellCompletionItem(element); + item.document = document; + item.position = position; + + completionItems.push(item); } - var currentWord = ''; - if (wordRange) { - currentWord = document.getTextInRange(new vscode.Range(wordRange.start, position)); - } - return [{ - currentWord: currentWord, - suggestions: suggests - }]; + + return completionItems; + }, (err:Proto.CompletionsResponse) => { return []; }); } + + public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): any | Thenable { + if (item instanceof PowerShellCompletionItem) { + + var args: Proto.CompletionDetailsRequestArgs = { + file: this.client.asAbsolutePath(item.document.uri), + line: item.position.line + 1, + offset: item.position.character + 1, + entryNames: [item.label] + }; + return this.client.execute('completionEntryDetails', args, token).then((response) => { + var details = response.body; + if (details && details.length > 0) { + var detail = details[0]; + item.documentation = Previewer.plain(detail.documentation); + item.detail = Previewer.plain(detail.displayParts); + } - public getSuggestionDetails(document:vscode.TextDocument, position:vscode.Position, suggestion:vscode.Modes.ISuggestion, token: vscode.CancellationToken): Promise { - if(suggestion.type === 'snippet') { - return Promise.resolve(suggestion); - } - - var args: Proto.CompletionDetailsRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1, - line: position.line, - offset: position.character, - entryNames: [ - suggestion.label - ] - }; - return this.client.execute('completionEntryDetails', args).then((response) => { - var details = response.body; - if (details && details.length > 0) { - var detail = details[0]; - suggestion.documentationLabel = Previewer.plain(detail.documentation); - suggestion.typeLabel = Previewer.plain(detail.displayParts); - } + if (item.kind === vscode.CompletionItemKind.Function) { + var codeSnippet = detail.name, + suggestionArgumentNames: string[]; - if (this.monacoTypeFromEntryKind(detail.kind) === 'function') { - var codeSnippet = detail.name, - suggestionArgumentNames: string[]; + // suggestionArgumentNames = detail.displayParts + // .filter(part => part.kind === 'parameterName') + // .map(part => `{{${part.text}}}`); - suggestionArgumentNames = detail.displayParts - .filter(part => part.kind === 'parameterName') - .map(part => `{{${part.text}}}`); + if (suggestionArgumentNames.length > 0) { + codeSnippet += '(' + suggestionArgumentNames.join(', ') + '){{}}'; + } else { + codeSnippet += '()'; + } - if (suggestionArgumentNames.length > 0) { - codeSnippet += '(' + suggestionArgumentNames.join(', ') + '){{}}'; - } else { - codeSnippet += '()'; + item.insertText = codeSnippet; } - suggestion.codeSnippet = codeSnippet; - } - return suggestion; - }, (err:Proto.CompletionDetailsResponse) => { - return suggestion; - }); - } - private monacoTypeFromEntryKind(kind:string):string { - switch(kind) { - case PConst.Kind.primitiveType: - case PConst.Kind.keyword: - return 'keyword'; + return item; - case PConst.Kind.variable: - case PConst.Kind.localVariable: - case PConst.Kind.memberVariable: - case PConst.Kind.memberGetAccessor: - case PConst.Kind.memberSetAccessor: - return 'field'; + }, (err:Proto.CompletionDetailsResponse) => { + return item; + }); - case PConst.Kind.function: - case PConst.Kind.memberFunction: - case PConst.Kind.constructSignature: - case PConst.Kind.callSignature: - return 'function'; } - return kind; - } + } private static bySortText(a: Proto.CompletionEntry, b: Proto.CompletionEntry): number { return a.sortText.localeCompare(b.sortText); diff --git a/src/powershellDef.ts b/src/powershellDef.ts deleted file mode 100644 index 8e0498bcc2..0000000000 --- a/src/powershellDef.ts +++ /dev/null @@ -1,120 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - -'use strict'; - -import vscode = require('vscode'); - -export var language = { - displayName: 'PowerShell', - name: 'ps1', - defaultToken: '', - ignoreCase: true, - - lineComment: '#', - blockCommentStart: '<#', - blockCommentEnd: '#>', - - // the default separators except `$-` - wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, - - brackets: [ - { token: 'delimiter.curly', open: '{', close: '}' }, - { token: 'delimiter.square', open: '[', close: ']' }, - { token: 'delimiter.parenthesis', open: '(', close: ')' }], - - enhancedBrackets: [ - { tokenType:'string', openTrigger: '"', open: /@"$/, closeComplete: '"@' }, - { tokenType:'string', openTrigger: '\'', open: /@'$/, closeComplete: '\'@' }, - { tokenType:'string', openTrigger: '"', open: /"$/, closeComplete: '"' }, - { tokenType: 'string', openTrigger: '\'', open: /'$/, closeComplete: '\'' } - ], - - autoClosingPairs: [['{', '}'], ['[', ']'], ['(', ')']], // Defined explicitly, to suppress the - // default auto-closing of ' and " which is - // override above by enhancedBrackets - - keywords: [ - 'begin', 'break', 'catch', 'class', 'continue', 'data', - 'define', 'do', 'dynamicparam', 'else', 'elseif', 'end', - 'exit', 'filter', 'finally', 'for', 'foreach', 'from', - 'function', 'if', 'in', 'param', 'process', 'return', - 'switch', 'throw', 'trap', 'try', 'until', 'using', - 'var', 'while', 'workflow', 'parallel', 'sequence', 'inlinescript', 'configuration' - ], - - helpKeywords: /SYNOPSIS|DESCRIPTION|PARAMETER|EXAMPLE|INPUTS|OUTPUTS|NOTES|LINK|COMPONENT|ROLE|FUNCTIONALITY|FORWARDHELPTARGETNAME|FORWARDHELPCATEGORY|REMOTEHELPRUNSPACE|EXTERNALHELP/, - - // we include these common regular expressions - symbols: /[=>/, 'comment', '@pop'], - [/(\.)(@helpKeywords)(?!\w)/, { token: 'comment.keyword.$2' } ], - [/[\.#]/, 'comment' ] - ], - }, -}; \ No newline at end of file diff --git a/src/powershellMain.ts b/src/powershellMain.ts index bd734b421f..d5b9b89393 100644 --- a/src/powershellMain.ts +++ b/src/powershellMain.ts @@ -7,9 +7,7 @@ import vscode = require('vscode'); import PowershellService = require('./powershellService'); -import PowerShellDef = require("./powerShellDef"); //import ExtraInfoSupport = require('./features/extraInfoSupport'); -import CommentsSupport = require('./features/commentsSupport'); import OccurrencesSupport = require('./features/occurrencesSupport'); import ParameterHintsSupport = require('./features/parameterHintsSupport'); import BufferSyncSupport = require('./features/bufferSyncSupport'); @@ -26,51 +24,61 @@ export function activate(subscriptions: vscode.Disposable[]): void { var MODE_ID = 'PowerShell'; var clientHost = new PowershellServiceClientHost(); var client = clientHost.serviceClient; - - subscriptions.push( - vscode.Modes.registerMonarchDefinition('PowerShell', PowerShellDef.language)); - - vscode.Modes.TokenTypeClassificationSupport.register(MODE_ID, { - wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g - }); - vscode.Modes.ElectricCharacterSupport.register(MODE_ID, { + + vscode.languages.setLanguageConfiguration(MODE_ID, + { + wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g, + + indentationRules: { + // ^(.*\*/)?\s*\}.*$ + decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/, + // ^.*\{[^}"']*$ + increaseIndentPattern: /^.*\{[^}"']*$/ + }, + + comments: { + lineComment: '#', + blockComment: ['<#', '#>'] + }, + brackets: [ - { tokenType:'delimiter.curly.ts', open: '{', close: '}', isElectric: true }, - { tokenType:'delimiter.square.ts', open: '[', close: ']', isElectric: true }, - { tokenType:'delimiter.paren.ts', open: '(', close: ')', isElectric: true } + ['{', '}'], + ['[', ']'], + ['(', ')'], ], - docComment: { scope:'comment.documentation', open:'/**', lineStart:' * ', close:' */' } - }); - vscode.Modes.CharacterPairSupport.register(MODE_ID, { - autoClosingPairs: [ - { open: '{', close: '}' }, - { open: '[', close: ']' }, - { open: '(', close: ')' }, - { open: '"', close: '"', notIn: ['string'] }, - { open: '\'', close: '\'', notIn: ['string', 'comment'] } - ] + + __electricCharacterSupport: { + brackets: [ + { tokenType:'delimiter.curly.ts', open: '{', close: '}', isElectric: true }, + { tokenType:'delimiter.square.ts', open: '[', close: ']', isElectric: true }, + { tokenType:'delimiter.paren.ts', open: '(', close: ')', isElectric: true } + ], + docComment: { scope:'comment.documentation', open:'/**', lineStart:' * ', close:' */' } + }, + + __characterPairSupport: { + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '"', close: '"', notIn: ['string'] }, + { open: '\'', close: '\'', notIn: ['string', 'comment'] } + ] + } + }); - + //vscode.languages.registerHoverProvider(MODE_ID, new ExtraInfoSupport(client)); - vscode.Modes.CommentsSupport.register(MODE_ID, new CommentsSupport()); - //vscode.languages.registerDefinitionProvider(MODE_ID, new DeclarationSupport(client)); - //vscode.languages.registerDocumentHighlightProvider(MODE_ID, new OccurrencesSupport(client)); - vscode.Modes.DeclarationSupport.register(MODE_ID, new DeclarationSupport(client)); - vscode.Modes.OccurrencesSupport.register(MODE_ID, new OccurrencesSupport(client)); - vscode.Modes.ParameterHintsSupport.register(MODE_ID, new ParameterHintsSupport(client)); - //vscode.languages.registerReferenceProvider(MODE_ID, new ReferenceSupport(client)); + vscode.languages.registerDefinitionProvider(MODE_ID, new DeclarationSupport(client)); + vscode.languages.registerDocumentHighlightProvider(MODE_ID, new OccurrencesSupport(client)); + vscode.languages.registerSignatureHelpProvider(MODE_ID, new ParameterHintsSupport(client)); + vscode.languages.registerReferenceProvider(MODE_ID, new ReferenceSupport(client)); //vscode.languages.registerWorkspaceSymbolProvider(new NavigateTypeSupport(client, MODE_ID)); - vscode.Modes.ReferenceSupport.register(MODE_ID, new ReferenceSupport(client)); - vscode.Modes.NavigateTypesSupport.register(MODE_ID, new NavigateTypeSupport(client, MODE_ID)); clientHost.addBufferSyncSupport(new BufferSyncSupport(client, MODE_ID)); var suggestSupport = new SuggestSupport(client); - vscode.Modes.SuggestSupport.register(MODE_ID, suggestSupport); - - Configuration.load(MODE_ID).then((config) => { - suggestSupport.setConfiguration(config); - }); + vscode.languages.registerCompletionItemProvider(MODE_ID, suggestSupport, '.'); } class PowershellServiceClientHost implements PowershellService.IPowershellServiceClientHost { @@ -78,7 +86,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic private client: PowershellServiceClient; private syntaxDiagnostics: {[key:string]:vscode.Diagnostic[];}; - private currentDiagnostics: { [key: string]: vscode.Disposable }; + private currentDiagnostics: vscode.DiagnosticCollection; private bufferSyncSupports: BufferSyncSupport[]; constructor() { @@ -99,7 +107,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic this.client = new PowershellServiceClient(this); this.syntaxDiagnostics = Object.create(null); - this.currentDiagnostics = Object.create(null); + this.currentDiagnostics = vscode.languages.createDiagnosticCollection('PowerShell'); } public addBufferSyncSupport(support: BufferSyncSupport): void { @@ -117,7 +125,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic /* internal */ syntaxDiagnosticsReceived(event:Proto.DiagnosticEvent):void { var body = event.body; if (body.diagnostics) { - var markers = this.createMarkerDatas(body.file, body.diagnostics); + var markers = this.createMarkerDatas(body.diagnostics); this.syntaxDiagnostics[body.file] = markers; } } @@ -125,45 +133,25 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic /* internal */ semanticDiagnosticsReceived(event:Proto.DiagnosticEvent):void { var body = event.body; if (body.diagnostics) { - var diagnostics = this.createMarkerDatas(body.file, body.diagnostics); + var diagnostics = this.createMarkerDatas(body.diagnostics); var syntaxMarkers = this.syntaxDiagnostics[body.file]; if (syntaxMarkers) { delete this.syntaxDiagnostics[body.file]; diagnostics = syntaxMarkers.concat(diagnostics); } - this.currentDiagnostics[body.file] && this.currentDiagnostics[body.file].dispose(); - this.currentDiagnostics[body.file] = vscode.languages.addDiagnostics(diagnostics); + + this.currentDiagnostics.set(vscode.Uri.file(body.file), diagnostics); } } - private createMarkerDatas(fileName: string, diagnostics: Proto.Diagnostic[]): vscode.Diagnostic[] { + private createMarkerDatas(diagnostics: Proto.Diagnostic[]): vscode.Diagnostic[] { let result: vscode.Diagnostic[] = []; for (let diagnostic of diagnostics) { - let uri = vscode.Uri.file(fileName); let {start, end, text} = diagnostic; - //let range = new vscode.Range(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1); - let range = new vscode.Range(start.line, start.offset, end.line, end.offset); - let location = new vscode.Location(uri, range); + let range = new vscode.Range(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1); - result.push(new vscode.Diagnostic(diagnostic.severity, location, text, 'powershell')); + result.push(new vscode.Diagnostic(range, text)); } return result; } - - // private createMarkerDatas(diagnostics:Proto.Diagnostic[]):vscode.Services.IMarkerData[] { - // var markers: vscode.Services.IMarkerData[] = []; - // for (var i = 0; i < diagnostics.length; i++) { - // var diagnostic = diagnostics[i]; - // var marker:vscode.Services.IMarkerData = { - // severity: diagnostic.severity, - // message: diagnostic.text, - // startLineNumber: diagnostic.start.line, - // startColumn: diagnostic.start.offset, - // endLineNumber: diagnostic.end.line, - // endColumn : diagnostic.end.offset - // }; - // markers.push(marker); - // } - // return markers; - // } } diff --git a/src/powershellServiceClient.ts b/src/powershellServiceClient.ts index 9e564d60be..a270cc3c23 100644 --- a/src/powershellServiceClient.ts +++ b/src/powershellServiceClient.ts @@ -88,73 +88,74 @@ class PowershellServiceClient implements PowershellService.IPowershellServiceCli private startService(): void { this.servicePromise = new Promise((resolve, reject) => { - configuration.load('PowerShell').then(config => { - //vscode.extensions.getConfigurationMemento('PowerShell').getValue('editorServicesHostPath').then(editorServicesHostPath => { - var editorServicesHostPath = config.editorServicesHostPath; - - PowershellServiceClient.Trace = true; //config.enableLogging; - console.log("-- PowerShell logging enabled? " + PowershellServiceClient.Trace); + var config = configuration.load('PowerShell'); + var editorServicesHostPath = config.editorServicesHostPath; + + PowershellServiceClient.Trace = config.enableLogging; + console.log("POWERSHELL> Logging enabled: " + PowershellServiceClient.Trace); + + if (config.editorServicesHostPath) + { + this.log("Found Editor Services path from config: " + editorServicesHostPath); + + // Make the path absolute if it's not + editorServicesHostPath = + path.resolve( + __dirname, + config.editorServicesHostPath); + + this.log(" Resolved path to: " + editorServicesHostPath); + } + else + { + // Use the default path in the plugin's 'bin' folder + editorServicesHostPath = + path.join( + __dirname, + '..', + 'bin', + 'Microsoft.PowerShell.EditorServices.Host.exe'); + + this.log("Using default Editor Services path: " + editorServicesHostPath); + } + + var childProcess:cp.ChildProcess = null; + try { + var args: string[]; - if (config.editorServicesHostPath) + if (config.waitForDebugger) { - // Make the path absolute if it's not - editorServicesHostPath = - path.resolve( - config.editorServicesHostPath); - - this.log("Found Editor Services path from config: " + editorServicesHostPath); + args = ['/waitForDebugger']; + this.log("Language service will wait for debugger after launching."); } - else - { - // Use the default path in the plugin's 'bin' folder - editorServicesHostPath = - path.join( - __dirname, - '..', - 'bin', - 'Microsoft.PowerShell.EditorServices.Host.exe'); - - this.log("Using default Editor Services path: " + editorServicesHostPath); - } - - var childProcess:cp.ChildProcess = null; - try { - var args: string[]; - - if (config.waitForDebugger) - { - args = ['/waitForDebugger']; - this.log("Language service will wait for debugger after launching."); - } - - if (isWin) { - childProcess = cp.spawn(editorServicesHostPath, args); - - } /*else if (isDarwin) { - childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/osx/node'), args); - } else if (isLinux && arch === 'x64') { - childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/linux/x64/node'), args); - }*/ - - childProcess.on('error', (err:Error) => { - this.lastError = err; - this.serviceExited(); - }); - childProcess.on('exit', (err:Error) => { - this.serviceExited(); - }); - this.reader = new WireProtocol.Reader(childProcess.stdout, (msg) => { - this.dispatchMessage(msg); - }); - - this.log("Finished spawning language service."); - - resolve(childProcess); - } catch (error) { - this.log("Failed to launch the language service! -> " + error); - reject(error); - } - }); + + if (isWin) { + childProcess = cp.spawn(editorServicesHostPath, args); + + } /*else if (isDarwin) { + childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/osx/node'), args); + } else if (isLinux && arch === 'x64') { + childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/linux/x64/node'), args); + }*/ + + childProcess.on('error', (err:Error) => { + this.lastError = err; + this.serviceExited(); + }); + childProcess.on('exit', (err:Error) => { + this.serviceExited(); + }); + this.reader = new WireProtocol.Reader(childProcess.stdout, (msg) => { + this.dispatchMessage(msg); + }); + + this.log("Finished spawning language service."); + + resolve(childProcess); + } catch (error) { + this.log("Failed to launch the language service! -> " + error); + reject(error); + } }); } diff --git a/typings/vscode-typings.d.ts b/typings/vscode-typings.d.ts index 379fb23d39..ae9f2e5cad 100644 --- a/typings/vscode-typings.d.ts +++ b/typings/vscode-typings.d.ts @@ -1,7 +1,4 @@ -// TODO: Re-enable this once we're building against the shipped 0.10.0 typings -/* */ - -// TODO: Remove these once we move back to the packaged typings +/// /// /// /// diff --git a/typings/vscode.d.ts b/typings/vscode.d.ts deleted file mode 100644 index a845e5bfa3..0000000000 --- a/typings/vscode.d.ts +++ /dev/null @@ -1,1309 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - - -declare module 'vscode' { - - // TODO@api - // Naming: Command, Action, ... - - /** - * The command callback. - */ - export interface CommandCallback { - - /** - * - */ - (...args:any[]):T | Thenable; - } - - /** - * Namespace for commanding - */ - export namespace commands { - - /** - * Registers a command that can be invoked via a keyboard shortcut, - * an menu item, an action, or directly. - * - * @param command - The unique identifier of this command - * @param callback - The command callback - * @param thisArgs - (optional) The this context used when invoking {{callback}} - * @return Disposable which unregisters this command on disposal - */ - export function registerCommand(command: string, callback: CommandCallback, thisArg?: any): Disposable; - - /** - * Register a text editor command that will make edits. - * It can be invoked via a keyboard shortcut, a menu item, an action, or directly. - * - * @param command - The unique identifier of this command - * @param callback - The command callback. The {{textEditor}} and {{edit}} passed in are available only for the duration of the callback. - * @param thisArgs - (optional) The `this` context used when invoking {{callback}} - * @return Disposable which unregisters this command on disposal - */ - export function registerTextEditorCommand(command: string, callback: (textEditor:TextEditor, edit:TextEditorEdit) => void, thisArg?: any): Disposable; - - /** - * Executes a command - * - * @param command - Identifier of the command to execute - * @param ...rest - Parameter passed to the command function - * @return - */ - export function executeCommand(command: string, ...rest: any[]): Thenable; - } - - export interface TextEditorOptions { - tabSize: number; - insertSpaces: boolean; - } - - export class TextDocument { - - constructor(uri: Uri, lines: string[], eol: string, languageId: string, versionId: number, isDirty:boolean); - - /** - * Get the associated URI for this document. Most documents have the file:// scheme, indicating that they represent files on disk. - * However, some documents may have other schemes indicating that they are not available on disk. - */ - getUri(): Uri; - - /** - * Returns the file system path of the file associated with this document. Shorthand - * notation for ```TextDocument.getUri().fsPath``` - */ - getPath(): string; - - /** - * Is this document representing an untitled file. - */ - isUntitled(): boolean; - - isDirty(): boolean; - - save(): Thenable; - - /** - * The language identifier associated with this document. - */ - getLanguageId(): string; - - /** - * The version number of this document (it will strictly increase after each change). - */ - getVersionId(): number; - - /** - * Get the entire text in this document. - */ - getText(): string; - - /** - * Get the text in a specific range in this document. - */ - getTextInRange(range: Range): string; - - /** - * Get the text on a specific line in this document. - */ - getTextOnLine(line:number): string; - - /** - * Ensure a range sticks to the text. - */ - validateRange(range:Range): Range; - - /** - * Ensure a position sticks to the text. - */ - validatePosition(position:Position): Position; - - /** - * Get the number of lines in this document. - */ - getLineCount(): number; - - /** - * Get the maximum column for line {{line}}. - */ - getLineMaxColumn(line:number): number; - - /** - * Get the word under a certain position. May return null if position is at whitespace, on empty line, etc. - */ - getWordRangeAtPosition(position:Position): Range; - } - - export class Position { - - line: number; - - character: number; - - constructor(line: number, character: number); - - isBefore(other: Position): boolean; - - isBeforeOrEqual(other: Position): boolean; - } - - export class Range { - - start: Position; - - end: Position; - - constructor(start: Position, end: Position); - constructor(startLine: number, startColumn: number, endLine:number, endColumn:number); - - contains(positionOrRange: Position | Range): boolean; - - /** - * @return `true` iff `start` and `end` are equal - */ - isEmpty(): boolean; - - /** - * @return `true` iff start and end are on the same line - */ - isOneLine(): boolean; - } - - export class Selection extends Range { - - anchor: Position; - - active: Position; - - constructor(anchor: Position, active: Position); - constructor(anchorLine: number, anchorColumn: number, activeLine:number, activeColumn:number); - - isReversed(): boolean; - } - - export class TextEditor { - - constructor(document: TextDocument, selections: Selection[], options: TextEditorOptions); - - dispose(); - - /** - * Get the document associated with this text editor. The document will be the same for the entire lifetime of this text editor. - */ - getTextDocument(): TextDocument; - - /** - * Get the primary selection on this text editor. In case the text editor has multiple selections, the first one will be returned. - */ - getSelection(): Selection; - - /** - * Set the selection on this text editor. - */ - setSelection(value: Position | Range | Selection): Thenable; - - /** - * Get the selections in this text editor. - */ - getSelections(): Selection[]; - - /** - * Set the selections in this text editor. - */ - setSelections(value: Selection[]): Thenable; - - /** - * Get text editor options. - */ - getOptions(): TextEditorOptions; - - /** - * Change text editor options. - */ - setOptions(options: TextEditorOptions): Thenable; - - /** - * Perform an edit on the document associated with this text editor. - * The passed in {{editBuilder}} is available only for the duration of the callback. - */ - edit(callback:(editBuilder:TextEditorEdit)=>void): Thenable; - - } - - /** - * A complex edit that will be applied on a TextEditor. - * This holds a description of the edits and if the edits are valid (i.e. no overlapping regions, etc.) they can be applied on a Document associated with a TextEditor. - */ - export interface TextEditorEdit { - /** - * Replace a certain text region with a new value. - */ - replace(location: Position | Range | Selection, value: string): void; - - /** - * Insert text at a location - */ - insert(location: Position, value: string): void; - - /** - * Delete a certain text region. - */ - delete(location: Range | Selection): void; - - } - - /** - * A universal resource identifier representing either a file on disk on - * or another resource, e.g untitled. - */ - class Uri { - - constructor(); - static parse(path: string): Uri; - static file(path: string): Uri; - static create(path: string): Uri; - - /** - * scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'. - * The part before the first colon. - */ - scheme: string; - - - /** - * authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'. - * The part between the first double slashes and the next slash. - */ - authority: string; - - - /** - * path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'. - */ - path: string; - - /** - * query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'. - */ - query: string; - - /** - * fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'. - */ - fragment: string; - - /** - * Retuns a string representing the corresponding file system path of this URI. - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this URI. - */ - fsPath: string; - - /** - * Returns a canonical representation of this URI. The representation and normalization - * of a URI depends on the scheme. - */ - toString(): string; - - toJSON(): any; - } - - interface CancellationToken { - isCancellationRequested: boolean; - onCancellationRequested: Event; - } - - class CancellationTokenSource { - - token: CancellationToken; - - cancel(): void; - - dispose(): void; - } - - /** - * Represents a type which can release resources, such - * as event listening or a timer. - */ - class Disposable { - - /** - * Combine many disposables into one. - * - * @return Returns a new disposable which, upon dispose, will - * dispose all provided disposables - */ - static of(...disposables: Disposable[]): Disposable; - - /** - * Combine many disposable-likes into one. Use this method - * when having objects with a dispose function which are not - * instances of Disposable. - * - * @return Returns a new disposable which, upon dispose, will - * dispose all provides disposable-likes. - */ - static from(...disposableLikes: { dispose: () => any }[]): Disposable; - - /** - * Creates a new Disposable calling the provided function - * on dispose - * @param callOnDispose Function that disposes something - */ - constructor(callOnDispose: Function); - - /** - * Dispose this object. - */ - dispose(): any; - } - - /** - * Represents a typed event. - */ - interface Event { - - /** - * - * @param listener The listener function will be call when the event happens. - * @param thisArgs The 'this' which will be used when calling the event listener. - * @param disposables An array to which a {{IDisposable}} will be added. The - * @return - */ - (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; - } - - /** - * A file system watcher notifies about changes to files and folders - * on disk. To get an instanceof of a {{FileSystemWatcher}} use - * {{workspace.createFileSystemWatcher}}. - */ - export interface FileSystemWatcher extends Disposable { - - /** - * Happens on file/folder creation. - */ - onDidCreate: Event; - - /** - * Happens on file/folder change. - */ - onDidChange: Event; - - /** - * Happens on file/folder deletion. - */ - onDidDelete: Event; - } - - /** - * - */ - export interface QuickPickOptions { - /** - * an optional flag to include the description when filtering the picks - */ - matchOnDescription?: boolean; - - /** - * an optional string to show as place holder in the input box to guide the user what she picks on - */ - placeHolder?: string; - } - - /** - * - */ - export interface QuickPickItem { - label: string; - description: string; - } - - /** - * - */ - export interface InputBoxOptions { - /** - * The text to display underneath the input box. - */ - prompt?: string; - - /** - * an optional string to show as place holder in the input box to guide the user what to type - */ - placeHolder?: string; - } - - /** - * - */ - interface LanguageFilter { - language?: string; - scheme?: string; - pattern?: string; - } - - /** - * - */ - type LanguageSelector = string|LanguageFilter|(string|LanguageFilter)[]; - - - /** - * - */ - interface ReadOnlyMemento { - - /** - * @param key The name of a property to read. - * @param defaultValue The default value in case the denoted property doesn't exists. - * @return - */ - getValue(key: string, defaultValue?: T): Thenable; - - /** - * - */ - getValues(defaultValue?: T): Thenable; - } - - /** - * - */ - interface Memento extends ReadOnlyMemento { - setValue(key: string, value: any): Thenable; - } - - /** - * Represents the severity of diagnostics. - */ - export enum DiagnosticSeverity { - Warning = 1, - Error = 2 - } - - /** - * Represents a location inside a resource, such as a line - * inside a text file. - */ - export class Location { - constructor(uri: Uri, range: Selection | Range | Position); - uri: Uri; - range: Range; - } - - /** - * Represents a diagnostic, such as a compiler error or warning, along with the location - * in which they occurred. - */ - export class Diagnostic { - - constructor(severity: DiagnosticSeverity, location: Location, message: string, source?:string); - - severity: DiagnosticSeverity; - - location: Location; - - message: string; - - source: string; - } - - // TODO@api, TODO@Joh,Ben - // output channels need to be known upfront (contributes in package.json) - export interface OutputChannel extends Disposable { - append(value: string): void; - appendLine(value: string): void; - clear(): void; - reveal(): void; - } - - export interface ExecutionOptions { - cwd?: string; - env?: { [name: string]: any }; - } - - export interface TextEditorSelectionChangeEvent { - textEditor: TextEditor; - selections: Selection[]; - } - - export interface TextEditorOptionsChangeEvent { - textEditor: TextEditor; - options: TextEditorOptions; - } - - export interface ITelemetryInfo { - sessionId: string; - machineId: string; - instanceId: string; - } - - export namespace window { - - export function getActiveTextEditor(): TextEditor; - - export const onDidChangeActiveTextEditor: Event; - - export const onDidChangeTextEditorSelection: Event; - - export const onDidChangeTextEditorOptions: Event; - - export function showInformationMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function showWarningMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function showErrorMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function setStatusBarMessage(message: string, hideAfterSeconds?: number): Disposable; - - export function showQuickPick(items: string[], options?: QuickPickOptions): Thenable; - - export function showQuickPick(items: T[], options?: QuickPickOptions): Thenable; - - /** - * Opens an input box to ask the user for input. - */ - export function showInputBox(options?: InputBoxOptions): Thenable; - - export function getOutputChannel(name: string): OutputChannel; - - /** - * ✂ - don't use. Will be cut soone! - TODO@api move into a node_module - */ - export function runInTerminal(command: string, args: string[], options?: ExecutionOptions): Thenable; - } - - /** - * An event describing a change in the text of a model. - */ - export interface TextDocumentContentChangeEvent { - /** - * The range that got replaced. - */ - range: Range; - /** - * The length of the range that got replaced. - */ - rangeLength: number; - /** - * The new text for the range. - */ - text: string; - } - - export interface TextDocumentChangeEvent { - document: TextDocument; - contentChanges: TextDocumentContentChangeEvent[]; - } - - // TODO@api in the future there might be multiple opened folder in VSCode - // so that we shouldn't make broken assumptions here - export namespace workspace { - - /** - * Creates a file system watcher. A glob pattern that filters the - * file events must be provided. Optionally, flags to ignore certain - * kind of events can be provided. - * - * @param globPattern - A glob pattern that is applied to the names of created, changed, and deleted files. - * @param ignoreCreateEvents - Ignore when files have been created. - * @param ignoreChangeEvents - Ignore when files have been changed. - * @param ignoreDeleteEvents - Ignore when files have been deleted. - */ - export function createFileSystemWatcher(globPattern: string, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher; - - // TODO@api - justify this being here - export function getPath(): string; - - export function getRelativePath(pathOrUri: string|Uri): string; - - // TODO@api - justify this being here - export function findFiles(include: string, exclude: string, maxResults?:number): Thenable; - - /** - * save all dirty files - */ - export function saveAll(includeUntitled?: boolean): Thenable; - - export function getTextDocuments(): TextDocument[]; - export function getTextDocument(resource: Uri): TextDocument; - export const onDidOpenTextDocument: Event; - export const onDidCloseTextDocument: Event; - export const onDidChangeTextDocument: Event; - export const onDidSaveTextDocument: Event; - } - - export namespace languages { - - /** - * Add diagnostics, such as compiler errors or warnings. They will be represented as - * squiggles in text editors and in a list of diagnostics. - * To remove the diagnostics again, dispose the `Disposable` which is returned - * from this function call. - * - * @param diagnostics Array of diagnostics - * @return A disposable the removes the diagnostics again. - */ - export function addDiagnostics(diagnostics: Diagnostic[]): Disposable; - - /** - * - */ - export function addInformationLanguageStatus(language: LanguageSelector|Uri|Uri[], message: string | { octicon: string; message: string;}, command: string | CommandCallback): Disposable; - - /** - * - */ - export function addWarningLanguageStatus(language: LanguageSelector | Uri | Uri[], message: string | { octicon: string; message: string; }, command: string | CommandCallback): Disposable; - - /** - * - */ - export function addErrorLanguageStatus(language: LanguageSelector | Uri | Uri[], message: string | { octicon: string; message: string; }, command: string | CommandCallback): Disposable; - } - - export namespace extensions { - - export function getStateMemento(extensionId: string, global?: boolean): Memento; - - export function getConfigurationMemento(extensionId: string): ReadOnlyMemento; - - export function getExtension(extensionId: string): any; - - export function getTelemetryInfo(): Thenable; - } - - export interface IHTMLContentElement { - formattedText?:string; - text?: string; - className?: string; - style?: string; - customStyle?: any; - tagName?: string; - children?: IHTMLContentElement[]; - isText?: boolean; - } - - // --- Begin Monaco.Modes - module Modes { - interface ILanguage { - // required - name: string; // unique name to identify the language - tokenizer: Object; // map from string to ILanguageRule[] - - // optional - displayName?: string; // nice display name - ignoreCase?: boolean; // is the language case insensitive? - lineComment?: string; // used to insert/delete line comments in the editor - blockCommentStart?: string; // used to insert/delete block comments in the editor - blockCommentEnd?: string; - defaultToken?: string; // if no match in the tokenizer assign this token class (default 'source') - brackets?: ILanguageBracket[]; // for example [['{','}','delimiter.curly']] - - // advanced - start?: string; // start symbol in the tokenizer (by default the first entry is used) - tokenPostfix?: string; // attach this to every token class (by default '.' + name) - autoClosingPairs?: string[][]; // for example [['"','"']] - wordDefinition?: RegExp; // word definition regular expression - outdentTriggers?: string; // characters that could potentially cause outdentation - enhancedBrackets?: Modes.IRegexBracketPair[];// Advanced auto completion, auto indenting, and bracket matching - } - - /** - * This interface can be shortened as an array, ie. ['{','}','delimiter.curly'] - */ - interface ILanguageBracket { - open: string; // open bracket - close: string; // closeing bracket - token: string; // token class - } - - interface ILanguageAutoComplete { - triggers: string; // characters that trigger auto completion rules - match: string|RegExp; // autocomplete if this matches - complete: string; // complete with this string - } - - interface ILanguageAutoIndent { - match: string|RegExp; // auto indent if this matches on enter - matchAfter: string|RegExp; // and auto-outdent if this matches on the next line - } - - /** - * Standard brackets used for auto indentation - */ - export interface IBracketPair { - tokenType:string; - open:string; - close:string; - isElectric:boolean; - } - - /** - * Regular expression based brackets. These are always electric. - */ - export interface IRegexBracketPair { - openTrigger?: string; // The character that will trigger the evaluation of 'open'. - open: RegExp; // The definition of when an opening brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character). - closeComplete?: string; // How to complete a matching open brace. Matches from 'open' will be expanded, e.g. '' - matchCase?: boolean; // If set to true, the case of the string captured in 'open' will be detected an applied also to 'closeComplete'. - // This is useful for cases like BEGIN/END or begin/end where the opening and closing phrases are unrelated. - // For identical phrases, use the $1 replacement syntax above directly in closeComplete, as it will - // include the proper casing from the captured string in 'open'. - // Upper/Lower/Camel cases are detected. Camel case dection uses only the first two characters and assumes - // that 'closeComplete' contains wors separated by spaces (e.g. 'End Loop') - - closeTrigger?: string; // The character that will trigger the evaluation of 'close'. - close?: RegExp; // The definition of when a closing brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character). - tokenType?: string; // The type of the token. Matches from 'open' or 'close' will be expanded, e.g. 'keyword.$1'. - // Only used to auto-(un)indent a closing bracket. - } - - /** - * Definition of documentation comments (e.g. Javadoc/JSdoc) - */ - export interface IDocComment { - scope: string; // What tokens should be used to detect a doc comment (e.g. 'comment.documentation'). - open: string; // The string that starts a doc comment (e.g. '/**') - lineStart: string; // The string that appears at the start of each line, except the first and last (e.g. ' * '). - close?: string; // The string that appears on the last line and closes the doc comment (e.g. ' */'). - } - - // --- Begin InplaceReplaceSupport - /** - * Interface used to navigate with a value-set. - */ - interface IInplaceReplaceSupport { - sets: string[][]; - } - var InplaceReplaceSupport: { - register(modeId: string, inplaceReplaceSupport: Modes.IInplaceReplaceSupport): Disposable; - }; - // --- End InplaceReplaceSupport - - - // --- Begin TokenizationSupport - enum Bracket { - None = 0, - Open = 1, - Close = -1 - } - // --- End TokenizationSupport - - // --- Begin IDeclarationSupport - export interface IDeclarationSupport { - tokens?: string[]; - findDeclaration(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var DeclarationSupport: { - register(modeId: string, declarationSupport: IDeclarationSupport): Disposable; - }; - // --- End IDeclarationSupport - - // --- Begin ICodeLensSupport - export interface ICodeLensSupport { - findCodeLensSymbols(document: TextDocument, token: CancellationToken): Thenable; - findCodeLensReferences(document: TextDocument, requests: ICodeLensSymbolRequest[], token: CancellationToken): Thenable; - } - export interface ICodeLensSymbolRequest { - position: Position; - languageModeStateId?: number; - } - export interface ICodeLensSymbol { - range: Range; - } - export interface ICodeLensReferences { - references: IReference[][]; - languageModeStateId?: number; - } - var CodeLensSupport: { - register(modeId: string, codeLensSupport: ICodeLensSupport): Disposable; - }; - // --- End ICodeLensSupport - - // --- Begin IOccurrencesSupport - export interface IOccurrence { - kind?:string; - range:Range; - } - export interface IOccurrencesSupport { - findOccurrences(resource: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var OccurrencesSupport: { - register(modeId: string, occurrencesSupport:IOccurrencesSupport): Disposable; - }; - // --- End IOccurrencesSupport - - // --- Begin IOutlineSupport - export interface IOutlineEntry { - label: string; - type: string; - icon?: string; // icon class or null to use the default images based on the type - range: Range; - children?: IOutlineEntry[]; - } - export interface IOutlineSupport { - getOutline(document: TextDocument, token: CancellationToken): Thenable; - outlineGroupLabel?: { [name: string]: string; }; - } - var OutlineSupport: { - register(modeId: string, outlineSupport:IOutlineSupport): Disposable; - }; - // --- End IOutlineSupport - - // --- Begin IOutlineSupport - export interface IQuickFix { - label: string; - id: any; - score: number; - documentation?: string; - } - - export interface IQuickFixResult { - edits: IResourceEdit[]; - } - - export interface IQuickFixSupport { - getQuickFixes(resource: TextDocument, marker: Range, token: CancellationToken): Thenable; - runQuickFixAction(resource: TextDocument, range: Range, id: any, token: CancellationToken): Thenable; - } - var QuickFixSupport: { - register(modeId: string, quickFixSupport:IQuickFixSupport): Disposable - }; - // --- End IOutlineSupport - - // --- Begin IReferenceSupport - export interface IReferenceSupport { - tokens?: string[]; - - /** - * @returns a list of reference of the symbol at the position in the - * given resource. - */ - findReferences(document: TextDocument, position: Position, includeDeclaration: boolean, token: CancellationToken): Thenable; - } - var ReferenceSupport: { - register(modeId: string, quickFixSupport:IReferenceSupport): Disposable; - }; - // --- End IReferenceSupport - - // --- Begin IParameterHintsSupport - export interface IParameter { - label:string; - documentation?:string; - signatureLabelOffset?:number; - signatureLabelEnd?:number; - } - - export interface ISignature { - label:string; - documentation?:string; - parameters:IParameter[]; - } - - export interface IParameterHints { - currentSignature:number; - currentParameter:number; - signatures:ISignature[]; - } - - export interface IParameterHintsSupport { - /** - * On which characters presses should parameter hints be potentially shown. - */ - triggerCharacters: string[]; - - /** - * A list of token types that prevent the parameter hints from being shown (e.g. comment, string) - */ - excludeTokens: string[]; - /** - * @returns the parameter hints for the specified position in the file. - */ - getParameterHints(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var ParameterHintsSupport: { - register(modeId: string, parameterHintsSupport:IParameterHintsSupport): Disposable; - }; - // --- End IParameterHintsSupport - - // --- Begin IExtraInfoSupport - export interface IComputeExtraInfoResult { - range: Range; - value?: string; - htmlContent?: IHTMLContentElement[]; - className?: string; - } - export interface IExtraInfoSupport { - computeInfo(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var ExtraInfoSupport: { - register(modeId: string, extraInfoSupport:IExtraInfoSupport): Disposable; - }; - // --- End IExtraInfoSupport - - // --- Begin IRenameSupport - export interface IRenameResult { - currentName: string; - edits: IResourceEdit[]; - rejectReason?: string; - } - export interface IRenameSupport { - filter?: string[]; - rename(document: TextDocument, position: Position, newName: string, token: CancellationToken): Thenable; - } - var RenameSupport: { - register(modeId: string, renameSupport:IRenameSupport): Disposable; - }; - // --- End IRenameSupport - - // --- Begin IFormattingSupport - /** - * Interface used to format a model - */ - export interface IFormattingOptions { - tabSize:number; - insertSpaces:boolean; - } - /** - * A single edit operation, that acts as a simple replace. - * i.e. Replace text at `range` with `text` in model. - */ - export interface ISingleEditOperation { - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: Range; - /** - * The text to replace with. This can be null to emulate a simple delete. - */ - text: string; - } - /** - * Supports to format source code. There are three levels - * on which formatting can be offered: - * (1) format a document - * (2) format a selectin - * (3) format on keystroke - */ - export interface IFormattingSupport { - formatDocument: (document: TextDocument, options: IFormattingOptions, token: CancellationToken) => Thenable; - formatRange?: (document: TextDocument, range: Range, options: IFormattingOptions, token: CancellationToken) => Thenable; - autoFormatTriggerCharacters?: string[]; - formatAfterKeystroke?: (document: TextDocument, position: Position, ch: string, options: IFormattingOptions, token: CancellationToken) => Thenable; - } - var FormattingSupport: { - register(modeId: string, formattingSupport:IFormattingSupport): Disposable; - }; - // --- End IRenameSupport - - // --- Begin ISuggestSupport - export interface ISortingTypeAndSeparator { - type: string; - partSeparator?: string; - } - export interface IHighlight { - start:number; - end:number; - } - export interface ISuggestion { - label: string; - codeSnippet: string; - type: string; - highlights?: IHighlight[]; - typeLabel?: string; - documentationLabel?: string; - } - export interface ISuggestions { - currentWord:string; - suggestions:ISuggestion[]; - incomplete?: boolean; - overwriteBefore?: number; - overwriteAfter?: number; - } - export interface ISuggestSupport { - triggerCharacters: string[]; - excludeTokens: string[]; - - sortBy?: ISortingTypeAndSeparator[]; - - suggest: (document: TextDocument, position: Position, token: CancellationToken) => Thenable; - getSuggestionDetails? : (document: TextDocument, position: Position, suggestion:ISuggestion, token: CancellationToken) => Thenable; - } - var SuggestSupport: { - register(modeId:string, suggestSupport:ISuggestSupport): Disposable; - }; - // --- End ISuggestSupport - - // --- Start INavigateTypesSupport - - export interface ITypeBearing { - containerName: string; - name: string; - parameters: string; - type: string; - range: Range; - resourceUri: Uri; - } - - export interface INavigateTypesSupport { - getNavigateToItems:(search: string, token: CancellationToken) => Thenable; - } - var NavigateTypesSupport: { - register(modeId:string, navigateTypeSupport:INavigateTypesSupport): Disposable; - }; - - // --- End INavigateTypesSupport - - // --- Begin ICommentsSupport - export interface ICommentsSupport { - commentsConfiguration: ICommentsConfiguration; - } - export interface ICommentsConfiguration { - lineCommentTokens?:string[]; - blockCommentStartToken?:string; - blockCommentEndToken?:string; - } - var CommentsSupport: { - register(modeId:string, commentsSupport:ICommentsSupport): Disposable; - }; - // --- End ICommentsSupport - - // --- Begin ITokenTypeClassificationSupport - export interface ITokenTypeClassificationSupport { - wordDefinition?: RegExp; - } - var TokenTypeClassificationSupport: { - register(modeId:string, tokenTypeClassificationSupport:ITokenTypeClassificationSupport): Disposable; - }; - // --- End ITokenTypeClassificationSupport - - // --- Begin IElectricCharacterSupport - export interface IElectricCharacterSupport { - brackets: IBracketPair[]; - regexBrackets?: IRegexBracketPair[]; - docComment?: IDocComment; - caseInsensitive?: boolean; - embeddedElectricCharacters?: string[]; - } - var ElectricCharacterSupport: { - register(modeId:string, electricCharacterSupport:IElectricCharacterSupport): Disposable; - }; - // --- End IElectricCharacterSupport - - // --- Begin ICharacterPairSupport - export interface ICharacterPairSupport { - autoClosingPairs: IAutoClosingPairConditional[]; - surroundingPairs?: IAutoClosingPair[]; - } - /** - * Interface used to support insertion of matching characters like brackets and qoutes. - */ - export interface IAutoClosingPair { - open:string; - close:string; - } - export interface IAutoClosingPairConditional extends IAutoClosingPair { - notIn?: string[]; - } - var CharacterPairSupport: { - register(modeId:string, characterPairSupport:ICharacterPairSupport): Disposable; - }; - // --- End ICharacterPairSupport - - // --- Begin IOnEnterSupport - export interface IBracketPair2 { - open: string; - close: string; - } - export interface IIndentationRules { - decreaseIndentPattern: RegExp; - increaseIndentPattern: RegExp; - indentNextLinePattern?: RegExp; - unIndentedLinePattern?: RegExp; - } - export enum IndentAction { - None, - Indent, - IndentOutdent, - Outdent - } - export interface IEnterAction { - indentAction:IndentAction; - appendText?:string; - removeText?:number; - } - export interface IOnEnterRegExpRules { - beforeText: RegExp; - afterText?: RegExp; - action: IEnterAction; - } - export interface IOnEnterSupportOptions { - brackets?: IBracketPair2[]; - indentationRules?: IIndentationRules; - regExpRules?: IOnEnterRegExpRules[]; - } - var OnEnterSupport: { - register(modeId:string, opts:IOnEnterSupportOptions): Disposable; - }; - // --- End IOnEnterSupport - - export interface IResourceEdit { - resource: Uri; - range?: Range; - newText: string; - } - - export interface IReference { - resource: Uri; - range: Range; - } - - interface IMode { - getId(): string; - } - - export interface IWorker { - disposable: Disposable; - load(): Thenable; - } - - function registerMonarchDefinition(modeId: string, language: Modes.ILanguage): Disposable; - function loadInBackgroundWorker(scriptSrc: string): IWorker; - - } - - -} - -declare module 'vscode-testing' { - import vscode = require('vscode'); - export interface IRelaxedToken { - startIndex: number; - type: string; - bracket?: vscode.Modes.Bracket; - } - export interface ITestItem { - line: string; - tokens: IRelaxedToken[]; - } - export function testTokenization(name:string, language: vscode.Modes.ILanguage, tests:ITestItem[][]): void; - export interface IOnEnterAsserter { - nothing(oneLineAboveText:string, beforeText:string, afterText:string): void; - indents(oneLineAboveText:string, beforeText:string, afterText:string): void; - outdents(oneLineAboveText:string, beforeText:string, afterText:string): void; - indentsOutdents(oneLineAboveText:string, beforeText:string, afterText:string): void; - } - export function testOnEnter(name:string, language: vscode.Modes.ILanguage, callback:(assertOnEnter:IOnEnterAsserter) => void): void; -} - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise libary is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommand the use of native promises which are available in VS Code. - */ -interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -// ---- ES6 promise ------------------------------------------------------ - -/** - * Represents the completion of an asynchronous operation - */ -interface Promise extends Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Promise; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onrejected?: (reason: any) => T | Thenable): Promise; - - // [Symbol.toStringTag]: string; -} - -interface PromiseConstructor { - // /** - // * A reference to the prototype. - // */ - // prototype: Promise; - - /** - * Creates a new Promise. - * @param executor A callback used to initialize the promise. This callback is passed two arguments: - * a resolve callback used resolve the promise with a value or the result of another promise, - * and a reject callback used to reject the promise with a provided reason or error. - */ - new (executor: (resolve: (value?: T | Thenable) => void, reject: (reason?: any) => void) => void): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - all(values: Array>): Promise; - - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - race(values: Array>): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Thenable): Promise; - - /** - * Creates a new resolved promise . - * @returns A resolved promise. - */ - resolve(): Promise; - - // [Symbol.species]: Function; -} - -declare var Promise: PromiseConstructor;