7 Days of VS Code
A series of short articles I wrote while exploring VS Code, from navigating the editor to customizing it and working with version control.
01 / 07
An Overview of VS Code
Originally published January 8, 2018
Intro
Out of the box, VS Code is described as a "lightning fast" and "lightweight" source code editor that supports hundreds of programming languages. It can be used on any platform — Mac, Linux, Windows.
The guts
VS Code is built on Electron, along with JavaScript, Node.js and some Microsoft-y things like the Visual Studio debugger and TypeScript. So it's a pretty powerful editor.
It has built-in IntelliSense (note: not all languages, so you may need to pick up an extension for ones not included). For those who are not familiar, IntelliSense provides a number of features like code completion, parameter info, and more. You may have heard IntelliSense called in a different form like code completion or code hinting.
And to be honest, it's the kind of thing you don't really know you're missing until you fully use it.
It's got the Visual Studio debugger allowing you to step through code, inspect vars, view call stacks, and execute commands in console easily.
VS Code is great for building cross-platform applications. It was originally described as being created for building web and cloud applications, but I believe it is and will continue to be for more than just that.
So, why VS Code?
Why choose something like VS Code, well let's see...
Customization
Firstly, how customizable it is. It's super easy to install many third-party extensions or to even create your own (which we will be learning how to do later on!).
Open source
It's open source. So you can contribute to it and join the community on GitHub. I always find a tool most powerful when the community can come in and improve it.
Missing a feature? Let the community create it and it helps to expand the improvement for integration with other tools. Super!
Git diff view
I have adored IntelliJ's git diff view for the longest time and now VS Code has got a great one as well. VS Code displays the current and the previous versions side by side for a quick comparison and makes it easy to solve merge issues!
The fact that git is integrated already is also just great.
Easy split-screen
Forget remembering the shortcut for split-screen. VS Code makes it easy with the click of an icon.
Located at the upper right side of the editor. There are also several other ways to split: keyboard shortcuts, drag and drop, or Ctrl and click on the file in the Explorer.
Peek view
Want to check something quickly without doing a huge context switch? VS Code introduces peeked editors so that you can easily search, and even make edits right there in the peeked editor.
Terminal
VS Code makes it convenient to execute a command line task without the need to switch windows. (Note: it starts at the root of your workspace.) And you can even manage multiple terminals if you want.
Zen Mode
Zen Mode hides all the UI features (activity bar, status bar, side panels, etc.) and lets you focus on your code. The editor becomes fullscreen.
To enable Zen Mode you can either select it by the
View menu, the
Command Palette, or by hitting
Ctrl+K Z.
There's probably an extension for that...
Whatever you are in need of, whatever feature you love in another editor/IDE, there's probably an extension for that!
Wait, why an editor over an IDE?
Let's compare
An editor, like VS Code, is built for speed, starts up fast since it's so lightweight and extensions are loaded in a separate process.
An IDE, like Visual Studio, is feature rich, robust, and can "do everything". However, it tends to be slower and you can feel overloaded with features. You might be so overloaded that you can not even utilize the IDE's full potential... or maybe you don't even need all those luxurious features.
Let's dive in a bit. Let's compare VS Code to Visual Studio. VS Code is portable as hell, works on all platforms and generally requires fewer admin rights. VS Code allows you to install plugins and extensions as you go, as you need.
As mentioned earlier Visual Studio, being an IDE, is feature rich. If you don't need all those features, maybe go for something lighter.
Examples of editors: Sublime, Vim, Brackets, Atom, VS Code.
Examples of IDEs: Visual Studio, IntelliJ, Eclipse, WebStorm.
TL;DR
Your setup is an important part of how you work and how productive you will be as a developer. And so your choice of code editor is no exception!
I highly recommend checking out VS Code. Considering it requires little configuration to get up and running it makes it a must try in my books!
02 / 07
Navigating VS Code
Originally published January 10, 2018
New to Visual Studio Code? Its look and feel is pretty similar to most editors and IDEs. But let's take a bit to become familiar with it.
I will quickly introduce you to the fundamentals: the Activity Bar, the Editor, Tabs, the Status Bar, the Command Palette, and the Minimap. All in under 3 minutes!
Activity Bar
Explorer: Explorer allows you to browse and manage
files and folders in your current workspace/folder.
Windows: Ctrl+Shift+E
Mac: Cmd+Shift+E
Search: Ctrl+Shift+F.
Search current files open for a specific string. Also allowing
you the option for "Find and Replace".
Source control: Ctrl+Shift+G.
Integration with your version control system — namely Git!
Which comes built in. You have the ability to initialize the
current workspace/folder and/or perform version control functions
like commit, pull, etc.
Debugger: Ctrl+Shift+D.
Displays useful debugging information like call stacks,
variables, and breakpoints.
Editor
The main area! You can open up to 3 editors side by side in one single instance of VS Code. You can have multiple tabs within each (a.k.a open multiple files).
Switch between them by using
Windows: Ctrl or
Mac: Cmd
along with the number key 1, 2,
or 3.
Re-arrange the editors by drag and dropping along the top bar.
Tabs
When you open a file in VS Code, it'll open a new tab in the current editor.
By default, tabs are added to the right, but you can re-arrange tabs the same way you would editors, by drag and dropping the filename header located at the top.
Status Bar
The status bar gives you info about the project, or in particular the file, you currently have open.
Right side: The current line you are on, the indentation setting, the encoding, EOL sequence, and the language mode.
Left side: If you have Git setup, you will be able to see things like what branch you currently have checked out, along with any errors and warnings.
Command Palette
Allows quick keyboard accessibility for even quicker access to
VS Code functionality and commands.
Ctrl+Shift+P or Ctrl+P with
>.
What you'll find in the palette will differ based on the extensions you installed. Therefore, the more you install the more functionality you'll have access to.
Depending on where you are in your code, you can find out what you
can execute by typing ? into the command palette.
It'll pop back to you a list of available commands.
Minimap
Located on the right side of the editor. Click or drag the shaded area to navigate to that section of the code. The minimap gives you a nice overview of the file you have open.
And that's it for navigating VS Code!
03 / 07
Customizing VS Code
Originally published January 11, 2018
I always love when I have the option to customize and add a little of my own flavor to something!
Changing Editor Theme
VS Code lets you change your background color, text color, and language syntax colorization. You can edit the theme directly in the settings, or you can use the 'Color Theme Picker' for an easier time.
To navigate to the Color Theme Picker either hit
Ctrl+K Ctrl+T or head over to
File > Preferences > Color Theme.
To customize the theme items yourself, you can open the command
palette (remember Ctrl+Shift+P) and type
themes.
Changing Icon Theme
This one is a small change, but it's one of the most important for me! Head over to the 'File Icon Theme' and select a colorful or discrete set for your icons displayed in the explorer.
Changing Workspace Settings
Open User Settings under File > Preferences > Settings.
I'll go through a few quick ones...
Font
"editor.fontFamily": "Consolas, 'Courier New', monospace",
Font Size
Default = 14
"editor.fontSize": 18,
Word Wrap
Default = off
"editor.wordWrap": "on",
Format
Default = false
"editor.formatOnPaste": true,
Auto Save
One of my favs! Default = off
"files.autoSave": "afterDelay",
Exclude Files
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/.CVS": true,
"**/.DS_Store": true,
"somefolder/": true,
"somefile": true
}
Auto Closing Brackets
Default = true
"editor.autoClosingBrackets": false,
Indentations
Default = inserts spaces and uses 4 spaces per Tab key.
"editor.insertSpaces": true,
"editor.tabSize": 4,
And the list goes on!
Language File Type Editing
For each language, whether it be TypeScript, JavaScript, Rust, etc., you may want to have different editing settings for each one. To customize these settings open the command palette and type 'Configure language specific settings'.
At which point you can select the language you want to edit and begin specifying the settings you want. It's that simple!
Keymappings
To see all keymappings navigate to File > Preferences > Keyboard Shortcuts.
Editing Current Keymappings
To edit a current keybinding, navigate to the keyboard shortcuts
scroll and type in the command you want to edit. Either right
click and select 'Change Keybinding', select the command and hit
Ctrl+K Ctrl+K, or hover beside the command and click
the pencil icon.
Adding New Keymappings
Open the Command Palette and type 'Open Keyboard Shortcuts File'.
Find the rule that triggers the action in the
Default Keyboard Shortcuts file and write a
modified version of it in your keybindings.json
file.
Keymapping Extensions
You can import keybindings from other popular editors in the VS Code Marketplace.
Or navigate to File > Preferences > Keymap Extensions.
Dealing With Conflicts
Having many extensions and customizations are great! But this also makes room for conflicts. The same keyboard shortcut can be mapped to several commands and can make for some wonky behavior.
Luckily, VS Code has provided us with a nifty Show Conflicts feature which filters keybindings based on the shortcut and displays the resulting conflicts, if any.
Extensions
And of course, there are tons of extensions you can find in the marketplace to extend and make the most of your VS Code experience.
04 / 07
VS Code & Version Control
Originally published January 13, 2018
VS Code has Git Version Control built into the editor when you install it. You can also install other source control systems from the marketplace.
Other Version Control System Integrations for VS Code
- Mercurial
- Perforce
- SVN
- Team Foundation Server
Let's take a look specifically at the Git support VS Code offers.
Git Integration
This article will assume you have basic knowledge of Git. It also assumes you have already installed the Git client.
Let's dive in!
Features in the Activity Bar
Remember the Activity Bar we saw in Navigating VS Code? The
Source Control icon
(Ctrl+Shift+G) will display an overview of the
changes made to your repository.
You will be able to view details like changes, staged changes, and merge changes.
Clicking on any of these will provide further details on the changes.
Features in the Status Bar
Remember the Status Bar we saw in Navigating VS Code? Here we can also see details regarding the status of our repository changes. We can view our current branch, modified tracked files and staged changes, along with commits.
The status bar allows us to switch between branches or even create a new branch on the fly.
There is also the Synchronize changes action in the Status Bar. When there is an available upstream branch configured you can synchronize with it. You can pull down the remote changes to your local copy and/or push your local changes to the upstream branch.
When no upstream is available, then you will have a Publish action available to set up with a remote repository.
Commit Actions
Hit the ... menu on the top of the Git view to see
all available actions. These actions include pull, push, commit,
stage, etc.
We can quickly go from our changes to stage changes by hovering
over the number of files and with the click of the
+ button.
You can also stage a portion of a file by selecting and then choosing Stage Selected Ranges from the command palette.
Resolve Merge Conflicts and Git Diff
During a merge, click the Source Control button in the Activity Bar and make changes in the diff view. Select and accept current, incoming or both changes in just one click.
Differences are highlighted and you are presented with various actions to accept.
Git diff is also supported in VS Code. You can view side by side or inline.
Clone or Initialize Repository
To clone a repository, you can run a
Git Clone command from the command palette
(Ctrl+Shift+P).
To initialize a repository, you can run an Initialize Git Repository command from the command palette and the necessary metadata will be created.
Multiple Source Control Integrations
VS Code is capable of handling multiple source control integrations across various projects. The source control providers list shows the providers and repos.
That's it for my overview of using Git with VS Code.
05 / 07
Extending VS Code: Part 1
Originally published January 15, 2018
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 — Node.js
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 find 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, for example: kims-awesome-extension.
Once it is created, navigate to that folder.
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— the name of the extension and should be all lowercase with no spaces. -
version —
string— semantic versioning number for compatibility. -
publisher —
string— the publisher's username in the VS Code Marketplace.
Optional fields include:
-
license —
string -
displayName —
string— the name 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— 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"
}
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.
"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 latter 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": "#00FFFF"
}
Testing an extension
At this point, we can stop and test our extension. We can leave
the tokenColors field as an empty array.
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.
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.
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).
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 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.
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.
06 / 07
Extending VS Code: Part 2
Originally published January 16, 2018
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.
Let's begin
Requirements — Node.js
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 find 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
│ ├── extension.test.js
│ └── index.js
├── node_modules
│ └── vscode
├── package.json
└── jsconfig.json
Let's explore a few of these folders and files
- .vscode — The VS Code integration.
-
.vscodeignore — Works just like
.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 and can be run against the VS Code API.
- package.json — Our extension's manifest file and the entry point to our extension.
- extension.js — Contains the logic.
Manifest — package.json
Let's explore the various keys.
-
name —
string— the name of the extension and should be all lowercase with no spaces. -
version —
string— semantic versioning number for compatibility. -
publisher —
string— the publisher's username in the VS Code Marketplace. -
license —
string— the extension's license. -
displayName —
string— the name displayed in the VS Code Marketplace. -
description —
string— a short description of the extension. -
keywords —
array— keywords or tags used to find the extension. -
main —
string— the entry point to the extension. -
activationEvents —
array— the activation events for the extension. - engines — the compatible versions of VS Code for the extension.
- devDependencies — required Node.js dependencies for the extension.
Within the manifest file, we also find 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 activate method gets invoked only once from the activation event that we specified in our manifest.
deactivate
A deactivate method can be implemented if the
extension makes use of OS resources. The method is used for
clean-up at the time the application shuts down.
So, how does the extension come into existence?
Depending on the activationEvent we choose and
define for our extension, it will partly affect how our extension
is loaded. It could be when a specific file type is loaded,
when a command is fired, etc.
The extension activation process, as an example, can go a little something like this:
- 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.
- An activation event is created.
-
The logic of the extension — the
extension.jsfile — gets loaded in the JavaScript VM. -
The
activatefunction defined inextension.jsis found and called. - One last step: the implementation is invoked and it does its 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.
View the package.json example ↗
Create your extension.js file.
View the extension.js example ↗
Remember how to reload the window? Activate the command palette and select Reload Window.
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 or 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 peek ahead!!
...
But I'll show you my code.
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, 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.
07 / 07
Features of VS Code's Extensibility Model
Originally published January 20, 2018
I abstracted this part out of my Extending VS Code: PART 2 so that it can be referenced without needing to go through the entire tutorial. Enjoy!
Structure
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 find that directory at:
~/.vscode/extensions
Your extensions can be built in TypeScript or JavaScript. We will be exploring an imaginary JavaScript extension.
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
.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 and can be run against the VS Code API.
- package.json — Our extension's manifest file and acts as the entry point to our extension.
- extension.js — Contains the logic.
Manifest — package.json
Let's explore the various keys.
-
name —
string— the name of the extension and should be all lowercase with no spaces. -
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. -
displayName —
string— the name displayed in the VS Code Marketplace. -
description —
string— a short description of the extension. -
keywords —
array— keywords or tags used to find the extension. -
main —
string— the entry point to the extension. -
activationEvents —
array— the activation events for the extension. - engines — the compatible versions of VS Code for the extension.
- devDependencies — required Node.js dependencies for the extension.
For more key fields, check out the Extension Manifest documentation ↗ .
Within the manifest file, we find 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 activate method gets invoked only once from the activation event that we specified in our manifest.
deactivate
A deactivate method can be implemented if the
extension makes use of OS resources. The method is used for
clean-up at the time the application shuts down.
So, how does the extension come into existence?
Depending on the activationEvent we choose and
define for our extension, it will partly affect how our
extension is loaded. It could be when a specific file type
is loaded, when a command is fired, etc.
The extension activation process, as an example, can go a little something like this:
- 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.
- An activation event is created.
-
At which point the logic of the extension, the
extension.jsfile, gets loaded in the JavaScript VM. -
The
activatefunction defined inextension.jsis found and called. - One last step: the implementation is invoked and it does its thing!
This is just a quick overview of some of the features of Visual Studio Code's extensibility.