January 2018 (version 1.20)

Update 1.20.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 January 2018 release of Visual Studio Code. This release includes the VS Code team's work during the January milestone as well as the community PRs contributed in December and January which means there are a lot of great updates. Here are some of the release highlights:

If you'd like to read these release notes online, go to Updates on code.visualstudio.com.
You can also check out this 1.20 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:

  • Workbench - "Smart case" search, theme specific color customization.
  • Editor - New snippet variables, Emmet improvements, minimap on the right or left.
  • Languages - TypeScript automatic bracket and member property suggestions.
  • Debugging - Automatically detect Node.js subprocesses, nvm support.
  • Extensions - Extension recommendations for new file types.
  • Extension Authoring - Custom view support, new menu groupings.

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.


Multi select in the Explorer

You can now select multiple files in the File Explorer and OPEN EDITORS view to run actions (Delete, Drag and Drop, Open to the Side) on multiple items. Uses the Ctrl/Cmd key with click to select individual files and Shift + click to select a range. If you select two items, you can now use the Compare Selected command to quickly diff two files.

Multi Select

Clicking with the Ctrl/Cmd key pressed will no longer open an editor to the side because this key is now used to add more items to the multi-selection. A new setting, workbench.list.multiSelectModifier, allows you to change back to the old behavior by setting it to "workbench.list.multiSelectModifier": "alt". With this setting, you use the Alt key to add items to the selection.

Error indicators in the Explorer

We now show files with errors or warnings in the File Explorer and the OPEN EDITORS view.

Error Decorations

The number of errors/warnings is shown in the decoration. The setting problems.decorations.enabled allows you to enable/disable the error/warning decorations.

VS Code provides many settings to customize the editor, and it can be hard to find the setting you're looking for when you don't know which terms to use. We have improved the search functionality in the Settings editor to go beyond simple filtering with literal word matches. The Settings editor will now search with an awareness of alternate wordings, typos, stemmings ("saving" -> "save") and should provide a more natural language search experience.

Settings search

If you prefer the old style of search, you can disable this feature with "workbench.settings.enableNaturalLanguageSearch": false.

Save files that need admin privileges

It is now possible to save files that require administrator privileges. One example is making changes to /etc/hosts. If the file exists on disk and requires elevated permissions, a new action Retry as Admin... will show up on an error message. Saving as admin is supported on all platforms. Depending on the platform, the prompt to authenticate as administrator will look different.

Save large files >256 MB

It is now possible to save files >256 MB where previously an error was reported. This was achieved by changing the implementation of how VS Code stores the contents of the editor to disk. Instead of loading the entire file contents into memory, we leverage a snapshot of the content and stream it into the file in chunks of 64KB.

You can now set "search.smartCase": true to enable "smart case" mode for global search. When enabled, VS Code will automatically do a case-sensitive search when you search for a query that contains an uppercase character. If your search query is all lowercase, then the search will be case-insensitive.

For example, searching "code" will match "code" or "Code". Searching "Code" will only match "Code".

Double-click to open in list/tree

A new setting, workbench.list.openMode, was added that controls if items in trees and lists should open on single or double mouse-click. This setting applies both to opening items as well as expanding/collapsing items if they have children.

Note: The setting is supported for most trees/lists in VS Code, but in some case we left the default behavior when we thought single-click still makes the most sense. We are happy to hear your feedback!

Image preview zooming

You can now zoom image previews:

Zooming a preview

Zoom in and out by clicking, using the scroll wheel (with Ctrl on Windows/Linux or Alt on macOS), or pinching on a track pad. The current zoom level is shown in the Status Bar. Click on the zoom Status Bar item to quickly switch zoom levels or reset the view.

Theme specific color customizations

You can now fine tune a specific color theme in your user settings:

"editor.tokenColorCustomizations": {
    "[Monokai]": {
        "comments": "#229977"
"workbench.colorCustomizations": {
    "[Monokai]": {
        "sideBar.background": "#347890"

This example changes just the Monokai theme. See the Customize a Color Theme documentation for a more information on themes.

More themable colors for editor tabs

With this release, new themable colors are added for editor tabs:

  • tab.hoverBackground: Tab background color when hovering
  • tab.unfocusedHoverBackground: Tab background color in an unfocused group when hovering
  • tab.hoverBorder: Border to highlight tabs when hovering
  • tab.unfocusedHoverBorder: Border to highlight tabs in an unfocused group when hovering

You can configure these colors also from the workbench.colorCustomizations setting.

Custom dropdown (Windows, Linux)

On Windows and Linux, dropdowns now use a custom widget instead of the HTML control. The dropdown leverages the same colors as the tree/list widget in other parts:

Custom Dropdown

This fixes a couple of issues where the HTML dropdown was not showing up properly in some cases.


  • The OPEN EDITORS view can now be resized once it reaches the maximum size specified by explorer.openEditors.visible. Due to this change, the setting explorer.openEditors.dynamicHeight is no longer supported.
  • The ability to set explorer.openEditors.visible to 0 to hide the OPEN EDITORS view is being deprecated in the January release and we plan to drop it in February. To hide the OPEN EDITORS view, use the context menu in the Explorer title area to control the visibility of views.

Disable macOS Touch Bar entries

A new setting keyboard.touchbar.enabled disables the macOS Touch Bar entries that VS Code is providing.

workbench.fontAliasing setting

You can now set "workbench.fontAliasing": "auto" on macOS to control font aliasing depending on the DPI of the monitor that VS Code is showing on. If set to auto, VS Code will apply default or antialiased automatically based on the DPI of the display.

Output panel

Now you can see VS Code logs with syntax highlighting in the Output panel. Thanks to emilast for providing the grammar for syntax highlighting log files.

Log channels

The Output panel also now consumes less memory resources with our new implementation. Memory resources of an output channel are released when not shown.


Global snippets

VS Code now supports global snippets meaning snippets that aren't scoped to a single language but can target any kind of files. Using the Preferences: Configure User Snippets command, select the New Global Snippets file... option which will open a .code-snippets file for new snippets. Use the scope attribute to list the languages that are targeted by a snippet. For instance, the snippet below can add a copyright header for JavaScript and TypeScript files:

"JS & TS Stub": {
  "scope": "javascript,typescript",
  "prefix": "stub",
  "body": [
    " *  Copyright (c) Your Corporation. All rights reserved.",
    " *  Licensed under the MIT License.",
    " *-------------------------------------------------------------*/",
    "'use strict';",
  "description": "Insert Copyright Statement"

Extension authors can also contribute global snippets. Include a code-snippets file in your extension and omit the language property in the contributes.snippets section of your package.json.

More snippet variables

We have added new snippet variables to read your clipboard, CLIPBOARD, and to insert the current date and time. For date and time, combine any of these variables:


Keybindings for Quick Fixes and Code Actions

The new editor.action.codeAction command lets you configure keybindings for specific Code Actions. This keybinding for example triggers the Extract function refactoring Code Actions:

  "key": "ctrl+shift+r ctrl+e",
  "command": "editor.action.codeAction",
  "args": {
    "kind": "refactor.extract.function"

Code Action kinds are specified by extensions using the enhanced CodeActionProvider API. Kinds are hierarchical, so "kind": "refactor" will show all refactoring Code Actions, whereas "kind": "refactor.extract.function" will only show Extract function refactorings.

Using the above keybinding, if only a single "refactor.extract.function" Code Action is available, it will be automatically applied. If multiple Extract function Code Actions are available, we bring up a context menu to select them:

Select Code Action context menu

You can also control how/when Code Actions are automatically applied using the apply argument:

  "key": "ctrl+shift+r ctrl+e",
  "command": "editor.action.codeAction",
  "args": {
    "kind": "refactor.extract.function",
    "apply": "first"

Valid values for "apply":

  • "first" - Always automatically apply the first available Code Action.
  • "ifSingle" - Default. Automatically apply the Code Action if only one is available. Otherwise, show the context menu.
  • "never" - Always show the Code Action context menu, even if only a single Code Action is available.

Suggestion improvements

We have refined how suggestions are prioritized and we have added a new setting, editor.suggestSelection, to control how suggestions are selected in the UI. You can make sure the top item is always selected (first), you can make it select the previously used item (recentlyUsed), or you can selected items based on prefixes you have used (recentlyUsedByPrefix). A more complete explanation with screenshots is in this GitHub issue.

Emmet improvements

You can now prefix your CSS abbreviations with - to get all applicable vendor prefixes included in the expanded abbreviation.

Vendor prefix in Emmet

Read more on how to control vendor prefix in Emmet.

Other notable bug fixes in Emmet:

  • Use of @- to get numbering in descending order in repeaters not working. #35296
  • The snippets.json file for custom Emmet snippets fails to get parsed in the presence of comments. #33818
  • When using bem style, part of class names that appear after - get cut. #38768
  • Emmet: Wrap with Abbreviation command should wrap the entire HTML element when cursor is in either open or close tag. #41516
  • Emmet: Wrap with Abbreviation command should support |c and |bem filters. #40471
  • Emmet: Update Tag and Emmet: Remove Tag commands matches wrong pair in the presence of self closing tags. #39789
  • Emmet: Expand Abbreviation command doesn't expand abbreviation that contains unescaped single quotes. #38807
  • Emmet expansion gets triggered when editing the value of a CSS property. #34162

Control cursor width

Use the new setting editor.cursorWidth to control the width of the cursor in pixels. This is only applicable when the editor.cursorStyle is set to line. The cursor stops growing wider after reaching the character width.

Control cursor width

Global macOS find clipboard

In the 1.19 release, we integrated with the macOS global find clipboard which makes it easier to share search text across applications. This is now disabled by default, but can be enabled with the "editor.find.globalFindClipboard" setting. It's also now supported by the Search view (also disabled by default) and can be enabled with the "search.globalFindClipboard" setting.

Select text while jumping between brackets

There is a new command, Select to Bracket, that will select the text between two matching brackets (as opposed to the already existing command, Go to Bracket, which only moves the cursor to the matching bracket).

Display minimap to the left

There is a new setting, editor.minimap.side, which can be configured to render the minimap (code outline) on the left:

Minimap Left Side

Toggle for Ignore Trim Whitespace in the Diff Editor

There is now a new action in the Diff Editor title area to quickly toggle the ignore trim whitespace setting:

Toggle Ignore Trim Whitespace

Source Control

Git submodules

This release introduces Git submodule support. Since submodules are Git repositories themselves, they appear in the repositories list. There is basic support in place which lets you stage, unstage or discard submodule changes in the outer repository. You can disable automatic submodule detection with the git.detectSubmodules setting.

Log channels

Git: Prompt to save files before committing

You can enable Git to prompt you to save unsaved files before committing. You can enable this with the git.promptToSaveFilesBeforeCommit setting.

Git: Commit input validation

The Git extension now provides commit message length validation:

Git input validation

You can configure the validation's behavior using the git.inputValidation setting, which has the following possible values: always, warn and none. The previous screenshot showcases the always option, while the default is warn.

Setting for editor diff decorations

Control when and how inline diff decorations show up in the editor using the scm.diffDecorations setting. Possible values are all, gutter, overview and none.

Integrated Terminal

Screen reader support

Screen reader support was added to the terminal. In order to enable this, VS Code needs to be in "Screen Reader Optimized" mode which is typically auto-detected but can also be manually toggled by opening up editor accessibility help .

We consider this a first step and are actively looking into ways to make using the terminal easier for those with vision issues.

Mouse wheel now works as expected in terminal applications

Applications such as vim and tmux which are hosted in the terminal's alt buffer now have mouse wheel events translated to arrow events which enabled scrolling. Thanks to Manoj Patel for helping define the correct behavior here.

Option as meta on macOS

The option key can now be used as the meta key in the terminal, allowing the use of typical shell shortcuts like option+B to jump back a word and option+F to jump forward a word.

"terminal.integrated.macOptionIsMeta": true

Copy on selection

You can now automatically copy whenever you select text in the terminal:

"terminal.integrated.copyOnSelection": true

This is disabled by default.

Variables resolved in env setting

Variables are now resolved in terminal.integrated.env.* settings. This uses the standard variable format used in other settings:

"terminal.integrated.env.linux": {
  "FOO": "${workspaceRoot}",
  "BAR": "${env:PATH}"


Improved debugging support for multi root workspaces

A multi-root workspace can be used to work on related projects (for example "Server" and "Client") in a single workspace. Each of these folders have their own launch configurations (for example "Launch Server" and "Launch Client") but until now it was not possible to combine launch configurations from different folders into a "compound" launch configuration (because there was no mechanism to reference launch configurations across folders).

In this milestone, we have addressed this limitation: first we've added support for "workspace" scoped launch configurations, and second we've introduced a syntax for referencing launch configurations across folders. With this compound launch configs that reach into different folders can be kept where they belong: at the workspace level.

Workspace scoped launch configurations live in the "launch" section of the workspace configuration file which can be easily edited via Workspaces: Open Workspace Configuration File in the Command Palette:

Workspace Settings

Alternatively new launch configurations can be added via the Add Config (workspace) entry of the Launch Configuration dropdown menu:

Add Config

A compound launch configuration can reference the individual launch configurations by name as long as the names are unique within the workspace, for example:

  "compounds": [{
      "name": "Launch Server & Client",
      "configurations": [
        "Launch Server",
        "Launch Client"

If the individual launch configuration names are not unique, the qualifying folder can be specified with a more verbose "folder" syntax:

  "compounds": [{
      "name": "Launch Server & Client",
      "configurations": [
        "Launch Server",
          "folder": "Web Client",
          "name": "Launch Client"
          "folder": "Desktop Client",
          "name": "Launch Client"

In addition to compounds the launch section of the workspace configuration file can contain regular launch configurations too. Just make sure that all used variables are explicitly scoped to a specific folder because otherwise they are not valid for the workspace. You can find more details about explicitly scoped variables in the section below.

Here is an example for a launch configuration where the program lives in a folder "Program" and where all files from a folder "Library" should be skipped when stepping:

"launch": {
  "configurations": [{
      "type": "node",
      "request": "launch",
      "name": "Launch test",
      "program": "${workspaceFolder:Program}/test.js",
      "skipFiles": [

Scoped configuration variables

We've introduced a new variable syntax to scope configuration variables in launch.json and tasks.json files to a specific workspace folder. By appending the root folder's name to a variable (separated by a colon), it is possible to reach into sibling root folders of a workspace. Without the root folder name, the variable is scoped to the same folder where it is used.

For example, in a multi-root workspace with folders Server and Client, a ${workspaceFolder:Client} refers to the path of the Client root. For a more involved example see section Improved debugging support for multi-root workspaces.

More about variable substitution can be found here

Node debugging

Automatically attach debugger to Node.js subprocesses

For node-debug we've added a mechanism that tracks all subprocesses of a debuggee and tries to automatically attach to those processes that are launched in debug mode. This feature simplifies debugging of programs that fork or spawn Node.js processes like programs based on the "cluster" node module:

Auto Attach shown with Cluster Example

The feature is enabled by setting the launch config attribute autoAttachChildProcesses to true:

  "type": "node",
  "request": "launch",
  "name": "Cluster",
  "program": "${workspaceFolder}/cluster.js",
  "autoAttachChildProcesses": true

Please note: In order to be able to track the subprocesses, we need the process ID of the parent. For this we require that the main debuggee launched from the launch config is a Node.js process and we use an "evaluate" to find its process ID.

Whether a process is in debug mode is guessed by analyzing the program arguments. Currently we detect the patterns --inspect, --inspect-brk, --inspect-port, --debug, --debug-brk, --debug-port (all optionally followed by a = and a port number).

"nvm" support

If you are using "nvm" (or "nvm-windows") to manage your Node.js versions it is now possible to specify a runtimeVersion attribute in a launch configuration for selecting a specific version of Node.js.

Here is an example launch config:

  "type": "node",
  "request": "launch",
  "name": "Launch test",
  "runtimeVersion": "7.10.1",
  "program": "${workspaceFolder}/test.js"

Please note: Make sure to have those Node.js versions installed that you want to use with the runtimeVersion attribute as the feature will not download and install the version itself. So you will have to run something like nvm install 7.10.1 from the integrated terminal if you plan to add "runtimeVersion": "7.10.1" to your launch configuration.


Extension recommendations

When you are working on file types not supported out-of-the-box by VS Code or by any installed extension, you may not see syntax highlighting. If there are extensions in the Marketplace that can support such files, you will now be notified.

Extension Recommendations for unknown file types

The extension recommendation list will now include extensions that are popular among other users who work on the same repository as you.

Extension Recommendation based on what is popular on the same repo


TypeScript 2.7.1

VS Code now ships with TypeScript 2.7.1. This update brings a number of new features and bug fixes.

Quick Fix all for JavaScript and TypeScript

Fix errors in a flash with new Quick Fix all for JavaScript and TypeScript. Move your cursor to a fixable error such as an unused variable, and trigger Quick Fixes using the lightbulb or by pressing ⌘. (Windows, Linux Ctrl+.). If one of the available Quick Fixes can be applied to multiple errors in the current file, you'll see a new Fix all in file Code Action.

Quick fix all in file

Accept and all errors will disappear:

Quick fix all fixes all similar errors in the current file

Bracket property suggestions

Spaces got you down? When you type ., VS Code now shows all known properties for JavaScript and TypeScript, even if a property name contain whitespaces or other non-identifier characters.

Suggestions for properties with spaces or other special characters are now shown

Accepting one of these suggestions automatically converts to bracket accessor notation.

Bracket accessor automatically inserted

Automatic member property suggestions

Tired of typing this. to access class properties in JavaScript and TypeScript? Now you can just start typing to see available members.

No more need to type this. to see property suggestions

Accept a member property suggestion, and VS Code automatically inserts the require this..

this. is automatically inserted when you suggest a property suggestion

Marking of optional property in suggestions

Suggestions for optional TypeScript properties are now suffixed with a ?:

Optional property suggestions

JavaScript users will also see ? for completions that come from *.d.ts Type Declaration (typings) packages.

Auto-imports based on filename

Auto-imports for JavaScript and TypeScript now support importing default exported objects based on filename:

importing a default exported object by filename

Extension contributed TypeScript plugins

TypeScript plugins let developers extend VS Code's JavaScript and TypeScript language support. For example, a TypeScript plugin might add additional linting to a file or add IntelliSense when working within JavaScript template strings.

Styled component IntelliSense from the typescript-styled plugin

TypeScript plugins were first introduced in TypeScript 2.3, but they previously required installing plugins into your workspace with npm and then configuring a jsconfig.json or tsconfig.json file to load them. VS Code 1.20 simplifies this by allowing extensions to contribute a set of global TypeScript plugins that are automatically activated without any configuration. All you need to do is install the extension.

A few extensions are already making use of this:

Extension contributed plugins are automatically activated for VS Code's version of TypeScript. If you are using a workspace version of TypeScript, you must still install the TypeScript plugins in your workspace.

Our extension authoring documentation has more information about the new TypeScript Plugin contribution point. We're very excited to see how extension authors leverage this!


Reporting an issue through the Help: Report Issue or Help: Report Performance Issue commands now opens a separate window.

The issue reporter

This window can collect information based on the type of issue you want to report. This includes basic information about your system, your active extensions, the running VS Code processes, and the types of files in your workspace. You choose which information to send and the reporter will open a browser window to preview the issue on GitHub.

Extension Authoring

Custom views

Custom views will become better and better with following additions to the API:

Inline actions

Extension authors can now contribute inline actions to tree items using inline group in view/item/context menu contribution. For example:

"contributes": {
  "commands": [
      "command": "jsonOutline.refreshNode",
      "title": "Refresh",
      "icon": {
        "light": "resources/light/refresh.svg",
        "dark": "resources/dark/refresh.svg"
  "menus": {
    "view/item/context": [
        "command": "jsonOutline.refreshNode",
        "when": "view == jsonOutline",
        "group": "inline"

Inline actions

Resource URI

If the custom tree view is based on file resources, then extension authors can provide the resource URI in the TreeItem representing it. This will adopt your view to the user configured File Icon theme and make it look similar to the File Explorer view in the Explorer.

 * The [uri](#_Uri) of the resource representing this item.
 * Will be used to derive the [label](#_TreeItem.label), when it is not provided.
 * Will be used to derive the icon from current file icon theme, when [iconPath](#_TreeItem.iconPath) is not provided.
resourceUri?: Uri;

Custom file view

Id property

Extension authors can provide an id to the TreeItem so that its selection and expansion state can be retained reliably when it gets changed.

 * Optional id for the tree item that has to be unique across tree. The id is used to preserve the selection and expansion state of the tree item.
 * If not provided, an id is generated using the tree item's label. **Note** that when labels change, ids will change and that selection and expansion state cannot be kept stable anymore.
id?: string;

Multi selection context for Explorer commands

This milestone we have introduced multi-selection in the Explorer as mentioned above. Extensions that contribute commands to the Explorer can respond to multi selection in the Explorer by respecting the new arguments passed to their commands.

As before VS Code tries to infer the currently selected resource in the Explorer and passes that as a parameter when invoking the command. However if multi selection is enabled, VS Code will pass an additional second argument to the command, an array of resources which are selected. This array always contains the first resource argument.

New menu group identifiers

Several menus now have new group identifiers for finer control on command placement:

Explorer context menu

  • navigation: Commands related to navigation across VS Code. As before this is the primary group of the Explorer context menu.
  • 2_workspace: Commands related to workspace manipulation.
  • 3_compare: Commands related to comparing files in the diff editor.
  • 4_search: Commands related to searching in the search view.
  • 5_cutcopypaste: Commands related to cutting, copying and pasting of files.
  • 7_modification: Commands related to the modification of a files.

Editor Tab context menu

  • 1_close: Commands related to closing editors.
  • 3_preview: Commands related to pinning editors.

Editor Title menu

  • 1_diff: Commands related to working with diff editors.
  • 3_open: Commands related to opening editors.
  • 5_close: Commands related to closing editors.

New keyboard shortcut context operator

Keyboard shortcut contexts allow users to control when keybindings are active. They are also referred to as when clauses because they define when a keybinding is active or enabled. In this release, there is a new key-value pair operator for when clauses. The expression key =~ value treats the right hand side as a regular expression to match against the left hand side. For example, to contribute context menu items for all Docker files, one could use:

   "when": "resourceFilename =~ /docker/"

CodeActionProvider improvements

A CodeActionProvider can now return objects of the new CodeAction class. CodeAction adds additional metadata and functionality over Command, and better captures what Code Actions are and how they are used in VS Code's UI.

A CodeAction primarily consists of a title, kind, and at least a Command or (new in VS Code 1.20) a WorkspaceEdit.

import * as vscode from 'vscode';

 * Quick fix provider that converts :) to 😀
export class Emojizer implements vscode.CodeActionProvider {
  provideCodeActions(document: vscode.TextDocument, range: vscode.Range) {
    const pos = range.start;
    const line = document.lineAt(pos.line);

    // Check if we are at a :)
    if (line.text[pos.character] === ':' && line.text[pos.character + 1] === ')') {
      const fix = new vscode.CodeAction('Convert to 😀', vscode.CodeActionKind.QuickFix);
      fix.edit = new vscode.WorkspaceEdit();
      fix.edit.replace(document.uri, new vscode.Range(pos, pos.translate(0, 2)), '😀');
      return [fix];
    return undefined;

CodeAction also adds metadata about Code Actions, including the Code Action's kind (vscode.CodeActionKind.QuickFix in the example above) and the set of diagnostics that the Code Action addresses. We use this metadata to implement features such as the Refactor command and vscode.action.codeAction keybindings, and plan to build additional features using it in the future.

Remove files from the Open Recent list

A new command vscode.removeFromRecentlyOpened removes entries from the Open Recent list in the File menu.

Specify current directory when creating terminals

There is a new cwd property to set the current working directory when calling createTerminal:

  name: 'My Ext Terminal',
  cwd: process.env.HOME

Debug API

Adding and removing breakpoints

In this milestone, we've continued work on the breakpoints debug API. It is now possible to add and remove SourceBreakpoints and FunctionBreakpoints.

Note: The breakpoints API is 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.

new DebugConfigurationProvider.debugAdapterExecutable replaces adapterExecutableCommand commands

Currently a debugger extension can contribute the "hook"-like command adapterExecutableCommand to return a dynamically calculated path (and corresponding program arguments) of the debug adapter about to be launched by VS Code. In this milestone, we are proposing "real" API that replaces the untyped command based mechanism with a typed solution. At the same time we are deprecating the adapterExecutableCommand command (and we will remove support for it as soon it is no longer used).

The new API is an optional method debugAdapterExecutable on the DebugConfigurationProvider that returns the path and arguments wrapped as an DebugAdapterExecutable object.

Command vscode.logToDebugConsole will be removed

As announced in the previous release, we have deprecated the vscode.logToDebugConsole command in favor of real debug API. We plan to remove support for the vscode.logToDebugConsole command in the February milestone.

Run a debug adapter inside the debug extension

Developing a debugger extension typically involves debugging both the extension and the debug adapter in two parallel sessions. 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 session.

In this milestone we've explored a way to run the debug adapter inside the extension. The basic idea is to intercept the launch of a debug session in the resolveDebugConfiguration method of a DebugConfigurationProvider and starting to listen for connect requests and creating a new debug adapter session for every request. To make VS Code use connect requests (instead of always launching new debug adapter), the launch configuration is modified by adding the debugServer attribute to it.

These lines of code implement this approach for the "Mock Debug" extension (enable this feature by setting the compile time flag EMBED_DEBUG_ADAPTER to true).

Proposed Extension APIs

This milestone we added new proposed extension APIs for two areas. 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.

Extension logging

Extensions are now able to write logs to their own folder inside VS Code's log folder.

 * The severity level of a log message
export enum LogLevel {
  Trace = 1,
  Debug = 2,
  Info = 3,
  Warning = 4,
  Error = 5,
  Critical = 6,
  Off = 7

 * A logger for writing to an extension's log file, and accessing its dedicated log directory.
export interface Logger {
  readonly onDidChangeLogLevel: Event<LogLevel>;
  readonly currentLevel: LogLevel;
  readonly logDirectory: Thenable<string>;

  trace(message: string, ...args: any[]): void;
  debug(message: string, ...args: any[]): void;
  info(message: string, ...args: any[]): void;
  warn(message: string, ...args: any[]): void;
  error(message: string | Error, ...args: any[]): void;
  critical(message: string | Error, ...args: any[]): void;

export interface ExtensionContext {
   * This extension's logger
  logger: Logger;

Your extension can use the methods on Logger to write log messages with some log level, and the user can use the Developer: Set Log Level command to specify at which minimum level should log messages be recorded.

You can find the log files by running the Developer: Open Logs Folder command. That folder will contain a folder for each running instance of an extension that has written logs.

Add, remove and change workspace folders

A new proposed API was added to change workspace folders in the currently opened workspace:

  start: number,
  deleteCount: number,
  ...workspaceFoldersToAdd: { uri: Uri, name?: string }[]
): boolean

This method can:

  • Remove existing workspace folders (by providing the index of the folder to delete via start and the number of folders to remove via deleteCount).
  • Add new workspace folders to a specific index (by providing the index where to add to via start, leaving deleteCount as 0 and providing the workspace folders to add as arguments).
  • Update existing folders, for example, move them or rename them (by removing existing folders first and then adding them back again).


The proposed RenameProvider2 extension to RenameProvider allows extensions to provide additional rename information, including range of the symbol to rename and the initial name shown when a user triggers rename:

export interface RenameInitialValue {
  range: Range;
  text?: string;

export interface RenameProvider2 extends RenameProvider {
    document: TextDocument,
    position: Position,
    token: CancellationToken
  ): ProviderResult<RenameInitialValue>;

Preview Features

This milestone we worked on several features which are not ready to be released but we would like your feedback.

Language packs

We added support for language packs which will allow adding additional translations to VS Code using an extension. The screenshot below shows VS Code running using a Bulgarian language pack generated from VS Code's Transifex project:

Language Pack

In the next months we will work with the translators in Transifex to establish a process on how to best publish their translations as language pack extensions in the Marketplace.

UX designs for notifications

During this milestone, the UX (User Experience) team worked on redesigning the notifications display in VS Code. We plan to start development work on these designs in the February milestone. More details about the design can be found in this GitHub issue and we are happy for your feedback.

New Documentation

Node.js deployment tutorials for Docker and Azure App Service

We have two new tutorials for deploying Node.js applications to Azure.

Tutorial Description
Deploy using Azure App Service Manage Azure resources directly in VS Code with the Azure App Service extension.
Deploy using Docker Deploy your website using a Docker container with the Docker extension.

Variable substitution reference

We added a Variables Reference describing VS Code's support for variable substitution (for example ${workspaceFolder}, ${file}) in your debugging and task configuration files.

VS Code recipe for Vue.js

There is now a Vue.js debugging recipe to help configure the Chrome debugger for applications which use the popular Vue.js framework.

Language Server Protocol website

For extension authors, we've create a new Language Server Protocol website providing documentation, the LSP specification, and listing the current implementations.

New Commands

Key Command Command id
⌃⇧R (Windows, Linux Ctrl+Shift+R) Open refactoring context menu at current position workbench.action.refactor
⌃⌘1 (Windows, Linux Shift+Alt+1) Move Editor into First Group workbench.action.moveEditorToFirstGroup
Move Editor into Second Group workbench.action.moveEditorToSecondGroup
Move Editor into Third Group workbench.action.moveEditorToThirdGroup
⇧↓ (Windows, Linux Shift+Down) Multi-Select in lists/trees: expand selection down list.expandSelectionDown
⇧↑ (Windows, Linux Shift+Up) Multi-Select in lists/trees: expand selection up list.expandSelectionUp
Developer: Open Log File... workbench.action.openLogFile
Developer: Open Logs Folder workbench.action.openLogsFolder
Developer: Show Logs... workbench.action.showLogs
Developer: Set Log Level workbench.action.setLogLevel
Edit focused setting in the Settings editor settings.action.editFocusedSetting

Command workbench.action.files.revealActiveFileInWindows is a duplication of an already available command revealFileInOS. Therefore we are deprecating the workbench.action.files.revealActiveFileInWindows command in the January release and plan to drop it in February.

Command workbench.action.files.copyPathOfActiveFile is a duplication of an already available command copyFilePath. Therefore we are deprecating the workbench.action.files.copyPathOfActiveFile command in the January release and plan to drop it in February.

Notable Changes

  • 7893: Tweet feedback button - make it hideable
  • 16852: Allow to search commands related to problems view with "error" or "warning"
  • 19707: Add "(Administrator)" suffix to window title when running as administrator in Windows
  • 31988: Terminal processes exit too eagerly if window close is canceled
  • 34320: Terminal font squished when changing monitors with varying DPIs
  • 35462: Remember visibility of custom view globally for all windows
  • 37589: Multiple Process Debugging not possible with integratedTerminal
  • 39371: Call stack only shows top frame after restart
  • 39536: Change to use async API for modal dialogs
  • 39574: Allow to change the log level of all log services at runtime
  • 39719: Double click in Debugger watch panel should trigger new watch UI
  • 40088: Running Extensions - provide action to disable an extension
  • 41071: Quick access to custom views
  • 41759: Show installing status while installing a VSIX extension

Thank You

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

  • BlueC0re(@bluec0re): Pointed out a security vulnerability that we have addressed in version 1.19.3.

Contributions to vscode:

Contributions to vscode-extension-samples:

Contributions to language-server-protocol:

Contributions to vscode-languageserver-node:

Contributions to vscode-eslint:

Contributions to vscode-github-issues-prs:

Contributions to vscode-chrome-debug-core:

Contributions to vscode-chrome-debug:

Contributions to vscode-html-languageservice

Contributions to vscode-json-languageservice

Contributions to vscode-recipes

Contributions to node-jsonc-parser

  • @sqs: add JSON formatter and editor from VS Code PR #5

Contributions to localization:

This is the tenth month since we opened community localization in Transifex. We now have nearly 700 members in the Transifex VS Code project team. We appreciate your contributions, either by providing new translations, voting on translations, or suggesting process improvements.

Here is a snapshot of top 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.
  • Italian: Alessandro Alpi, Piero Azi, Aldo Donetti, Michele Ferracin, Nicolò Carandini, Emilie Rollandin.
  • German: Carsten Siemens, Jakob von der Haar, Carsten Kneip, Stephan, jublonet, thefreshman89, Levin Rickert, Ullmie02, Aldo Donetti, DSiekmeier, Dejan Dinic, Ettore Atalan.
  • Spanish: Andy Gonzalez, Eickhel Mendoza, José M. Aguilar, Alberto Poblacion, Carlos Mendible, Carlos Herrera, Jorge Serrano Pérez, Thierry DEMAN-BARCELO.
  • Japanese: EbXpJ6bp, Yuichi Nukiyama, Momoto.Seiji, Yoshihisa Ozaki, Hiroyuki Mori, tempura.sukiyaki.
  • Chinese (Simplified): Joel Yang, pluwen, Bingxing Wang, joeqi, Ricky Wang, Simon Chan, Zhijian Zeng, Zou Jian, Ying Feng.
  • Chinese (Traditional): Poy Chang, Winnie Lin, Ryan Tseng, duranHsieh, Han Lin, Alan Tsai, Ke-Hsu Chen.
  • Korean: ChangJoon Lee, Ian Y. Choi, Sei Kwang Chung, Kyunghee Ko, Paul Lee.
  • Hungarian: Tar Dániel.
  • Portuguese (Brazil): Roberto Fonseca, Kayky de Brito dos Santos, Danilo Dantas, Alessandro Fragnani, Bruno Sonnino, Felipe Caputo, Thiago Franco, Leonardo Santos, Isaac Henrique.
  • Portuguese (Portugal): BlueKore, António Campos, Gustavo Silva, José Luís, André Vala.
  • Turkish: Adem Coşkuner, Burak Karahan, Volkan Nazmi Metin, Onat Yiğit Mercan, Türker YILDIRIM, Ata Binen, Mehmet Tolga Avcioglu, Volkan Nazmi Metin, Burak Karahan.
  • Bangla: Mehedi Hassan.
  • Bosnian: Bahrudin, Ismar Bašanović, Almir Vuk, Ahmet Novalić.
  • Bulgarian: Любомир Василев, Didi Milikina, Ilia Iliev, Georgi Yanev.
  • Dutch: Gerald Versluis, Jan Mulkens, Armand Duijn, Sander van de Velde, Maarten van Stam, Bram Lemenu, Gerjan.
  • Greek: Deilv, Dimitris Trachiotis.
  • Indonesian: Joseph Aditya P G, Wildan Mubarok, Aden Aziz, Riwut Libinuko, codenameupik, Febrian Setianto (Feber), Alfa Phi, simplyeazy, Herman Prawiro, Mulia Arifandi Nasution, Rizki Adiguno Wibowo, Septian Adi.
  • Lithuanian: Martynas Jusys, Robertas Želvys, Emilis.
  • Polish: Adam Borowski, Szymon Zak, Wojciech Maj.
  • Romanian: Bogdan Mateescu, Schiriac Robert, ovisan.
  • Russian: Svitlana Galianova, iVAN2002, Артём Давыдов, Alexander Filimonov, Aleksey Romanenko, Veronika Kolesnikova.
  • Serbian: Марко М. Костић, Nikola Radovanović, Darko Puflović.
  • Tamil: Karunakaran Samayan, Avinash, rajakvk.
  • Ukrainian: Serhii Shulhin, R.M., Oleksandr, Borys Lebeda, Svitlana Galianova, Volodymyr Holovka, Yevhen Kuzminov, Bogdan Surai.
  • Vietnamese: Vuong, Hung Nguyen, Trung Đào.