Skip to content

Commit

Permalink
Show-Command explorer v1 (#1406)
Browse files Browse the repository at this point in the history
* Implement TreeView
First pass at bringing a TreeView into vscode-powershell. Built currently failing on unrelated code...

* Implement TreeView
First pass at bringing a TreeView into vscode-powershell. Built currently failing on unrelated code...

* Missed some variable names.
Updated from previous name incarnation..

* Adding svg for activitybar.
Require an svg for the activity bar. Taken from https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample/media (MIT Licensed I think...)

* Added a PowerShell SVG.

Taken from gist: https://gist.github.com/Xainey/d5bde7d01dcbac51ac951810e94313aa?short_path=ec01c8c

* First Attempt to call to PSES

* Get data from PSES
PSES isn't returning a string. Make sure we're expecting it. Allowing for console.log for debugging. These will all be removed prior to shipping.

* Refactoring code

* Pulling live data.
Unable to currently update the list. If you run PowerShell.GetCommands prior to opening the treeview, it is populated with your commands. Need to get it to update.

* WIP: Something something it's broken...

* Still not refreshing. I give up for now :'(

* Correct dimensions on sidebar icon
Other icons appear to be 32 px square. This one was 50. Adjusting size to 32.

* Minor cleanup
Cleaning up the tslinter hints. Remove CommandNode, was part of a failed experiment to get the tree refresh working.

* Cleanup casing and variable names.
Correct casing of some things. Adjust names to increase chance of uniqueness.

* Fix the refresh.
Thanks to glennsarti for finding that the API expects to call back to a particular variable.

* Insert Command from treeview
Add Insert Command
Add Right Click Options to View
Reset PSES Logging to Normal
Update OnlineHelp to take an item from the treeview. Pass that to online help PSES handler.

* Have Command Explorer load fully on extension load.

* Change to match PSES changes.

Adding functionality to PSES to get all commands (Name and Module Name), or get all of a single command. This solves performance issues with getting all of all of them.

* Move toCommand to be a standalone function

* Remove unneccesary svg files.

* Fix formatting. Remove overly verbose selection

* Add some TODOs so we don't forget to do this.

* Remove GetAllCommands.
Refactor into a single command. If nothing is passed, it will return all objects.

* Add logging when language client not defined.
Clean up TODO comments
Clean up request type naming.
White space cleanup

* Bring Treeview into using ShowHelp
OnlineHelp has been deprecated as of 1.9.0.

* Move anonymous functions to Named.

Clean up some naming and whitespace.

* Add interface for command. Eliminate any from RequestType

* Eliminate another any.

* Adjust casing
  • Loading branch information
corbob authored and TylerLeonhardt committed Nov 28, 2018
1 parent 7883879 commit f725c92
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
@@ -1,6 +1,9 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Set svg to binary type, as SVG is unlikely to be editted by hand. Can be treated as checked in blob
*.svg binary

# .gitattributes in project root
# npm now seems to be insisting on LF - see https://github.com/npm/npm/issues/17161
package.json text eol=lf
Expand Down
4 changes: 4 additions & 0 deletions media/PwSh.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 51 additions & 2 deletions package.json
Expand Up @@ -34,7 +34,8 @@
"onCommand:PowerShell.SpecifyScriptArgs",
"onCommand:PowerShell.ShowSessionConsole",
"onCommand:PowerShell.ShowSessionMenu",
"onCommand:PowerShell.RestartSession"
"onCommand:PowerShell.RestartSession",
"onView:PowerShellCommands"
],
"dependencies": {
"vscode-languageclient": "~5.0.0"
Expand All @@ -58,6 +59,23 @@
"test": "node ./node_modules/vscode/bin/test"
},
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "PowerShellCommandExplorer",
"title": "PowerShell Command Explorer",
"icon": "media/pwsh.svg"
}
]
},
"views": {
"PowerShellCommandExplorer": [
{
"id": "PowerShellCommands",
"name": "PowerShell Commands"
}
]
},
"keybindings": [
{
"command": "PowerShell.ShowHelp",
Expand Down Expand Up @@ -93,6 +111,20 @@
"title": "Expand Alias",
"category": "PowerShell"
},
{
"command": "PowerShell.RefreshCommandsExplorer",
"title": "Refresh",
"icon": {
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh.svg"
},
"category": "PowerShell"
},
{
"command": "PowerShell.InsertCommand",
"title": "Insert Command",
"category": "PowerShell"
},
{
"command": "PowerShell.OnlineHelp",
"title": "Get Online Help for Command (Deprecated)",
Expand Down Expand Up @@ -181,6 +213,23 @@
"command": "PowerShell.ShowHelp",
"group": "2_powershell"
}
],
"view/title": [
{
"command": "PowerShell.RefreshCommandsExplorer",
"when": "view == PowerShellCommands",
"group": "navigation"
}
],
"view/item/context": [
{
"command": "PowerShell.ShowHelp",
"when": "view == PowerShellCommands"
},
{
"command": "PowerShell.InsertCommand",
"when": "view == PowerShellCommands"
}
]
},
"problemMatchers": [
Expand Down Expand Up @@ -609,4 +658,4 @@
]
},
"private": true
}
}
1 change: 1 addition & 0 deletions resources/dark/refresh.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/light/refresh.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 127 additions & 0 deletions src/features/GetCommands.ts
@@ -0,0 +1,127 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import * as vscode from "vscode";
import { LanguageClient, RequestType } from "vscode-languageclient";
import { IFeature } from "../feature";
import { Logger } from "../logging";

interface ICommand {
name: string;
moduleName: string;
defaultParameterSet: string;
parameterSets: object;
parameters: object;
}

/**
* RequestType sent over to PSES.
* Expects: ICommand to be returned
*/
export const GetCommandRequestType = new RequestType<string, ICommand[], void, void>("powerShell/getCommand");

/**
* A PowerShell Command listing feature. Implements a treeview control.
*/
export class GetCommandsFeature implements IFeature {
private command: vscode.Disposable;
private languageClient: LanguageClient;
private commandsExplorerProvider: CommandsExplorerProvider;

constructor(private log: Logger) {
this.command = vscode.commands.registerCommand("PowerShell.RefreshCommandsExplorer",
() => this.CommandExplorerRefresh());
this.commandsExplorerProvider = new CommandsExplorerProvider();
vscode.window.registerTreeDataProvider("PowerShellCommands", this.commandsExplorerProvider);
vscode.commands.registerCommand("PowerShell.InsertCommand", (item) => this.InsertCommand(item));
}

public dispose() {
this.command.dispose();
}

public setLanguageClient(languageclient: LanguageClient) {
this.languageClient = languageclient;
vscode.commands.executeCommand("PowerShell.RefreshCommandsExplorer");
}

private CommandExplorerRefresh() {
if (this.languageClient === undefined) {
this.log.writeAndShowError(`<${GetCommandsFeature.name}>: ` +
"Unable to instantiate; language client undefined.");
return;
}
this.languageClient.sendRequest(GetCommandRequestType, "").then((result) => {
this.commandsExplorerProvider.powerShellCommands = result.map(toCommand);
this.commandsExplorerProvider.refresh();
});
}

private InsertCommand(item) {
const editor = vscode.window.activeTextEditor;
const sls = editor.selection.start;
const sle = editor.selection.end;
const range = new vscode.Range(sls.line, sls.character, sle.line, sle.character);
editor.edit((editBuilder) => {
editBuilder.replace(range, item.Name);
});
}
}

class CommandsExplorerProvider implements vscode.TreeDataProvider<Command> {
public readonly onDidChangeTreeData: vscode.Event<Command | undefined>;
public powerShellCommands: Command[];
private didChangeTreeData: vscode.EventEmitter<Command | undefined> = new vscode.EventEmitter<Command>();

constructor() {
this.onDidChangeTreeData = this.didChangeTreeData.event;
}

public refresh(): void {
this.didChangeTreeData.fire();
}

public getTreeItem(element: Command): vscode.TreeItem {
return element;
}

public getChildren(element?: Command): Thenable<Command[]> {
return Promise.resolve(this.powerShellCommands || []);
}
}

function toCommand(command: ICommand): Command {
return new Command(
command.name,
command.moduleName,
command.defaultParameterSet,
command.parameterSets,
command.parameters,
);
}

class Command extends vscode.TreeItem {
constructor(
public readonly Name: string,
public readonly ModuleName: string,
public readonly defaultParameterSet: string,
public readonly ParameterSets: object,
public readonly Parameters: object,
public readonly collapsibleState = vscode.TreeItemCollapsibleState.None,
) {
super(Name, collapsibleState);
}

public getTreeItem(): vscode.TreeItem {
return {
label: this.label,
collapsibleState: this.collapsibleState,
};
}

public async getChildren(element?): Promise<Command[]> {
return [];
// Returning an empty array because we need to return something.
}

}
19 changes: 12 additions & 7 deletions src/features/ShowHelp.ts
Expand Up @@ -16,20 +16,25 @@ export class ShowHelpFeature implements IFeature {
private languageClient: LanguageClient;

constructor(private log: Logger) {
this.command = vscode.commands.registerCommand("PowerShell.ShowHelp", () => {
this.command = vscode.commands.registerCommand("PowerShell.ShowHelp", (item?) => {
if (this.languageClient === undefined) {
this.log.writeAndShowError(`<${ShowHelpFeature.name}>: ` +
"Unable to instantiate; language client undefined.");
return;
}
if (item === undefined) {

const editor = vscode.window.activeTextEditor;
const selection = editor.selection;
const doc = editor.document;
const cwr = doc.getWordRangeAtPosition(selection.active);
const text = doc.getText(cwr);
const editor = vscode.window.activeTextEditor;

this.languageClient.sendRequest(ShowHelpRequestType, text);
const selection = editor.selection;
const doc = editor.document;
const cwr = doc.getWordRangeAtPosition(selection.active);
const text = doc.getText(cwr);

this.languageClient.sendRequest(ShowHelpRequestType, text);
} else {
this.languageClient.sendRequest(ShowHelpRequestType, item.Name);
}
});

this.deprecatedCommand = vscode.commands.registerCommand("PowerShell.OnlineHelp", () => {
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Expand Up @@ -21,6 +21,7 @@ import { ExtensionCommandsFeature } from "./features/ExtensionCommands";
import { FindModuleFeature } from "./features/FindModule";
import { FoldingFeature } from "./features/Folding";
import { GenerateBugReportFeature } from "./features/GenerateBugReport";
import { GetCommandsFeature } from "./features/GetCommands";
import { HelpCompletionFeature } from "./features/HelpCompletion";
import { NewFileOrProjectFeature } from "./features/NewFileOrProject";
import { OpenInISEFeature } from "./features/OpenInISE";
Expand Down Expand Up @@ -123,6 +124,7 @@ export function activate(context: vscode.ExtensionContext): void {
new OpenInISEFeature(),
new GenerateBugReportFeature(sessionManager),
new ExpandAliasFeature(logger),
new GetCommandsFeature(logger),
new ShowHelpFeature(logger),
new FindModuleFeature(),
new PesterTestsFeature(sessionManager),
Expand Down

0 comments on commit f725c92

Please sign in to comment.