Extending VS Code: PART 1

There are many ways to extend VS Code. For this part, we will be building a theme extension.

Building a custom theme extension from scratch

Requirements – NodeJS

All extensions belong to a directory. On a Windows machine you can find it under %USERNAME%\.vscode\extensions on a Mac or Linux you can that directory at ~/.vscode/extensions Therefore, all extensions we build will fall under this folder.

First step

Create a directory within the extension directory. The name of this folder should be the name of your extension, example: kims-awesome-extension.

Once it is created, navigate to that folder i.e. kimcodes\.vscode\kims-awesome-extension

Second step

Extension Manifest File – package.json

package.json is going to describe our extension. This JSON file will contain metadata about the extension.

Let’s take a look at all the required fields:

  • name –  string – this is the name of the extension and should be ALL lowercase with no space
  • version – string – semantic versioning number for compatibility
  • publisher – string – the publisher’s username in the VS Code Marketplace

Optional fields include:

  • license – string – the license file should be at the root and this line should read as SEE LICENSE IN <filename>
  • displayName – string – this will be the named displayed in the VS Code Marketplace
  • description – string – a short description of the extension
  • keywords – array – keywords or tags to find the extension
  • main – string – the entry point to the extension
  • activationEvents –  array – array of the activation events for the extension

and a few others.

Here is an example of a package.json file:

{
    "name": "kims-awesome-extension",
    "displayName": "The Ultimate Extension",
    "version": "0.1.0",
    "publisher": "kim-codes",
    "description": "The extension to rule all extensions.",
    "categories": [
        "Other"
    ],
    "icon": "images/icon.png",
    "activationEvents": [
        "onLanguage:markdown"
    ],
    "engines": {
        "vscode": "^1.0.0"
    },
    "main": "./out/extension",
    "devDependencies": {
        "vscode": "0.10.x",
        "typescript": "^1.6.2"
    },
    "license": "SEE LICENSE IN LICENSE.txt",
    "bugs": {
        "url": "https://github.com/kim-codes/kims-awesome-extension/issues"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/kim-codes/kims-awesome-extension.git"
    }
}

However, since for this example, we are building a theme our package.json file is going to be slightly different and includes a contribution section like such:

  • contributions –  object  –  describes the contribution point, in this case, it is a theme, which requires a label, to specify whether it is a dark or light theme and the path to the file.
 ... 
    "contributes": {
        "themes": [
            {
               "label": "KimsTheme",
               "uiTheme": "vs-dark",
               "path": "./themes/kims-theme.json"
            }
        ]
     }
  ...

Now that we have our package.json file, we need to create a theme JSON file, kims-theme.json. 

Third step

Theme JSON file

Within the theme JSON file, we will be able to modify almost all elements of the VS Code interface. To be able to modify an item, we will need a way to select that item and a syntax to define how it will change. The later could include applying a new color or applying a new font style.

The structure of our theme file will start off with a skeleton like such:

{
    "name": "kims-theme",
    "type": "dark",
    "colors": {
    },
    "tokenColors": [
    ]
}

To make changes (and start building our custom theme), we use workbench colors for the UI and ‘tokens’ for defining syntax highlighting aspects.

Colors

For the colors field, we can add key-value pairs that will edit items such as the background, the foreground, etc. For example:

"colors": {
    "editor.background": "#F5F5DC",
    "editor.foreground": "#OOFFFF",
}

 A list of all the definitions can be found here.

At this point, we can stop and test our extension (we can leave the tokenColors field as an empty array).

Testing an extension

If VS Code is already open simply open the command palette and run Reload Window, a relaunch is not necessary. After which run Preferences: Color Theme or navigate to File > Preferences > Color Theme . If all went well, you should now see your theme within the list of available themes. Note: VS Code won’t complain if there are errors in your JSON files.

vscode-kimstheme

Tokens

The tokenColors field is a bit more complex compared to the colors field. Instead of a key-value pair, it takes an array of objects.

There are two ways to work with token colors. You can either reference an existing TextMate theme (.tmTheme file), or you can come up with your own theming rules. Either way, let’s take a quick look at some TextMate rules, grammars and scopes.

VS Code describes them as the following:

TextMate grammars consist of a set of regular expression that are used create a syntax tree out of the source code. Each tree node spans a source range and represents scope. Scopes have a name and stand for either code sections (such as functions, blocks, comments) or symbols (for example keywords, numbers, operators).

I like to think of scopes as defining elements that you can actually select to do something with or modify.

Let’s take a look at the code which will help us understand what’s going on.

{
    "name": "Functions",
    "scope": [
        "entity.name.function",
        "meta.selector.css entity.name.tag",
        "entity.name.method - source.java"
    ],
    "settings": {
        "foreground": "#8ab1b0",
        "fontStyle": "italic"
    }
}

Here we have a token called Functions. Within this token we define a scope (you can have more than one scope).  At which point this token, Functions, whenever the syntax highlighter parser reaches this defined scope, the defined settings for that token are applied.

That scope stuff looks pretty tricky, doesn’t it? An easy way to be able to identify scopes that we want to style in our theme is to navigate to the type of file we want to customize, for example, JavaScript files. We can open a JavaScript file and from the command palette run a command called Developer: Inspect TM Scopes.

vscode-tmscope.png

It’ll look something like this!

Last step

After adding your tokens for your theme, re-test your extension like before and voilà!

 

Want to modify a few UI items and not build a whole theme?

Head back over to Customizing VS Code and simply override the few workspace settings to get the colors you want in your theme (you do this by using the workbench.colorCustomizations object in user settings).

Thanks for making it to the end and stay tuned for building our next extension in VS Code (part 2)!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s