From 4ae52438974ecc60ada3bae7ddced5ac6bfdc7d6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 25 Oct 2018 18:28:48 +0200 Subject: [PATCH] Improve Samples --- .scripts/samples.js | 8 +- tree-view-sample/.vscode/extensions.json | 5 + tree-view-sample/.vscode/launch.json | 18 +-- tree-view-sample/.vscode/settings.json | 3 +- tree-view-sample/README.md | 45 ++++-- tree-view-sample/USAGE.md | 131 ++++++++++++------ tree-view-sample/src/extension.ts | 16 +-- ...umentContentProvider.ts => ftpExplorer.ts} | 0 tree-view-sample/src/nodeDependencies.ts | 4 +- tree-view-sample/tsconfig.json | 13 +- tree-view-sample/tslint.json | 12 ++ 11 files changed, 172 insertions(+), 83 deletions(-) create mode 100644 tree-view-sample/.vscode/extensions.json rename tree-view-sample/src/{ftpExplorer.textDocumentContentProvider.ts => ftpExplorer.ts} (100%) create mode 100644 tree-view-sample/tslint.json diff --git a/.scripts/samples.js b/.scripts/samples.js index 7cb87008..f1df2df2 100644 --- a/.scripts/samples.js +++ b/.scripts/samples.js @@ -83,7 +83,13 @@ const samples = [ contributions: [] }, // { description: 'theme-sample', path: 'theme-sample', guide: null, apis: [], contributions: [] }, - // { description: 'tree-view-sample', path: 'tree-view-sample', guide: null, apis: [], contributions: [] }, + { + description: 'tree-view-sample', + path: 'tree-view-sample', + guide: '/api/extension-guides/tree-view', + apis: ['window.createTreeView', 'window.registerTreeDataProvider', 'TreeView', 'TreeDataProvider'], + contributions: ['views', 'viewsContainers'] + }, // { description: 'vim-sample', path: 'vim-sample', guide: null, apis: [], contributions: [] }, // { description: 'webpack-sample', path: 'webpack-sample', guide: null, apis: [], contributions: [] }, ]; diff --git a/tree-view-sample/.vscode/extensions.json b/tree-view-sample/.vscode/extensions.json new file mode 100644 index 00000000..607e9e52 --- /dev/null +++ b/tree-view-sample/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "eg2.tslint" + ] +} \ No newline at end of file diff --git a/tree-view-sample/.vscode/launch.json b/tree-view-sample/.vscode/launch.json index 03ee7339..9b05b66b 100644 --- a/tree-view-sample/.vscode/launch.json +++ b/tree-view-sample/.vscode/launch.json @@ -1,6 +1,6 @@ // A launch configuration that compiles the extension and then opens it inside a new window { - "version": "0.1.0", + "version": "0.2.0", "configurations": [ { "name": "Launch Extension", @@ -17,22 +17,6 @@ ], "preLaunchTask": "npm: watch" }, - { - "name": "Launch Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test" - ], - "stopOnEntry": false, - "sourceMaps": true, - "outFiles": [ - "${workspaceRoot}/out/test/**/*.js" - ], - "preLaunchTask": "npm: watch" - }, { "type": "node", "request": "attach", diff --git a/tree-view-sample/.vscode/settings.json b/tree-view-sample/.vscode/settings.json index 66ed94c5..c89394a5 100644 --- a/tree-view-sample/.vscode/settings.json +++ b/tree-view-sample/.vscode/settings.json @@ -7,5 +7,6 @@ "out": true // set this to false to include "out" folder in search results }, "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version - "typescript.tsc.autoDetect": "off" + "typescript.tsc.autoDetect": "off", + "editor.insertSpaces": false, } \ No newline at end of file diff --git a/tree-view-sample/README.md b/tree-view-sample/README.md index cfaf5f3b..5f802ada 100644 --- a/tree-view-sample/README.md +++ b/tree-view-sample/README.md @@ -1,24 +1,51 @@ # Views & View Containers -This sample shows how to register and implement a custom tree view using the VS Code API. It has implementation for following views +This sample demonstrates how to implement and contribute a tree view in VS Code. This includes: + +- Contributing views and view containers. +- Contributing actions in various location of the view. +- Implementing the tree data provider for the view. +- Creating and working with the view. + +This sample provides following views - Node dependencies view -- Json Outline view - Ftp file explorer view -These views help you in understanding how to use TreeView API, title actions, inline actions, context menu actions and how to use `when` context to show views and actions. - -You can also learn how to contribute custom view containers and contribute views to it. For eg., Node dependencies view is shown under a Package Explorer custom view container. +Following example shows Node dependencies view in Package Explorer View container. ![Package Explorer](./resources/package-explorer.png) -## Running the example +## VS Code API + +This sample uses following contribution points, activation events and APIs + +### Contribution Points + +- `views` +- `viewContainers` +- `menu` + - `view/title` + - `view/item/context` + +### Activation Events + +- `onView:${viewId}` + +### APIs + +- `window.createTreeView` +- `window.registerTreeDataProvider` +- `TreeView` +- `TreeDataProvider` + +Refer to [Usage](./USAGE.md) document for more details. + +## Running the Sample - Open this example in VS Code Insiders - `npm install` - `npm run watch` - `F5` to start debugging -- FTP file explorer view should be shown in Explorer -- File explorer view replicating the file explorer in VS Code should be shown in Explorer -- Json Outline view is shown in explorer when you open a json file and gets hidden when json file is closed. - Node dependencies view is shown in Package explorer view container in Activity bar. +- FTP file explorer view should be shown in Explorer \ No newline at end of file diff --git a/tree-view-sample/USAGE.md b/tree-view-sample/USAGE.md index 38257e75..92ae15e4 100644 --- a/tree-view-sample/USAGE.md +++ b/tree-view-sample/USAGE.md @@ -1,44 +1,11 @@ -# Contributing a View +# Contributing a View Container & View +* Contribute a view container using the [viewContainers](https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributesviewscontainers) extension point. * Contribute a view using the [views](https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributesviews) extension point. * Register a data provider for the view using the [TreeDataProvider](https://code.visualstudio.com/docs/extensionAPI/vscode-api#_TreeDataProvider) API. * Contribute actions to the view using `view/title` and `view/item/context` locations in [menus](https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributesmenus) extension point. - -# contributes.views extension point - -You must specify an identifier and name for the view. You can contribute to following locations - -- `explorer`: Explorer view in the Side bar -- `debug`: Debug view in the Side bar - -When the user opens the view, VS Code will then emit an activationEvent `onView:${viewId}` (e.g. `onView:nodeDependencies` for the example below). You can also control the visibility of the view by providing the `when` context value. - -```json -"contributes": { - "views": { - "explorer": [ - { - "id": "nodeDependencies", - "name": "Node Dependencies", - "when": "workspaceHasPackageJSON" - } - ] - } -} -``` - -# TreeDataProvider - -Extension writers should register a [provider](/docs/extensionAPI/vscode-api.md#TreeDataProvider) programmatically to populate data in the view. - -```typescript -vscode.window.registerTreeDataProvider('nodeDependencies', new DepNodeProvider()); -``` - -See [nodeDependencies.ts](src/nodeDependencies.ts) for the implementation. - -# contributes.viewsContainers extension point +## contributes.viewsContainers extension point As of Visual Studio Code v1.23.0, you can move custom views into your own view container which will show up in the activity bar. @@ -48,6 +15,17 @@ To do such, extension writers can add a `viewContainers` object in the contribut - `title`: The name which will show up at the top of the view - `icon`: an image which will be displayed for the view container in the activity bar + +## contributes.views extension point + +You must specify an identifier and name for the view. You can contribute to following locations + +- `explorer`: Explorer view in the Side bar +- `debug`: Debug view in the Side bar +- `scm`: Debug view in the Side bar + +When the user opens the view, VS Code will then emit an activationEvent `onView:${viewId}` (e.g. `onView:nodeDependencies` for the example below). You can also control the visibility of the view by providing the `when` context value. + Following, in the views object, you can then add a field with the same string as the `id` in the `viewContainers`. ```json @@ -55,9 +33,9 @@ Following, in the views object, you can then add a field with the same string as "viewContainers": { "activitybar": [ { - "id": "tree-view", - "title": "Tree View", - "icon": "media/dep.svg" + "id": "package-explorer", + "title": "Package Explorer", + "icon": "media/dep.svg" } ] }, @@ -71,4 +49,77 @@ Following, in the views object, you can then add a field with the same string as ] } } -``` \ No newline at end of file +``` + +## View actions + +You can contribute actions at following locations in the view + +- `view/title`: Location to show actions in the view title. Primary or inline actions use `"group": "navigation"` and rest are secondary actions which are in `...` menu. +- `view/item/context`: Location to show actions for the tree item. Inline actions use `"group": "inline"` and rest are secondary actions which are in `...` menu. + +You can control the visibility of these actions using the `when` property. + +Examples: + +```json +"contributes": { + "commands": [ + { + "command": "nodeDependencies.refreshEntry", + "title": "Refresh", + "icon": { + "light": "resources/light/refresh.svg", + "dark": "resources/dark/refresh.svg" + } + } + ], + "menus": { + "view/title": [ + { + "command": "nodeDependencies.refreshEntry", + "when": "view == nodeDependencies", + "group": "navigation" + } + ] + } +} +``` + +**Note:** If you want to show an action for specific items, you can do it by defining context of a tree item using `TreeItem.contextValue` and you can specify the context value for key `viewItem` in `when` expression. + +Examples: + +```json +"contributes": { + "menus": { + "view/item/context": [ + { + "command": "nodeDependencies.deleteEntry", + "when": "view == nodeDependencies && viewItem == dependency" + } + ] + } +} +``` + +## TreeDataProvider + +Extension writers should register a [provider](/docs/extensionAPI/vscode-api.md#TreeDataProvider) programmatically to populate data in the view. + +```typescript +vscode.window.registerTreeDataProvider('nodeDependencies', new DepNodeProvider()); +``` + +See [nodeDependencies.ts](src/nodeDependencies.ts) for the implementation. + + +## TreeView + +If you would like to perform some UI operations on the view programatically, you can use `window.createTreeView` instead of `window.registerDataProvider`. This will give access to the view which you can use for performing view operations. + +```typescript +vscode.window.createTreeView('ftpExplorer', { treeDataProvider: new FtpTreeDataProvider() }); +``` + +See [ftpExplorer.ts](src/ftpExplorer.ts) for the implementation. \ No newline at end of file diff --git a/tree-view-sample/src/extension.ts b/tree-view-sample/src/extension.ts index f236fc55..0b0103c6 100644 --- a/tree-view-sample/src/extension.ts +++ b/tree-view-sample/src/extension.ts @@ -4,29 +4,27 @@ import * as vscode from 'vscode'; import { DepNodeProvider } from './nodeDependencies' import { JsonOutlineProvider } from './jsonOutline' -import { FtpExplorer } from './ftpExplorer.textDocumentContentProvider' +import { FtpExplorer } from './ftpExplorer' import { FileExplorer } from './fileExplorer'; export function activate(context: vscode.ExtensionContext) { - // Complete Tree View Sample - new FtpExplorer(context); - new FileExplorer(context); - - // Following are just data provider samples - const rootPath = vscode.workspace.rootPath; - const nodeDependenciesProvider = new DepNodeProvider(rootPath); - const jsonOutlineProvider = new JsonOutlineProvider(context); + // Samples of `window.registerTreeDataProvider` + const nodeDependenciesProvider = new DepNodeProvider(vscode.workspace.rootPath); vscode.window.registerTreeDataProvider('nodeDependencies', nodeDependenciesProvider); vscode.commands.registerCommand('nodeDependencies.refreshEntry', () => nodeDependenciesProvider.refresh()); vscode.commands.registerCommand('nodeDependencies.addEntry', node => vscode.window.showInformationMessage('Successfully called add entry')); vscode.commands.registerCommand('nodeDependencies.deleteEntry', node => vscode.window.showInformationMessage('Successfully called delete entry')); vscode.commands.registerCommand('extension.openPackageOnNpm', moduleName => vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(`https://www.npmjs.com/package/${moduleName}`))); + const jsonOutlineProvider = new JsonOutlineProvider(context); vscode.window.registerTreeDataProvider('jsonOutline', jsonOutlineProvider); vscode.commands.registerCommand('jsonOutline.refresh', () => jsonOutlineProvider.refresh()); vscode.commands.registerCommand('jsonOutline.refreshNode', offset => jsonOutlineProvider.refresh(offset)); vscode.commands.registerCommand('jsonOutline.renameNode', offset => jsonOutlineProvider.rename(offset)); vscode.commands.registerCommand('extension.openJsonSelection', range => jsonOutlineProvider.select(range)); + // Samples of `window.createView` + new FtpExplorer(context); + new FileExplorer(context); } diff --git a/tree-view-sample/src/ftpExplorer.textDocumentContentProvider.ts b/tree-view-sample/src/ftpExplorer.ts similarity index 100% rename from tree-view-sample/src/ftpExplorer.textDocumentContentProvider.ts rename to tree-view-sample/src/ftpExplorer.ts diff --git a/tree-view-sample/src/nodeDependencies.ts b/tree-view-sample/src/nodeDependencies.ts index b6f26870..7a92b308 100644 --- a/tree-view-sample/src/nodeDependencies.ts +++ b/tree-view-sample/src/nodeDependencies.ts @@ -23,7 +23,7 @@ export class DepNodeProvider implements vscode.TreeDataProvider { vscode.window.showInformationMessage('No dependency in empty workspace'); return Promise.resolve([]); } - + if (element) { return Promise.resolve(this.getDepsInPackageJson(path.join(this.workspaceRoot, 'node_modules', element.label, 'package.json'))); } else { @@ -35,7 +35,7 @@ export class DepNodeProvider implements vscode.TreeDataProvider { return Promise.resolve([]); } } - + } /** diff --git a/tree-view-sample/tsconfig.json b/tree-view-sample/tsconfig.json index 384ad19e..f782f289 100644 --- a/tree-view-sample/tsconfig.json +++ b/tree-view-sample/tsconfig.json @@ -3,9 +3,14 @@ "module": "commonjs", "target": "es6", "outDir": "out", - "lib": ["es6"], + "lib": [ + "es6" + ], "sourceMap": true, - "rootDir": "." + "rootDir": "src" }, - "exclude": ["node_modules", ".vscode-test"] -} + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file diff --git a/tree-view-sample/tslint.json b/tree-view-sample/tslint.json new file mode 100644 index 00000000..522458b3 --- /dev/null +++ b/tree-view-sample/tslint.json @@ -0,0 +1,12 @@ +{ + "rules": { + "indent": [ + true, + "tabs" + ], + "semicolon": [ + true, + "always" + ] + } +} \ No newline at end of file