Skip to content
Permalink
Browse files

Show-Command explorer v1 (#1406)

* 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 f725c92125f80f8b584079ddc0dcbac37bd7cf78
Showing with 201 additions and 9 deletions.
  1. +3 −0 .gitattributes
  2. +4 −0 media/PwSh.svg
  3. +51 −2 package.json
  4. +1 −0 resources/dark/refresh.svg
  5. +1 −0 resources/light/refresh.svg
  6. +127 −0 src/features/GetCommands.ts
  7. +12 −7 src/features/ShowHelp.ts
  8. +2 −0 src/main.ts
@@ -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
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32px" height="32px">
<path style="line-height:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;block-progression:tb;isolation:auto;mix-blend-mode:normal" d="M 8.0683594 5 C 7.5985478 5 7.0740085 5.0706042 6.6347656 5.4277344 C 6.1955227 5.7848645 6.0182993 6.2800756 5.9160156 6.7441406 C 4.6319924 12.607247 3.3484294 18.470878 2.0664062 24.333984 L 2.0664062 24.335938 C 1.9318566 24.956936 1.9940452 25.635268 2.3847656 26.175781 C 2.7754858 26.716249 3.4591241 27 4.125 27 L 24 27 C 24.514455 27 25.07303 26.820004 25.447266 26.451172 C 25.821502 26.08234 25.979845 25.634726 26.072266 25.212891 L 26.072266 25.210938 C 27.361317 19.31975 28.647572 13.427473 29.931641 7.5351562 C 30.063187 6.9314661 30.019975 6.2444204 29.595703 5.7167969 C 29.171432 5.1891733 28.509634 5 27.896484 5 L 8.0683594 5 z M 8.0683594 7 L 27.896484 7 C 27.959617 7 27.96256 7.0043131 27.992188 7.0078125 C 27.989342 7.0385555 27.99271 7.0442762 27.978516 7.109375 C 26.694585 13.001058 25.406136 18.89439 24.117188 24.785156 L 24.119141 24.783203 C 24.076503 24.977811 24.040539 25.0106 24.050781 25.001953 C 24.038906 25.001318 24.043479 25 24 25 L 4.125 25 C 3.9368759 25 3.9881392 24.979396 4.0058594 25.003906 C 4.0234384 25.028226 3.9740033 24.976286 4.0195312 24.761719 L 4.0195312 24.759766 C 5.3013723 18.897546 6.5852999 13.036101 7.8691406 7.1738281 C 7.8913694 7.0729753 7.905601 7.0435266 7.9179688 7.0097656 C 7.9510846 7.0057327 7.9748357 7 8.0683594 7 z M 11.533203 7.984375 A 1.50015 1.50015 0 0 0 10.40625 10.525391 L 15.25 15.695312 L 7.6132812 21.291016 A 1.50015 1.50015 0 1 0 9.3867188 23.708984 L 18.386719 17.115234 A 1.50015 1.50015 0 0 0 18.59375 14.878906 L 12.59375 8.4746094 A 1.50015 1.50015 0 0 0 11.533203 7.984375 z M 15.5 21 A 1.50015 1.50015 0 1 0 15.5 24 L 19.5 24 A 1.50015 1.50015 0 1 0 19.5 21 L 15.5 21 z" font-weight="400" font-family="sans-serif" white-space="normal" overflow="visible"/>
</svg>
@@ -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"
@@ -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",
@@ -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)",
@@ -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": [
@@ -609,4 +658,4 @@
]
},
"private": true
}
}
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#F6F6F6"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#424242"/></svg>
@@ -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.
}

}
@@ -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", () => {
@@ -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";
@@ -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),

0 comments on commit f725c92

Please sign in to comment.
You can’t perform that action at this time.