diff --git a/examples/PSScriptAnalyzerSettings.psd1 b/examples/PSScriptAnalyzerSettings.psd1 index 044342877a..3ab1a66ec2 100644 --- a/examples/PSScriptAnalyzerSettings.psd1 +++ b/examples/PSScriptAnalyzerSettings.psd1 @@ -16,6 +16,7 @@ 'PSReservedParams', 'PSShouldProcess', 'PSUseApprovedVerbs', + 'PSAvoidUsingAliases', 'PSUseDeclaredVarsMoreThanAssigments') # Do not analyze the following rules. Use ExcludeRules when you have diff --git a/package.json b/package.json index a0f58698e7..53d8209f16 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "configurationSnippets": [ { - "label": "PowerShell: Launch Current File Configuration", + "label": "PowerShell: Launch Current Script Configuration", "description": "A new configuration for launching the current opened PowerShell script", "body": { "type": "PowerShell", @@ -172,7 +172,7 @@ } }, { - "label": "PowerShell: Launch Configuration", + "label": "PowerShell: Launch Script Configuration", "description": "A new configuration for launching a PowerShell script", "body": { "type": "PowerShell", @@ -182,14 +182,31 @@ "args": [], "cwd": "^\"\\${workspaceRoot}\"" } + }, + { + "label": "PowerShell: Attach to PowerShell Process Configuration", + "description": "A new configuration for debugging a runspace in another process.", + "body": { + "type": "PowerShell", + "request": "attach", + "name": "PowerShell Attach to Process", + "processId": "${ProcessId}", + "runspaceId": "1" + } + }, + { + "label": "PowerShell: Launch Interactive Session Configuration", + "description": "A new configuration for debugging an interactive session.", + "body": { + "type": "PowerShell", + "request": "launch", + "name": "PowerShell Interactive Session" + } } ], "configurationAttributes": { "launch": { - "required": [ - "script" - ], "properties": { "program": { "type": "string", @@ -197,7 +214,7 @@ }, "script": { "type": "string", - "description": "Absolute path to the PowerShell script to launch under the debugger." + "description": "Optional: Absolute path to the PowerShell script to launch under the debugger." }, "args": { "type": "array", @@ -213,6 +230,23 @@ "default": "${workspaceRoot}" } } + }, + "attach": { + "properties": { + "computerName": { + "type": "string", + "description": "Optional: The computer name to which a remote session will be established. Works only on PowerShell 4 and above." + }, + "processId": { + "type": "number", + "description": "The ID of the process to be attached. Works only on PowerShell 5 and above." + }, + "runspaceId": { + "type": "number", + "description": "Optional: The ID of the runspace to debug in the attached process. Defaults to 1. Works only on PowerShell 5 and above.", + "default": 1 + } + } } }, "initialConfigurations": [ @@ -223,6 +257,18 @@ "script": "${file}", "args": [], "cwd": "${file}" + }, + { + "type": "PowerShell", + "request": "attach", + "name": "PowerShell Attach", + "processId": "12345" + }, + { + "type": "PowerShell", + "request": "launch", + "name": "PowerShell Interactive Session", + "cwd": "${workspaceRoot}" } ] } diff --git a/src/features/ExtensionCommands.ts b/src/features/ExtensionCommands.ts index 745d86f620..e0478adadc 100644 --- a/src/features/ExtensionCommands.ts +++ b/src/features/ExtensionCommands.ts @@ -122,6 +122,11 @@ export namespace OpenFileRequest { { get method() { return 'editor/openFile'; } }; } +export namespace CloseFileRequest { + export const type: RequestType = + { get method() { return 'editor/closeFile'; } }; +} + export namespace ShowErrorMessageRequest { export const type: RequestType = { get method() { return 'editor/showErrorMessage'; } }; @@ -198,6 +203,10 @@ export class ExtensionCommandsFeature implements IFeature { OpenFileRequest.type, filePath => this.openFile(filePath)); + this.languageClient.onRequest( + CloseFileRequest.type, + filePath => this.closeFile(filePath)); + this.languageClient.onRequest( ShowInformationMessageRequest.type, message => this.showInformationMessage(message)); @@ -317,6 +326,37 @@ export class ExtensionCommandsFeature implements IFeature { return promise; } + private closeFile(filePath: string): Thenable { + + var promise: Thenable; + + // Make sure the file path is absolute + if (!path.win32.isAbsolute(filePath)) + { + filePath = path.win32.resolve( + vscode.workspace.rootPath, + filePath); + } + + // Normalize file path case for comparison + var normalizedFilePath = filePath.toLowerCase(); + + if (vscode.workspace.textDocuments.find(doc => doc.fileName.toLowerCase() == normalizedFilePath)) + { + promise = + vscode.workspace.openTextDocument(filePath) + .then(doc => vscode.window.showTextDocument(doc)) + .then(editor => vscode.commands.executeCommand("workbench.action.closeActiveEditor")) + .then(_ => EditorOperationResponse.Completed); + } + else + { + promise = Promise.resolve(EditorOperationResponse.Completed); + } + + return promise; + } + private setSelection(details: SetSelectionRequestArguments): EditorOperationResponse { vscode.window.activeTextEditor.selections = [ new vscode.Selection( diff --git a/src/session.ts b/src/session.ts index 300bdda8a2..8961e8cf00 100644 --- a/src/session.ts +++ b/src/session.ts @@ -189,6 +189,23 @@ export class SessionManager { } } + private setStatusBarVersionString( + runspaceDetails: RunspaceDetails) { + + var versionString = + this.versionDetails.architecture === "x86" + ? `${runspaceDetails.powerShellVersion.displayVersion} (${runspaceDetails.powerShellVersion.architecture})` + : runspaceDetails.powerShellVersion.displayVersion; + + if (runspaceDetails.runspaceType != RunspaceType.Local) { + versionString += ` [${runspaceDetails.connectionString}]` + } + + this.setSessionStatus( + versionString, + SessionStatus.Running); + } + private registerCommands() : void { this.registeredCommands = [ vscode.commands.registerCommand('PowerShell.RestartSession', () => { this.restartSession(); }), @@ -365,6 +382,10 @@ export class SessionManager { this.setSessionFailure("Could not start language service: ", reason); }); + this.languageServerClient.onNotification( + RunspaceChangedEvent.type, + (runspaceDetails) => { this.setStatusBarVersionString(runspaceDetails); }); + this.languageServerClient.start(); } catch (e) @@ -623,3 +644,20 @@ export interface PowerShellVersionDetails { edition: string; architecture: string; } + +export enum RunspaceType { + Local, + Process, + Remote +} + +export interface RunspaceDetails { + powerShellVersion: PowerShellVersionDetails; + runspaceType: RunspaceType; + connectionString: string; +} + +export namespace RunspaceChangedEvent { + export const type: NotificationType = + { get method() { return 'powerShell/runspaceChanged'; } }; +} \ No newline at end of file