Your first Visual Studio Code Extension
I find myself using Github Gists quite often. I also found myself getting quite a bit annoyed at having to copy and paste code manually into a new Gist. I thought to myself hey, self, why don’t you just make a VS Code extension that will create a Gist out of selected text. My self replied that is an excellent idea, lets figure out how to do it without even checking the marketplace for an existing solution.
So I made and extension, and I was quite proud of myself. Probably too proud, but not proud enough to advertise it before checking the marketplace to see if it was actually there. And thank goodness I didnt, because, to my horror, this is what I found when I searched for “gist”
Turns out this is a problem that has been solved several times over. The good extensions (i.e. not mine) not only create Gists, but handle authentication AND management of Gists for you. One of them even works using Personal Access Tokens so you can get around 2 factor authentication. Mine just creates a dumb anonymous Gist. Whatever.
So, what did I learn? I learned how to make a basic Code extension, sure, but more importantly, I learned you should probably try seeing if there is an existing solution to your problem first.
Determined to not let the hour or two I spent on this extension go to waste, I decided to explain my exact process for creating this stupid extension, just for you, dear reader.
The Process
First, I Googled “How do you make a VS Code extension”. Any senior web developer will tell you that Googling stuff is a required first step, and usually an ongoing process. I discovered that the Visual Studio Code team has written some very well documented examples to get started. I followed the Hello World example — the extension generator saved a lot of time and is a very nice tool. Good job, VS Code team!
Second, I knew that I wanted the user to be able to right click selected text in the editor and click a menu option that would then give them the ability to input a file name for the gist. Basically, I needed to be able to add an option to the editor’s context menu. I Googled “adding context menu item to VS Code extension” or something along those lines, which led me to the documentation on menu contribution points.
I found out that in the extension’s package.json
you can add menus
to the contributes
block, so after reading the documentation VERY haphazardly, I replaced contributes
in the package.json
with this:
This will now add a menu item to the context menu in the editor, which you bring up by right-clicking.
Cool. Cool cool cool. So, now I needed to figure out how to make my extension do stuff when that item is clicked. I figured I’d have to make all these changes inside the callback function of the generated registerCommand
function that sat inside the activate
function. I also realized that because I was accepting user input and also calling an API, I’d probably want to use async/await. So, I created an async function called CreateGist
— here’s the entirety of the extension for reference.
On line 40, I call CreateGist
— this will get called whenever the extension.createGist
command is executed, which happens when that context menu item is clicked.
I had to figure out how to get the selected text, which was easy enough. Turns out that the vscode
package has a window
property which in turn has an activeTextEditor
property. Here’s the documentation for window, which, again, I very quickly glimpsed through.
On line 6, I get the currently selected text in the active editor:
const text = editor.document.getText(editor.selection);
Sweet. Now I just want to give the user the ability to name the file. Not entirely sure how to do that, I did a command + f
in the vscode API documentation page for the word “input” hoping there was something there, AND THERE WAS!
Turns out you can easily render an input box using vscode.window.showInputBox
, which I did on lines 9 through 11. The rest of the code is not extension related. I make an HTTP Post request to Github’s api to create a gist. All pretty boring, really.
Lastly, I wanted to open the newly created Gist in the user’s browser window. Not feeling so lucky, I turned back to Google and searched “open a new window in VS Code extension” where I learned about Complex Commands, which at first scared me. Turns out, they aren’t that complex. There is a vscode.open
command that accepts a URI as an argument and will open a new browser window. So, on line 31 you can see that I take the html_url
from the response Github API call, and execute the open
command.
Voila!
Again, don’t use this dumb extension because the alternatives are way better.