Extending VS Code: PART 2

Today, we will be building an extension for our workspace that targets working with the status bar in the editor. We will build a character counter for a specific selection of text in the editor.

The extension will be built using JavaScript. The TypeScript version can be found by Microsoft here

Let’s begin

Requirements – NodeJS 

Creating a command extension is a bit different than creating a theme extension.

The Structure of an extension

VS Code stores all its extensions in 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 .

Your extensions can be built in TypeScript or JavaScript. We will be exploring a JavaScript example.

For a JavaScript extension, the structure will look something like this:

── .vscode                     
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── .vscodeignore
├── README.md
├── src                         
│   └── extension.js            
├── test                        // tests folder
│   ├── extension.test.js      
│   └── index.js               
├── node_modules
│   ├── vscode                  // language services
├── package.json                // extension's manifest
├── jsconfig.json               

Let’s explore a few of these folders and files

  • .vscode – The VS Code integration.
  • .vscodeignore – Works just like the .gitignore. It signals what files to ignore when publishing the extension
  • README.md – Used to describe the extension to users.
  • test – Unit tests reside here (able to run the tests against the VS Code API)
  • package.json – Our extensions manifest file and act as the entry point to our extension.
  • extension.js  – Contains the logic.

Manifest – package.json

Let’s explore the various keys.

  • 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
  • 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
  • engines – the compatible versions of VS Code for the extension
  • devDependencies – required Node.js dependencies for the extension (same as npm)

For more key fields, check out Extension Manifest File description.

Within the manifest file, we find contribution points.

Contribution points

Logic – extension.js

activate

Our logic for the extension can be found in the extension.js file, which will contain a method called activate. The active method gets invoked only once from the activationEvents method that we specified in our manifest.

deactivate

deactivate method can be implemented if the extension makes use of OS resources. So the method is used for clean-up at time of shutdown of the application.

So, how does the extension come into existence?

Depending on the activationEvent we choose and defined for out extension, will partly affect how our extension is loaded. It could be when a specific file type is loaded, when a command is fired, etc. What we do know is that VS Code does not load extensions upon startup. You can read more about that here.

The extension activation process, as an example, can go a little something like this:

  1. As we mentioned earlier, the manifest file is the entry point to an extension. It is the first thing the extension development host instance looks for and reads. So, when the extension is called upon, for example from the command palette, it is invoked.
  2. An action event is created.
  3. At which point the logic of the extension, the extension.js file, gets loaded in the JavaScript VM.
  4. The activate function, the one we specified to be called in the activationEvents, defined in extension.js, is found and called.
  5. One last step is the implementation is invoked and it does it’s thing!

Let’s get to coding!

First challenge

Let’s try displaying a message.

Create your package.json file.

I included only a few fields, just to quickly get this up and rolling.

Create your extension.js file.

Rember how to reload the window? Activate the command palette and select ‘Reload Window’.

vscode-extension1.png

Second challenge

Let’s try grabbing a selected piece of text in the editor and displaying it.

First, you’ll need to get the current editor. From the current editor, we will need to grab the selection to get the word/phrase that has been highlighted. After which, we store the value in a variable and use it however we want. For this second challenge, we will merely display it back to the user.

Try not to peak ahead!!

But I’ll show you my code

P.S. Feel free to share your own code in the comments below 🙃

Third challenge

Now let’s try connecting our code to an external dictionary API that will let us look up the definition of the word selected.

I’ll be using an API from Oxford Dictionaries, but feel free to use any dictionary API that you are comfortable with.

Behind the scenes

I am sending an XMLHttpRequest to the API by providing my credentials and adding an event listener to the request. This event listener, when it receives a notification that transactions have been completed, it will parse the results( in JSON format). The results I get back contain a ton of information. However, all we want right now is the first definition.

Conclusion

And it’s that simple to create a VS Code extension 🙂 Stay tuned for next time! I shall reveal how to complete the third challenge if you had trouble.

 

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