April 2018 (version 1.23)

Update 1.23.1: The update addresses these issues.

Downloads: Windows | Mac | Linux 64-bit: .tar.gz .deb .rpm | Linux 32-bit: .tar.gz .deb .rpm

Welcome to the April 2018 release of Visual Studio Code. This milestone the VS Code team has been focused on API work to support extension authors, but there are still plenty of updates in this version that we hope you will like. Some of the key highlights include:

If you'd like to read these release notes online, go to Updates on code.visualstudio.com.
You can also check out this 1.23 release highlights video from Cloud Developer Advocate Brian Clark.

The release notes are arranged in the following sections related to VS Code focus areas. Here are some further updates:

  • Editor - Better Unicode file support, more stable editor positioning.
  • Workbench - Copy search results, better Git clone workflow, VS Code process explorer.
  • Debugging - Logpoint expressions support smart completions and displaying structured objects.
  • Languages - JavaScript/TypeScript Organize Imports action, persistent Markdown previews.
  • Extension Authoring - New webview and FileSystem Provider APIs, 'Source' file level actions.

Insiders: Want to see new features as soon as possible? You can download the nightly Insiders build and try the latest updates as soon as they are available.


Highlighted indent guides

VS Code can now highlight the active indent guide, as you move your cursor between various source code blocks.

Highlighted indent guides

The highlight color name is editorIndentGuide.activeBackground, which you can modify in the workbench.colorCustomizations setting:

"workbench.colorCustomizations": {
    "editorIndentGuide.activeBackground": "#ff0000"

Run Code Actions on save

The new editor.codeActionsOnSave setting lets you configure a set of Code Actions that are run when a file is saved. For example, for JavaScript, TypeScript, and other extensions that contribute an organize imports Code Action, you can enable organize imports on save by setting:

"editor.codeActionsOnSave": {
     "source.organizeImports": true

You can also enable or disable which Code Actions are run on save per language using a language specific setting. The following settings enable organize imports on save for TypeScript files only:

"[typescript]": {
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
"[typescriptreact]": {
    "editor.codeActionsOnSave": {
        "source.organizeImports": true

Column selection using middle mouse button

In VS Code, column (box) selection can be added by holding Shift and Alt and then using the left mouse button. Now the middle mouse button can also be used to create a column selection:

Editor column selection

Note: When setting editor.multiCursorModifier to ctrlCmd, the modifiers are Shift and Ctrl on Windows and Shift and Cmd on macOS.

Improved handling of UTF-16 encoded files

VS Code always supported the UTF-16 encoding for files but required a BOM (byte order mark) to properly detect this encoding. If VS Code didn't find a BOM, the file would not be opened and the user saw an information message.

With this release, we added a new action to this message to open the file as text in the editor:

Open binary file message

Once opened, you can then change the encoding to try to decode the text.

In addition, VS Code now uses a heuristic that tries to detect UTF-16 without a BOM automatically. This heuristic should work for all UTF-16 files that contain only ASCII characters.

Improved editor positioning

In certain cases when changing the editor scroll height (such as resizing a wrapped editor, using mouse wheel zooming, or modifying a CodeLens), the editor would attempt to maintain the centered line in the viewport. VS Code now maintains the first line in the viewport, providing a more stable appearance.

Improved editor stability


Problems view filtering

You can now include or exclude files in the Problems view using filters.

  • Use glob patterns in the filter input box to include/exclude files. An exclude pattern must be prefixed with !. For example, !*.js will remove all files that have a .js extension.
  • There is a Filter using Files Exclude Setting button to remove all files matching your files.exclude setting.

The short video below shows filtering the project out directory based on the files.exclude setting and ignoring all node_modules by typing !**/node_module/** in the filter input box:

Filter problems

NPM script running

With the setting npm.enableScriptExplorer, you can enable an explorer that shows the scripts defined in your workspace.

NPM script explorer

The explorer supports:

  • Open a script inside a package.json file or the scripts section when the package.json file is selected. This is the default action when selecting a script.
  • Run a script as a task with the output shown in the Integrated Terminal.
  • Debug a script. To launch the node debugger, the script needs to define a node debug option like --inspect-brk (see also).

Use the npm.exclude setting to exclude scripts in package.json files contained in particular folders.

Git clone improvements

There have been several improvements to the Git clone workflow. When running the Git: Clone command:

  • A native dialog is used to pick the repository location.
  • The new notification progress API is used, improving the operation status reporting.
  • VS Code will prompt you whether you'd like to add the cloned repository to your workspace or open it directly.

The Git extension also adopted the new proposed API to handle system-wide URIs and invokes Git clone on specific URIs. Here's an example URI which clones https://github.com/Microsoft/vscode-vsce.git:


If you'd like to try this out:

  • Windows: In a Command Prompt, type: explorer "vscode://vscode.git/clone?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fvscode-vsce.git".
  • macOS: In a shell, type: open vscode://vscode.git/clone?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fvscode-vsce.git.

Copy results from search context menu

The search results tree context menu includes three new options: Copy, Copy Path, and Copy All. This was a highly 👍'd request which will make it easier to share or export your search results.

Copy search

Return of the separate search include and exclude input boxes

Last month, we merged the include and exclude input boxes in the Search view in an attempt to simplify and streamline it, while also saving a little vertical space. However, we heard from many of you that this didn't fit with the way you were using the Search view. Eventually, we decided to simply revert the change and so with this release, we are back to having separate include/exclude boxes as we had before 1.22. Note that you don't need to use ! on patterns in the exclude box.

include exclude

Custom Activity Bar views

Extension authors can now add their own view containers to the Activity Bar. Depending on your installed extensions, after an update you may see UI such as custom explorers move from the File Explorer to a new custom view container. For example, below you can see that the explorers from the Azure App Service and Azure Cosmos DB extensions have moved to a dedicated Azure view.

Azure view in the Activity Bar

See the running Visual Studio Code processes

Use the Developer: Open Process Explorer command or Help > Open Process Explorer menu item to open a new window that contains continuously updating information about running VS Code processes. Processes are listed with their CPU and memory usage, PID, and friendly name, and can be killed from a context menu that appears on right-clicking.

Process Explorer

Integrated Terminal

Multi-root support for terminal splitting

You will now be able to select the folder to split the terminal into when inside a multi-root workspace. The old behavior can be reenabled by keybinding the workbench.action.terminal.splitInActiveWorkspace command.


CSS region folding

You can now use /* #region */ and /* #endregion */ to mark a region as foldable in CSS/SCSS/Less. In SCSS/Less, you can also use // #region and // #endregion as folding markers.

Improved CSS Folding

Improved CSS support for new properties

Previously, VS Code would show an "Unknown Property" error for some experimental CSS properties, such as backdrop-filter:

CSS Unknown Property

You would either have to turn off CSS linting completely or endure this error, even if you are using CSS frameworks such as PostCSS that allows you to use experimental CSS properties.

In this release, with data sourced from Mozilla Developer Network, VS Code now identifies 87 new CSS properties. If you can find a CSS property on MDN, VS Code should recognize it.

Furthermore, with data from MDN, VS Code now provides enhanced completions in CSS/SCSS/Less, showing the syntax and status value of each CSS properties.

CSS Support powered by MDN data

Although there is no built-in support for validating CSS property values yet, the CSSTree validator extension also uses data from MDN and offers linting for each property value based on its value definition syntax:


Markdown now has support for workspace symbol search. After opening a Markdown file for the first time, you can use (⌘T (Windows, Linux Ctrl+T)) to search through the headers of all Markdown files in the current workspace:

Markdown workspace symbol in the VS Code docs repo

Persistent Markdown previews

Markdown previews are now automatically restored when you reopen VS Code:

A Markdown preview automatically being reopened when VS Code restarts

Previously previews had to be reopened whenever you restarted VS Code.

TypeScript 2.8.3

VS Code now ships with TypeScript 2.8.3. This release fixes a number of important bugs.

JavaScript and TypeScript Organize Imports

The JavaScript and TypeScript organize imports feature is now out of preview. Run Organize Imports (⇧⌥O (Windows, Linux Shift+Alt+O)) to quickly remove unused imports and sort the remaining imports in your JavaScript and TypeScript source code.

You can now also configure organize imports to be run on save using the new editor.codeActionsOnSave setting. Here are the settings to enable organize imports on save for TypeScript files:

"[typescript]": {
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
"[typescriptreact]": {
    "editor.codeActionsOnSave": {
        "source.organizeImports": true


Logpoint improvements

Logpoints were introduced in the last release and we've improved their ease of use and usefulness:

  • IntelliSense (smart completion) has been added for expressions embedded in log messages and conditional breakpoints.

  • When using Logpoints in Node.js debugging, structured objects embedded in the log message appear as expandable object in the Debug Console:

    IntelliSense for Logpoint expressions

  • Logpoints in Node.js debugging now show their source location in the Debug Console:

    Logpoint location

  • Since Logpoints and breakpoints can be easily deleted by clicking on their icon in the editor's gutter, you can accidentally lose a log message or a breakpoint condition. To prevent this, VS Code now prompts when a breakpoint with a condition or log message is deleted by clicking in the gutter. The alert gives you the option to disable the breakpoint instead of deleting it.

  • Last but not least, we've added a New Breakpoint > Logpoint... action to the Debug menu.

Extension Authoring

Contributions to the Activity Bar

As more and more extensions are creating custom views and the majority of them are contributed to the File Explorer, we noticed the Explorer was getting cluttered. To scale up, VS Code now provides a way to contribute to the Activity Bar. As an example, there is now a Test contribution to the Activity Bar. Extensions can now make their own contributions.

Test view container

A new Test contribution is now provided in the Activity Bar for the extensions to contribute Test related views. This Test contribution is empty and hidden by default and is shown whenever views are contributed to it. The example shows how the mocha custom view is contributed to the Test activity in the Activity Bar.

"contributes": {
    "views": {
        "test": [
                "id": "mocha",
                "name": "mocha"

Test views container

Custom view containers

An extension can now define additional activities in the Activity Bar using the contribution point viewsContainers.

"contributes": {
        "viewsContainers": {
            "activitybar": [
                    "id": "package-explorer",
                    "title": "Package Explorer",
                    "icon": "resources/package-explorer.svg"
        "views": {
            "package-explorer": [
                    "id": "package-dependencies",
                    "name": "Dependencies"
                    "id": "package-outline",
                    "name": "Outline"

Custom views container

Icon specifications

  • Size: Icons are 28x28 centered on a 50x40 square.

  • Color: Icons should use a single monochrome color.

  • Format: It is recommended that icons be in SVG, though any image file type is accepted.

  • States: All icons inherit the following state styles:

    State Opacity
    Default 60%
    Hover 100%
    Active 100%

A command is registered to show each registered view container. In the Package Explorer example above, it would be View: Show Package Explorer. You can also find all view containers listed when you run the command View: Open View....

Open View

NOTE: It is recommended that you group related views into a single view container instead of creating a view container for each view.

Custom views in Source Control

You can now contribute Source Control Management (SCM) related custom views into the Source Control view container in the Activity Bar. You can show, hide and re-order these views just like in the Explorer.

"contributes": {
    "views": {
        "scm": [
                "id": "git-compare",
                "name": "Compare"

SCM Custom views

FileSystem Providers

Extensions can now serve files and folders from arbitrary sources, like ftp-servers, and VS Code will handle them just like regular files. To do so, use the FileSystemProvider interface which an extension associates with a URI scheme, like ftp. With that interface, the editor can discover and manage files and folders (create, delete, read, and write).

Files and Folders from a filesystem provider

VS Code can also read and modify configuration files (settings.json, tasks.json, launch.json) served by FileSystem Providers.

Language Identifiers and Document Selectors

The addition of FileSystem Providers means that not all files live on disk and extensions should be aware of this. The short, but important, message is that not all documents live on disk and if your extension relies on disk-access, you must check the scheme first.

To raise awareness, we have added an information message which shows when you register a language feature using just a language identifier, not a document filter. For more details, visit the Document Selector topic.

Last, there is a sample extension which you can use for testing. It implements a filesystem that keeps everything in memory, nothing is on disk, and you can test your language features against that. Get the extension here.

Watch out: TextDocument.isUntitled

Due to the addition of FileSystem Providers, we have adjusted the semantics of TextDocument.isUntitled to be true only for newly created documents (using the untitled scheme). Before, all documents not from disk were treated as untitled. This change might alter the behavior of your extension, especially if it assumes that documents that aren't untitled are stored on disk.

Reading Diagnostics

There is new API to read diagnostics and to be notified when diagnostics change, see languages.getDiagnostics and languages.onDidChangeDiagnostics. For instance, an SCM extension can now check that there are no errors before sharing changes with the team.

Refined RenameProvider

We have refined the RenameProvider API and it can now, optionally, implement a new function called prepareRename. With that function, the provider can help VS Code resolve and validate the symbol to be renamed.

Include offset based information in document change events

TextDocumentContentChangeEvent has a new property, rangeOffset, which, together with rangeLength, allows extensions to use (offset,length) coordinates to keep track of text document changes.

Source Code Action kinds

CodeActionKind.Source identifies Code Actions that apply to the entire file. Organize imports is a good example of a Source Code Action since it can be triggered from any position in a file.

Source Code Actions do not show up in the normal Quick Fix lightbulb menu. They must be explicitly requested using the editor.action.sourceAction command. Source Code Actions also show up in the new Source Actions context menu.

Organize imports Code Actions

Building on Source Code Actions, the newly added CodeActionKind.SourceOrganizeImports identifies an organize imports Code Action. These actions can be triggered using editor.action.organizeImports and have a standard keyboard shortcut: ⇧⌥O (Windows, Linux Shift+Alt+O).

If your extension already implements organize imports, we highly recommend that you migrate it to use CodeActionKind.SourceOrganizeImports so that users have a more consistent experience across languages.


registerCodeActionsProvider now takes an optional CodeActionProviderMetadata argument which lets extensions tell VS Code about the kind of Code Actions that a CodeActionProvider will provide. This information is used by VS Code to enable the new Refactor and Source Action context menus. The Refactor context menu, for example, will only be enabled when a CodeActionProvider is registered with CodeActionProviderMetadata indicating that it that provide will return refactor.* Code Actions.

Webview API

The webview API allows extensions to create fully customizable views within VS 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.

A webview showing a cat gif

A new extension authoring page covers the webview API. You can also find an example webview API extension here. We look forward to see how extension authors put this powerful new API to use.

Application scope settings

If you want your settings to be applied at application level and not get overridden at a window or resource level, you can do that now by using application scope.

"configuration": {
    "properties": {
        "git.path": {
            "type": "string",
            "description": "Path to the git executable",
            "scope": "application"

Note: Deprecated isExecutable property in favor of using application scope since it was meant for the same purpose.

Proposed Extension APIs

This milestone we added several new proposed extension APIs. We plan to add these APIs to stable in a future milestone once we are confident enough with them. We welcome any feedback on how they work for your extension.

Note: These APIs are still proposed, so in order to use it, you must opt into it by adding a "enableProposedApi": true to package.json and you'll have to copy the vscode.proposed.d.ts into your extension project. Also be aware that you cannot publish an extension to the Marketplace that uses the enableProposedApi attribute.

Integrated Terminal API

The Integrated Terminal API has several proposed features that can help extension authors access all terminals and also enables multiplexing of terminals across different machines. All terminals can now be accessed via the API, unlike before where an extension could only access terminal which it created:


There's a matching event for this:

window.onDidOpenTerminal(terminal => {
    console.log('New terminal: ' + terminal.name);

You can also hook into the raw data stream coming from the terminal's process, including ANSI escape sequences:

const terminal = window.createTerminal();
terminal.onData(data => {
    console.log('Terminal data: ' + data);

Task API

The task API received further polish around task querying and execution from an extension. The newly supported API is:

  • fetchTasks takes a filter to only query for a subset of tasks.
  • taskExecutions support fetching the execution objects for all running tasks.
  • TaskExecution objects provided via executeTask, taskExecutions or one of the events can be compared using ===.

The API is still in the proposed state.

Protocol Handler API

The Protocol Handler API lets extensions handle system-wide URIs. This functionality is useful for cross-application integrations, since it lets other applications send URIs to specific extensions.

export interface ProtocolHandler {
  handleUri(uri: Uri): void;

export namespace window {

  * Registers a protocol handler capable of handling system-wide URIs.
  export function registerProtocolHandler(handler: ProtocolHandler): Disposable;

Here's an example Protocol Handler registration:

function activate() {
        handleUri(uri: Uri) {
            console.log('Received URI', uri.toString());

For this API, there is a strict relationship between URI authorities and extensions which will handle them: the URI authority must be the extension's ID (publisher.name). Take the following URI, for example:

 \____/   \________/ \___/ \_________/
   |           |        |       |
scheme    authority    path   query

This URI's authority is vscode.git, so VS Code will forward it to the vscode.git extension, given that it has properly registered a Protocol Handler.

Since it can happen that URIs are open before extensions are even registered, a new onUri activation event was also introduced. This lets your extension be activated whenever a URI directed towards it is opened.

Note: URI handling is not yet supported in Linux.

Folding Provider API

The folding range provider proposed in release 1.22 was updated and is now an official API. Language extensions can now provide syntax aware folding ranges.

    * Register a folding range provider.
    * Multiple providers can be registered for a language. In that case providers are asked in
    * parallel and the results are merged.
    * If multiple folding ranges start at the same position, only the range of the first registered provider is used.
    * If a folding range overlaps with an other range that has a smaller position, it is also ignored.
    * A failing provider (rejected promise or exception) will
    * not cause a failure of the whole operation.
    * @param selector A selector that defines the documents this provider is applicable to.
    * @param provider A folding range provider.
    * @return A [disposable](#_Disposable) that unregisters this provider when being disposed.
   export function registerFoldingRangeProvider(selector: DocumentSelector, provider: FoldingRangeProvider): Disposable;

Contributions to Extensions

Our team maintains or contributes to a number of VS Code extensions. Most notably this month:

Sublime Text Keymap extension

The Sublime Text Keymap extension is now able to import settings from Sublime.

The first time the extension is launched, a prompt is shown that displays all your importable Sublime settings. If you want to import your settings at a later time, use the Sublime Text Keymap: Import Sublime Text Settings command from the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)).

Sublime Settings Importer


Improved Smoke Test stability

VS Code has always had a smoke test, which is used to keep quality under strict control. We had automated the smoke test yet failed to make it stable. This milestone we worked on improving the stability and performance of the smoke test. More details can be found in pull request #47471.

New Documentation

Website deployment tutorial using Azure Storage

We have a new Deploy static website to Azure tutorial for creating and deploying a static website using Azure Storage.

VS Code blog posts

There were two recent posts on the VS Code blog:

Notable Changes

  • 10663: Preserve view state when switching tabs on compare view
  • 24634: macOS: Add a setting to enable acceptsFirstMouse for window
  • 29549: Multi thread debugging should support stopping thread
  • 46785: With no file in focus, "Reveal in Finder" should open the workspace's folder
  • 47274: Node Logpoints shows up as the VM source in Debug Console
  • 47478: Detect incomplete installed extensions
  • 48733: Introduce an option debug.enableAllHovers to enable calls to hover providers while debugging
  • 46414: Debugging Node.js process in a terminal no longer shows output in the Debug Console

Thank You

Last but certainly not least, a big Thank You! to the following folks that helped to make VS Code even better:

Contributions to vscode:

Contributions to vscode-extension-samples:

Contributions to language-server-protocol:

Contributions to vscode-languageserver-node:

Contributions to vscode-chrome-debug:

Contributions to vscode-chrome-debug:

  • @digeff
    • Ignore bp resolved for unknown script PR #325
    • Sanitize stack traces so they don't contain full file paths PR #322
    • Update notice to latest version PR #320

Contributions to vscode-node-debug2:

Contributions to localization:

There are over 800 members in the Transifex VS Code project team with about 100 active contributors every month. We appreciate your contributions, either by providing new translations, voting on translations, or suggesting process improvements.

Here is a snapshot of contributors for this release. For details about the project including the contributor name list, visit the project site at https://aka.ms/vscodeloc.

  • French: Antoine Griffard, Adrien Clerbois, Thierry DEMAN-BARCELO, Jean Cuteaux, Quentin BRETON.
  • Italian: Alessandro Alpi, Andrea Dottor, Aldo Donetti, Marco Dal Pino, Riccardo Cappello.
  • German: J.M., Levin Rickert.
  • Spanish: Andy Gonzalez, Alejandro Medina, Alberto Poblacion, Thierry DEMAN-BARCELO, Eickhel Mendoza.
  • Japanese: Shunya Tajima, Yuichi Nukiyama, Yosuke Sano, Seiji Momoto, Satoshi Kajiura, Toshinori Sugita.
  • Chinese (Simplified): Joel Yang, YF, pluwen.
  • Chinese (Traditional): Winnie Lin, Duran Hsieh, Ryan Tseng, Alan Tsai, alantea, Will 保哥.
  • Korean: ChangJoon Lee, HANSEULMARO KIM.
  • Russian: Michel Ace, Ivan.
  • Bulgarian: Любомир Василев.
  • Hungarian: Tar Dániel.
  • Portuguese (Brazil): Alessandro Fragnani, Roberto Fonseca, Marcelo Fernandes, Rodrigo Crespi, Matheus Palu, Bruno Sonnino, Douglas Eccker, douglas.martim.
  • Portuguese (Portugal): Hugo Martins, Daniel Correia, Isac Van Dunem, Tiago Costa, João Mata.
  • Turkish: Adem Coşkuner, Burak Karahan, Özgür Öktem, Ömer Büyükçelik.
  • Bosnian: Muharem Basanovic, Bahrudin Hrnjica, Ismar Bašanović, Almir Vuk.
  • Czechia: Vít Staniček, Vojtěch Habarta, m_fr, Frantisek Veris, Jakub Skořepa, Michal Zobec, Ferdinand Prantl, Ľubomír Kováč, Jan Brudný.
  • Dutch: Marco van den Hout, Maarten van Stam, Gerald Versluis.
  • Finnish: Petri Niinimäki, Feetu Nyrhinen.
  • Hindi: Brahma Dev.
  • Indonesian: Febrian Setianto (Feber), Wildan Mubarok, Adrian M. R., G-RiNe Project, Joseph Aditya P G, Mulia Arifandi Nasution, Herman Prawiro.
  • Latvian: kozete, Pēteris Kļaviņš, Edgars, Simone Chiaretta.
  • Polish: Joanna Skurzyńska, Mateusz Wyczawski.
  • Romania: Schiriac Robert.
  • Serbian: Jean Cuteaux.
  • Thai: ภูมิไผท จันทรศรีวงศ์.
  • Ukrainian: Dmytro Kyrychuk, Borys Lebeda.
  • Esperanto: Andy Hampton.