Commit LFS
This commit is contained in:
Родитель
50ab54386a
Коммит
792ded4db5
|
@ -0,0 +1,5 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
|
@ -0,0 +1,10 @@
|
|||
_build
|
||||
node_modules
|
||||
|
||||
.DS_Store
|
||||
.vscode/spell.json
|
||||
|
||||
.idea
|
||||
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
|
@ -0,0 +1,9 @@
|
|||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"editor.wordWrap": "on",
|
||||
"files.eol": "\n",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"files.associations": {
|
||||
"**/toc.json": "jsonc"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
# Visual Studio Code Documentation
|
||||
|
||||
You've found the GitHub repository that houses the source for the VS Code docs at <https://code.visualstudio.com/docs>.
|
||||
|
||||
## Contribute to VS Code documentation
|
||||
|
||||
Thank you for your interest in VS Code documentation!
|
||||
|
||||
* [Contributing](#contributing)
|
||||
* [Documentation intent](#documentation-intent)
|
||||
* [Repository organization](#repository-organization)
|
||||
* [Branches](#branches)
|
||||
* [Authoring Tools](#authoring-tools)
|
||||
* [How to use Markdown to format your topic](#how-to-use-markdown-to-format-your-topic)
|
||||
* [Topic Metadata](#topic-metadata)
|
||||
* [Formatting](#formatting)
|
||||
|
||||
>**Note**: Before submitting a pull request, especially for rendering or link issues, please review the content on the official VS Code website, [code.visualstudio.com](https://code.visualstudio.com). The element in question may render correctly after processing by the website build.
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute to [VS Code documentation](https://code.visualstudio.com/docs), you need to fork this repository and submit a pull request for the Markdown and/or image changes that you're proposing.
|
||||
|
||||
* [How to fork a repository](https://help.github.com/articles/fork-a-repo)
|
||||
* [How to make a pull request](https://help.github.com/articles/creating-a-pull-request/)
|
||||
* [Changing a commit message](https://help.github.com/articles/changing-a-commit-message/)
|
||||
* [How to squash commits](https://help.github.com/articles/about-pull-request-merges/)
|
||||
|
||||
## Documentation intent
|
||||
|
||||
The goal of the VS Code documentation is to educate users on VS Code features and how VS Code can be used to enhance their development experience with different programming languages and runtimes.
|
||||
|
||||
The documentation is not intended to provide:
|
||||
|
||||
* An introduction to coding or software development
|
||||
* Tutorials on technologies independent from VS Code
|
||||
* Promotion of third-party tools, plug-ins or services
|
||||
* Excessive detail or advanced walkthroughs
|
||||
|
||||
The documentation should target developers learning to use VS Code or searching for quick answers to commonly asked questions. Other forums such as blog posts can provide more detailed content elaborating on specific scenarios.
|
||||
|
||||
## Repository organization
|
||||
|
||||
The content in this repository follows the organization of documentation at <https://code.visualstudio.com/docs>.
|
||||
|
||||
This repository contains the following folders:
|
||||
|
||||
* \setup
|
||||
* \introvideos
|
||||
* \getstarted
|
||||
* \editor
|
||||
* \languages
|
||||
* \extensions
|
||||
* \extensionAPI
|
||||
* \other
|
||||
* \supporting
|
||||
|
||||
Within these folders you'll find the Markdown files used for the content. Each of these folders also contains an \images folder that references the images (such as screenshots) used in the topics.
|
||||
|
||||
### Branches
|
||||
|
||||
We recommend that you create local working branches that target a specific scope of change (and then submit a pull request when your changes are ready). Each branch should be limited to a single concept/topic, both to streamline work flow, and to reduce the possibility of merge conflicts. The following efforts are of the appropriate scope for a new branch:
|
||||
|
||||
* A new topic (and associated images).
|
||||
* Spelling and grammar edits on a topic.
|
||||
* Applying a single formatting change across a large set of topics.
|
||||
|
||||
## Authoring tools
|
||||
|
||||
[Visual Studio Code](https://code.visualstudio.com) is a great editor for Markdown!
|
||||
|
||||
In fact, VS Code and its core documentation are written using VS Code.
|
||||
|
||||
## How to use Markdown to format your topic
|
||||
|
||||
The topics in this repository use Markdown. Here is a good overview of [Markdown basics](https://help.github.com/articles/markdown-basics/).
|
||||
|
||||
## Topic Metadata
|
||||
|
||||
Topic metadata enables certain functionalities for the topics such as table of contents order, topic descriptions, and online search optimization as well as aiding Microsoft in evaluating the effectiveness of the content.
|
||||
|
||||
* **Order** - This is the order that is used in the left rail TOC, the page is left out of the TOC if this is blank
|
||||
* **Area** - General area within VS Code
|
||||
* **TOCTitle** - The title used in the left rail Table of Contents for this page
|
||||
* **PageTitle** - The title used in the HTML title for the page and in search results
|
||||
* **ContentId** - A GUID which uniquely identifies the topic to DevDiv doc reporting.
|
||||
* **DateApproved** - This is set when the page is actually published on the VS Code portal. You can ignore it.
|
||||
* **MetaDescription** - The meta description for this page which helps for search. Use sentence structure limited to 300 characters.
|
||||
* **MetaSocialImage** - Optional. Used for og:image in page header for sharing on social media. Should be 1024 x 512 .png.
|
||||
* **MetaTags** - Optional. Further tags for this page again for search.
|
||||
|
||||
## Product name
|
||||
|
||||
Use the full product name "Visual Studio Code" in the topic MetaDescription and the first use in a topic. You can use the shortened "VS Code" after that throughout the rest of the content. Do not use "VSCode" (no space) or "Code".
|
||||
|
||||
### Metadata for /api docs
|
||||
|
||||
**For Writer**:
|
||||
|
||||
* **MetaDescription** - The meta description for this page which helps for search
|
||||
|
||||
**For Doc Maintainer**:
|
||||
|
||||
* **DateApproved** - This is set when the page is actually published on the VS Code portal.
|
||||
|
||||
## Formatting
|
||||
|
||||
### Headings & Right Nav
|
||||
|
||||
H2 subheadings `##` end up in the right hand jump list for the document (this happens in our compile script). It's a good idea to include h2 subheadings to help users get an overview of the doc and quickly navigate to the major topics.
|
||||
|
||||
### Text formatting
|
||||
|
||||
Use bold for VS Code commands and UI elements.
|
||||
|
||||
**Extensions: Install Extension**
|
||||
**Debug Console**
|
||||
|
||||
Limit the use of bold for emphasis unless it is crucial to get the user's attention. Avoid the use of italics for emphasis since italics doesn't render well on the code.visualstudio.com site.
|
||||
|
||||
Use inline code formatting (backticks) for settings, filename and JSON attributes.
|
||||
|
||||
`files.exclude`
|
||||
`tasks.json`
|
||||
`preLaunchTask`
|
||||
|
||||
Use '>' to show menu sequence.
|
||||
|
||||
**File** > **Preferences** > **Settings**
|
||||
**View** > **Command Palette**
|
||||
|
||||
### Links
|
||||
|
||||
For links within our own documentation, use a site relative link like `/docs/editor/codebasics.md`.
|
||||
|
||||
>For example: `[Why VS Code](/docs/editor/whyvscode.md)` - links to the **Why Visual Studio Code** page
|
||||
|
||||
>**Correction:** For this repo to ease content development you should add the .md suffix. We will parse these out for the website deployment.
|
||||
|
||||
### Bookmarks
|
||||
|
||||
To provide links to h2 subheadings (Markdown ##), the format is `[Link Text](page.md#subheading-title)`.
|
||||
|
||||
Note the subheading title is lowercase and subheading title words are separated by '-' hyphens.
|
||||
|
||||
>For example: `[Keyboard Shortcuts](/docs/editor/codebasics.md#keyboard-shortcuts)` - links to https://code.visualstudio.com/docs/editor/codebasics#_keyboard-shortcuts.
|
||||
|
||||
### Images
|
||||
|
||||
Images are important to bring the product to life - even if people can't try the product, these really help them to see what they are missing.
|
||||
|
||||
For images you're adding to the repo, store them in the `images` subfolder of the TOC section, for example: `editor\images\debugging`.
|
||||
|
||||
When you link to an image, the path and filename are case-sensitive. The convention is for image filenames to be all lowercase.
|
||||
|
||||
>For example: `![Debug Breakpoints](images/debugging/breakpoints.png)`
|
||||
|
||||
### Key bindings
|
||||
|
||||
The VS Code portal is able to show the correct key bindings depending on the reader's operating system (macOS, Windows or Linux).
|
||||
|
||||
To enable this for keyboard shortcuts, use the format `kb(workbench.action.files.openFile)` where the command name is included in parentheses.
|
||||
|
||||
>For a list of key bindings and the relevant `Command Ids` review the [key bindings document](https://code.visualstudio.com/docs/getstarted/keybindings).
|
||||
|
||||
If you are listing out multiple key bindings, you can use a table.
|
||||
|
||||
>Shortcut|Key Strokes
|
||||
>--------|-----------
|
||||
>Cut|`kb(editor.action.clipboardCutAction)`
|
||||
>Copy|`kb(editor.action.clipboardCopyAction)`
|
||||
>Paste|`kb(editor.action.clipboardPasteAction)`
|
||||
|
||||
### Source Code
|
||||
|
||||
For source code we use the fenced code block notation ```` ``` ````.
|
||||
|
||||
>**Note:** You can add an optional language identifier to enable syntax highlighting in your fenced code block. E.g. ```` ```json ```` or ```` ```javascript ````. [Read more →](https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting)
|
||||
|
||||
Some JavaScript code...
|
||||
|
||||
```javascript
|
||||
function fancyAlert(arg) {
|
||||
if (arg) {
|
||||
$.facebox({ div: foo });
|
||||
}
|
||||
}
|
||||
```
|
|
@ -0,0 +1,6 @@
|
|||
Copyright (c) Microsoft Corporation. All rights reserved. Distributed under the following terms:
|
||||
|
||||
1. Documentation is licensed under the [Creative Commons Attribution 3.0 United States License](https://creativecommons.org/licenses/by/3.0/us/legalcode). Code is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
2. This license does not grant you rights to use any trademarks or logos of Microsoft. For Microsoft’s general trademark guidelines, go to https://go.microsoft.com/fwlink/?LinkID=254653.
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<center>
|
||||
<img alt="vscode logo" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Visual_Studio_Code_1.18_icon.svg/1200px-Visual_Studio_Code_1.18_icon.svg.png" width="100px">
|
||||
</center>
|
||||
|
||||
# Visual Studio Code Documentation
|
||||
|
||||
You've found the Visual Studio Code documentation GitHub repository, which contains the content for the [Visual Studio Code documentation](https://code.visualstudio.com/docs).
|
||||
|
||||
Topics submitted here will be published to the [Visual Studio Code](https://code.visualstudio.com) portal.
|
||||
|
||||
If you are looking for the VS Code product GitHub repository, you can find it [here](https://github.com/Microsoft/vscode).
|
||||
|
||||
## Index
|
||||
1. [About Visual Studio Code](#visual-studio-code)
|
||||
2. [Contributing to the documentation](#contributing-to-the-documentation)
|
||||
3. [Feedback](#feedback)
|
||||
4. [Documentation Issues](#documentation-issues)
|
||||
5. [Editing](#editing)
|
||||
6. [Publishing](#publishing)
|
||||
|
||||
## Visual Studio Code
|
||||
|
||||
[VS Code](https://code.visualstudio.com/) is a lightweight source code editor and powerful development environment for building and debugging modern web and cloud applications. It is free and available on your favorite platform - Linux, macOS, and Windows.
|
||||
|
||||
If you landed here looking for other information about VS Code, head over to [our website](https://code.visualstudio.com) for additional information.
|
||||
|
||||
## Contributing to the documentation
|
||||
|
||||
To contribute with new topics/information or make changes to existing documentation, see [contributing](https://github.com/Microsoft/vscode-docs/blob/master/CONTRIBUTING.md#contributing) for instructions and guidelines.
|
||||
|
||||
## Feedback
|
||||
|
||||
If you want to give documentation feedback, please use the feedback control located at the bottom of each documentation page.
|
||||
|
||||
## Documentation Issues
|
||||
|
||||
To enter documentation bugs, please create a [new GitHub issue](https://github.com/Microsoft/vscode-docs/issues) (try to check if there isn't a topic about your issue already).
|
||||
|
||||
If you think the issue is with the VS Code product itself, please enter issues [here](https://github.com/Microsoft/vscode/issues).
|
||||
|
||||
## Editing
|
||||
|
||||
In order to edit the VS Code documentation, ensure that you have [Git](https://git-scm.com/downloads) installed.
|
||||
|
||||
Clone a copy of the repo:
|
||||
|
||||
```
|
||||
git clone https://github.com/Microsoft/vscode-docs.git
|
||||
```
|
||||
|
||||
VS Code itself is great for reviewing and editing [Markdown](https://code.visualstudio.com/docs/languages/markdown) with nice preview support.
|
||||
|
||||
If you want to use VS Code, simply navigate to the `vscode-docs` directory and launch VS Code from there:
|
||||
|
||||
```
|
||||
cd vscode-docs
|
||||
code .
|
||||
```
|
||||
|
||||
You can open any of the Markdown files and see a preview with the **Open Preview to the Side** button in the upper right of the editor.
|
||||
|
||||
![Markdown Preview Button](images/MDPreviewButton.png)
|
||||
|
||||
## Publishing
|
||||
|
||||
Steps for how to publish documentation changes can be found [here](https://github.com/Microsoft/vscode-website#publishing-a-documentation-change) in the (private) repository of the VS Code website.
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"printWidth": 92,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 106AA11C-DB26-493A-9E3C-16F513B2AEC8
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: The Visual Studio Code Extension Host is responsible for managing extensions and ensuring the stability and performance of Visual Studio Code.
|
||||
---
|
||||
|
||||
# Extension Host
|
||||
|
||||
As you learned in the [Extension Anatomy](/api/get-started/extension-anatomy) topic, an extension exposes the `activate` and `deactivate` methods and VS Code will manage its lifecycle. This topic provides more details on the **Extension Host** that manages all running extensions.
|
||||
|
||||
**Extension host** is a Node.js process in VS Code responsible for loading and running extensions. Although you don't need to worry about the Extension Host when you are writing extensions, it is still useful to know what the Extension Host does to your extension.
|
||||
|
||||
## Stability and Performance
|
||||
|
||||
VS Code aims to deliver a stable and performant editor to end users, and misbehaving extensions should not impact the user experience. The Extension Host in VS Code prevents extensions from:
|
||||
|
||||
- Impacting startup performance
|
||||
- Slowing down UI operations
|
||||
- Modifying the UI
|
||||
|
||||
Additionally, VS Code lets extensions declare its [Activation Events](/api/references/activation-events) and loads them lazily. For example, the Markdown extension should only be loaded when a user opens a Markdown file. This makes sure that extensions do not consume unnecessary CPU and memory.
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: f4d4e9e0-8901-405c-aaf5-faa16c32588b
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Use Visual Studio Code's Proposed API
|
||||
---
|
||||
|
||||
# Using Proposed API
|
||||
|
||||
At Visual Studio Code, we take Extension API compatibility seriously. We give our best effort to avoid breaking API changes, and extension authors could expect published extensions to continue to work. However, this puts great limitation on us: once we introduce an API, we cannot easily change it any more.
|
||||
|
||||
Proposed API solves the problem for us. Proposed API is a set of unstable API that are implemented in VS Code but not exposed to the public as stable API does. They are **subject to change**, **only available in Insider distribution** and **cannot be used in published extensions**. Nevertheless, extension authors could test these new API in local development and provide feedback for VS Code team to iterate on the API. Eventually, Proposed API finds their way into the stable API and becomes available for general use.
|
||||
|
||||
## Using Proposed API
|
||||
|
||||
These are the steps for testing Proposed API in local extension development:
|
||||
|
||||
- Use [Insiders](/insiders) release of VS Code.
|
||||
- Add `"enableProposedApi": true` to your `package.json`.
|
||||
- Copy the latest version of the [`vscode.proposed.d.ts`](https://github.com/Microsoft/vscode/blob/master/src/vs/vscode.proposed.d.ts) into your project.
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 9c48dfbf-e49d-4f33-aadc-5ebf06d5dde0
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Common capabilities that Visual Studio Code extensions (plug-ins) can take advantage of
|
||||
---
|
||||
|
||||
# Common Capabilities
|
||||
|
||||
Common Capabilities are important building blocks for your extensions. Almost all extensions use some of these functionalities. Here is how you can take advantage of them.
|
||||
|
||||
## Command
|
||||
|
||||
Command is central to how VS Code works. You open the Command Palette to execute commands, bind custom keybindings to commands, and right-click to invoke commands in Context Menus.
|
||||
|
||||
An extension could:
|
||||
|
||||
- Register and execute commands with the [`vscode.commands`](/api/references/vscode-api#commands) API.
|
||||
- Make commands available in the Command Palette with the [`contributes.commands`](/api/references/contribution-points#contributes.commands) Contribution Point.
|
||||
|
||||
Learn more about commands at the [Extension Guides / Command](/api/extension-guides/command) topic.
|
||||
|
||||
## Configuration
|
||||
|
||||
An extension can contribute extension-specific settings with the [`contributes.configuration`](/api/references/contribution-points#contributes.configuration) Contribution Point and read them using the [`workspace.getConfiguration`](/api/references/vscode-api#workspace.getConfiguration) API.
|
||||
|
||||
## Keybinding
|
||||
|
||||
An extension can add custom keybindings. Read more in the [`contributes.keybindings`](/api/references/contribution-points#contributes.keybindings) and [Key Bindings](/docs/getstarted/keybindings) topics.
|
||||
|
||||
## Context Menu
|
||||
|
||||
An extension can register custom Context Menu items that will be displayed in different parts of the VS Code UI on right-click. Read more at the [`contributes.menus`](/api/references/contribution-points#contributes.menus) Contribution Point.
|
||||
|
||||
## Data Storage
|
||||
|
||||
There are three options for storing data:
|
||||
|
||||
- [`ExtensionContext.workspaceState`](/api/references/vscode-api#ExtensionContext.workspaceState): A workspace storage where you can write key/value pairs. VS Code manages the storage and will restore it when the same workspace is opened again.
|
||||
- [`ExtensionContext.globalState`](/api/references/vscode-api#ExtensionContext.globalState): A global storage where you can write key/value pairs. VS Code manages the storage and will restore it for each extension activation.
|
||||
- [`ExtensionContext.storagePath`](/api/references/vscode-api#ExtensionContext.storagePath): A workspace specific storage path pointing to a local directory where your extension has write/read access. This is a good option if you need to store large files that is accessible only from current workspace.
|
||||
- [`ExtensionContext.globalStoragePath`](/api/references/vscode-api#ExtensionContext.globalStoragePath): A global storage path pointing to a local directory where your extension has write/read access. This is a good option if you need to store large files that is accessible from all workspaces.
|
||||
|
||||
The extension context is available to the `activate` function in the [Extension Entry File](/api/get-started/extension-anatomy#extension-entry-file).
|
||||
|
||||
## Display Notifications
|
||||
|
||||
Almost all extensions need to present information to the user at some point. VS Code offers three APIs for displaying notification messages of different severity:
|
||||
|
||||
- [`window.showInformationMessage`](/api/references/vscode-api#window.showInformationMessage)
|
||||
- [`window.showWarningMessage`](/api/references/vscode-api#window.showWarningMessage)
|
||||
- [`window.showErrorMessage`](/api/references/vscode-api#window.showErrorMessage)
|
||||
|
||||
## Quick Pick
|
||||
|
||||
With the [`vscode.QuickPick`](/api/references/vscode-api#QuickPick) API, you can easily collect user input or let the user make a selection from multiple options. The [QuickInput Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/quickinput-sample) illustrates the API.
|
||||
|
||||
## File Picker
|
||||
|
||||
Extensions can use the [`vscode.window.showOpenDialog`](/api/references/vscode-api#vscode.window.showOpenDialog) API to open the system file picker and select files or folders.
|
||||
|
||||
## Output Channel
|
||||
|
||||
The Output Panel displays a collection of [`OutputChannel`](/api/references/vscode-api#OutputChannel), which are great for logging purpose. You can easily take advantage of it with the [`window.createOutputChannel`](/api/references/vscode-api#window.createOutputChannel) API.
|
||||
|
||||
## Progress API
|
||||
|
||||
You can use the [`vscode.Progress`](/api/references/vscode-api#Progress) API for reporting progress updates to the user.
|
||||
|
||||
Progress can be shown in different locations using the [`ProgressLocation`](/api/references/vscode-api#ProgressLocation) option:
|
||||
|
||||
- In the Notifications area
|
||||
- In the Source Control view
|
||||
- General progress in the VS Code window
|
||||
|
||||
The [Progress Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/progress-sample) illustrates this API.
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# Extending Core Functionalities
|
||||
|
||||
Talk about the core functionalities that extension could plug-in their providers for:
|
||||
|
||||
- File System Provider
|
||||
- Search Provider
|
||||
- SCM Provider
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: e0d5bd37-f020-4235-ad81-c977baaeb24f
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Explain how to extend Visual Studio Code's workbench area with custom UI components
|
||||
---
|
||||
|
||||
# Extending Workbench
|
||||
|
||||
"Workbench" refers to the overall Visual Studio Code UI that encompasses the following UI components:
|
||||
|
||||
- Title Bar
|
||||
- Activity Bar
|
||||
- Side Bar
|
||||
- Panel
|
||||
- Editor Group
|
||||
- Status Bar
|
||||
|
||||
VS Code provides various APIs that allow you to add your own components to the Workbench. For example, in the image below:
|
||||
|
||||
![workbench-contribution](images/extending-workbench/workbench-contribution.png)
|
||||
|
||||
- Activity Bar: The [Azure App Service extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice) adds a [View Container](#view-container)
|
||||
- Side Bar: The built-in [NPM extension](https://github.com/Microsoft/vscode/tree/master/extensions/npm) adds a [Tree View](#tree-view) to the Explorer View
|
||||
- Editor Group: The built-in [Markdown extension](https://github.com/Microsoft/vscode/tree/master/extensions/markdown-language-features) adds a [Webview](#webview) next to other editors in the Editor Group
|
||||
- Status Bar: The [VSCodeVim extension](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) adds a [Status Bar Item](#status-bar-item) in the Status Bar
|
||||
|
||||
## Views Container
|
||||
|
||||
With the [`contributes.viewsContainers`](/api/references/contribution-points#contributes.viewsContainers) Contribution Point, you can add new Views Containers that display next to the five built-in Views Containers. Learn more at the [Tree View](/api/extension-guides/tree-view) topic.
|
||||
|
||||
## Tree View
|
||||
|
||||
With the [`contributes.views`](/api/references/contribution-points#contributes.views) Contribution Point, you can add new Views that display in any of the View Containers. Learn more at the [Tree View](/api/extension-guides/tree-view) topic.
|
||||
|
||||
## Webview
|
||||
|
||||
Webviews are highly customizable views built with HTML/CSS/JavaScript. They display next to text editors in the Editor Group areas. Read more about Webview in the [Webview Guide](/api/extension-guides/webview).
|
||||
|
||||
## Status Bar Item
|
||||
|
||||
Extensions can create custom [`StatusBarItem`](/api/references/vscode-api#StatusBarItem) that display in the Status Bar. Status Bar Items can show text and icons and run commands on click events.
|
||||
|
||||
- Show text and icons
|
||||
- Run a command on click
|
||||
|
||||
A Status Bar extension sample can be found [here](https://github.com/Microsoft/vscode-extension-samples/tree/master/statusbar-sample).
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5776da85f8813b18ade37dc4ceece172001ee5a5308d20caa05b437450ccb787
|
||||
size 417626
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:150f31aeda53cfe4eb832a69457f3258fdd5f262d286db5b5acaeb1610a356f6
|
||||
size 275820
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f791379a21d1276af0571483da9235ec0fd79aa33b8eef5d75b69bc3000bb8ed
|
||||
size 664370
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: d22675fc-6609-43f2-a66b-8f2a52597195
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn the details of what's possible with Visual Studio Code's rich extension (plug-in) API.
|
||||
---
|
||||
|
||||
# Extensions Capabilities Overview
|
||||
|
||||
Visual Studio Code offers many ways for extensions to extend its capabilities. It can sometimes be hard to find the right [Contribution Points](/api/references/contribution-points) and [VS Code API](/api/references/vscode-api) to use. This topic splits extension capabilities into a few categories. Each category describes:
|
||||
|
||||
- Some functionalities your extension could use
|
||||
- Links to more detailed topics for using these functionalities
|
||||
- A few extension ideas
|
||||
|
||||
However, we also impose [restrictions](#restrictions) upon extensions to ensure the stability and performance of VS Code. For example, extensions cannot access the DOM of VS Code UI.
|
||||
|
||||
## Common Capabilities
|
||||
|
||||
[Common Capabilities](./common-capabilities) are core pieces of functionality that you can use in any extension.
|
||||
|
||||
Some of these capabilities include:
|
||||
|
||||
- Registering commands, configurations, keybindings, or context menu items.
|
||||
- Storing workspace or global data.
|
||||
- Displaying notification messages.
|
||||
- Using Quick Pick to collect user input.
|
||||
- Open the system file picker to let users select files or folders.
|
||||
- Use the Progress API to indicate long-running operations.
|
||||
|
||||
## Theming
|
||||
|
||||
[Theming](./theming) controls the look of VS Code, both the colors of source code in the editor and the colors of the VS Code UI. If you've ever wanted to make it look like you're coding the Matrix by making VS Code different shades of green, or just wanted to create the ultimate, minimalist grayscale workspace, then themes are for you.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Change colors of your source code.
|
||||
- Change colors of the VS Code UI.
|
||||
- Port an existing TextMate theme to VS Code.
|
||||
- Add custom file icons.
|
||||
|
||||
## Declarative Language Features
|
||||
|
||||
[Declarative Language Features](/api/language-extensions/overview#declarative-language-features) adds basic text editing support for a programming language such as bracket matching, auto-indentation and syntax highlighting. This is done declaratively, without writing any code. For more advanced language features, like IntelliSense or debugging, see [Programmatic Language Features](#programmatic-language-features).
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Bundle common JavaScript snippets into an extension.
|
||||
- Tell VS Code about a new programming language.
|
||||
- Add or replace the grammar for a programming language.
|
||||
- Extend an existing grammar with grammar injections.
|
||||
- Port an existing TextMate grammar to VS Code.
|
||||
|
||||
## Programmatic Language Features
|
||||
|
||||
[Programmatic Language Features](/api/language-extensions/overview#programmatic-language-features) add rich programming language support such as Hovers, Go to Definition, diagnostic errors, IntelliSense and CodeLens. These language features are exposed through the [`vscode.languages.*`](/api/references/vscode-api#languages) API. An extension can either use these API directly, or write a Language Server and adapt it to VS Code using the VS Code [Language Server library](https://github.com/Microsoft/vscode-languageserver-node).
|
||||
|
||||
Although we provide a listing of [language features](/api/language-extensions/programmatic-language-features) and their intended usage, nothing prevents you from using these API creatively. For example, CodeLens and Hovers are a great way to present additional information inline, while diagnostic errors can be used to highlight spelling or code style errors.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Add hovers that show sample usage of an API.
|
||||
- Report spelling or linter errors in source code using diagnostics.
|
||||
- Register a new code formatter for HTML.
|
||||
- Provide rich, context-aware IntelliSense.
|
||||
- Add folding, breadcrumbs and outline support for a language.
|
||||
|
||||
## Workbench Extensions
|
||||
|
||||
[Workbench Extensions](./extending-workbench) extend the VS Code Workbench UI. Add new right-click actions to the File Explorer, or even build a custom explorer using VS Code's [TreeView](/api/extension-guides/tree-view) API. And if your extension needs a fully customized user interface, use the [Webview API](/api/extension-guides/webview) to build your own document preview or UI using standard HTML, CSS, and JavaScript.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Add custom context menu actions to the File Explorer.
|
||||
- Create a new, interactive TreeView in the Side Bar.
|
||||
- Define a new Activity Bar view.
|
||||
- Show new information in the Status Bar.
|
||||
- Render custom content using the `WebView` API.
|
||||
- Contribute Source Control providers.
|
||||
|
||||
## Debugging
|
||||
|
||||
You can take advantage of VS Code's [Debugging](/docs/editor/debugging) functionality by writing [Debugger Extensions](/api/extension-guides/debugger-extension) that connect VS Code's debugging UI to a specific debugger or runtime.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Connect VS Code's debugging UI to a debugger or runtime by contributing a [Debug Adapter implementation](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/).
|
||||
- Specify the languages supported by a debugger extension.
|
||||
- Provide rich IntelliSense and hover information for the debug configuration attributes used by the debugger.
|
||||
- Provide debug configuration snippets.
|
||||
|
||||
On the other hand, VS Code also offers a set of [Debug Extension API](/api/references/vscode-api#debug), with which you can implement debug-related functionality on top of any VS Code debugger, in order to automate users' debugging experience.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Start debug sessions based on dynamically created debug configurations.
|
||||
- Track the lifecycle of debug sessions.
|
||||
- Create and manage breakpoints programmatically.
|
||||
|
||||
<!-- Add below content back after writing ./extending-core-functionalities.md -->
|
||||
<!-- ## Core Extensions
|
||||
|
||||
[Core Extensions](extending-core-functionalities) are for very advanced users. These let you build a custom back end for many of VS Code's low-level functionality. For example, the `FileSystem` API can be used to support working with files over FTP or other protocols. Core extensions typically work transparently from a user's point of view.
|
||||
|
||||
**Extension Ideas**
|
||||
|
||||
- Add support for working with remote files over FTP or SFTP.
|
||||
- Register new source control provider, such as Mercurial.
|
||||
- Implement a custom file search provider. -->
|
||||
|
||||
## Restrictions
|
||||
|
||||
There are certain restrictions we impose upon extensions. Here are the restrictions and their purposes.
|
||||
|
||||
### No DOM Access
|
||||
|
||||
Extensions have no access to the DOM of VS Code UI. You **cannot** write an extension that applies custom CSS to VS Code or adds a HTML element to VS Code UI.
|
||||
|
||||
At VS Code, we're continually trying to optimize use of the underlying web technologies to deliver an always available, highly responsive editor and we will continue to tune our use of the DOM as these technologies and our product evolve. To ensure that extensions cannot interfere with the stability and performance of VS Code, and that we can continue to improve the DOM of VS Code without breaking existing extensions, we run extensions in an [Extension Host](/api/advanced-topics/extension-host) process and prevent direct access to the DOM.
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 37b6ae0a-d1b5-48b6-9bd4-9b50ef11d573
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn how to add custom themes for colors and icons in Visual Studio Code.
|
||||
---
|
||||
|
||||
# Theming
|
||||
|
||||
In Visual Studio Code, there are two types of themes:
|
||||
|
||||
- **Color Theme**: A mapping from both UI Component Identifier and Text Token Identifier to colors. Color theme allows you to apply your favorite colors to both VS Code UI Components and the text in the editor.
|
||||
- **Icon Theme**: A mapping from file type / file name to images. The file icon is displayed across the VS Code UI in places such as File Explorer, Quick Open List, and Editor Tab.
|
||||
|
||||
## Color Theme
|
||||
|
||||
![color-theme](images/theming/color-theme.png)
|
||||
|
||||
As you can see in the illustration, Color Theme defines two mappings:
|
||||
|
||||
- The `colors` mapping that controls colors for UI Components.
|
||||
- The `tokenColors` mapping that controls colors for each source code token (your source code is broken into tokens by a [grammar](/api/language-extensions/syntax-highlight-guide)).
|
||||
|
||||
We have a [Color Theme Guide](/api/extension-guides/color-theme) and a [Color Theme Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/theme-sample) that illustrates how to create a theme.
|
||||
|
||||
## Icon Theme
|
||||
|
||||
Icon themes allow you to:
|
||||
|
||||
- Create a mapping from unique icon identifiers to images or font icons.
|
||||
- Associate files to these unique icon identifiers by filenames or file language types.
|
||||
|
||||
The [Icon Theme Guide](/api/extension-guides/icon-theme) discusses how to create an Icon Theme.
|
||||
|
||||
![icon-theme](images/theming/icon-theme.png)
|
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 113b458a-3692-4ccf-a181-048bd572a120
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide to creating Color Theme in Visual Studio Code
|
||||
---
|
||||
|
||||
# Color Theme
|
||||
|
||||
Colors visible in the Visual Studio Code user interface fall in two categories:
|
||||
|
||||
- Workbench colors used in views and editors, from the Activity Bar to the Status Bar. A complete list of all these colors can be found in the [theme color reference](/api/references/theme-color).
|
||||
- Syntax colors used for source code in the editor. The theming of these colors is different as syntax colorization is based on TextMate grammars and TextMate themes.
|
||||
|
||||
This guide will cover the different ways in which you can create themes.
|
||||
|
||||
## Workbench colors
|
||||
|
||||
The easiest way to create a new workbench color theme is to start with an existing color theme and customize it. First switch to the color theme that you want to modify, then open your [settings](/docs/getstarted/settings) and make changes to the `workbench.colorCustomizations` setting. Changes are applied live to your VS Code instance.
|
||||
|
||||
The following, for example, would change the color of the title bar:
|
||||
|
||||
```json
|
||||
{
|
||||
"workbench.colorCustomizations": {
|
||||
"titleBar.activeBackground": "#ff0000"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A complete list of all themable colors can be found in the [color reference](/api/references/theme-color).
|
||||
|
||||
## Syntax colors
|
||||
|
||||
For syntax highlighting colors, there are two approaches. You just simply reference an existing TextMate theme (`.tmTheme` file) from the community, or you can come up with your own theming rules. The easiest way is to start with an existing theme and customize it, much like in the workbench colors section above.
|
||||
|
||||
First switch to the color theme to customize and use the `editor.tokenColorCustomizations` [settings](/docs/getstarted/settings). Changes are applied live to your VS Code instance and no refreshing or reloading is necessary.
|
||||
|
||||
For example, the following would change the color of comments within the editor:
|
||||
|
||||
```json
|
||||
{
|
||||
"editor.tokenColorCustomizations": {
|
||||
"comments": "#FF0000"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The setting supports a simple model with a set of common token types such as 'comments', 'strings' and 'numbers' available. If you want to color more than that, you need to use TextMate theme rules directly, which are explained in detail in the [Syntax Highlighting Guide](/api/language-extensions/syntax-highlight-guide).
|
||||
|
||||
## Create a new Color Theme
|
||||
|
||||
Once you have tweaked your theme colors using `workbench.colorCustomizations` and `editor.tokenColorCustomizations`, it's time to create the actual theme.
|
||||
|
||||
1. Generate a theme file using the **Developer: Generate Color Theme from Current Settings** command from the **Command Palette**
|
||||
2. Use VS Code's [Yeoman](http://yeoman.io) extension generator to generate a new theme extension:
|
||||
|
||||
```bash
|
||||
npm install -g yo generator-code
|
||||
yo code
|
||||
```
|
||||
|
||||
3. If you customized a theme as described above, select 'Start fresh'.
|
||||
|
||||
![yo code theme](./images/color-theme/yocode-colortheme.png)
|
||||
|
||||
4. Copy the theme file generated from your settings to the new extension.
|
||||
|
||||
You can also use an existing TextMate theme by telling the extension generator to import a TextMate theme file (.tmTheme) and package it for use in VS Code. Alternatively, if you have already downloaded the theme, replace the `tokenColors` section with a link to the `.tmTheme` file to use.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "dark",
|
||||
"colors": {
|
||||
"editor.background": "#1e1e1e",
|
||||
"editor.foreground": "#d4d4d4",
|
||||
"editorIndentGuide.background": "#404040",
|
||||
"editorRuler.foreground": "#333333",
|
||||
"activityBarBadge.background": "#007acc",
|
||||
"sideBarTitle.foreground": "#bbbbbb"
|
||||
},
|
||||
"tokenColors": "./Diner.tmTheme"
|
||||
}
|
||||
```
|
||||
|
||||
> **Tip:** Give your color definition file the `.color-theme.json` suffix and you will get hovers, code completion, color decorators, and color pickers when editing.
|
||||
|
||||
> **Tip:** [ColorSublime](https://colorsublime.github.io) has hundreds of existing TextMate themes to choose from. Pick a theme you like and copy the Download link to use in the Yeoman generator or into your extension. It will be in a format like `"https://raw.githubusercontent.com/Colorsublime/Colorsublime-Themes/master/themes/(name).tmTheme"`
|
||||
|
||||
## Test a new Color Theme
|
||||
|
||||
To try out the new theme, press F5 to launch an Extension Development Host window.
|
||||
|
||||
There, open the Color Theme picker with **File** > **Preferences** > **Color Theme** and you can see your theme in the drop-down list. Arrow up and down to see a live preview of your theme.
|
||||
|
||||
![select my theme](images/color-theme/mytheme.png)
|
||||
|
||||
Changes to the theme file are applied live in the `Extension Development Host` window.
|
||||
|
||||
## Publishing a Theme to the Extension Marketplace
|
||||
|
||||
If you'd like to share your new theme with the community, you can publish it to the [Extension Marketplace](/docs/editor/extension-gallery). Use the [vsce publishing tool](/api/working-with-extensions/publishing-extension) to package your theme and publish it to the VS Code Marketplace.
|
||||
|
||||
> **Tip:** To make it easy for users to find your theme, include the word "theme" in the extension description and set the `Category` to `Theme` in your `package.json`.
|
||||
|
||||
We also have recommendations on how to make your extension look great on the VS Code Marketplace, see [Marketplace Presentation Tips](/api/references/extension-manifest#marketplace-presentation-tips).
|
||||
|
||||
## Adding a new Color Id
|
||||
|
||||
Color ids can also be contributed by extensions through the [color contribution point](/api/references/contribution-points#contributes.colors). These colors also appear when using code complete in the `workbench.colorCustomizations` settings and the color theme definition file. Users can see what colors an extension defines in the [extension contributions](/docs/editor/extension-gallery#_extension-details) tab.
|
||||
|
||||
## Further reading
|
||||
|
||||
- [CSS Tricks - Creating a VS Code theme](https://css-tricks.com/creating-a-vs-code-theme/)
|
|
@ -0,0 +1,201 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 995c7085-5fc0-44e0-a171-30a759c0b7da
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide to using commands programmatically in Visual Studio Code extensions (plug-ins)
|
||||
---
|
||||
|
||||
# Commands
|
||||
|
||||
Commands trigger actions in Visual Studio Code. If you have ever [configured a keybinding](/docs/getstarted/keybindings), then you've worked with commands. Commands are also used by extensions to expose functionality to users, bind to actions in VS Code's UI, and implement internal logic.
|
||||
|
||||
## Using Commands
|
||||
|
||||
VS Code includes a large set of [built-in commands](/api/references/commands) that you can use to interact with the editor, control the user interface, or perform background operations. Many extensions also expose their core functionality as commands that users and other extensions can leverage.
|
||||
|
||||
### Programmatically executing a command
|
||||
|
||||
The [`vscode.commands.executeCommand`](/api/references/vscode-api#commands.executeCommand) API programmatically executes a command. This lets you leverage VS Code's built-in functionality, and build on extensions such as VS Code's built-in Git and Markdown extensions.
|
||||
|
||||
The `editor.action.addCommentLine` command, for example, comments the currently selected lines in the active text editor:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
function commentLine() {
|
||||
vscode.commands.executeCommand('editor.action.addCommentLine');
|
||||
}
|
||||
```
|
||||
|
||||
Some commands take arguments that control their behavior. Commands may also return a result. The API-like `vscode.executeDefinitionProvider` command, for example, queries a document for definitions at a given position. It takes a document URI and a position as arguments, and returns a promise with a list of definitions:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
async function printDefinitionsForActiveEditor() {
|
||||
const activeEditor = vscode.window.activeTextEditor;
|
||||
if (!activeEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const definitions = await vscode.commands.executeCommand<vscode.Location[]>(
|
||||
'vscode.executeDefinitionProvider',
|
||||
activeEditor.document.uri,
|
||||
activeEditor.selection.active
|
||||
);
|
||||
|
||||
for (const definition of definitions) {
|
||||
console.log(definition);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To find available commands:
|
||||
|
||||
- [Browse the keyboard shortcuts](/docs/getstarted/keybindings)
|
||||
- [Look through VS Code's built-in advanced commands api](/api/references/commands)
|
||||
|
||||
### Command URIs
|
||||
|
||||
Commands URIs are links that execute a given command. They can be used as clickable links in hover text, completion item details, or inside of webviews.
|
||||
|
||||
A command URI uses the `command` scheme followed by the command name. The command URI for the `editor.action.addCommentLine` command, for example, is `command:editor.action.addCommentLine`. Here's a hover provider that shows a link in the comments of the current line in the active text editor:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
vscode.languages.registerHoverProvider(
|
||||
'javascript',
|
||||
new class implements vscode.HoverProvider {
|
||||
provideHover(
|
||||
_document: vscode.TextDocument,
|
||||
_position: vscode.Position,
|
||||
_token: vscode.CancellationToken
|
||||
): vscode.ProviderResult<vscode.Hover> {
|
||||
const commentCommandUri = vscode.Uri.parse(`command:editor.action.addCommentLine`);
|
||||
const contents = new vscode.MarkdownString(`[Add comment](${commentCommandUri})`);
|
||||
|
||||
// To enable command URIs in Markdown content, you must set the `isTrusted` flag.
|
||||
// When creating trusted Markdown string, make sure to properly sanitize all the
|
||||
// input content so that only expected command URIs can be executed
|
||||
contents.isTrusted = true;
|
||||
|
||||
return new vscode.Hover(contents);
|
||||
}
|
||||
}()
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The list of arguments to the command is passed as a JSON array that has been properly URI encoded: The example below uses the `git.stage` command to create a hover like that stages the current file:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
vscode.languages.registerHoverProvider(
|
||||
'javascript',
|
||||
new class implements vscode.HoverProvider {
|
||||
provideHover(
|
||||
document: vscode.TextDocument,
|
||||
_position: vscode.Position,
|
||||
_token: vscode.CancellationToken
|
||||
): vscode.ProviderResult<vscode.Hover> {
|
||||
const args = [{ resourceUri: document.uri }];
|
||||
const stageCommandUri = vscode.Uri.parse(
|
||||
`command:git.stage?${encodeURIComponent(JSON.stringify(args))}`
|
||||
);
|
||||
const contents = new vscode.MarkdownString(`[Stage file](${stageCommandUri})`);
|
||||
contents.isTrusted = true;
|
||||
return new vscode.Hover(contents);
|
||||
}
|
||||
}()
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Creating new commands
|
||||
|
||||
### Registering a command
|
||||
|
||||
[`vscode.commands.registerCommand`](/api/references/vscode-api#commands.registerCommand) binds a command id to a handler function in your extension:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const command = 'myExtension.sayHello';
|
||||
|
||||
const commandHandler = (name?: string = 'world') => {
|
||||
console.log(`Hello ${name}!!!`);
|
||||
};
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand(command, commandHandler));
|
||||
}
|
||||
```
|
||||
|
||||
The handler function will be invoked whenever the `myExtension.sayHello` command is executed, be it programmatically with `executeCommand`, from the VS Code UI, or through a keybinding.
|
||||
|
||||
### Creating a user facing command
|
||||
|
||||
`vscode.commands.registerCommand` only binds a command id to a handler function. To expose this command in the Command Palette so it is discoverable by users, you also need a corresponding command `contribution` in your extension's `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "myExtension.sayHello",
|
||||
"title": "Say Hello"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `commands` contribution tells VS Code that your extension provides a given command, and also lets you control how the command is displayed in the UI. Now our command will show up in the Command Palette:
|
||||
|
||||
![The contributed command in the Command Palette](images/commands/palette.png)
|
||||
|
||||
We still need to call `registerCommand` to actually tie the command id to the handler. This means that if the user selects the `myExtension.sayHello` command from the Command Palette but our extension has not been activated yet, nothing will happen. To prevent this, extensions must register an `onCommand` `activiationEvent` for all user facing commands:
|
||||
|
||||
```json
|
||||
{
|
||||
"activationEvents": ["onCommand:myExtension.sayHello"]
|
||||
}
|
||||
```
|
||||
|
||||
Now when a user first invokes the `myExtension.sayHello` command from the Command Palette or through a keybinding, the extension will be activated and `registerCommand` will bind `myExtension.sayHello` to the proper handler.
|
||||
|
||||
You do not need an `onCommand` activation event for internal commands but you must define them for any commands that:
|
||||
|
||||
- Can be invoked using the Command Palette.
|
||||
- Can be invoked using a keybinding.
|
||||
- Can be invoked through the VS Code UI, such as through the editor title bar.
|
||||
- Is intended as an API for other extensions to consume.
|
||||
|
||||
### Controlling when a command shows up in the Command Palette
|
||||
|
||||
By default, all user facing commands contributed through the `commands` section of the `package.json` show up in the Command Palette. However, many commands are only relevant in certain circumstances, such as when there is an active text editor of a given language or when the user has a certain configuration option set.
|
||||
|
||||
The [`menus.commandPalette`](/api/references/contribution-points#contributes.menus) contribution point lets you restrict when a command should show in the Command Palette. It takes the id of the target command and a [when clause](/docs/getstarted/keybindings#_when-clause-contexts) that controls when the command is shown:
|
||||
|
||||
```json
|
||||
{
|
||||
"contributes": {
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "myExtension.sayHello",
|
||||
"when": "editorLangId == markdown"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now the `myExtension.sayHello` command will only show up in the Command Palette when the user is in a Markdown file.
|
|
@ -0,0 +1,367 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 49EF49AD-8BE6-4D46-ADC8-D678BDC04E85
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn how to provide debugger extensions (plug-ins) for Visual Studio Code through a Debug Adapter.
|
||||
---
|
||||
|
||||
# Debugger Extension
|
||||
|
||||
Visual Studio Code's debugging architecture allows extension authors to easily integrate existing debuggers into VS Code, while having a common user interface with all of them.
|
||||
|
||||
VS Code ships with one built-in debugger extension, the [Node.js](https://nodejs.org) debugger extension, which is an excellent showcase for the many debugger features supported by VS Code:
|
||||
|
||||
![VS Code Debug Features](images/debugger-extension/debug-features.png)
|
||||
|
||||
This screenshot shows the following debugging features:
|
||||
|
||||
1. Debug configuration management.
|
||||
2. Debug actions for starting/stopping and stepping.
|
||||
3. Source-, function-, conditional-, inline breakpoints, and log points.
|
||||
4. Stack traces, including multi-thread and multi-process support.
|
||||
5. Navigating through complex data structures in views and hovers.
|
||||
6. Variable values shown in hovers or inlined in the source.
|
||||
7. Managing watch expressions.
|
||||
8. Debug console for interactive evaluation with autocomplete.
|
||||
|
||||
This documentation will help you create a debugger extension which can make any debugger work with VS Code.
|
||||
|
||||
## Debugging Architecture of VS Code
|
||||
|
||||
VS Code implements a generic (language-agnostic) debugger UI based on an abstract protocol that we've introduced to communicate with debugger backends.
|
||||
Because debuggers typically do not implement this protocol, some intermediary is needed to "adapt" the debugger to the protocol.
|
||||
This intermediary is typically a standalone process that communicates with the debugger.
|
||||
|
||||
![VS Code Debug Architecture](images/debugger-extension/debug-arch1.png)
|
||||
|
||||
We call this intermediary the **Debug Adapter** (or **DA** for short) and the abstract protocol that is used between the DA and VS Code is the **Debug Adapter Protocol** (**DAP** for short).
|
||||
Since the Debug Adapter Protocol is independent from VS Code, it has its own [web site](https://microsoft.github.io/debug-adapter-protocol/) where you can find an [introduction and overview](https://microsoft.github.io/debug-adapter-protocol/overview), the detailed [specification](https://microsoft.github.io/debug-adapter-protocol/specification), and some lists with [known implementations and supporting tools](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/).
|
||||
The history of and motivation behind DAP is explained in this [blog post](https://code.visualstudio.com/blogs/2018/08/07/debug-adapter-protocol-website#_why-the-need-for-decoupling-with-protocols).
|
||||
|
||||
Since debug adapters are independent from VS Code and can be used in [other developments tools](https://microsoft.github.io/debug-adapter-protocol/implementors/tools/), they do not match VS Code's extensibility architecture which is based on extensions and contribution points.
|
||||
|
||||
For this reason VS Code provides a contribution point, `debuggers`, where a debug adapter can be contributed under a specific debug type (e.g. `node` for the Node.js debugger). VS Code launches the registered DA whenever the user starts a debug session of that type.
|
||||
|
||||
So in its most minimal form, a debugger extension is just a declarative contribution of a debug adapter implementation and the extension is basically a packaging container for the debug adapter without any additional code.
|
||||
|
||||
![VS Code Debug Architecture 2](images/debugger-extension/debug-arch2.png)
|
||||
|
||||
A more realistic debugger extension contributes many or all of the following declarative items to VS Code:
|
||||
|
||||
- List of languages supported by the debugger. VS Code enables the UI to set breakpoints for those languages.
|
||||
- JSON schema for the debug configuration attributes introduced by the debugger. VS Code uses this schema to verify the configuration in the launch.json editor and provides IntelliSense.
|
||||
- Default debug configurations for the initial launch.json created by VS Code.
|
||||
- Debug configuration snippets that a user can add to a launch.json file.
|
||||
- Declaration of variables that can be used in debug configurations.
|
||||
|
||||
You can find more information in [`contributes.breakpoints`](/api/references/contribution-points#contributes.breakpoints) and [`contributes.debuggers`](/api/references/contribution-points#contributes.debuggers) references.
|
||||
|
||||
In addition to the purely declarative contributions from above, the Debug Extension API enables this code-based functionality:
|
||||
|
||||
- Dynamically generated default debug configurations for the initial launch.json created by VS Code.
|
||||
- Determine the debug adapter to use dynamically.
|
||||
- Verify or modify debug configurations before they are passed to the debug adapter.
|
||||
- Communicate with the debug adapter.
|
||||
- Send messages to the debug console.
|
||||
|
||||
In the rest of this document we show how to develop a debugger extension.
|
||||
|
||||
## The Mock Debug Extension
|
||||
|
||||
Since creating a debug adapter from scratch is a bit heavy for this tutorial, we will start with a simple DA which we have created as an educational "debug adapter starter kit". It is called _Mock Debug_ because it does not talk to a real debugger, but mocks one. Mock Debug simulates a debugger and supports step, continue, breakpoints, exceptions, and variable access, but it is not connected to any real debugger.
|
||||
|
||||
Before delving into the development setup for mock-debug, let's first install a [pre-built version](https://marketplace.visualstudio.com/items/andreweinand.mock-debug)
|
||||
from the VS Code Marketplace and play with it:
|
||||
|
||||
- Switch to the Extensions viewlet and type "mock" to search for the Mock Debug extension,
|
||||
- "Install" and "Reload" the extension.
|
||||
|
||||
To try Mock Debug:
|
||||
|
||||
- Create a new empty folder `mock test` and open it in VS Code.
|
||||
- Create a file `readme.md` and enter several lines of arbitrary text.
|
||||
- Switch to the Debug view and press the gear icon.
|
||||
- VS Code will let you select an "environment" in order to create a default launch configuration. Pick "Mock Debug".
|
||||
- Press the green Start button and then Enter to confirm the suggested file `readme.md`.
|
||||
|
||||
A debug session starts and you can "step" through the readme file, set and hit breakpoints, and run into exceptions (if the word `exception` appears in a line).
|
||||
|
||||
![Mock Debugger running](images/debugger-extension/mock-debug.gif)
|
||||
|
||||
Before using Mock Debug as a starting point for your own development, we recommend to uninstall the pre-built version first:
|
||||
|
||||
- Switch to the Extensions viewlet and click on the gear icon of the Mock Debug extension.
|
||||
- Run the "Uninstall" action and then "Reload" the window.
|
||||
|
||||
## Development Setup for Mock Debug
|
||||
|
||||
Now let's get the source for Mock Debug and start development on it within VS Code:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Microsoft/vscode-mock-debug.git
|
||||
cd vscode-mock-debug
|
||||
npm install
|
||||
```
|
||||
|
||||
Open the project folder `vscode-mock-debug` in VS Code.
|
||||
|
||||
What's in the package?
|
||||
|
||||
- `package.json` is the manifest for the mock-debug extension:
|
||||
- It lists the contributions of the mock-debug extension.
|
||||
- The `compile` and `watch` scripts are used to transpile the TypeScript source into the `out` folder and watch for subsequent source modifications.
|
||||
- The dependencies `vscode-debugprotocol`, `vscode-debugadapter`, and `vscode-debugadapter-testsupport` are NPM modules that simplify the development of node-based debug adapters.
|
||||
- `src/mockRuntime.ts` is a _mock_ runtime with a simple debug API.
|
||||
- The code that _adapts_ the runtime to the Debug Adapter Protocol lives in `src/mockDebug.ts`. Here you find the handlers for the various requests of the DAP.
|
||||
- Since the implementation of debugger extension lives in the debug adapter, there is no need to have extension code at all (i.e. code that runs in the extension host process). However, Mock Debug has a small `src/extension.ts` because it illustrates what can be done in the extension code of a debugger extension.
|
||||
|
||||
Now build and launch the Mock Debug extension by selecting the **Extension** launch configuration and hitting `F5`.
|
||||
Initially, this will do a full transpile of the TypeScript sources into the `out` folder.
|
||||
After the full build, a _watcher task_ is started that transpiles any changes you make.
|
||||
|
||||
After transpiling the source, a new VS Code window labelled "[Extension Development Host]" appears with the Mock Debug extension now running in debug mode. From that window open your `mock test` project with the `readme.md` file, start a debug session with 'F5', and then step through it:
|
||||
|
||||
![Debugging Extension and Server](images/debugger-extension/debug-mock-session.png)
|
||||
|
||||
Since you are running the extension in debug mode, you could now set and hit breakpoints in `src/extension.ts` but as I've mentioned above, there is not much interesting code executing in the extension. The interesting code runs in the debug adapter which is a separate process.
|
||||
|
||||
In order to debug the debug adapter itself, we have to run it in debug mode. This is most easily achieved by running the debug adapter in _server mode_ and configure VS Code to connect to it. In your VS Code vscode-mock-debug project select the launch configuration **Server** from the drop down menu and press the green start button.
|
||||
|
||||
Since we already had an active debug session for the extension the VS Code debugger UI now enters _multi session_ mode which is indicated by seeing the names of the two debug sessions **Extension** and **Server** showing up in the CALL STACK view:
|
||||
|
||||
![Debugging Extension and Server](images/debugger-extension/debugger-extension-server.png)
|
||||
|
||||
Now we are able to debug both the extension and the DA simultaneously.
|
||||
A faster way to arrive here is by using the **Extension + Server** launch configuration which launches both sessions automatically.
|
||||
|
||||
An alternative, even simpler approach for debugging the extension and the DA can be found [below](#alternative-approach-to-develop-a-debugger-extension).
|
||||
|
||||
Set a breakpoint at the beginning of method `launchRequest(...)` in file `src/mockDebug.ts` and as a last step configure the mock debugger to connect to the DA server by adding a `debugServer` attribute for port `4711` to your mock test launch config:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "mock",
|
||||
"request": "launch",
|
||||
"name": "mock test",
|
||||
"program": "${workspaceFolder}/readme.md",
|
||||
"stopOnEntry": true,
|
||||
"debugServer": 4711
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
If you now launch this debug configuration, VS Code does not start the mock debug adapter as a separate process, but directly connects to local port 4711 of the already running server, and you should hit the breakpoint in `launchRequest`.
|
||||
|
||||
With this setup, you can now easily edit, transpile, and debug Mock Debug.
|
||||
|
||||
But now the real work begins: you will have to replace the mock implementation of the debug adapter in `src/mockDebug.ts` and `src/mockRuntime.ts` by some code that talks to a "real" debugger or runtime. This involves understanding and implementing the Debug Adapter Protocol. More details
|
||||
about this can be found [here](https://microsoft.github.io/debug-adapter-protocol/overview#How_it_works).
|
||||
|
||||
## Anatomy of the package.json of a Debugger Extension
|
||||
|
||||
Besides providing a debugger-specific implementation of the debug adapter a debugger extension needs a `package.json` that contributes to the various debug-related contributions points.
|
||||
|
||||
So let's have a closer look at the `package.json` of Mock Debug.
|
||||
|
||||
Like every VS Code extension, the `package.json` declares the fundamental properties **name**, **publisher**, and **version** of the extension. Use the **categories** field to make the extension easier to find in the VS Code Extension Marketplace.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "mock-debug",
|
||||
"displayName": "Mock Debug",
|
||||
"version": "0.24.0",
|
||||
"publisher": "...",
|
||||
"description": "Starter extension for developing debug adapters for VS Code.",
|
||||
"author": {
|
||||
"name": "...",
|
||||
"email": "..."
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.17.0",
|
||||
"node": "^7.9.0"
|
||||
},
|
||||
"icon": "images/mock-debug-icon.png",
|
||||
"categories": ["Debuggers"],
|
||||
|
||||
"contributes": {
|
||||
"breakpoints": [{ "language": "markdown" }],
|
||||
"debuggers": [
|
||||
{
|
||||
"type": "mock",
|
||||
"label": "Mock Debug",
|
||||
|
||||
"program": "./out/mockDebug.js",
|
||||
"runtime": "node",
|
||||
|
||||
"configurationAttributes": {
|
||||
"launch": {
|
||||
"required": ["program"],
|
||||
"properties": {
|
||||
"program": {
|
||||
"type": "string",
|
||||
"description": "Absolute path to a text file.",
|
||||
"default": "${workspaceFolder}/${command:AskForProgramName}"
|
||||
},
|
||||
"stopOnEntry": {
|
||||
"type": "boolean",
|
||||
"description": "Automatically stop after launch.",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"initialConfigurations": [
|
||||
{
|
||||
"type": "mock",
|
||||
"request": "launch",
|
||||
"name": "Ask for file name",
|
||||
"program": "${workspaceFolder}/${command:AskForProgramName}",
|
||||
"stopOnEntry": true
|
||||
}
|
||||
],
|
||||
|
||||
"configurationSnippets": [
|
||||
{
|
||||
"label": "Mock Debug: Launch",
|
||||
"description": "A new configuration for launching a mock debug program",
|
||||
"body": {
|
||||
"type": "mock",
|
||||
"request": "launch",
|
||||
"name": "${2:Launch Program}",
|
||||
"program": "^\"\\${workspaceFolder}/${1:Program}\""
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"variables": {
|
||||
"AskForProgramName": "extension.mock-debug.getProgramName"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"activationEvents": ["onDebug", "onCommand:extension.mock-debug.getProgramName"]
|
||||
}
|
||||
```
|
||||
|
||||
Now take a look at the **contributes** section which contains the contributions specific to debug extensions.
|
||||
|
||||
First, we use the **breakpoints** contribution point to list the languages for which setting breakpoints will be enabled. Without this, it would not be possible to set breakpoints in Markdown files.
|
||||
|
||||
Next is the **debuggers** section. Here, one debugger is introduced under a debug **type** `mock`. The user can reference this type in launch configurations. The optional attribute **label** can be used to give the debug type a nice name when showing it in the UI.
|
||||
|
||||
Since the debug extension uses a debug adapter, a relative path to its code is given as the **program** attribute.
|
||||
In order to make the extension self-contained the application must live inside the extension folder. By convention, we keep this applications inside a folder named `out` or `bin`, but you are free to use a different name.
|
||||
|
||||
Since VS Code runs on different platforms, we have to make sure that the DA program supports the different platforms as well. For this we have the following options:
|
||||
|
||||
1. If the program is implemented in a platform independent way, e.g. as program that runs on a runtime that is available on all supported platforms, you can specify this runtime via the **runtime** attribute. As of today, VS Code supports `node` and `mono` runtimes. Our Mock debug adapter from above uses this approach.
|
||||
|
||||
1. If your DA implementation needs different executables on different platforms, the **program** attribute can be qualified for specific platforms like this:
|
||||
|
||||
```json
|
||||
"debuggers": [{
|
||||
"type": "gdb",
|
||||
"windows": {
|
||||
"program": "./bin/gdbDebug.exe",
|
||||
},
|
||||
"osx": {
|
||||
"program": "./bin/gdbDebug.sh",
|
||||
},
|
||||
"linux": {
|
||||
"program": "./bin/gdbDebug.sh",
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
1. A combination of both approaches is possible too. The following example is from the Mono DA which is implemented as a mono application that needs a runtime on macOS and Linux but not on Windows:
|
||||
|
||||
```json
|
||||
"debuggers": [{
|
||||
"type": "mono",
|
||||
"program": "./bin/monoDebug.exe",
|
||||
"osx": {
|
||||
"runtime": "mono"
|
||||
},
|
||||
"linux": {
|
||||
"runtime": "mono"
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
**configurationAttributes** declares the schema for the `launch.json` attributes that are available for this debugger. This schema is used for validating the `launch.json` and supporting IntelliSense and hover help when editing the launch configuration.
|
||||
|
||||
The **initialConfigurations** define the initial content of the default `launch.json` for this debugger. This information is used when a project does not have a `launch.json` and a user starts a debug session or clicks on the gear icon in the debug viewlet. In this case VS Code lets the user pick a debug environment and then creates the corresponding `launch.json`:
|
||||
|
||||
![Debugger Quickpick](images/debugger-extension/debug-init-config.png)
|
||||
|
||||
Instead of defining the initial content of the `launch.json` statically in the `package.json`, it is possible to compute the initial configurations dynamically by implementing a `DebugConfigurationProvider` (for details see the section [Using a DebugConfigurationProvider below](#using-a-debugconfigurationprovider)).
|
||||
|
||||
**configurationSnippets** define launch configuration snippets that get surfaced in IntelliSense when editing the `launch.json`. As a convention, prefix the `label` attribute of a snippet by the debug environment name so that it can be clearly identified when presented in a list of many snippet proposals.
|
||||
|
||||
The **variables** contribution binds "variables" to "commands". These variables can be used in the launch configuration using the **\${command:xyz}** syntax and the variables are substituted by the value returned from the bound command when a debug session is started.
|
||||
|
||||
The implementation of a command lives in the extension and it can range from a simple expression with no UI, to sophisticated functionality based on the UI features available in the extension API.
|
||||
Mock Debug binds a variable `AskForProgramName` to the command `extension.mock-debug.getProgramName`. The [implementation](https://github.com/Microsoft/vscode-mock-debug/blob/606454ff3bd669867a38d9b2dc7b348d324a3f6b/src/extension.ts#L21-L26) of this command in `src/extension.ts` uses the `showInputBox` to let the user enter a program name:
|
||||
|
||||
```ts
|
||||
vscode.commands.registerCommand('extension.mock-debug.getProgramName', config => {
|
||||
return vscode.window.showInputBox({
|
||||
placeHolder: 'Please enter the name of a markdown file in the workspace folder',
|
||||
value: 'readme.md'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The variable can now be used in any string typed value of a launch configuration as **\${command:AskForProgramName}**.
|
||||
|
||||
## Using a DebugConfigurationProvider
|
||||
|
||||
If the static nature of debug contributions in the `package.json` is not sufficient, a `DebugConfigurationProvider` can be used to dynamically control the following aspects of a debug extension:
|
||||
|
||||
- The initial debug configurations for a newly created launch.json can be generated dynamically, e.g. based on some contextual information available in the workspace.
|
||||
- A launch configuration can be _resolved_ (or modified) before it is used to start a new debug session. This allows for filling in default values based on information available in the workspace.
|
||||
|
||||
The `MockConfigurationProvider` in `src/extension.ts` implements `resolveDebugConfiguration` to detect the case where a debug session is started when no launch.json exists, but a Markdown file is open in the active editor. This is a typical scenario where the user has a file open in the editor and just wants to debug it without creating a launch.json.
|
||||
|
||||
A debug configuration provider is registered for a specific debug type via `vscode.debug.registerDebugConfigurationProvider`, typically in the extension's `activate` function.
|
||||
To ensure that the `DebugConfigurationProvider` is registered early enough, the extension must be activated as soon as the debug functionality is used. This can be easily achieved by configuring extension activation for the `onDebug` event in the `package.json`:
|
||||
|
||||
```json
|
||||
"activationEvents": [
|
||||
"onDebug",
|
||||
// ...
|
||||
],
|
||||
```
|
||||
|
||||
This catch-all `onDebug` is triggered as soon as any debug functionality is used. This works fine as long as the extension has cheap startup costs (i.e. does not spend a lot of time in its startup sequence). If a debug extension has an expensive startup (for instance because of starting a language server), the `onDebug` activation event could negatively affect other debug extensions, because it is triggered rather early and does not take a specific debug type into account.
|
||||
|
||||
A better approach for expensive debug extensions is to use more fine-grained activation events:
|
||||
|
||||
- `onDebugInitialConfigurations` is fired just before the `provideDebugConfigurations` method of the `DebugConfigurationProvider` is called.
|
||||
- `onDebugResolve:type` is fired just before the `resolveDebugConfiguration` method of the `DebugConfigurationProvider` for the specified type is called.
|
||||
|
||||
**Rule of thumb:** If activation of a debug extensions is cheap, use `onDebug`. If it is expensive, use `onDebugInitialConfigurations` and/or `onDebugResolve` depending on whether the `DebugConfigurationProvider` implements the corresponding methods `provideDebugConfigurations` and/or `resolveDebugConfiguration`.
|
||||
|
||||
## Publishing your debugger extension
|
||||
|
||||
Once you have created your debugger extension you can publish it to the Marketplace:
|
||||
|
||||
- Update the attributes in the `package.json` to reflect the naming and purpose of your debugger extension.
|
||||
- Upload to the Marketplace as described in [Publishing Extension](/api/working-with-extensions/publishing-extension).
|
||||
|
||||
## Alternative approach to develop a debugger extension
|
||||
|
||||
As we have seen, developing a debugger extension typically involves debugging both the extension and the debug adapter in two parallel sessions. As explained above VS Code supports this nicely but development could be easier if both the extension and the debug adapter would be one program that could be debugged in one debug session.
|
||||
|
||||
This approach is in fact easily doable as long as your debug adapter is implemented in TypeScript/JavaScript. The basic idea is to run the debug adapter as a server inside the extension host and to make VS Code to connect to it instead of launching a new debug adapter per session.
|
||||
|
||||
Mock Debug shows how a [DebugAdapterDescriptorFactory](https://github.com/Microsoft/vscode-mock-debug/blob/6a2ef01b95bb22cdf55683f4d616cad501051510/src/extension.ts#L74-L98) can be used to create and [register](https://github.com/Microsoft/vscode-mock-debug/blob/6a2ef01b95bb22cdf55683f4d616cad501051510/src/extension.ts#L32-L36) a server-based debug adapter.
|
||||
The feature is enabled by setting the compile time flag [`EMBED_DEBUG_ADAPTER`](https://github.com/Microsoft/vscode-mock-debug/blob/6a2ef01b95bb22cdf55683f4d616cad501051510/src/extension.ts#L17) to true. If you now start debugging the extension with **F5** you will hit breakpoints not only in the extension host but in the debug adapter as well.
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# File System Provider
|
||||
|
||||
For https://github.com/Microsoft/vscode-extension-samples/tree/master/fsprovider-sample and https://github.com/Microsoft/vscode-extension-samples/tree/master/nodefs-provider-sample
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# Internationalization
|
||||
|
||||
https://github.com/Microsoft/vscode-extension-samples/tree/master/i18n-sample
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: f470466d-89b0-4115-ab7a-2448023b0a6d
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide to creating Icon Theme in Visual Studio Code
|
||||
---
|
||||
|
||||
# Icon Theme
|
||||
|
||||
Visual Studio Code displays icons next to filenames throughout its UI, and extensions can contribute new sets of file icons that users can choose from.
|
||||
|
||||
## Adding a new Icon Theme
|
||||
|
||||
You can create your own icon theme from icons (preferably SVG) and from icon fonts. As example, check out the two built-in themes: [Minimal](https://github.com/Microsoft/vscode/tree/master/extensions/theme-defaults) and [Seti](https://github.com/Microsoft/vscode/tree/master/extensions/theme-seti).
|
||||
|
||||
To begin, create a VS Code extension and add the `iconTheme` contribution point.
|
||||
|
||||
```json
|
||||
{
|
||||
"contributes": {
|
||||
"iconThemes": [
|
||||
{
|
||||
"id": "turtles",
|
||||
"label": "Turtles",
|
||||
"path": "./fileicons/turtles-icon-theme.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `id` is the identifier for the icon theme. It is currently only used internally. In the future, it might be used in the settings, so make it unique but also readable. `label` is shown in the icon theme picker drop-down. The `path` points to a file in the extension that defines the icon set. If your icon set name follows the `*icon-theme.json` name scheme, you will get completion support and hovers in VS Code.
|
||||
|
||||
### Icon Set File
|
||||
|
||||
The icon set file is a JSON file consisting of file icon associations and icon definitions.
|
||||
|
||||
An icon association maps a file type ('file', 'folder', 'json-file'...) to an icon definition. Icon definitions define where the icon is located: That can be an image file or also glyph in a font.
|
||||
|
||||
### Icon definitions
|
||||
|
||||
The `iconDefinitions` section contains all definitions. Each definition has an id, which will be used to reference the definition. A definition can be referenced also by more than one file association.
|
||||
|
||||
```json
|
||||
{
|
||||
"iconDefinitions": {
|
||||
"_folder_dark": {
|
||||
"iconPath": "./images/Folder_16x_inverse.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This icon definition above contains a definition with the identifier `_folder_dark`.
|
||||
|
||||
The following properties are supported:
|
||||
|
||||
- `iconPath`: When using a svg/png: the path to the image.
|
||||
- `fontCharacter`: When using a glyph font: The character in the font to use.
|
||||
- `fontColor`: When using a glyph font: The color to use for the glyph.
|
||||
- `fontSize`: When using a font: The font size. By default, the size specified in the font specification is used. Should be a relative size (e.g. 150%) to the parent font size.
|
||||
- `fontId`: When using a font: The id of the font. If not specified, the first font specified in font specification section will be picked.
|
||||
|
||||
### File association
|
||||
|
||||
Icons can be associated to folders, folder names, files, file extensions, file names and [language ids](/api/references/contribution-points#contributes.languages).
|
||||
|
||||
Additionally each of these associations can be refined for 'light' and 'highContrast' color themes.
|
||||
|
||||
Each file association points to an icon definition.
|
||||
|
||||
```json
|
||||
{
|
||||
"file": "_file_dark",
|
||||
"folder": "_folder_dark",
|
||||
"folderExpanded": "_folder_open_dark",
|
||||
"folderNames": {
|
||||
".vscode": "_vscode_folder"
|
||||
},
|
||||
"fileExtensions": {
|
||||
"ini": "_ini_file"
|
||||
},
|
||||
"fileNames": {
|
||||
"win.ini": "_win_ini_file"
|
||||
},
|
||||
"languageIds": {
|
||||
"ini": "_ini_file"
|
||||
},
|
||||
"light": {
|
||||
"folderExpanded": "_folder_open_light",
|
||||
"folder": "_folder_light",
|
||||
"file": "_file_light",
|
||||
"fileExtensions": {
|
||||
"ini": "_ini_file_light"
|
||||
}
|
||||
},
|
||||
"highContrast": {}
|
||||
}
|
||||
```
|
||||
|
||||
- `file` is the default file icon, shown for all files that don't match any extension, filename or language id. Currently all properties defined by the definition of the file icon will be inherited (only relevant for font glyphs, useful for the fontSize).
|
||||
- `folder` is the folder icon for collapsed folders, and if `folderExpanded` is not set, also for expanded folders. Icons for specific folder names can be associated using the `folderNames` property.
|
||||
The folder icon is optional. If not set, no icon will be shown for folder.
|
||||
- `folderExpanded` is the folder icon for expanded folders. The expanded folder icon is optional. If not set, the icon defined for `folder` will be shown.
|
||||
- `folderNames` associates folder names to icons. The key of the set is the folder name, not including any path segments. Patterns or wildcards are not supported. Folder name matching is case insensitive.
|
||||
- `folderNamesExpanded` associates folder names to icons for expanded folder. The key of the set is the folder name, not including any path segments. Patterns or wildcards are not supported. Folder name matching is case insensitive.
|
||||
- `rootFolder` is the folder icon for collapsed workspace root folders , and if `rootFolderExpanded` is not set, also for expanded workspace root folders. If not set, the icon defined for `folder` will be shown for workspace root folders.
|
||||
- `rootFolderExpanded` is the folder icon for expanded workspace root folders. If not set, the icon defined for `rootFolder` will be shown for exanded workspace root folders.
|
||||
- `languageIds` associates languages to icons. The key in the set is the language id as defined in the [language contribution point](/api/references/contribution-points#contributes.languages). The language of a file is evaluated based on the file extensions and file names as defined in the language contribution. Note that the 'first line match' of the language contribution is not considered.
|
||||
- `fileExtensions` associates file extensions to icons. The key in the set is the file extension name. The extension name is a file name segment after a dot (not including the dot). File names with multiple dots such as `lib.d.ts` can match multiple extensions; 'd.ts' and 'ts'. Extensions are compared case insensitive.
|
||||
- `fileNames` associates file names to icons. The key in the set is the full file name, not including any path segments. Patterns or wildcards are not supported. File name matching is case insensitive. A 'fileName' match is the strongest match, and the icon associated to the file name will be preferred over an icon of a matching fileExtension and also of a matching language Id.
|
||||
|
||||
A file extension match is preferred over a language match, but is weaker than a file name match.
|
||||
|
||||
The `light` and the `highContrast` section have the same file association properties as just listed. They allow to override icons for the corresponding themes.
|
||||
|
||||
### Font definitions
|
||||
|
||||
The `fonts` section lets you declare any number of glyph fonts that you want to use.
|
||||
You can later reference these fonts in the icon definitions. The font declared first will be used as the default if an icon definition does not specify a font id.
|
||||
|
||||
Copy the font file into your extension and set the path accordingly.
|
||||
It is recommended to use [WOFF](https://developer.mozilla.org/docs/Web/Guide/WOFF) fonts.
|
||||
|
||||
- Set 'woff' as the format.
|
||||
- the weight property values are defined [here](https://developer.mozilla.org/docs/Web/CSS/font-weight#Values).
|
||||
- the style property values are defined [here](https://developer.mozilla.org/docs/Web/CSS/@font-face/font-style#Values).
|
||||
- the size should be relative to the font size where the icon is used. Therefore, always use percentage.
|
||||
|
||||
```json
|
||||
{
|
||||
"fonts": [
|
||||
{
|
||||
"id": "turtles-font",
|
||||
"src": [
|
||||
{
|
||||
"path": "./turtles.woff",
|
||||
"format": "woff"
|
||||
}
|
||||
],
|
||||
"weight": "normal",
|
||||
"style": "normal",
|
||||
"size": "150%"
|
||||
}
|
||||
],
|
||||
"iconDefinitions": {
|
||||
"_file": {
|
||||
"fontCharacter": "\\E002",
|
||||
"fontColor": "#5f8b3b",
|
||||
"fontId": "turtles-font"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Folder icons in File Icon Themes
|
||||
|
||||
File Icon themes can instruct the File Explorer not to show the default folder icon (the rotating triangles or "twisties") when the folder icons are good enough to indicate the expansion state of a folder. This mode is enabled by setting `"hidesExplorerArrows":true` in the File Icon theme definition file.
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3e33b786a5cb42ababa7e6b95c1588a4e118a9c6cca4d702744f8c180b710379
|
||||
size 272836
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d60195c3ed09ca395de9f858c4856d8ee49d063529db8e5e859c58943968549
|
||||
size 31172
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:38c9f842e34507294d648d60dece29479cec9be8f93df5b04ac830cfceb110e7
|
||||
size 203332
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:663237a98151ab1eea3831905789dd18dc7916b0ffb82f22b23dd2e841a6bea0
|
||||
size 28250
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:53a77c9dce6b68d92c6387faf64a7740eefbd3d50bafb7cbe888a4a5f2d1b24e
|
||||
size 22131
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7e7e09d70c1d77daac16e516f95821dc509be14015cc457ffdbde04602922285
|
||||
size 32995
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d25725868a31d7316bf95a12dcb941ffcf107061fe034e1df3483f7c6ebf429c
|
||||
size 41571
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:085536ca6bc19742828c0cdee02b5c7f013686d9c3fb92d7fbb57029a774d88f
|
||||
size 295752
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c0c02ce262b362a0c5d5fccfdaaea969c06bc1681b0ecadc533514dda3748904
|
||||
size 14585
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3afc658951f24b55a583ebfb846997815baab47db9821e00ab447fe618b13e63
|
||||
size 75089
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3b5f4be4fb2d8ad12f6722c57eb6b58363d09960d823b2afe4f1dac72b7be397
|
||||
size 134016
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4315f93fe647e71568cbaa7d8e7297875040c1db4ed336ccc9c32e9f492db0d1
|
||||
size 154049
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ce6b00f3376e735723c1ae3741633ee599bde296e61b35486332a8b9c2c63831
|
||||
size 62160
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:528418c3db30eebd16f50e9c2359623cd5515af83d636dfd7f621dca3fb23dc0
|
||||
size 30048
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8895d7d77b061fbb137233782977085b11e8d7c8618e70c5555f2c856b9da577
|
||||
size 66039
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bc9c63a4aeae194bc8ae984d9ac7a3fbcd0f663abb0c6317a78955992e60e780
|
||||
size 44782
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:09b50cf5590a8f0fb6d999ad3d7c6108b522650221b9cc9af7a384c56f2f1f7b
|
||||
size 85300
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:74c51920a7f9c98aa6342011b7f61258fdbb4b62cce8b6c5fad28b9cca2ef737
|
||||
size 290751
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4a3c49093b50691f93b8a6b6fa48f14fcc7d39f011565df194cbcb917df6368b
|
||||
size 50075
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dd83c36a42663d3ed949e48cca7b0062748472a3a7254ebcba5e9573cbb5584d
|
||||
size 12935
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ebc3aa5e2d941b410b02f06a6182fc1b685d1ebd24a6605da9550d6a808a1516
|
||||
size 219184
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6b7c66d2a0ad3d0da8c3bba86fcdbeb5979f863e88349a2b7752838ec80ddfa0
|
||||
size 2933557
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:686667a12313d31ffe7c30d9d2ef31d05766a729e6e9c702362a845048f65179
|
||||
size 135389
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:62063f7543ca92a2509a73336ecc397a66b8d2328211a0a8fb98ebd3e359e991
|
||||
size 14513
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:16588bcda79469423503d5f0c9e6fe8be26b2af270889328a48552b82a86dae4
|
||||
size 3508124
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:63608084786607862bb87ba9cf678e9e3e6b93b9aa38696f4279fbbe9c51d823
|
||||
size 1782364
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:401215894ce1288485c7f35f56e5137b8388a5fa0b55cf268ff2a5696f7b5721
|
||||
size 1695365
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:99b4b60c1692d04fed0bf8efc54fad95c87b387aa5a024ac141857e3107713df
|
||||
size 2491751
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e0056dcffa8a1665bf35297ffd84a47ac65507ffb46b6bc87943f30baed9446d
|
||||
size 21648
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f63795044995ea1006c530b3609790884daaf8a358ce87e2593e5b7d43a6a2da
|
||||
size 2452603
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6df523a70c90b6537519d2fcb05ab526f5129ca5c1a0ee2c3b60d6f3ae708229
|
||||
size 1462384
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:84e5dc0889a2c38df66f5e823a6593a0ccdd20e6a2abf31cadf9e1c393147140
|
||||
size 1913275
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:74221dac8e7a0bc3b1419d32e734aa2b84dc6567134759720ab732efe8f85fac
|
||||
size 2727491
|
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 1664249a-ba7a-4a53-b3f0-9d757cff7d27
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn how to extend Visual Studio Code's built-in Markdown preview.
|
||||
---
|
||||
|
||||
# Markdown Extension
|
||||
|
||||
Markdown extensions allow you to extend and enhance Visual Studio Code's built-in Markdown preview. This includes changing the look of the preview or adding support for new Markdown syntax.
|
||||
|
||||
## Changing the look of the Markdown preview with CSS
|
||||
|
||||
Extensions can contribute CSS to change the look or layout of the Markdown preview. Stylesheets are registered using the `markdown.previewStyles` [Contribution Point](/api/references/contribution-points) in the extension's `package.json`:
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"markdown.previewStyles": [
|
||||
"./style.css"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`"markdown.previewStyles"` is a list of files relative to the extension's root folder.
|
||||
|
||||
Contributed styles are added after the built-in Markdown preview styles but before a user's `"markdown.styles"`.
|
||||
|
||||
The [Markdown Preview GitHub Styling](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles) extension is a good example that demonstrates using a stylesheet to make the Markdown preview look like GitHub's rendered Markdown. You can review the extension's source code on [GitHub](https://github.com/mjbvz/vscode-github-markdown-preview-style).
|
||||
|
||||
## Adding support for new syntax with markdown-it plugins
|
||||
|
||||
The VS Code Markdown preview supports the [CommonMark specification](https://spec.commonmark.org). Extensions can add support for additional Markdown syntax by contributing a [markdown-it plugin.](https://github.com/markdown-it/markdown-it#syntax-extensions)
|
||||
|
||||
To contribute a markdown-it plugin, first add a `"markdown.markdownItPlugins"` contribution in your extension's `package.json`:
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"markdown.markdownItPlugins": true
|
||||
}
|
||||
```
|
||||
|
||||
Then, in the extension's main `activation` function, return an object with a function named `extendMarkdownIt`. This function takes the current markdown-it instance and must return a new markdown-it instance:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
return {
|
||||
extendMarkdownIt(md: any) {
|
||||
return md.use(require('markdown-it-emoji'));
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
To contribute multiple markdown-it plugins, simply return multiple `use` statements chained together:
|
||||
|
||||
```ts
|
||||
return md.use(require('markdown-it-emoji')).use(require('markdown-it-hashtag'));
|
||||
```
|
||||
|
||||
Extensions that contribute markdown-it plugins are activated lazily, when a Markdown preview is shown for the first time.
|
||||
|
||||
The [markdown-emoji](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-emoji) extension demonstrates using a markdown-it plugin to add emoji support to the markdown preview. You can review the Emoji extension's source code on [GitHub](https://github.com/mjbvz/vscode-markdown-emoji).
|
||||
|
||||
You may also want to review:
|
||||
|
||||
- [Guidelines](https://github.com/markdown-it/markdown-it/blob/master/docs/development.md) for markdown-it plugin developers
|
||||
- [Existing markdown-it plugins](https://www.npmjs.com/browse/keyword/markdown-it-plugin)
|
||||
|
||||
## Adding advanced functionality with scripts
|
||||
|
||||
For advanced functionality, extensions may contribute scripts that are executed inside of the Markdown preview.
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"markdown.previewScripts": [
|
||||
"./main.js"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Contributed scripts are loaded asynchronously and reloaded on every content change.
|
||||
|
||||
The [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid) extension demonstrates using scripts to add [mermaid](https://knsv.github.io/mermaid/index.html) diagrams and flowchart support to the markdown preview. You can review the Mermaid extension's source code on [GitHub](https://github.com/mjbvz/vscode-markdown-mermaid).
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: B32601A8-27ED-4D97-BA83-F1C8C945C635
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn from Visual Studio Code extension guides and code samples
|
||||
---
|
||||
|
||||
# Extension Guides
|
||||
|
||||
Once you have learned the basics of Visual Studio Code Extension API in the [Hello World](/api/get-started/your-first-extension) sample, it's time to build some real-world extensions. While the [Extension Capabilities](/api/extension-capabilities/overview) section offers high-level overviews of what extension **can** do, this section contains a list of detailed code guides and samples that explains **how** to use a specific VS Code API.
|
||||
|
||||
In each guide-sample combo, you can expect to find:
|
||||
|
||||
- Thoroughly commented source code.
|
||||
- A gif or image showing the usage of the sample extension.
|
||||
- Instructions for running the sample extension.
|
||||
- Listing of VS Code API being used.
|
||||
- Listing of Contribution Points being used.
|
||||
- Real-world extensions resembling the sample.
|
||||
- Explanation of API concepts.
|
||||
|
||||
## Guides & Samples
|
||||
|
||||
Here is a list of guides and samples. While each guide comes with sample code, some samples do not have a matching guide yet.
|
||||
|
||||
Each sample illustrates one [VS Code API](/api/references/vscode-api) usage or a [Contribution Point](/api/references/contribution-points).
|
||||
|
||||
| Sample | Guide on VS Code Website | API & Contribution |
|
||||
| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Webview Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/webview-sample) | [/api/extension-guides/webview](https://code.visualstudio.com/api/extension-guides/webview) | [window.createWebviewPanel](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)<br>[window.registerWebviewPanelSerializer](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewPanelSerializer) |
|
||||
| [Status Bar Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/statusbar-sample) | N/A | [window.createStatusBarItem](https://code.visualstudio.com/api/references/vscode-api#window.createStatusBarItem)<br>[StatusBarItem](https://code.visualstudio.com/api/references/vscode-api#StatusBarItem) |
|
||||
| [Tree View Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample) | [/api/extension-guides/tree-view](https://code.visualstudio.com/api/extension-guides/tree-view) | [window.createTreeView](https://code.visualstudio.com/api/references/vscode-api#window.createTreeView)<br>[window.registerTreeDataProvider](https://code.visualstudio.com/api/references/vscode-api#window.registerTreeDataProvider)<br>[TreeView](https://code.visualstudio.com/api/references/vscode-api#TreeView)<br>[TreeDataProvider](https://code.visualstudio.com/api/references/vscode-api#TreeDataProvider)<br>[contributes.views](https://code.visualstudio.com/api/references/contribution-points#contributes.views)<br>[contributes.viewsContainers](https://code.visualstudio.com/api/references/contribution-points#contributes.viewsContainers) |
|
||||
| [Task Provider Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample) | [/api/extension-guides/task-provider](https://code.visualstudio.com/api/extension-guides/task-provider) | [tasks.registerTaskProvider](https://code.visualstudio.com/api/references/vscode-api#tasks.registerTaskProvider)<br>[Task](https://code.visualstudio.com/api/references/vscode-api#Task)<br>[ShellExecution](https://code.visualstudio.com/api/references/vscode-api#ShellExecution)<br>[contributes.taskDefinitions](https://code.visualstudio.com/api/references/contribution-points#contributes.taskDefinitions) |
|
||||
| [Multi Root Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/basic-multi-root-sample) | N/A | [workspace.getWorkspaceFolder](https://code.visualstudio.com/api/references/vscode-api#workspace.getWorkspaceFolder)<br>[workspace.onDidChangeWorkspaceFolders](https://code.visualstudio.com/api/references/vscode-api#workspace.onDidChangeWorkspaceFolders) |
|
||||
| [Completion Provider Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/completions-sample) | N/A | [languages.registerCompletionItemProvider](https://code.visualstudio.com/api/references/vscode-api#languages.registerCompletionItemProvider)<br>[CompletionItem](https://code.visualstudio.com/api/references/vscode-api#CompletionItem)<br>[SnippetString](https://code.visualstudio.com/api/references/vscode-api#SnippetString) |
|
||||
| [File System Provider Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/fsprovider-sample) | N/A | [workspace.registerFileSystemProvider](https://code.visualstudio.com/api/references/vscode-api#workspace.registerFileSystemProvider) |
|
||||
| [Editor Decorator Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/decorator-sample) | N/A | [TextEditor.setDecorations](https://code.visualstudio.com/api/references/vscode-api#TextEditor.setDecorations)<br>[DecorationOptions](https://code.visualstudio.com/api/references/vscode-api#DecorationOptions)<br>[DecorationInstanceRenderOptions](https://code.visualstudio.com/api/references/vscode-api#DecorationInstanceRenderOptions)<br>[ThemableDecorationInstanceRenderOptions](https://code.visualstudio.com/api/references/vscode-api#ThemableDecorationInstanceRenderOptions)<br>[window.createTextEditorDecorationType](https://code.visualstudio.com/api/references/vscode-api#window.createTextEditorDecorationType)<br>[TextEditorDecorationType](https://code.visualstudio.com/api/references/vscode-api#TextEditorDecorationType)<br>[contributes.colors](https://code.visualstudio.com/api/references/contribution-points#contributes.colors) |
|
||||
| [I18n Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/i18n-sample) | N/A | |
|
||||
| [Terminal Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/terminal-sample) | N/A | [window.createTerminal](https://code.visualstudio.com/api/references/vscode-api#window.createTerminal)<br>[window.onDidChangeActiveTerminal](https://code.visualstudio.com/api/references/vscode-api#window.onDidChangeActiveTerminal)<br>[window.onDidCloseTerminal](https://code.visualstudio.com/api/references/vscode-api#window.onDidCloseTerminal)<br>[window.onDidOpenTerminal](https://code.visualstudio.com/api/references/vscode-api#window.onDidOpenTerminal)<br>[window.Terminal](https://code.visualstudio.com/api/references/vscode-api#window.Terminal)<br>[window.terminals](https://code.visualstudio.com/api/references/vscode-api#window.terminals) |
|
||||
| [Vim Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/vim-sample) | N/A | [commands](https://code.visualstudio.com/api/references/vscode-api#commands)<br>[StatusBarItem](https://code.visualstudio.com/api/references/vscode-api#StatusBarItem)<br>[window.createStatusBarItem](https://code.visualstudio.com/api/references/vscode-api#window.createStatusBarItem)<br>[TextEditorCursorStyle](https://code.visualstudio.com/api/references/vscode-api#TextEditorCursorStyle)<br>[window.activeTextEditor](https://code.visualstudio.com/api/references/vscode-api#window.activeTextEditor)<br>[Position](https://code.visualstudio.com/api/references/vscode-api#Position)<br>[Range](https://code.visualstudio.com/api/references/vscode-api#Range)<br>[Selection](https://code.visualstudio.com/api/references/vscode-api#Selection)<br>[TextEditor](https://code.visualstudio.com/api/references/vscode-api#TextEditor)<br>[TextEditorRevealType](https://code.visualstudio.com/api/references/vscode-api#TextEditorRevealType)<br>[TextDocument](https://code.visualstudio.com/api/references/vscode-api#TextDocument) |
|
||||
|
||||
## Language Extension Samples
|
||||
|
||||
These samples are [Language Extensions](/api/language-extensions/overview) samples:
|
||||
|
||||
| Sample | Guide on VS Code Website |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Snippet Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/snippet-sample) | [/api/language-extensions/snippet-guide](https://code.visualstudio.com/api/language-extensions/snippet-guide) | [contributes.snippets](https://code.visualstudio.com/api/references/contribution-points#contributes.snippets) |
|
||||
| [Language Configuration Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/language-configuration-sample) | [/api/language-extensions/language-configuration-guide](https://code.visualstudio.com/api/language-extensions/language-configuration-guide) | [contributes.languages](https://code.visualstudio.com/api/references/contribution-points#contributes.languages) |
|
||||
| [LSP Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/lsp-sample) | [/api/language-extensions/language-server-extension-guide](https://code.visualstudio.com/api/language-extensions/language-server-extension-guide) | |
|
||||
| [LSP Log Streaming Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/lsp-log-streaming-sample) | N/A | |
|
||||
| [LSP Multi Root Server Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/lsp-multi-server-sample) | https://github.com/Microsoft/vscode/wiki/Adopting-Multi-Root-Workspace-APIs#language-client--language-server | |
|
|
@ -0,0 +1,188 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 79996489-8D16-4C0A-8BE8-FF4B1E9C223A
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide illustrating how to use Source Control API.
|
||||
---
|
||||
|
||||
# Source Control API
|
||||
|
||||
The Source Control API allows extension authors to define Source Control Management (SCM) features. There is a slim, yet powerful API surface which allows many different SCM systems to be integrated in Visual Studio Code, while having a common user interface with all of them.
|
||||
|
||||
![VS Code SCM](images/scm-provider/main.png)
|
||||
|
||||
VS Code itself ships with one Source Control provider, the Git extension, which is the best reference for this API and is [a great starting point](https://github.com/Microsoft/vscode/blob/master/extensions/git/src/repository.ts) if you'd like to contribute your very own SCM provider. There are other great examples in the Marketplace such as the [SVN extension](https://marketplace.visualstudio.com/items?itemName=johnstoncode.svn-scm).
|
||||
|
||||
This documentation will help you build an extension which can make any SCM system work with VS Code.
|
||||
|
||||
> **Note:** that you can always refer to the [`vscode` namespace API reference](/api/references/vscode-api#scm) in our documentation.
|
||||
|
||||
## Source Control Model
|
||||
|
||||
A `SourceControl` is the entity responsible for populating the Source Control model with **resource states**, instances of `SourceControlResourceState`. Resource states are themselves organized in **groups**, instances of `SourceControlResourceGroup`.
|
||||
|
||||
You can create a new SourceControl with `vscode.scm.createSourceControl`.
|
||||
|
||||
In order to better understand how these three entities correlate with each other, let's take [Git](https://github.com/Microsoft/vscode/tree/master/extensions/git) as an example. Consider the following output of `git status`:
|
||||
|
||||
```bash
|
||||
vsce master* → git status
|
||||
On branch master
|
||||
Your branch is up-to-date with 'origin/master'.
|
||||
Changes to be committed:
|
||||
(use "git reset HEAD <file>..." to unstage)
|
||||
|
||||
modified: README.md
|
||||
renamed: src/api.ts -> src/test/api.ts
|
||||
|
||||
Changes not staged for commit:
|
||||
(use "git add/rm <file>..." to update what will be committed)
|
||||
(use "git checkout -- <file>..." to discard changes in working directory)
|
||||
|
||||
deleted: .travis.yml
|
||||
modified: README.md
|
||||
```
|
||||
|
||||
There are many things going on in this workspace. First, the `README.md` file has been modified, staged and then modified once again. Second, the `src/api.ts` file has been moved to `src/test/api.ts` and that move was staged. Finally, the `.travis.yml` file has been deleted.
|
||||
|
||||
For this workspace, Git defines two resource groups: the **working tree** and the **index**. Each **file change** within that group is **resource state**:
|
||||
|
||||
- **Index** - resource group
|
||||
- `README.md`, modified - resource state
|
||||
- `src/test/api.ts`, renamed from `src/api.ts` - resource state
|
||||
- **Working Tree** - resource group
|
||||
- `.travis.yml`, deleted - resource state
|
||||
- `README.md`, modified - resource state
|
||||
|
||||
Note how the same file, `README.md`, is part of two distinct resource states.
|
||||
|
||||
Here's how Git creates this model:
|
||||
|
||||
```ts
|
||||
function createResourceUri(relativePath: string): vscode.Uri {
|
||||
const absolutePath = path.join(vscode.workspace.rootPath, relativePath);
|
||||
return vscode.Uri.file(absolutePath);
|
||||
}
|
||||
|
||||
const gitSCM = vscode.scm.createSourceControl('git', 'Git');
|
||||
|
||||
const index = gitSCM.createResourceGroup('index', 'Index');
|
||||
index.resourceStates = [
|
||||
{ resourceUri: createResourceUri('README.md') },
|
||||
{ resourceUri: createResourceUri('src/test/api.ts') }
|
||||
];
|
||||
|
||||
const workingTree = gitSCM.createResourceGroup('workingTree', 'Changes');
|
||||
workingTree.resourceStates = [
|
||||
{ resourceUri: createResourceUri('.travis.yml') },
|
||||
{ resourceUri: createResourceUri('README.md') }
|
||||
];
|
||||
```
|
||||
|
||||
Changes made to the source control and resource groups will be propagated to the Source Control view.
|
||||
|
||||
## Source Control View
|
||||
|
||||
VS Code is able to populate the Source Control view, as the Source Control model changes. Resource states are customizable using `SourceControlResourceDecorations`:
|
||||
|
||||
```ts
|
||||
export interface SourceControlResourceState {
|
||||
readonly decorations?: SourceControlResourceDecorations;
|
||||
}
|
||||
```
|
||||
|
||||
The previous example would be sufficient to populate a simple list in the Source Control view, but there are many user interactions that the user might want to perform with each resource. For instance, what happens when the user clicks a resource state? The resource state can optionally provide a command to handle this action:
|
||||
|
||||
```ts
|
||||
export interface SourceControlResourceState {
|
||||
readonly command?: Command;
|
||||
}
|
||||
```
|
||||
|
||||
### Menus
|
||||
|
||||
There are five Source Control menu ids where you can place menu items, in order to provide the user with a much richer user interface.
|
||||
|
||||
The `scm/title` menu is located to the right of the SCM view title. The menu items in the `navigation` group will be inline, while all the others will be within the `…` drop-down menu.
|
||||
|
||||
The `scm/resourceGroup/context` and `scm/resourceState/context` are similar. The former will let you customize resource groups, while the later refers to resource states. Place menu items in the `inline` group to have them inline. All other menu item groups will be represented in a context menu usually accessible using the mouse right-click. Commands called from within these menus will have the respective resource states on passed as arguments. Note that the SCM view supports multiple selection thus a command might receive more than one resource at a time in its arguments.
|
||||
|
||||
For example, Git supports staging multiple files by adding the `git.stage` command to the `scm/resourceState/context` menu and using such a method declaration:
|
||||
|
||||
```ts
|
||||
stage(...resourceStates: SourceControlResourceState[]): Promise<void>;
|
||||
```
|
||||
|
||||
When creating them, `SourceControl` and `SourceControlResourceGroup` instances require you to provide an `id` string. These values will be populated in the `scmProvider` and `scmResourceGroup` context keys, respectively. You can rely on these [context keys](/docs/getstarted/keybindings#_when-clause-contexts) in the `when` clauses of your menu items. Here's how Git is able to show a menu item for its `git.stage` command:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "git.stage",
|
||||
"when": "scmProvider == git && scmResourceGroup == merge",
|
||||
"group": "inline"
|
||||
}
|
||||
```
|
||||
|
||||
The `scm/change/title` allows you to contribute commands to the title bar of an inline change. The command will be passed as arguments the URI of the document, the array of changes within it, and the index of the change which the inline change affordance is currently focused on. For example, here's the declaration of the `stageChange` Git command, which is contributed to this menu:
|
||||
|
||||
```ts
|
||||
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void>;
|
||||
```
|
||||
|
||||
The `scm/sourceControl` menu is located contextually near SourceControl instances:
|
||||
|
||||
![source control menu](images/scm-provider/sourcecontrol-menu.png)
|
||||
|
||||
Finally, the `scm/change/title` menu is related to the Quick Diff experience, showcased further ahead. It lets you contribute commands which are specific to code changes.
|
||||
|
||||
### SCM Input Box
|
||||
|
||||
The Source Control Input Box, located atop of each Source Control view, allows the user to input a message. You can get (and set) this message in order to perform operations. In Git, for example, this is used as the commit box, in which users type in commit messages and `git commit` commands pick them up.
|
||||
|
||||
```ts
|
||||
export interface SourceControlInputBox {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface SourceControl {
|
||||
readonly inputBox: SourceControlInputBox;
|
||||
}
|
||||
```
|
||||
|
||||
The user can type <kbd>Ctrl+Enter</kbd> (or <kbd>Cmd+Enter</kbd> on macOS) to accept any message. You can handle this event by providing a `acceptInputCommand` to your `SourceControl` instance.
|
||||
|
||||
```ts
|
||||
export interface SourceControl {
|
||||
readonly acceptInputCommand?: Command;
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Diff
|
||||
|
||||
VS Code also supports displaying **quick diff** editor gutter decorations. Clicking those decorations will reveal an inline diff experience, to which you can contribute contextual commands:
|
||||
|
||||
![SCM quick diff](images/scm-provider/quickdiff.png)
|
||||
|
||||
These decorations are computed by VS Code itself. All you need to do is provide VS Code with the original contents of any given file.
|
||||
|
||||
```ts
|
||||
export interface SourceControl {
|
||||
quickDiffProvider?: QuickDiffProvider;
|
||||
}
|
||||
```
|
||||
|
||||
Using a `QuickDiffProvider`, your implementation is able to tell VS Code what's the `Uri` of the original resource that matches the resource which `Uri` is provided as an argument.
|
||||
|
||||
You can combine this API with the [`registerTextDocumentContentProvider` method in the `workspace` namespace](/api/references/vscode-api#workspace), which lets you provide contents for arbitrary resources, given a `Uri`.
|
||||
|
||||
## Next steps
|
||||
|
||||
To learn more about VS Code extensibility model, try these topics:
|
||||
|
||||
- [SCM API Reference](/api/references/vscode-api#scm) - Read the full SCM API documentation
|
||||
- [Git Extension](https://github.com/Microsoft/vscode/tree/master/extensions/git) - Learn by reading the Git extension implementation
|
||||
- [Extension API Overview](/api) - Learn about the full VS Code extensibility model.
|
||||
- [Extension Manifest File](/api/references/extension-manifest) - VS Code package.json extension manifest file reference
|
||||
- [Contribution Points](/api/references/contribution-points) - VS Code contribution points reference
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# Search Provider
|
||||
|
||||
Sample to be written.
|
|
@ -0,0 +1,101 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 49744351-83ef-4ef6-99e7-2485e6e9c79f
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Learn how to contribute tasks to Visual Studio Code through an extension (plug-in).
|
||||
---
|
||||
|
||||
# Task Provider
|
||||
|
||||
Users normally define [tasks](/docs/editor/tasks) in Visual Studio Code in a `tasks.json` file. However, there are some tasks during software development that can be automatically detected by VS Code. This topic describes how extensions can auto-detect and provide tasks to end-users.
|
||||
|
||||
This guide teachs you how to build a Task Provider that auto-detects tasks defined in [Rakefiles](https://ruby.github.io/rake/). The complete source code is at: https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample.
|
||||
|
||||
## Task Definition
|
||||
|
||||
To uniquely identify a task in the system, an extension contributing a task needs to define the properties that identify a task. In the Rake example, the task definition looks like this:
|
||||
|
||||
```json
|
||||
"taskDefinitions": [
|
||||
{
|
||||
"type": "rake",
|
||||
"required": [
|
||||
"task"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"type": "string",
|
||||
"description": "The Rake task to customize"
|
||||
},
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "The Rake file that provides the task. Can be omitted."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
This contributes a task definition for `rake` tasks. The task definition has two attributes `task` and `file`. `task` is the name of the Rake task and `file` points to the Rake file that contains the task. The `task` property is required, the `file` property is optional. If the `file` attribute is omitted, the rake file in the root of the workspace folder is used.
|
||||
|
||||
## Task provider
|
||||
|
||||
Analogous to language providers that let extensions support code completion, an extension can register a task provider to compute all available tasks. This is done using the `vscode.tasks` namespace as shown in the following code snippet:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
let rakePromise: Thenable<vscode.Task[]> | undefined = undefined;
|
||||
const taskProvider = vscode.tasks.registerTaskProvider('rake', {
|
||||
provideTasks: () => {
|
||||
if (!rakePromise) {
|
||||
rakePromise = getRakeTasks();
|
||||
}
|
||||
return rakePromise;
|
||||
},
|
||||
resolveTask(_task: vscode.Task): vscode.Task | undefined {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The `resolveTask` method returns `undefined` and is currently not called by VS Code. It is there to optimize task loading in the future.
|
||||
|
||||
The `getRakeTasks` implementation does the following:
|
||||
|
||||
- Lists all rake tasks defined in a rake file using the `rake -AT -f Rakefile` command.
|
||||
- Parses the stdio output.
|
||||
- For every listed task, creates a `vscode.Task` implementation.
|
||||
|
||||
Since a Rake task instantiation needs a task definition as defined in the `package.json` file, VS Code also defines the structure using a TypeScript interface like this:
|
||||
|
||||
```typescript
|
||||
interface RakeTaskDefinition extends vscode.TaskDefinition {
|
||||
/**
|
||||
* The task name
|
||||
*/
|
||||
task: string;
|
||||
|
||||
/**
|
||||
* The rake file containing the task
|
||||
*/
|
||||
file?: string;
|
||||
}
|
||||
```
|
||||
|
||||
Assuming that the output comes from a task called `compile`, the corresponding task creation then looks like this:
|
||||
|
||||
```typescript
|
||||
let task = new vscode.Task(
|
||||
{ type: 'rake', task: 'compile' },
|
||||
'compile',
|
||||
'rake',
|
||||
new vscode.ShellExecution('rake compile')
|
||||
);
|
||||
```
|
||||
|
||||
For every task listed in the output, a corresponding VS Code task is created using the above pattern and then returns the array of all tasks from the `getRakeTasks` call.
|
||||
|
||||
The `ShellExecution` executes the `rake compile` command in the shell that is specific for the OS (for example under Windows the command would be executed in PowerShell, under Ubuntu in bash). If the task should directly execute a process (without spawning a shell), the `vscode.ProcessExecution` can be used. `ProcessExecution` has the advantage that the extension has full control over the arguments passed to the process. Using `ShellExecution` makes use of the shell command interpretation (like wildcard expanding under bash). If the `ShellExecution` is created with a single command line, then the extension needs to ensure proper quoting and escaping (for example to handle white spaces) inside the command.
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# Terminal Guide
|
||||
|
||||
https://github.com/Microsoft/vscode-extension-samples/tree/master/terminal-sample
|
|
@ -0,0 +1,177 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 9b10cda2-4eb0-4989-8f82-23a46b96c1bb
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide to using Tree View in Visual Studio Code extension (plug-in).
|
||||
---
|
||||
|
||||
# Tree View Guide
|
||||
|
||||
This guide teaches you how to write an extension that contributes view containers and tree views to Visual Studio Code. You can find a sample extension with source code at: https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample.
|
||||
|
||||
## View Container
|
||||
|
||||
A View Container contains a list of views that is displayed next to the built-in View Containers.
|
||||
|
||||
![View Container](images/tree-view/view-container.png)
|
||||
|
||||
To contribute a View Container, you should first register it using [`contributes.viewsContainers`](/api/references/contribution-points#contributes.viewsContainers) Contribution Point in `package.json`. You have to specify following required fields:
|
||||
|
||||
- `id`: The name of the new view container you're creating
|
||||
- `title`: The name which will show up at the top of the view container
|
||||
- `icon`: an image which will be displayed for the view container in the activity bar
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"id": "package-explorer",
|
||||
"title": "Package Explorer",
|
||||
"icon": "media/dep.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tree View
|
||||
|
||||
A view is an UI section that is shown inside the View Container. With the [`contributes.views`](/api/references/contribution-points#contributes.views) Contribution Point, you can add new views to the built-in or contributed View Containers.
|
||||
|
||||
![View](images/tree-view/view.png)
|
||||
|
||||
To contribute a view, you should first register it using [`contributes.views`](/api/references/vscode-api) Contribution Point in `package.json`. You must specify an identifier and name for the view, and you can contribute to following locations:
|
||||
|
||||
- `explorer`: Explorer view in the Side Bar
|
||||
- `debug`: Debug view in the Side Bar
|
||||
- `scm`: Source Control view in the Side Bar
|
||||
- `test`: Test explorer view in the Side Bar
|
||||
- Contributed View Containers
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"views": {
|
||||
"package-explorer": [
|
||||
{
|
||||
"id": "nodeDependencies",
|
||||
"name": "Node Dependencies",
|
||||
"when": "explorer"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When the user opens the view, VS Code will then emit an activationEvent [`onView:${viewId}`](/api/references/activation-events#onView) (e.g. `onView:nodeDependencies` for the example above). You can also control the visibility of the view by providing the `when` context value.
|
||||
|
||||
## View Actions
|
||||
|
||||
You can contribute actions at the 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.
|
||||
|
||||
![View Actions](images/tree-view/view-actions.png)
|
||||
|
||||
Examples:
|
||||
|
||||
```json
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "nodeDependencies.refreshEntry",
|
||||
"title": "Refresh",
|
||||
"icon": {
|
||||
"light": "resources/light/refresh.svg",
|
||||
"dark": "resources/dark/refresh.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "nodeDependencies.addEntry",
|
||||
"title": "Add"
|
||||
},
|
||||
{
|
||||
"command": "nodeDependencies.editEntry",
|
||||
"title": "Edit",
|
||||
"icon": {
|
||||
"light": "resources/light/edit.svg",
|
||||
"dark": "resources/dark/edit.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "nodeDependencies.deleteEntry",
|
||||
"title": "Delete"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"view/title": [
|
||||
{
|
||||
"command": "nodeDependencies.refreshEntry",
|
||||
"when": "view == nodeDependencies",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "nodeDependencies.addEntry",
|
||||
"when": "view == nodeDependencies"
|
||||
}
|
||||
],
|
||||
"view/item/context": [
|
||||
{
|
||||
"command": "nodeDependencies.editEntry",
|
||||
"when": "view == nodeDependencies && viewItem == dependency",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "nodeDependencies.deleteEntry",
|
||||
"when": "view == nodeDependencies && viewItem == dependency"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**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 [`TreeDataProvider`](/api/references/vscode-api#TreeDataProvider) programmatically to populate data in the view.
|
||||
|
||||
```typescript
|
||||
vscode.window.registerTreeDataProvider('nodeDependencies', new DepNodeProvider());
|
||||
```
|
||||
|
||||
See [nodeDependencies.ts](https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample/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.registerTreeDataProvider`. 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](https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample/src/ftpExplorer.ts) for the implementation.
|
|
@ -0,0 +1,123 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 54fdcc33-7ad1-40cc-bc87-ded1841d01ad
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: A guide to using Virtual Documents in Visual Studio Code extensions (plug-ins)
|
||||
---
|
||||
|
||||
# Virtual Documents
|
||||
|
||||
The text document content provider API allows you to create readonly documents in Visual Studio Code from arbitrary sources. You can find a sample extension with source code at: https://github.com/Microsoft/vscode-extension-samples/blob/master/virtual-document-sample/README.md
|
||||
|
||||
## TextDocumentContentProvider
|
||||
|
||||
The API works by claiming an uri-scheme for which your provider then returns text contents. The scheme must be provided when registering a provider and cannot change afterwards. The same provider can be used for multiple schemes and multiple providers can be registered for a single scheme.
|
||||
|
||||
```ts
|
||||
vscode.workspace.registerTextDocumentContentProvider(myScheme, myProvider);
|
||||
```
|
||||
|
||||
Calling `registerTextDocumentContentProvider` returns a disposable with which the registration can be undone. A provider must only implement the `provideTextDocumentContent`-function which is called with an uri and cancellation token.
|
||||
|
||||
```ts
|
||||
const myProvider = class implements vscode.TextDocumentContentProvider {
|
||||
provideTextDocumentContent(uri: vscode.Uri): string {
|
||||
// simply invoke cowsay, use uri-path as text
|
||||
return cowsay.say({ text: uri.path });
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Note how the provider doesn't create uris for virtual documents - its role is to **provide** contents given such an uri. In return, content providers are wired into the open document logic so that providers are always considered.
|
||||
|
||||
This sample uses a 'cowsay'-command that crafts an uri which the editor should then show:
|
||||
|
||||
```ts
|
||||
vscode.commands.registerCommand('cowsay.say', async () => {
|
||||
let what = await vscode.window.showInputBox({ placeHolder: 'cow say?' });
|
||||
if (what) {
|
||||
let uri = vscode.Uri.parse('cowsay:' + what);
|
||||
let doc = await vscode.workspace.openTextDocument(uri); // calls back into the provider
|
||||
await vscode.window.showTextDocument(doc, { preview: false });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The command prompts for input, creates an uri of the `cowsay`-scheme, opens a document for the uri, and finally opens an editor for that document. In step 3, opening the document, the provider is being asked to provide contents for that uri.
|
||||
|
||||
With this we have a fully functional text document content provider. The next sections describe how virtual documents can be updated and how UI commands can be registered for virtual documents.
|
||||
|
||||
### Update Virtual Documents
|
||||
|
||||
Depending on the scenario virtual documents might change. To support that, providers can implement a `onDidChange`-event. It must be fired for an uri and the editor will then ask for the new contents - assuming the document is still in use.
|
||||
|
||||
The `vscode.Event`-type defines the contract for eventing in VS Code. The easiest way to implement an event is `vscode.EventEmitter`, like so:
|
||||
|
||||
```ts
|
||||
const myProvider = class implements vscode.TextDocumentContentProvider {
|
||||
// emitter and its event
|
||||
onDidChangeEmitter = new vscode.EventEmitter<vscode.Uri>();
|
||||
onDidChange = this.onDidChangeEmitter.event;
|
||||
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
That's all what's needed to make VS code listen for changes of virtual document. The next section will add an editor action that uses the event emitter.
|
||||
|
||||
### Add Editor Commands
|
||||
|
||||
To illustrate above change-event and to get more cowsay, an editor action is needed that reverses what the cow just said. First we need a command that does that:
|
||||
|
||||
```ts
|
||||
// register a command that updates the current cowsay
|
||||
subscriptions.push(
|
||||
vscode.commands.registerCommand('cowsay.backwards', async () => {
|
||||
if (!vscode.window.activeTextEditor) {
|
||||
return; // no editor
|
||||
}
|
||||
let { document } = vscode.window.activeTextEditor;
|
||||
if (document.uri.scheme !== myScheme) {
|
||||
return; // not my scheme
|
||||
}
|
||||
// get path-components, reverse it, and create a new uri
|
||||
let say = document.uri.path;
|
||||
let newSay = say
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
let newUri = document.uri.with({ path: newSay });
|
||||
await vscode.window.showTextDocument(newUri, { preview: false });
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
The snippet above checks that we have an active editor and that its document is one of our scheme. These checks are needed because commands are available (and executable) to everyone. Then the path-component of the uri is reversed and a new uri is created from it, last an editor is opened.
|
||||
|
||||
To top things with an editor command a declarative part in `package.json` is needed. In the `contributes`-section add this config:
|
||||
|
||||
```json
|
||||
"menus": {
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "cowsay.backwards",
|
||||
"group": "navigation",
|
||||
"when": "resourceScheme == cowsay"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This references the `cowsay.backwards`-command that defined in the `contributes/commands`-section and says it should appear in the editor title menu (the toolbar in the upper right corner). Now, just that would mean the command always shows, for every editor. That's what the `when`-clause is used for - it describes what condition must be true to show the action. In this sample it states that the scheme of the document in the editor must be the `cowsay`-scheme. The configuration is then repeated for the `commandPalette`-menu - it shows all commands by default.
|
||||
|
||||
![cowsay-bwd](images/virtual-documents/cowsay-bwd.png)
|
||||
|
||||
### Events and Visibility
|
||||
|
||||
Document providers are first class citizens in VS Code, their contents appears in regular text documents, they use the same infrastructure as files etc. However, that also means that "your" documents cannot hide, they will appear in `onDidOpenTextDocument` and `onDidCloseTextDocument`-events, they are part of `vscode.workspace.textDocuments` and more. The rule for everyone is check the `scheme` of documents and then decide if you want to do something with/for the document.
|
||||
|
||||
### File System API
|
||||
|
||||
If you need more flexibility and power take a look at the [`FileSystemProvider`](/api/references/vscode-api#FileSystemProvider) API. It allows to implement a full file system, having files, folders, binary data, file-deletion, creation and more.
|
|
@ -0,0 +1,964 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: adddd33e-2de6-4146-853b-34d0d7e6c1f1
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Use the Webview API to create fully customizable views within Visual Studio Code.
|
||||
---
|
||||
|
||||
# Webview API
|
||||
|
||||
The webview API allows extensions to create fully customizable views within Visual Studio Code. For example, the built-in Markdown extension uses webviews to render Markdown previews. Webviews can also be used to build complex user interfaces beyond what VS Code's native APIs support.
|
||||
|
||||
Think of a webview as an `iframe` within VS Code that your extension controls. A webview can render almost any HTML content in this frame, and it communicates with extensions using message passing. This freedom makes webviews incredibly powerful, and opens up a whole new range of extension possibilities.
|
||||
|
||||
## Links
|
||||
|
||||
- [Webview Sample](https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample/README.md)
|
||||
|
||||
### VS Code API Usage
|
||||
|
||||
- [`window.createWebviewPanel`](/api/references/vscode-api#window.createWebviewPanel)
|
||||
- [`window.registerWebviewPanelSerializer`](/api/references/vscode-api#window.registerWebviewPanelSerializer)
|
||||
|
||||
## Should I use a webview?
|
||||
|
||||
Webviews are pretty amazing, but they should also be used sparingly and only when VS Code's native API is inadequate. Webviews are resource heavy and run in a separate context from normal extensions. A poorly designed webview can also easily feel out of place within VS Code.
|
||||
|
||||
Before using a webview, please consider the following:
|
||||
|
||||
- Does this functionality really need to live within VS Code? Would it be better as a separate application or website?
|
||||
|
||||
- Is a webview the only way to implement your feature? Can you use the regular VS Code APIs instead?
|
||||
|
||||
- Will your webview add enough user value to justify its high resource cost?
|
||||
|
||||
Remember: Just because you can do something with webviews, doesn't mean you should. However, if you are confident that you need to use webviews, then this document is here to help. Let's get started.
|
||||
|
||||
## Webviews API basics
|
||||
|
||||
To explain the webview API, we are going to build a simple extension called **Cat Coding**. This extension will use a webview to show a gif of a cat writing some code (presumably in VS Code). As we work through the API, we'll continue adding functionality to the extension, including a counter that keeps track of how many lines of source code our cat has written and notifications that inform the user when the cat introduces a bug.
|
||||
|
||||
Here's the `package.json` for the first version of the **Cat Coding** extension. You can find the complete code for the example app [here](https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample/README.md). The first version of our extension [contributes a command](/api/references/contribution-points#contributes.commands) called `catCoding.start`. When a user invokes this command, we will show a simple webview with our cat in it. Users will be able to invoke this command from the **Command Palette** as **Cat Coding: Start new cat coding session** or even create a keybinding for it if they are so inclined.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "cat-coding",
|
||||
"description": "Cat Coding",
|
||||
"version": "0.0.1",
|
||||
"publisher": "bierner",
|
||||
"engines": {
|
||||
"vscode": "^1.23.0"
|
||||
},
|
||||
"activationEvents": ["onCommand:catCoding.start"],
|
||||
"main": "./out/src/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "catCoding.start",
|
||||
"title": "Start new cat coding session",
|
||||
"category": "Cat Coding"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "tsc -p ./",
|
||||
"compile": "tsc -watch -p ./",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^9.4.6",
|
||||
"typescript": "^2.8.3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now let's implement the `catCoding.start` command. In our extension's main file, we register the `catCoding.start` command and use it to show a basic webview:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
// Create and show a new webview
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding', // Identifies the type of the webview. Used internally
|
||||
'Cat Coding', // Title of the panel displayed to the user
|
||||
vscode.ViewColumn.One, // Editor column to show the new webview panel in.
|
||||
{} // Webview options. More on these later.
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The `vscode.window.createWebviewPanel` function creates and shows a webview in the editor. Here is what you see if you try running the `catCoding.start` command in its current state:
|
||||
|
||||
![An empty webview](images/webview/basics-no_content.png)
|
||||
|
||||
Our command opens a new webview panel with the correct title, but with no content! To add our cat to new panel, we also need to set the HTML content of the webview using `webview.html`:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
// Create and show panel
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
|
||||
// And set its HTML content
|
||||
panel.webview.html = getWebviewContent();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" width="300" />
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
If you run the command again, now the webview looks like this:
|
||||
|
||||
![A webview with some HTML](images/webview/basics-html.png)
|
||||
|
||||
Progress!
|
||||
|
||||
`webview.html` should always be a complete HTML document. HTML fragments or malformed HTML may cause unexpected behavior.
|
||||
|
||||
### Updating webview content
|
||||
|
||||
`webview.html` can also update a webview's content after it has been created. Let's use this to make **Cat Coding** more dynamic by introducing a rotation of cats:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
const cats = {
|
||||
'Coding Cat': 'https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif',
|
||||
'Compiling Cat': 'https://media.giphy.com/media/mlvseq9yvZhba/giphy.gif'
|
||||
};
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
|
||||
let iteration = 0;
|
||||
const updateWebview = () => {
|
||||
const cat = iteration++ % 2 ? 'Compiling Cat' : 'Coding Cat';
|
||||
panel.title = cat;
|
||||
panel.webview.html = getWebviewContent(cat);
|
||||
};
|
||||
|
||||
// Set initial content
|
||||
updateWebview();
|
||||
|
||||
// And schedule updates to the content every second
|
||||
setInterval(updateWebview, 1000);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent(cat: keyof typeof cats) {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="${cats[cat]}" width="300" />
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
![Updating the webview content](images/webview/basics-update.gif)
|
||||
|
||||
Setting `webview.html` replaces the entire webview content, similar to reloading an iframe. This is important to remember once you start using scripts in a webview, since it means that setting `webview.html` also resets the script's state.
|
||||
|
||||
The example above also uses `webview.title` to change the title of the document displayed in the editor. Setting the title does not cause the webview to be reloaded.
|
||||
|
||||
### Lifecycle
|
||||
|
||||
Webview panels are owned by the extension that creates them. The extension must hold onto the webview returned from `createWebviewPanel`. If your extension loses this reference, it cannot regain access to that webview again, even though the webview will continue to show in VS Code.
|
||||
|
||||
As with text editors, a user can also close a webview panel at any time. When a webview panel is closed by the user, the webview itself is destroyed. Attempting to use a destroyed webview throws an exception. This means that the example above using `setInterval` actually has an important bug: if the user closes the panel, `setInterval` will continue to fire, which will try to update `panel.webview.html`, which of course will throw an exception. Cats hate exceptions. Let's fix this!
|
||||
|
||||
The `onDidDispose` event is fired when a webview is destroyed. We can use this event to cancel further updates and clean up the webview's resources:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
const cats = {
|
||||
'Coding Cat': 'https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif',
|
||||
'Compiling Cat': 'https://media.giphy.com/media/mlvseq9yvZhba/giphy.gif'
|
||||
};
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
|
||||
let iteration = 0;
|
||||
const updateWebview = () => {
|
||||
const cat = iteration++ % 2 ? 'Compiling Cat' : 'Coding Cat';
|
||||
panel.title = cat;
|
||||
panel.webview.html = getWebviewContent(cat);
|
||||
};
|
||||
|
||||
updateWebview();
|
||||
const interval = setInterval(updateWebview, 1000);
|
||||
|
||||
panel.onDidDispose(
|
||||
() => {
|
||||
// When the panel is closed, cancel any future updates to the webview content
|
||||
clearInterval(interval);
|
||||
},
|
||||
null,
|
||||
context.subscriptions
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Extensions can also programmatically close webviews by calling `dispose()` on them. If, for example, we wanted to restrict our cat's workday to five seconds:
|
||||
|
||||
```ts
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
|
||||
panel.webview.html = getWebviewContent(cats['Coding Cat']);
|
||||
|
||||
// After 5sec, pragmatically close the webview panel
|
||||
const timeout = setTimeout(() => panel.dispose(), 5000);
|
||||
|
||||
panel.onDidDispose(
|
||||
() => {
|
||||
// Handle user closing panel before the 5sec have passed
|
||||
clearTimeout(timeout);
|
||||
},
|
||||
null,
|
||||
context.subscriptions
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Visibility and Moving
|
||||
|
||||
When a webview panel is moved into a background tab, it becomes hidden. It is not destroyed however. VS Code will automatically restore the webview's content from `webview.html` when the panel is brought to the foreground again:
|
||||
|
||||
![Webview content is automatically restored when the webview becomes visible again](images/webview/basics-restore.gif)
|
||||
|
||||
The `.visible` property tells you if the webview panel is currently visible or not.
|
||||
|
||||
Extensions can programmatically bring a webview panel to the foreground by calling `reveal()`. This method takes an optional target view column to show the panel in. A webview panel may only show in a single editor column at a time. Calling `reveal()` or dragging a webview panel to a new editor column moves the webview into that new column.
|
||||
|
||||
![Webviews are moved when you drag them between tabs](images/webview/basics-drag.gif)
|
||||
|
||||
Let's update our extension to only allow a single webview to exist at a time. If the panel is in the background, then the `catCoding.start` command will bring it to the foreground:
|
||||
|
||||
```ts
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// Track currently webview panel
|
||||
let currentPanel: vscode.WebviewPanel | undefined = undefined;
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const columnToShowIn = vscode.window.activeTextEditor
|
||||
? vscode.window.activeTextEditor.viewColumn
|
||||
: undefined;
|
||||
|
||||
if (currentPanel) {
|
||||
// If we already have a panel, show it in the target column
|
||||
currentPanel.reveal(columnToShowIn);
|
||||
} else {
|
||||
// Otherwise, create a new panel
|
||||
currentPanel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
columnToShowIn,
|
||||
{}
|
||||
);
|
||||
currentPanel.webview.html = getWebviewContent(cats['Coding Cat']);
|
||||
|
||||
// Reset when the current panel is closed
|
||||
currentPanel.onDidDispose(
|
||||
() => {
|
||||
currentPanel = undefined;
|
||||
},
|
||||
null,
|
||||
context.subscriptions
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Here's the new extension in action:
|
||||
|
||||
![Using a single panel and reveal](images/webview/basics-single_panel.gif)
|
||||
|
||||
Whenever a webview's visibility changes, or when a webview is moved into a new column, the `onDidChangeViewState` event is fired. Our extension can use this event to change cats based on which column the webview is showing in:
|
||||
|
||||
```ts
|
||||
const cats = {
|
||||
'Coding Cat': 'https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif',
|
||||
'Compiling Cat': 'https://media.giphy.com/media/mlvseq9yvZhba/giphy.gif',
|
||||
'Testing Cat': 'https://media.giphy.com/media/3oriO0OEd9QIDdllqo/giphy.gif'
|
||||
};
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
panel.webview.html = getWebviewContent(cats['Coding Cat']);
|
||||
|
||||
// Update contents based on view state changes
|
||||
panel.onDidChangeViewState(
|
||||
e => {
|
||||
const panel = e.webviewPanel;
|
||||
switch (panel.viewColumn) {
|
||||
case vscode.ViewColumn.One:
|
||||
updateWebviewForCat(panel, 'Coding Cat');
|
||||
return;
|
||||
|
||||
case vscode.ViewColumn.Two:
|
||||
updateWebviewForCat(panel, 'Compiling Cat');
|
||||
return;
|
||||
|
||||
case vscode.ViewColumn.Three:
|
||||
updateWebviewForCat(panel, 'Testing Cat');
|
||||
return;
|
||||
}
|
||||
},
|
||||
null,
|
||||
context.subscriptions
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function updateWebviewForCat(panel: vscode.WebviewPanel, catName: keyof typeof cats) {
|
||||
panel.title = catName;
|
||||
panel.webview.html = getWebviewContent(cats[catName]);
|
||||
}
|
||||
```
|
||||
|
||||
![Responding to onDidChangeViewState events](images/webview/basics-ondidchangeviewstate.gif)
|
||||
|
||||
### Inspecting and debugging webviews
|
||||
|
||||
The **Developer: Open Webview Developer Tools** VS Code command lets you debug webviews. Running the command launches an instance of Developer Tools for any currently visible webviews:
|
||||
|
||||
![Webview Developer Tools](images/webview/basics-developer_tools.png)
|
||||
|
||||
The contents of the webview are within an iframe inside the webview document. You can use Developer Tools to inspect and modify the webview's DOM, and debug scripts running within the webview itself.
|
||||
|
||||
If you use the webview Developer Tools console, make sure to select the **active frame** environment from the drop-down in the top left corner of the Console panel:
|
||||
|
||||
![Selecting the active frame](images/webview/debug-active-frame.png)
|
||||
|
||||
The **active frame** environment is where the webview scripts themselves are executed.
|
||||
|
||||
In addition, the **Developer: Reload Webview** command reloads all active webviews. This can be helpful if you need to reset a webview's state, or if some webview content on disk has changed and you want the new content to be loaded.
|
||||
|
||||
## Loading local content
|
||||
|
||||
Webviews run in isolated contexts that cannot directly access local resources. This is done for security reasons. This means that in order to load images, stylesheets, and other resources from your extension, or to load any content from the user's current workspace, you must use the `vscode-resource:` scheme inside the webview.
|
||||
|
||||
The `vscode-resource:` scheme is similar to the `file:` scheme, but it only allows access to select local files. Like with `file:`, `vscode-resource:` loads a resource at a given absolute path from the disk.
|
||||
|
||||
Imagine that we want to start bundling the cat gifs into our extension rather pulling them from Giphy. To do this, we first create a URI to the file on disk and then update this URI to use the `vscode-resource` scheme:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{}
|
||||
);
|
||||
|
||||
// Get path to resource on disk
|
||||
const onDiskPath = vscode.Uri.file(
|
||||
path.join(context.extensionPath, 'media', 'cat.gif')
|
||||
);
|
||||
|
||||
// And get the special URI to use with the webview
|
||||
const catGifSrc = onDiskPath.with({ scheme: 'vscode-resource' });
|
||||
|
||||
panel.webview.html = getWebviewContent(catGifSrc);
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The value for `catGifSrc` will be something like:
|
||||
|
||||
```bash
|
||||
vscode-resource:/Users/toonces/projects/vscode-cat-coding/media/cat.gif
|
||||
```
|
||||
|
||||
By default, `vscode-resource:` can only access resources in the following locations:
|
||||
|
||||
- Within your extension's install directory.
|
||||
- Within the user's currently active workspace.
|
||||
|
||||
You can also always use data URIs to embed resources directly within the webview.
|
||||
|
||||
### Controlling access to local resources
|
||||
|
||||
Webviews can control which resources `vscode-resource:` can load using the `localResourceRoots` option. `localResourceRoots` defines a set of root URIs from which local content may be loaded.
|
||||
|
||||
We can use `localResourceRoots` to restrict **Cat Coding** webviews to only load resources from a `media` directory in our extension:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{
|
||||
// Only allow the webview to access resources in our extension's media directory
|
||||
localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'media'))]
|
||||
}
|
||||
);
|
||||
|
||||
const onDiskPath = vscode.Uri.file(
|
||||
path.join(context.extensionPath, 'media', 'cat.gif')
|
||||
);
|
||||
const catGifSrc = onDiskPath.with({ scheme: 'vscode-resource' });
|
||||
|
||||
panel.webview.html = getWebviewContent(catGifSrc);
|
||||
})
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
To disallow all local resources, just set `localResourceRoots` to `[]`.
|
||||
|
||||
In general, webviews should be as restrictive as possible in loading local resources. However, keep in mind that `vscode-resource` and `localResourceRoots` do not offer complete security protection on their own. Make sure your webview also follows [security best practices](#security), and strongly consider adding a [content security policy](#content-security-policy) to further restrict the content that can be loaded.
|
||||
|
||||
### Theming webview content
|
||||
|
||||
Webview can use CSS to change their appearance based on VS Code's current theme. VS Code groups themes into three categories, and adds a special class to the `body` element to indicate the current theme:
|
||||
|
||||
- `vscode-light` - Light themes.
|
||||
- `vscode-dark` - Dark themes.
|
||||
- `vscode-high-contrast` - High contrast themes.
|
||||
|
||||
The following CSS changes the text color of the webview based on the user's current theme:
|
||||
|
||||
```css
|
||||
body.vscode-light {
|
||||
color: black;
|
||||
}
|
||||
|
||||
body.vscode-dark {
|
||||
color: white;
|
||||
}
|
||||
|
||||
body.vscode-high-contrast {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
When developing a webview application, make sure that it works for the three types of themes. And always test your webview in high-contrast mode to make sure it will be usable by people with visual disabilities.
|
||||
|
||||
Webviews can also access VS Code theme colors using [CSS variables](https://developer.mozilla.org/docs/Web/CSS/Using_CSS_variables). These variable names are prefixed with `vscode` and replace the `.` with `-`. For example `editor.foreground` becomes `var(--vscode-editor-foreground)`:
|
||||
|
||||
```css
|
||||
code {
|
||||
color: var(--vscode-editor-foreground);
|
||||
}
|
||||
```
|
||||
|
||||
Review the [Theme Color Reference](/api/references/theme-color) for the available theme variables.
|
||||
|
||||
The following font related variables are also defined:
|
||||
|
||||
- `-vscode-editor-font-family` - Editor font family (from the `editor.fontFamily` setting).
|
||||
- `-vscode-editor-font-weight` - Editor font size (from the `editor.fontWeight` setting).
|
||||
- `-vscode-editor-font-size` - Editor font weight (from the `editor.fontWeight` setting).
|
||||
|
||||
## Scripts and message passing
|
||||
|
||||
Webviews are just like iframes, which means that they can also run scripts. JavaScript is disabled in webviews by default, but it can easily re-enable by passing in the `enableScripts: true` option.
|
||||
|
||||
Let's use a script to add a counter tracking the lines of source code our cat has written. Running a basic script is pretty simple, but note that this example is only for demonstration purposes. In practice, your webview should always disable inline scripts using a [content security policy](#content-security-policy):
|
||||
|
||||
```ts
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{
|
||||
// Enable scripts in the webview
|
||||
enableScripts: true
|
||||
}
|
||||
);
|
||||
|
||||
panel.webview.html = getWebviewContent();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" width="300" />
|
||||
<h1 id="lines-of-code-counter">0</h1>
|
||||
|
||||
<script>
|
||||
const counter = document.getElementById('lines-of-code-counter');
|
||||
|
||||
let count = 0;
|
||||
setInterval(() => {
|
||||
counter.textContent = count++;
|
||||
}, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
![A script running in a webview](images/webview/scripts-basic.gif)
|
||||
|
||||
Wow! that's one productive cat.
|
||||
|
||||
Webview scripts can do just about anything that a script on a normal webpage can. Keep in mind though that webviews exist in their own context, so scripts in a webview do not have access to the VS Code API. That's where message passing comes in!
|
||||
|
||||
### Passing messages from an extension to a webview
|
||||
|
||||
An extension can send data to its webviews using `webview.postMessage()`. This method sends any JSON serializable data to the webview. The message is received inside the webview through the standard `message` event.
|
||||
|
||||
To demonstrate this, let's add a new command to **Cat Coding** that instructs the currently coding cat to refactor their code (thereby reducing the total number of lines). The new `catCoding.doRefactor` command use `postMessage` to send the instruction to the current webview, and `window.addEventListener('message', event => { ... })` inside the webview itself to handle the message:
|
||||
|
||||
```ts
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// Only allow a single Cat Coder
|
||||
let currentPanel: vscode.WebviewPanel | undefined = undefined;
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
if (currentPanel) {
|
||||
currentPanel.reveal(vscode.ViewColumn.One);
|
||||
} else {
|
||||
currentPanel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{
|
||||
enableScripts: true
|
||||
}
|
||||
);
|
||||
currentPanel.webview.html = getWebviewContent();
|
||||
currentPanel.onDidDispose(
|
||||
() => {
|
||||
currentPanel = undefined;
|
||||
},
|
||||
undefined,
|
||||
context.subscriptions
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Our new command
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.doRefactor', () => {
|
||||
if (!currentPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a message to our webview.
|
||||
// You can send any JSON serializable data.
|
||||
currentPanel.webview.postMessage({ command: 'refactor' });
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" width="300" />
|
||||
<h1 id="lines-of-code-counter">0</h1>
|
||||
|
||||
<script>
|
||||
const counter = document.getElementById('lines-of-code-counter');
|
||||
|
||||
let count = 0;
|
||||
setInterval(() => {
|
||||
counter.textContent = count++;
|
||||
}, 100);
|
||||
|
||||
// Handle the message inside the webview
|
||||
window.addEventListener('message', event => {
|
||||
|
||||
const message = event.data; // The JSON data our extension sent
|
||||
|
||||
switch (message.command) {
|
||||
case 'refactor':
|
||||
count = Math.ceil(count * 0.5);
|
||||
counter.textContent = count;
|
||||
break;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
![Passing messages to a webview](images/webview/scripts-extension_to_webview.gif)
|
||||
|
||||
### Passing messages from a webview to an extension
|
||||
|
||||
Webviews can also pass messages back to their extension. This is accomplished using a `postMessage` function on a special VS Code API object inside the webview. To access the VS Code API object, call `acquireVsCodeApi` inside the webview. This function can only be invoked once per session. You must hang onto the instance of the VS Code API returned by this method, and hand it out to any other functions that wish to use it.
|
||||
|
||||
We can use the VS Code API and `postMessage` in our **Cat Coding** webview to alert the extension when our cat introduces a bug in their code:
|
||||
|
||||
```js
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{
|
||||
enableScripts: true
|
||||
}
|
||||
);
|
||||
|
||||
panel.webview.html = getWebviewContent();
|
||||
|
||||
// Handle messages from the webview
|
||||
panel.webview.onDidReceiveMessage(
|
||||
message => {
|
||||
switch (message.command) {
|
||||
case 'alert':
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
context.subscriptions
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" width="300" />
|
||||
<h1 id="lines-of-code-counter">0</h1>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const vscode = acquireVsCodeApi();
|
||||
const counter = document.getElementById('lines-of-code-counter');
|
||||
|
||||
let count = 0;
|
||||
setInterval(() => {
|
||||
counter.textContent = count++;
|
||||
|
||||
// Alert the extension when our cat introduces a bug
|
||||
if (Math.random() < 0.001 * count) {
|
||||
vscode.postMessage({
|
||||
command: 'alert',
|
||||
text: '🐛 on line ' + count
|
||||
})
|
||||
}
|
||||
}, 100);
|
||||
}())
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
![Passing messages from the webview to the main extension](images/webview/scripts-webview_to_extension.gif)
|
||||
|
||||
For security reasons, you must keep the VS Code API object private and make sure it is never leaked into the global state.
|
||||
|
||||
## Security
|
||||
|
||||
As with any webpage, when creating a webview you must follow some basic security best practices.
|
||||
|
||||
### Limit capabilities
|
||||
|
||||
A webview should have the minimum set of capabilities that it needs. For example, if your webview does not need to run scripts, do not set the `enableScripts: true`. If your webview does not need to load resources from the user's workspace, set `localResourceRoots` to `[vscode.Uri.file(extensionContext.extensionPath)]` or even `[]` to disallow access to all local resources.
|
||||
|
||||
### Content security policy
|
||||
|
||||
[Content security policies](https://developers.google.com/web/fundamentals/security/csp/) further restrict the content that can be loaded and executed in webviews. For example, a content security policy can make sure that only a whitelist of scripts can be run in the webview, or even tell the webview to only load images over `https`.
|
||||
|
||||
To add a content security policy, put a `<meta http-equiv="Content-Security-Policy">` directive at the top of the webview's `<head>`
|
||||
|
||||
```ts
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none';">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
...
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
The policy `default-src 'none';` disallows all content. We can then turn back on the minimal amount of content that our extension needs to function. Here's a content security policy that allows loading local scripts and stylesheets, and loading images over `https`:
|
||||
|
||||
```html
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; img-src vscode-resource: https:; script-src vscode-resource:; style-src vscode-resource:;"
|
||||
/>
|
||||
```
|
||||
|
||||
This content security policy also implicitly disables inline scripts and styles. It is a best practice to extract all inline styles and scripts to external files so that they can be properly loaded without relaxing the content security policy.
|
||||
|
||||
### Only load content over https
|
||||
|
||||
If your webview allows loading external resources, it is strongly recommended that you only allow these resources to be loaded over `https` and not over http. The example content security policy above already does this by only allowing images to be loaded over `https:`.
|
||||
|
||||
### Sanitize all user input
|
||||
|
||||
Just as you would for a normal webpage, when constructing the HTML for a webview, you must sanitize all user input. Failing to properly sanitize input can allow content injections, which may open your users up to a security risk.
|
||||
|
||||
Example values that must be sanitized:
|
||||
|
||||
- File contents.
|
||||
- File and folder paths.
|
||||
- User and workspace settings.
|
||||
|
||||
Consider using a helper library to construct your HTML strings, or at least ensure that all content from the user's workspace is properly sanitized.
|
||||
|
||||
Never rely on sanitization alone for security. Make sure to follow the other security best practices, such as having a [content security policy](#content-security-policy) to minimize the impact of any potential content injections.
|
||||
|
||||
## Persistence
|
||||
|
||||
In the standard webview [lifecycle](#lifecycle), webviews are created by `createWebviewPanel` and destroyed when the user closes them or when `.dispose()` is called. The contents of webviews however are created when the webview becomes visible and destroyed when the webview is moved into the background. Any state inside the webview will be lost when the webview is moved to a background tab.
|
||||
|
||||
The best way to solve this is to make your webview stateless. Use [message passing](#passing-messages-from-a-webview-to-an-extension) to save off the webview's state and then restore the state when the webview becomes visible again.
|
||||
|
||||
### getState and setState
|
||||
|
||||
Scripts running inside a webview can use the `getState` and `setState` methods to save off and restore a JSON serializable state object. This state is persisted even the webview content itself is destroyed when a webview panel becomes hidden. The state is destroyed when the webview panel is destroyed.
|
||||
|
||||
```js
|
||||
// Inside a webview script
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
const counter = document.getElementById('lines-of-code-counter');
|
||||
|
||||
// Check if we have an old state to restore from
|
||||
const previousState = vscode.getState();
|
||||
let count = previousState ? previousState.count : 0;
|
||||
counter.textContent = count;
|
||||
|
||||
setInterval(() => {
|
||||
counter.textContent = count++;
|
||||
// Update the saved state
|
||||
vscode.setState({ count });
|
||||
}, 100);
|
||||
```
|
||||
|
||||
`getState` and `setState` are the preferred way to persist state, as they have much lower performance overhead than `retainContextWhenHidden`.
|
||||
|
||||
### Serialization
|
||||
|
||||
By implementing a `WebviewPanelSerializer`, your webviews can be automatically restored when VS Code restarts. Serialization builds on `getState` and `setState`, and is only enabled if your extension registers a `WebviewPanelSerializer` for your webviews.
|
||||
|
||||
To make our coding cats persist across VS Code restarts, first add a `onWebviewPanel` activation event to the extension's `package.json`:
|
||||
|
||||
```json
|
||||
"activationEvents": [
|
||||
...,
|
||||
"onWebviewPanel:catCoding"
|
||||
]
|
||||
```
|
||||
|
||||
This activation event ensures that our extension will be activated whenever VS Code needs to restore a webview with the viewType: `catCoding`.
|
||||
|
||||
Then, in our extension's `activate` method, call `registerWebviewPanelSerializer` to register a new `WebviewPanelSerializer`. The `WebviewPanelSerializer` is responsible for restoring the contents of the webview from its persisted state. This state is the JSON blob that the webview contents set using `setState`.
|
||||
|
||||
```ts
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// Normal setup...
|
||||
|
||||
// And make sure we register a serializer for our webview type
|
||||
vscode.window.registerWebviewPanelSerializer('catCoding', new CatCodingSerializer());
|
||||
}
|
||||
|
||||
class CatCodingSerializer implements vscode.WebviewPanelSerializer {
|
||||
async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel, state: any) {
|
||||
// `state` is the state persisted using `setState` inside the webview
|
||||
console.log(`Got state: ${state}`);
|
||||
|
||||
// Restore the content of our webview.
|
||||
//
|
||||
// Make sure we hold on to the `webviewPanel` passed in here and
|
||||
// also restore any event listeners we need on it.
|
||||
webviewPanel.webview.html = getWebviewContent();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now if you restart VS Code with a cat coding panel open, the panel will be automatically restored in the same editor position.
|
||||
|
||||
### retainContextWhenHidden
|
||||
|
||||
For webviews with very complex UI or state that cannot be quickly saved and restored, you can instead use the `retainContextWhenHidden` option. This option makes a webview keep its content around but in a hidden state, even when the webview itself is no longer in the foreground.
|
||||
|
||||
Although **Cat Coding** can hardly be said to have complex state, let's try enabling `retainContextWhenHidden` to see how the option changes a webview's behavior:
|
||||
|
||||
```ts
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('catCoding.start', () => {
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
'catCoding',
|
||||
'Cat Coding',
|
||||
vscode.ViewColumn.One,
|
||||
{
|
||||
enableScripts: true,
|
||||
retainContextWhenHidden: true
|
||||
}
|
||||
);
|
||||
panel.webview.html = getWebviewContent();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getWebviewContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cat Coding</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" width="300" />
|
||||
<h1 id="lines-of-code-counter">0</h1>
|
||||
|
||||
<script>
|
||||
const counter = document.getElementById('lines-of-code-counter');
|
||||
|
||||
let count = 0;
|
||||
setInterval(() => {
|
||||
counter.textContent = count++;
|
||||
}, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
![persistence retrain](images/webview/persistence-retrain.gif)
|
||||
|
||||
Notice how the counter does not reset now when the webview is hidden and then restored. No extra code required! With `retainContextWhenHidden`, the webview acts similarly to a background tab in a web browser. Scripts and other dynamic content are suspended, but immediately resumed once the webview becomes visible again. You cannot send messages to a hidden webview, even when `retainContextWhenHidden` is enabled.
|
||||
|
||||
Although `retainContextWhenHidden` may be appealing, keep in mind that this has high memory overhead and should only be used when other persistence techniques will not work.
|
||||
|
||||
## Next steps
|
||||
|
||||
If you'd like to learn more about VS Code extensibility, try these topics:
|
||||
|
||||
- [Extension API](/api) - Learn about the full VS Code Extension API.
|
||||
- [Extension Capabilities](/api/extension-capabilities/overview) - Take a look at other ways to extend VS Code.
|
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: 8027f6fb-6c9e-4106-8ef1-f9b0ba1b7085
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Explain the structure of a Visual Studio Code extension (plug-in)
|
||||
---
|
||||
|
||||
# Extension Anatomy
|
||||
|
||||
In the last topic, you were able to get a basic extension running. How does it work under the hood?
|
||||
|
||||
The `Hello World` extension does 3 things:
|
||||
|
||||
- Registers the [`onCommand`](/api/references/activation-events#onCommand) [**Activation Event**](/api/references/activation-events): `onCommand:extension.helloWorld`, so the extension becomes activated when user runs the `Hello World` command.
|
||||
- Uses the [`contributes.commands`](/api/references/contribution-points#contributes.commands) [**Contribution Point**](/api/references/contribution-points) to make the command `Hello World` available in the Command Palette, and bind it to a command ID `extension.helloWorld`.
|
||||
- Uses the [`commands.registerCommand`](/api/references/vscode-api#commands.registerCommand) [**VS Code API**](/api/references/vscode-api) to bind a function to the registered command ID `extension.helloWorld`.
|
||||
|
||||
Understanding these three concepts is crucial to writing extensions in VS Code:
|
||||
|
||||
- [**Activation Events**](/api/references/activation-events): events upon which your extension becomes active.
|
||||
- [**Contribution Points**](/api/references/contribution-points): static declarations that you make in the `package.json` [Extension Manifest](#extension-manifest) to extend VS Code.
|
||||
- [**VS Code API**](/api/references/vscode-api): a set of JavaScript API that you can invoke in your extension code.
|
||||
|
||||
In general, your extension would use a combination of Contribution Points and VS Code API to extend VS Code's functionality. The [Extension Capabilities Overview](/api/extension-capabilities/overview) topic helps you find the right Contribution Point and VS Code API for your extension.
|
||||
|
||||
Let's take a closer look of `Hello World` sample's source code and see how these concepts apply to it.
|
||||
|
||||
## Extension File Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── .vscode
|
||||
│ ├── launch.json // Config for launching and debugging the extension
|
||||
│ └── tasks.json // Config for build task that compiles TypeScript
|
||||
├── .gitignore // Ignore build output and node_modules
|
||||
├── README.md // Readable description of your extension's functionality
|
||||
├── src
|
||||
│ └── extension.ts // Extension source code
|
||||
├── package.json // Extension manifest
|
||||
├── tsconfig.json // TypeScript configuration
|
||||
```
|
||||
|
||||
You can read more about the configuration files:
|
||||
|
||||
- `launch.json` used to configure VS Code [Debugging](/docs/editor/debugging)
|
||||
- `tasks.json` for defining VS Code [Tasks](/docs/editor/tasks)
|
||||
- `tsconfig.json` consult the TypeScript [Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)
|
||||
|
||||
However, let's focus on `package.json` and `extensions.ts`, which are essential to understanding the `Hello World` extension.
|
||||
|
||||
### Extension Manifest
|
||||
|
||||
Each VS Code extension must have a `package.json` as its [Extension Manifest](/api/references/extension-manifest). The `package.json` contains a mix of Node.js fields such as `scripts` and `dependencies` and VS Code specific fields such as `publisher`, `activationEvents` and `contributes`. You can find description of all VS Code specific fields in [Extension Manifest Reference](/api/references/extension-manifest). Here are some most important fields:
|
||||
|
||||
- `name` and `publisher`: VS Code uses `<publisher>.<name>` as a unique ID for the extension. For example, the Hello World sample has the ID `vscode-samples.helloworld-sample`. VS Code uses the ID to uniquely identify your extension
|
||||
- `main`: The extension entry point.
|
||||
- `activationEvents` and `contributes`: [Activation Events](/api/references/activation-events) and [Contribution Points](/api/references/contribution-points).
|
||||
- `engines.vscode`: This specifies the minimum version of VS Code API that the extension depends on.
|
||||
- The `postinstall` script: This would install the 1.25 version of VS Code API as specified in `engines.vscode`. Once the `vscode.d.ts` file is downloaded to `node_modules/vscode/vscode.d.ts`, you will get IntelliSense, jump to definition and error checking for all usage of VS Code API.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "helloworld-sample",
|
||||
"displayName": "helloworld-sample",
|
||||
"description": "HelloWorld example for VS Code",
|
||||
"version": "0.0.1",
|
||||
"publisher": "vscode-samples",
|
||||
"repository": "https://github.com/Microsoft/vscode-extension-samples/helloworld-sample",
|
||||
"engines": {
|
||||
"vscode": "^1.31.0"
|
||||
},
|
||||
"categories": ["Other"],
|
||||
"activationEvents": ["onCommand:extension.helloWorld"],
|
||||
"main": "./out/extension.js",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.helloWorld",
|
||||
"title": "Hello World"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"test": "npm run compile && node ./node_modules/vscode/bin/test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^3.3.1",
|
||||
"vscode": "^1.1.28",
|
||||
"tslint": "^5.12.1",
|
||||
"@types/node": "^10.12.21",
|
||||
"@types/mocha": "^2.2.42"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Extension Entry File
|
||||
|
||||
The extension entry file exports two functions, `activate` and `deactivate`. `activate` is executed when your registered **Activation Event** happens. `deactivate` gives you a chance to clean up before your extension becomes deactivated.
|
||||
|
||||
The [`vscode`](https://www.npmjs.com/package/vscode) module contains a script located at `node ./node_modules/vscode/bin/install`. The script pulls the VS Code API definition file depending on the `engines.vscode` field in `package.json`. After running the script, you would get IntelliSense, jump to definition and other TypeScript language features in your code.
|
||||
|
||||
```ts
|
||||
// The module 'vscode' contains the VS Code extensibility API
|
||||
// Import the module and reference it with the alias vscode in your code below
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// Use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// This line of code will only be executed once when your extension is activated
|
||||
console.log('Congratulations, your extension "helloworld-sample" is now active!');
|
||||
|
||||
// The command has been defined in the package.json file
|
||||
// Now provide the implementation of the command with registerCommand
|
||||
// The commandId parameter must match the command field in package.json
|
||||
let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
|
||||
// The code you place here will be executed every time your command is executed
|
||||
|
||||
// Display a message box to the user
|
||||
vscode.window.showInformationMessage('Hello World!');
|
||||
});
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() {}
|
||||
```
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6f8049c02c06561e684659bb34f370a43a0ff6c7e5d247f3cffd6380a1ac3646
|
||||
size 505351
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:72354e0f8d3f36d99071f6fd753ebbe08c5f1dd837190434bb4432dd06d30a1f
|
||||
size 225716
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:77f54ca12bfaa2f0d38c3c60edf7c49e821ff614f52075a3a99a0eabd6529f16
|
||||
size 315090
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: a15875fa-19b5-4c11-8903-864af133ce57
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Next steps to take after studying the Getting Started section
|
||||
---
|
||||
|
||||
# Wrapping Up
|
||||
|
||||
In the [Your First Extension](/api/get-started/your-first-extension) topic, you learned how to create, run and debug an extension. In the [Extension Anatomy](/api/get-started/extension-anatomy) topic, you learned fundamental concepts to Visual Studio Code extension development. However, we have only seen the tip of the iceberg, and here are some suggested routes for furthering your VS Code extension development skills.
|
||||
|
||||
## Working with Extensions
|
||||
|
||||
This section includes topics that help you develop high-quality VS Code extension. For example, you can learn
|
||||
|
||||
- How to add [integration tests](/api/working-with-extensions/testing-extension) for your extension
|
||||
- How to publish your extension to the [VS Code Marketplace](https://marketplace.visualstudio.com/)
|
||||
- How to set up [Continuous Integration](/api/working-with-extensions/continuous-integration) for your extension
|
||||
|
||||
## Extension Capabilities
|
||||
|
||||
In this section, we split the [VS Code API](/api/references/vscode-api) and [Contribution Points](/api/references/contribution-points) into a few categories, each with short descriptions as to what your extension could achieve. Validate that your extension idea is achievable with VS Code API or look for new extension ideas here.
|
||||
|
||||
## Guides & Samples
|
||||
|
||||
We have a great collection of sample extensions that you can adapt from, and some of them include a detailed guide that explains the source code. You can find all Samples & Guides in the [Extension Guide Listing](/api/extension-guides/overview) or the [vscode-extension-samples](https://github.com/Microsoft/vscode-extension-samples) repository.
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: DC915D6C-13D4-4022-9101-57C4A4118B07
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Create your first Visual Studio Code extension (plug-in) with a simple Hello World example.
|
||||
---
|
||||
|
||||
# Your First Extension
|
||||
|
||||
In this topic, we'll teach you the fundamental concepts for building extensions. Make sure you have [Node.js](https://nodejs.org/en/) and [Git](https://git-scm.com/) installed, then install [Yeoman](http://yeoman.io/) and [VS Code Extension Generator](https://www.npmjs.com/package/generator-code) with:
|
||||
|
||||
```bash
|
||||
npm install -g yo generator-code
|
||||
```
|
||||
|
||||
The generator scaffolds a project ready for development. Run the generator and fill out a few fields:
|
||||
|
||||
```bash
|
||||
yo code
|
||||
|
||||
# ? What type of extension do you want to create? New Extension (TypeScript)
|
||||
# ? What's the name of your extension? HelloWorld
|
||||
### Press <Enter> to choose default for all options below ###
|
||||
|
||||
# ? What's the identifier of your extension? helloworld
|
||||
# ? What's the description of your extension? LEAVE BLANK
|
||||
# ? Enable stricter TypeScript checking in 'tsconfig.json'? Yes
|
||||
# ? Setup linting using 'tslint'? Yes
|
||||
# ? Initialize a git repository? Yes
|
||||
# ? Which package manager to use? npm
|
||||
|
||||
code ./helloworld
|
||||
```
|
||||
|
||||
Then, inside the editor, press `kb(workbench.action.debug.start)`. This will compile and run the extension in a new **Extension Development Host** window.
|
||||
|
||||
Run the `Hello World` command from the Command Palette (`kb(workbench.action.showCommands)`) in the new window:
|
||||
|
||||
<video autoplay loop muted playsinline controls>
|
||||
<source src="/api/get-started/your-first-extension/launch.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
You should see the `Hello World` notification showing up. Success!
|
||||
|
||||
## Developing the extension
|
||||
|
||||
Let's make a change to the message:
|
||||
|
||||
- Change the message from `Hello World` to `Hello VS Code` in `extension.ts`
|
||||
- Run `Reload Window` in the new window
|
||||
- Run the command `Hello World` again
|
||||
|
||||
You should see the updated message showing up.
|
||||
|
||||
<video autoplay loop muted playsinline controls>
|
||||
<source src="/api/get-started/your-first-extension/reload.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
Here are some ideas for you to try:
|
||||
|
||||
- Give the `Hello World` command a new name in the Command Palette.
|
||||
- [Contribute](/api/references/contribution-points) another command that displays current time in an information message.
|
||||
- Replace the `vscode.window.showInformationMessage` with another [VS Code API](/api/references/vscode-api) call to show a warning message.
|
||||
|
||||
## Debugging the extension
|
||||
|
||||
VS Code's built-in debugging functionality makes it easy to debug extensions. Set a breakpoint by clicking the gutter next to a line, and VS Code will hit the breakpoint. You can hover over variables in the editor or use the Debug View in the left to check a variable's value. The Debug Console allows you to evaluate expressions.
|
||||
|
||||
<video autoplay loop muted playsinline controls>
|
||||
<source src="/api/get-started/your-first-extension/debug.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
You can learn more about debugging Node.js apps in VS Code in the [Node.js Debugging Topic](/docs/nodejs/nodejs-debugging).
|
||||
|
||||
## Next steps
|
||||
|
||||
In the next topic, [Extension Anatomy](/api/get-started/extension-anatomy), we'll take a closer look at the source code of the `Hello World` sample and explain key concepts.
|
||||
|
||||
You can find the source code of this tutorial at: https://github.com/Microsoft/vscode-extension-samples/tree/master/helloworld-sample. The [Extension Guides](/api/extension-guides/overview) topic contains other samples, each illustrating a different VS Code API or Contribution Point.
|
||||
|
||||
### Using JavaScript
|
||||
|
||||
In this guide, we mainly describe how to develop VS Code extension with TypeScript because we believe TypeScript offers the best experience for developing VS Code extensions. However, if you prefer JavaScript, you can still follow along using [helloworld-minimal-sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/helloworld-minimal-sample).
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
# DO NOT TOUCH — Managed by doc writer
|
||||
ContentId: AD26EFB1-FFC6-4284-BAB8-F3BCB8294728
|
||||
DateApproved: 3/7/2019
|
||||
|
||||
# Summarize the whole topic in less than 300 characters for SEO purpose
|
||||
MetaDescription: Visual Studio Code has a rich extension API. Learn how to create your own extensions for VS Code.
|
||||
---
|
||||
|
||||
# Extension API
|
||||
|
||||
Visual Studio Code is built with extensibility in mind. From the UI to the editing experience, almost every part of VS Code can be customized and enhanced through the Extension API. In fact, many core features of VS Code are built as [extensions](https://github.com/Microsoft/vscode/tree/master/extensions) and use the same Extension API.
|
||||
|
||||
This documentation describes:
|
||||
|
||||
- How to build, run, debug, test and publish an extension
|
||||
- How to take advantage of VS Code's rich Extension API
|
||||
- Where to find guides and code samples to help get you started
|
||||
|
||||
If you are looking for published extensions, head to the [VS Code Extension Marketplace](https://marketplace.visualstudio.com/vscode).
|
||||
|
||||
## What can extensions do?
|
||||
|
||||
Here are some examples of what you can achieve with the Extension API:
|
||||
|
||||
- Change the look of VS Code with a color or icon theme - [Theming](/api/extension-capabilities/theming)
|
||||
- Add custom components & views in the UI - [Extending the Workbench](/api/extension-capabilities/extending-workbench)
|
||||
- Create a Webview to display a custom webpage built with HTML/CSS/JS - [Webview Guide](/api/extension-guides/webview)
|
||||
- Support a new programming language - [Language Extensions Overview](/api/language-extensions/overview)
|
||||
- Support debugging a specific runtime - [Debugger Extension Guide](/api/extension-guides/debugger-extension)
|
||||
|
||||
If you'd like to have a more comprehensive overview of the Extension API, refer to the [Extension Capabilities Overview](/api/extension-capabilities/overview) page. [Extension Guides Overview](/api/extension-guides/overview) also includes a list of code samples and guides that illustrate various Extension API usage.
|
||||
|
||||
## How to build extensions?
|
||||
|
||||
Building a good extension can take a lot of effort. Here is how each section of the API doc can help you with:
|
||||
|
||||
- **Get Started** teaches fundamental concepts for building extensions with the [Hello World](https://github.com/Microsoft/vscode-extension-samples/tree/master/helloworld-sample) sample.
|
||||
- **Working with Extensions** includes in-depth guides on various extension development topics, such as [publishing](/api/working-with-extensions/publishing-extension) and [testing](/api/working-with-extensions/testing-extension) extensions.
|
||||
- **Extension Capabilities** dissects VS Code's vast API into smaller categories and points you to more detailed topics.
|
||||
- **Extension Guides** includes guides and code samples that explains specific usages of VS Code Extension API.
|
||||
- **Language Extensions** illustrates how to add support for a programming language with guides and code samples.
|
||||
- **Advanced Topics** explains advanced concepts such as [Extension Host](/api/advanced-topics/extension-host) and [Proposed API](/api/advanced-topics/using-proposed-api).
|
||||
- **References** contains exhaustive references for the [VS Code API](/api/references/vscode-api), [Contribution Points](/api/references/contribution-points), and many other topics.
|
||||
|
||||
## Looking for help
|
||||
|
||||
If you have questions for extension development, try asking on:
|
||||
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/visual-studio-code): There are [12k questions](https://stackoverflow.com/questions/tagged/visual-studio-code) tagged `visual-studio-code`, and over half of them already have answers. Search for your issue, ask questions, or help your fellow developers by answering VS Code extension development questions!
|
||||
- [Gitter Channel](https://gitter.im/Microsoft/vscode) and [VS Code Dev Slack](https://join.slack.com/t/vscode-dev-community/shared_invite/enQtMjIxOTgxNDE3NzM0LWU5M2ZiZDU1YjBlMzdlZjA2YjBjYzRhYTM5NTgzMTAxMjdiNWU0ZmQzYWI3MWU5N2Q1YjBiYmQ4MzY0NDE1MzY): Public chatroom for extension developers. Some VS Code team members chime in conversations.
|
||||
|
||||
To provide feedback on the documentation, create new issues at [Microsoft/vscode-docs](https://github.com/Microsoft/vscode-docs/issues).
|
||||
If you have extension questions that you cannot find an answer for, or issues with VS Code Extension API, please open new issues at [Microsoft/vscode](https://github.com/Microsoft/vscode/issues).
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
DateApproved:
|
||||
MetaDescription:
|
||||
---
|
||||
|
||||
# Embedded Languages
|
||||
|
||||
https://github.com/Microsoft/vscode/issues/47288
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a5feae560506773746a0a002e3468e087a1bf30bf65c921545cd2ac131ab20df
|
||||
size 51025
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:36e52ae5df00019deba4d5786dddfb4780c729dbde7c03a19c668fd217af95b8
|
||||
size 314979
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b1a27690b1e47aa75e056329ca75b75bab285cf8d3a9b9d8a4fed318662aee1f
|
||||
size 315792
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f4f6c14a9a8cf6efcb11464261bcbf433e234589f1a26f19d5e842485f8c9d04
|
||||
size 28842
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3730cb0286908e5e33eac87192e122073ddf22ef8cd1d60b8aff219479d83cd1
|
||||
size 27047
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ffab57aab93a48e578145e8db26a9288d00ffdd902d9206c6cfd9b07e80776c1
|
||||
size 225342
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3ff290a8b6d6623783b41624bae2a0cac5e5c1dfff893e0d35c7676125a8afec
|
||||
size 71365
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2e68101cb33b8e7963c75cfc574b0442a33ba4cfd65d88e761e9e9ab5f2f730c
|
||||
size 109768
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dae4b4fed44a1dd7ee8edc76e6451f593a2d15050224599dc3d241660d627178
|
||||
size 48989
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:53a4a46a2e5ee9118e323b03d9daebd814900787ace08257e2866c600b42db28
|
||||
size 48092
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bbc9ec3bd2090ba3e8ce5b643c6790ef6c192922a3a0ea6ea95e98582bfb0162
|
||||
size 351034
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d3b316b1d4d304a9ab96ac71119e9ca5207c1415b24e22be0b513b9b584c367c
|
||||
size 1129232
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d3b316b1d4d304a9ab96ac71119e9ca5207c1415b24e22be0b513b9b584c367c
|
||||
size 1129232
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f5c316e3c7871eacff83be2e910f5245b3f14268401f334a541c743e7656d15a
|
||||
size 25008
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:889f86907c4d49b70884360776579592f978b5e92b9088e2393def44888ec313
|
||||
size 62406
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0680448e97a5a9e43c6a7c9f282ad2a28fdf0610a5364bcb36a1d8460fb89aea
|
||||
size 114544
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:24af794e0aa70a4e679ef20ec3043113cde877db1e24b61e1bd591540a0b8b1e
|
||||
size 687724
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3f05d4f34cfffaee608f5e43c2673a3ca64cdb5b7b2b5ae6dbd33ec6516bae7f
|
||||
size 491626
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:50cfb552fe9dd911513bb7b5eec88663ffb80924a6248d90977adb7d9ac17aa5
|
||||
size 421575
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3cc74718d3bd1b4e62017791886c668bc149809c471c67572d103d165e7c0771
|
||||
size 210381
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:20a6cef81364af13cf7b3fa1d47d69ac60b3f8efaf34630018d712bbdb5fe65e
|
||||
size 34654
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:258c8a88e659af2c2ebfc30a9d8cb5e62d34441b1c700c0db811ebd051579f51
|
||||
size 201040
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7a29e16ecb8c22ce8c5dd6ffc2a5bb0566219a6de44b2406f031a946809772c8
|
||||
size 156868
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2107803e03cf863b32754ecf48d7d1a69379ff7dcc694ff3e2c8561305c1d154
|
||||
size 152650
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c56959054670a76484ad3b7a254a70bfcf889531aba7a2359e3b6182bd0ec3a5
|
||||
size 459464
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:10e5b7afacdbb880e1128e188cafb9e9f09834ee496fcf4a05fb42cf1293f6d6
|
||||
size 78883
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:71a345610f7b7da2e14796832c4a9f771dfee816f6872cf2a91cbfb73760c91a
|
||||
size 66714
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче