diff --git a/Source/azService.ts b/Source/azService.ts index 8462aca..74b3ebe 100644 --- a/Source/azService.ts +++ b/Source/azService.ts @@ -2,11 +2,11 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { spawn, ChildProcess, SpawnOptions } from "child_process"; +import { ChildProcess, SpawnOptions, spawn } from "child_process"; import { join } from "path"; import * as semver from "semver"; -import { exec, realpath, exists, readdir } from "./utils"; +import { exec, exists, readdir, realpath } from "./utils"; const isWindows = process.platform === "win32"; @@ -67,7 +67,7 @@ export class AzService { private listeners: { [sequence: number]: ( err: undefined | any, - response: Message | undefined + response: Message | undefined, ) => void; } = {}; private nextSequenceNumber = 1; @@ -81,7 +81,7 @@ export class AzService { async getCompletions( query: CompletionQuery, - onCancel: (handle: () => void) => void + onCancel: (handle: () => void) => void, ): Promise { try { return this.send(query, onCancel); @@ -97,20 +97,20 @@ export class AzService { async getHover( command: Command, - onCancel: (handle: () => void) => void + onCancel: (handle: () => void) => void, ): Promise { return this.send( { request: "hover", command, }, - onCancel + onCancel, ); } private async send( data: T, - onCancel?: (handle: () => void) => void + onCancel?: (handle: () => void) => void, ): Promise { const process = await this.getProcess(); return new Promise((resolve, reject) => { @@ -161,7 +161,7 @@ export class AzService { throw "wrongVersion"; } const pythonLocation = (/^Python location '([^']*)'/m.exec( - stdout + stdout, ) || [])[1]; const processOptions = await this.getSpawnProcessOptions(); return this.spawn(pythonLocation, processOptions); @@ -180,7 +180,7 @@ export class AzService { if (binPath.startsWith(cellarBasePath)) { const installPath = binPath.substr( 0, - binPath.indexOf("/", cellarBasePath.length) + binPath.indexOf("/", cellarBasePath.length), ); const libPath = `${installPath}/libexec/lib`; const entries = await readdir(libPath); @@ -202,10 +202,10 @@ export class AzService { const process = spawn( join( __dirname, - `../../service/az-service${isWindows ? ".bat" : ""}` + `../../service/az-service${isWindows ? ".bat" : ""}`, ), [pythonLocation], - processOptions + processOptions, ); process.stdout.setEncoding("utf8"); process.stdout.on("data", (data) => { @@ -237,7 +237,7 @@ export class AzService { delete this.listeners[sequence]; listener( `Python process terminated with exit code ${code}, signal ${signal}.`, - undefined + undefined, ); } }); diff --git a/Source/extension.ts b/Source/extension.ts index d16d87c..03b4e48 100644 --- a/Source/extension.ts +++ b/Source/extension.ts @@ -3,42 +3,42 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as jmespath from "jmespath"; +import * as process from "process"; import { - HoverProvider, + CancellationToken, + CompletionItem, + CompletionItemKind, + CompletionItemProvider, + CompletionList, + Disposable, + ExtensionContext, Hover, + HoverProvider, + Position, + ProviderResult, + Range, + Selection, SnippetString, StatusBarAlignment, StatusBarItem, - ExtensionContext, TextDocument, TextDocumentChangeEvent, - Disposable, TextEditor, - Selection, - languages, - commands, - Range, - ViewColumn, - Position, - CancellationToken, - ProviderResult, - CompletionItem, - CompletionList, - CompletionItemKind, - CompletionItemProvider, - window, - workspace, - env, Uri, + ViewColumn, WorkspaceEdit, + commands, + env, l10n, + languages, + window, + workspace, } from "vscode"; -import * as process from "process"; -import { AzService, CompletionKind, Arguments, Status } from "./azService"; -import { parse, findNode } from "./parser"; -import { exec } from "./utils"; import * as spinner from "elegant-spinner"; +import { Arguments, AzService, CompletionKind, Status } from "./azService"; +import { findNode, parse } from "./parser"; +import { exec } from "./utils"; export function activate(context: ExtensionContext) { const azService = new AzService(azNotFound); @@ -46,18 +46,24 @@ export function activate(context: ExtensionContext) { languages.registerCompletionItemProvider( "azcli", new AzCompletionItemProvider(azService), - " " - ) + " ", + ), ); context.subscriptions.push( - languages.registerHoverProvider("azcli", new AzHoverProvider(azService)) + languages.registerHoverProvider( + "azcli", + new AzHoverProvider(azService), + ), ); const status = new StatusBarInfo(azService); context.subscriptions.push(status); context.subscriptions.push(new RunLineInTerminal()); context.subscriptions.push(new RunLineInEditor(status)); context.subscriptions.push( - commands.registerCommand("ms-azurecli.installAzureCLI", installAzureCLI) + commands.registerCommand( + "ms-azurecli.installAzureCLI", + installAzureCLI, + ), ); } @@ -75,7 +81,7 @@ class AzCompletionItemProvider implements CompletionItemProvider { provideCompletionItems( document: TextDocument, position: Position, - token: CancellationToken + token: CancellationToken, ): ProviderResult { const line = document.lineAt(position).text; const parsed = parse(line); @@ -110,9 +116,9 @@ class AzCompletionItemProvider implements CompletionItemProvider { subcommand: subcommand.slice(1).join(" "), argument, arguments: args, - } + } : {}, - token.onCancellationRequested + token.onCancellationRequested, ) .then((completions) => completions.map( @@ -126,7 +132,7 @@ class AzCompletionItemProvider implements CompletionItemProvider { }) => { const item = new CompletionItem( name, - completionKinds[kind] + completionKinds[kind], ); if (snippet) { item.insertText = new SnippetString(snippet); @@ -143,8 +149,8 @@ class AzCompletionItemProvider implements CompletionItemProvider { item.sortText = sortText; } return item; - } - ) + }, + ), ); } @@ -154,7 +160,7 @@ class AzCompletionItemProvider implements CompletionItemProvider { for (const match of allMatches( /-[^\s"']*|"[^"]*"|'[^']*'|[^\s"']+/g, line, - 0 + 0, )) { if (match.startsWith("-")) { name = match as string; @@ -178,7 +184,7 @@ class AzHoverProvider implements HoverProvider { provideHover( document: TextDocument, position: Position, - token: CancellationToken + token: CancellationToken, ): ProviderResult { const line = document.lineAt(position.line).text; const command = parse(line); @@ -196,7 +202,7 @@ class AzHoverProvider implements HoverProvider { return this.azService .getHover( { subcommand }, - token.onCancellationRequested + token.onCancellationRequested, ) .then( (text) => @@ -207,9 +213,9 @@ class AzHoverProvider implements HoverProvider { position.line, node.offset, position.line, - node.offset + node.length - ) - ) + node.offset + node.length, + ), + ), ); } } else if (node.kind === "argument_name") { @@ -220,7 +226,7 @@ class AzHoverProvider implements HoverProvider { return this.azService .getHover( { subcommand, argument: node.text }, - token.onCancellationRequested + token.onCancellationRequested, ) .then( (text) => @@ -231,9 +237,9 @@ class AzHoverProvider implements HoverProvider { position.line, node.offset, position.line, - node.offset + node.length - ) - ) + node.offset + node.length, + ), + ), ); } } @@ -248,14 +254,14 @@ class RunLineInTerminal { this.disposables.push( commands.registerTextEditorCommand( "ms-azurecli.runLineInTerminal", - (editor) => this.run(editor) - ) + (editor) => this.run(editor), + ), ); } private run(editor: TextEditor) { return commands.executeCommand( - "workbench.action.terminal.runSelectedText" + "workbench.action.terminal.runSelectedText", ); } @@ -274,7 +280,7 @@ class RunLineInEditor { private statusBarUpdateInterval!: NodeJS.Timer; private statusBarSpinner = spinner(); private hideStatusBarItemTimeout!: NodeJS.Timeout; - private statusBarItemText: string = ""; + private statusBarItemText = ""; // using backtick (`) as continuation character on Windows, backslash (\) on other systems private continuationCharacter: string = process.platform === "win32" ? "`" : "\\"; @@ -283,29 +289,31 @@ class RunLineInEditor { this.disposables.push( commands.registerTextEditorCommand( "ms-azurecli.toggleLiveQuery", - (editor) => this.toggleQuery(editor) - ) + (editor) => this.toggleQuery(editor), + ), ); this.disposables.push( commands.registerTextEditorCommand( "ms-azurecli.runLineInEditor", - (editor) => this.run(editor) - ) + (editor) => this.run(editor), + ), ); this.disposables.push( - workspace.onDidCloseTextDocument((document) => this.close(document)) + workspace.onDidCloseTextDocument((document) => + this.close(document), + ), ); this.disposables.push( - workspace.onDidChangeTextDocument((event) => this.change(event)) + workspace.onDidChangeTextDocument((event) => this.change(event)), ); this.commandRunningStatusBarItem = window.createStatusBarItem( - StatusBarAlignment.Left + StatusBarAlignment.Left, ); this.disposables.push(this.commandRunningStatusBarItem); } - private runningCommandCount: number = 0; + private runningCommandCount = 0; private run(source: TextEditor) { this.refreshContinuationCharacter(); const command = this.getSelectedCommand(source); @@ -314,7 +322,7 @@ class RunLineInEditor { const t0 = Date.now(); if (this.runningCommandCount === 1) { this.statusBarItemText = l10n.t( - "Azure CLI: Waiting for response" + "Azure CLI: Waiting for response", ); this.statusBarUpdateInterval = setInterval(() => { if (this.runningCommandCount === 1) { @@ -337,31 +345,35 @@ class RunLineInEditor { this.query = undefined; // TODO return this.findResultDocument() .then((document) => - window.showTextDocument(document, ViewColumn.Two, true) + window.showTextDocument(document, ViewColumn.Two, true), ) .then((target) => replaceContent( target, JSON.stringify({ [l10n.t("Running command")]: command, - }) + "\n" + }) + "\n", ) .then(() => exec(command)) .then( ({ stdout }) => stdout, ({ stdout, stderr }) => - JSON.stringify({ stderr, stdout }, null, " ") + JSON.stringify( + { stderr, stdout }, + null, + " ", + ), ) .then((content) => replaceContent(target, content) .then( () => (this.parsedResult = - JSON.parse(content)) + JSON.parse(content)), ) - .then(undefined, (err) => {}) + .then(undefined, (err) => {}), ) - .then(() => this.commandFinished(t0)) + .then(() => this.commandFinished(t0)), ) .then(undefined, console.error); } @@ -388,8 +400,8 @@ class RunLineInEditor { if (source.document.lineAt(lineNumber).text.length === 0) { window.showInformationMessage( l10n.t( - "Please put the cursor on a line that contains a command (or part of a command)." - ) + "Please put the cursor on a line that contains a command (or part of a command).", + ), ); return ""; } @@ -407,7 +419,7 @@ class RunLineInEditor { // this will be the first (maybe only) line of the command var command = this.stripComments( - source.document.lineAt(lineNumber).text + source.document.lineAt(lineNumber).text, ); while (command.trim().endsWith(this.continuationCharacter)) { @@ -426,15 +438,15 @@ class RunLineInEditor { // single line command return this.stripComments( source.document.getText( - new Range(selectionStart, selectionEnd) - ) + new Range(selectionStart, selectionEnd), + ), ); } else { // multiline command command = this.stripComments( source.document .lineAt(selectionStart.line) - .text.substring(selectionStart.character) + .text.substring(selectionStart.character), ); for ( let index = selectionStart.line + 1; @@ -446,12 +458,12 @@ class RunLineInEditor { } var line = this.stripComments( - source.document.lineAt(index).text + source.document.lineAt(index).text, ); if (line.trim().toLowerCase().startsWith(commandPrefix)) { window.showErrorMessage( - l10n.t("Multiple command selection not supported") + l10n.t("Multiple command selection not supported"), ); return ""; } @@ -510,7 +522,7 @@ class RunLineInEditor { this.runningCommandCount -= 1; this.statusBarItemText = l10n.t( "Azure CLI: Executed in {0} milliseconds", - Date.now() - startTime + Date.now() - startTime, ); this.commandRunningStatusBarItem.text = this.statusBarItemText; @@ -520,7 +532,7 @@ class RunLineInEditor { // hide status bar item after 10 seconds to keep status bar uncluttered this.hideStatusBarItemTimeout = setTimeout( () => this.commandRunningStatusBarItem.hide(), - 10000 + 10000, ); } } @@ -573,7 +585,7 @@ class RunLineInEditor { private updateResult() { if (this.resultDocument && this.parsedResult) { const resultEditor = window.visibleTextEditors.find( - (editor) => editor.document === this.resultDocument + (editor) => editor.document === this.resultDocument, ); if (resultEditor) { try { @@ -583,7 +595,7 @@ class RunLineInEditor { : this.parsedResult; replaceContent( resultEditor, - JSON.stringify(result, null, " ") + JSON.stringify(result, null, " "), ).then(undefined, console.error); } catch (err: any) { if (!(err && err.name === "ParserError")) { @@ -597,7 +609,7 @@ class RunLineInEditor { private getQueryArgument(line: string) { return ( (/\s--query\s+("([^"]*)"|'([^']*)'|([^\s"']+))/.exec( - line + line, ) as string[]) || [] ).filter((group) => !!group)[2]; } @@ -617,10 +629,10 @@ class StatusBarInfo { constructor(private azService: AzService) { this.disposables.push( - (this.info = window.createStatusBarItem(StatusBarAlignment.Left)) + (this.info = window.createStatusBarItem(StatusBarAlignment.Left)), ); this.disposables.push( - window.onDidChangeActiveTextEditor(() => this.update()) + window.onDidChangeActiveTextEditor(() => this.update()), ); this.disposables.push({ dispose: () => this.timer && clearTimeout(this.timer), @@ -674,7 +686,7 @@ function replaceContent(editor: TextEditor, content: string) { const document = editor.document; const all = new Range( new Position(0, 0), - document.lineAt(document.lineCount - 1).range.end + document.lineAt(document.lineCount - 1).range.end, ); const edit = new WorkspaceEdit(); edit.replace(document.uri, all, content); diff --git a/Source/parser.ts b/Source/parser.ts index 789ed8a..cb7adcd 100644 --- a/Source/parser.ts +++ b/Source/parser.ts @@ -42,10 +42,10 @@ export function parse(line: string) { kind: subcommand ? "subcommand" : isArgument - ? "argument_name" - : isComment - ? "comment" - : "argument_value", + ? "argument_name" + : isComment + ? "comment" + : "argument_value", offset: regex.lastIndex - length, length, text, @@ -88,6 +88,6 @@ export function parse(line: string) { export function findNode(command: Command, offset: number) { return command.tokens.find( (token) => - token.offset <= offset && token.offset + token.length > offset + token.offset <= offset && token.offset + token.length > offset, ); } diff --git a/language-configuration.json b/language-configuration.json index 77e0118..15a1b3f 100644 --- a/language-configuration.json +++ b/language-configuration.json @@ -2,11 +2,7 @@ "comments": { "lineComment": "#" }, - "brackets": [ - ["{", "}"], - ["[", "]"], - ["(", ")"] - ], + "brackets": [["{", "}"], ["[", "]"], ["(", ")"]], "autoClosingPairs": [ ["{", "}"], ["[", "]"],