In my previous article in CODE Magazine (https://www.codemag.com/Article/2408031/VS-Code-Tips), I shared some of my favorite tips when working with VS Code. As I wrote the article, I realized that I was just brain dumping tidbits I've gathered over many years of using VS Code. The list seemed endless. But what about some larger chunks of tips? Things that every developer uses and are built into VS Code that can supercharge your development? I thought it might be nice to take a logical break and come back with those larger chunks of items.

Git

These days, if you're a developer, you most likely use Git. It has sort of become the de facto source control mechanism, whether it's GitHub, or Azure DevOps, or anything else, chances are you use the Git command quite a bit. It's therefore natural that VS Code offers some fabulous Git integration.

Right out of the box, VS Code has some Git features built into it. To demonstrate many of these features, I'll use the source code for MSAL Python hosted at https://github.com/AzureAD/microsoft-authentication-library-for-python. But feel free to use any moderately realistic Git-based repo.

VS Code's Git integration can be accessed by clicking on the sidebar button shown in Figure 1.

Figure 1: VS Code's out of the box Git integration
Figure 1: VS Code's out of the box Git integration

You can click on that button and VS Code prompts you to either clone a repo or open a folder. Either way, you can work with Git-based repos right inside VS Code. For now, I'll clone the MSAL python repo and open it in VS Code. I made a minor modification to the README.md file and added a file, and immediately VS Code's Git integration shows me that I have changes. In fact, right through VS Code, I can perform common functions, such as staging my changes, reverting my changes, or committing the changes, and give it a decent commit message. I can also click on individual files and view a diff. Additionally, each file shows me a nomenclature showing whether a file is modified, untracked, or deleted. You can see in Figure 2 that I have an untracked and a modified file.

Figure       2      : VS Code's Git view
Figure 2 : VS Code's Git view

But we know that Git is much more powerful than this basic stuff. If you click the triple dots on the corner of the source control window, you can see a pretty interesting menu. This can be seen in Figure 3.

Figure 3: Additional Git features
Figure 3: Additional Git features

It appears that I've made this change in the dev branch. This is probably something I shouldn't have done. But I don't want to lose all the work I've done. What I should probably do here is stash my changes, branch, and then apply stash. Let's see if I can achieve this through VS Code. To do it, I simply went to the “Stash” menu and created a stash including unstaged. Then I went to branch and created a branch. Finally, I applied my stash right through the menu. If you're curious, you can choose to see the Git output using the “Show Git Output” menu item at the bottom of Figure 3, and it'll show you exactly the Git commands being executed behind the scenes. I find VS Code's Git commands to be extremely chatty, but sometimes they can be helpful in figuring out the syntax of a particularly wiry command.

There are many other Git capabilities built right inside VS Code. For instance, it has a pretty good diffing tool built right into it. I'll talk more about diffing later, but all the diff capabilities of VS Code are extremely useful when working with a Git repo. For instance, it lets you do a three-way merge editor where it shows you the incoming (from the server) version on the left, your version on the right, and the merged version at the bottom. It also lets you do merge conflict resolution. When you do a push to a repo, and the version on the server has changed since you last pushed, you get a merge conflict. This is where Git cannot resolve things automatically for you, so it must ask you what changes are still legit. Git splinters your code with weird text that looks like <<<<<<<<< HEAD or >>>>>>>> theirs, which can become very difficult to fix on a text editor. Although GitHub has a pretty nice resolve conflicts facility built right into the web-based UI, VS Code also neatly highlights all such changes for you with convenient buttons for which change to accept.

VS Code also has a pretty nice timeline view, which is hidden by default. To view it, press CMD_P, and “> Focus on timeline”. This view for the currently open file can be seen in Figure 4.

Figure 4: Timeline view
Figure 4: Timeline view

I find the timeline view particularly useful. For instance, I can click on any commit, and view a nice diff view of the change in that particular commit. I can, in fact, right-click on any commit and select for compare, and then compare with selected to compare any two commits.

Frequently, I look at other people's code, trying to figure out what the heck they were thinking when they wrote this. It's really nice to hover over any particular commit. Simply hovering over any commit and the tooltip shows me the developer's comments, which gives me some idea of why the developer made the change. Or I can select a particular commit and click the “View commit” button on the right to get a full snapshot of the commit across all files included in a given commit, without ever leaving VS Code.

When working with Git, frequently Git asks you to provide input. Usually, Git uses Vim as its default editor, which is a great text-based editor, once you master all the shortcuts. I never have to restart my Mac unless I have to exit Vim. Well, not anymore. I can tell Git to use VS Code as my default editor by issuing the following command on terminal:

git config --global 
    core.editor "code --wait"

VS Code offers great Git integration right out of the box. But a particular VS Code extension I really like when working with Git repos is GitLens. It really supercharges VS Code's capabilities when working with Git.

Once the extension is installed, you'll start seeing Git intelligence right inside your code. For instance, I opened broker.py and placed my cursor on a particular line, and look what it shows me in Figure 5.

Figure 5: Gitlens integration inside VS Code
Figure 5: Gitlens integration inside VS Code

Every single line now shows you who wrote that line and when. A simple tooltip tells you why that line of code was written. For instance, that particular line was written in a certain commit because Ray Luo wanted to disable SSH cert when using brokers.

You can also choose to view the commit graph in a visual manner of any repo, so you can get an idea what was released and merged at what time and why. This can be seen in Figure 6.

Figure 6: Commit graph in GitLens
Figure 6: Commit graph in GitLens

Also, note that right through the UI, I can fetch a particular commit and replicate the world as it existed at that time. Sure, I could do that through Git commands too, but this is quicker and easier.

There are a lot of amazing features here, but let's switch gears a bit now and talk a bit about terminal integration in VS Code.

Terminal

In any modern programming language, you'll find yourself on the command line sooner or later. This isn't an unreasonable expectation because these days we develop on a *nix or pretend *nix environment, with the eventual goal of running things in a very lightweight container somewhere, which is typically Linux or similar. Some of that mentality bleeds into our programming lifecycle.

I really like this lightweight and super customizable way of coding. Scripting also ensures reusability, automation, among other things. It's not a surprise therefore that VS Code has tight integration with your terminal. Right inside of VS Code, you can press the CTRL_`   keyboard shortcut to launch terminal. You can have multiple terminals right inside of VS Code using the CTRL_SHIFT_ `   keyboard shortcut, or you can launch your actual terminal outside of VS Code using the SHIFT_COMMAND_C shortcut. Either way, the terminal of your choice is just a shortcut key away.

Personally, I like to have terminal open within VS Code. I have mentally replaced ALT_TAB with CTRL_`   when thinking terminal. Try this out yourself. Open VS Code, open any code file, and press CTRL_SHIFT_`  . It immediately takes you to terminal. Your cursor is now on terminal so you can start typing shell commands. Now, to go back to your code file, press CTRL_`   again, and you're back in code and the terminal window is hidden. Don't worry, the terminal is still there. It's just hidden. You can maintain multiple such terminal windows right within VS Code and go back and forth between code and terminal using CTRL_`  .

Another reason I prefer having terminal right inside VS Code is because frequently I do development on a remote container, and terminal is simply SSHed into that terminal. You could run VS Code in an incredibly lightweight machine, like an Android tablet perhaps, do your actual dev on a container with supercomputer resources, and it'll feel completely natural.

Although I like having a window that appears/disappears when using terminal, sometimes you run a command and a lot of output scrolls by. You wish you had more vertical space. Sure, you can use the “more” command to pause the output, but that's an afterthought. To do so, you can choose to move the terminal to the editor area, as shown in Figure 7.

Figure 7: Move terminal to editor area
Figure 7: Move terminal to editor area

By moving terminal to the editor area, it now becomes a tab, like any other code file within VS Code. Now you can use CTRL_TAB to go between your terminal and code or use split view to have your code and terminal side by side. You can even go Zen mode using CMD_K_Z to remove all distractions. One trick here is that Zen mode won't get activated with terminal in focus. This is because terminal interprets CMD_K differently and essentially cancels out Zen mode. You can open a code file and terminal, focus on the code file, and activate Zen mode. Now you have Zen mode with two tabs: one with code and another with terminal. Neat!

A long time ago, in a pure Windows world, the only terminal we had was DOS. These days things are a bit more interesting. You have PowerShell, WSL, and so many flavors of Unix shells. VS Code lets you toggle easily between the specific kind of terminal you want. This can be seen in Figure 8.

Figure       8      : Terminal types
Figure 8 : Terminal types

When in terminal, all your usual terminal tricks apply. This isn't an emulated terminal; this is your actual operating system terminal, so all your settings will carry over. All those shortcut keys you are used to, all those nifty aliases and scripts you've set up will still work.

VS Code adds a few more interesting bits on top.

You can use the “code -r” command to open any file within VS Code and reuse the same code window. I find this very useful when I want to view a certain file. I navigate to it using terminal, but I don't want a whole another window to open. Especially on a Mac where ALT_TAB feels wrong, it's so nice to open the file in your current context, grab what you need, press CMD_W to close it, and move on with your life.

The other really nice thing in the integrated terminal is that holding the CMD key down turns a lot of things into links. In fact, VS Code can be taught to customize the behavior of many of these links under terminal settings, but right out of the box, CMD_CLICK on a file opens the file in the current VS Code window.

I confess that I spend most of my time on a Mac and I'm not aware of all the nice things Microsoft has been building into terminal/command prompt on the Windows side lately. But there are a number of things I find useful in the Mac terminal that VS Code makes available inside terminal as hosted by VS Code. I'd be curious to know what your Windows experience is like here. Things like dragging and dropping a file onto terminal and getting the path written out, or pressing CMD_F to search through, or CMD_cursor up or down to iterate between commands, or holding OPTION down and using your mouse to do a vertical select, etc.

An interesting default I do like to change, though, is the right-click behavior on the integrated terminal in VS Code. When I right-click in terminal in VS Code, by default, VS Code takes ownership of the right-click behavior and presents a minimum common denominator featureset. The MacOS terminal offers a number of nifty tricks behind right-click in terminal. For instance, right-clicking on something that looks like a date allows you to create an event or open the calendar for that date. Right-clicking on any word allows you to run the man command against that keyword, do automations via services, or search in your favorite search engine.

To allow VS Code to send right-click commands to terminal directly, you can simply set the terminal.integrated.rightClickBehavior setting to “nothing.”

What's even more fun is that you can tie all this with profiles. More on that shortly.

There are many other interesting tricks you can use with the integrated terminal inside VS Code. For instance, you can right-click on any folder and launch directly into that folder in the integrated terminal, or, via settings, you can configure which terminal you'd rather use. For instance, for my PowerShell projects, I prefer to use pwsh. Remember, all these settings are configurable either at the user level or at the workspace level. So if I have a PowerShell project, I want my terminal to be pwsh automatically without having to start terminal and then launch PowerShell.

Profiles

VS Code is an incredibly flexible tool. And it's my and many other developer's de facto tool these days because developers these days are also polyglot. One moment I'm in PowerShell, another in shell scripting, another in JavaScript, then Python, Golang, and sometimes .NET too. The reality is that all these development environments require different settings, preferences, sometimes even colors and fonts.

This is where profiles come in. VS Code profiles let you create sets of customizations that you can use yourself or share with your friends.

By default, all the settings you customize go in the default profile. You can choose to create a new profile or import/export profiles, as can be seen in Figure 9.

Figure 9: VS Code profiles
Figure 9: VS Code profiles

In fact, when I create a profile, VS Code even helps me pick smart defaults, as can be seen in Figure 10.

Figure 10: VS Code profile defaults
Figure 10: VS Code profile defaults

Because we have a Python project open, go ahead and create a Python profile. I went ahead and created one and called it “Custom Python”. Next to the gear icon at the bottom left, VS Code shows me the currently loaded profile. Also, when I choose to edit the profile, it shows me all the things that are unique to this profile. This can be seen in Figure 11.

Figure 11: My custom Python profile.
Figure 11: My custom Python profile.

This is so amazing. Just with a click, I was able to set up my IDE with extensions specific to Python, a dev environment with Docker and Kubernetes support, and even shortcuts and code snippets that are so well suited to Python.

Of course, you'll find things that you want to have available across all profiles. VS Code allows you to apply any setting to all profiles. When you're customizing a setting, just click the gear next to it and choose to apply it to all profiles. Similarly, you can choose to apply an extension across all profiles too.

The other side benefit here, of course, is that when I'm running PowerShell, I don't pay the penalty of loading the Pylance extension. My IDE remains specific and lightweight and suited for the purpose I'm trying to solve. This is very much unlike Visual Studio where the IDE has gotten so bloated over the years that I launch it and go get coffee.

Developing Remotely

This is a technique that I use often and I'm completely blown away by. Sometimes I've been sitting in this chair for 12 hours, and I want to go sit on the couch and work. Or maybe I'm remote desktopped into a Windows machine, and developing on that RDP link is just icky, so I wish I could just develop locally instead but I'm on that remote desktop machine.

This is where the “tunnel” feature comes in handy.

On the remote machine, “cd” in terminal to the folder that contains your workspace and run the following command:

code tunnel

The first time you run this command, depending upon the auth provider you use, you'll be asked to authenticate and grant permissions. Once you do that, you'll be shown a website URL. This URL is available anywhere in the world and it starts with “vscode.dev”.

Go ahead and open this URL in a browser on any machine. What do you see? As can be seen in Figure 12, this is your project loaded up in the browser, with full VS Code running.

Figure 12: My custom Python profile.
Figure 12: My custom Python profile.

Let's play around with this a bit. Try some shortcut keys like CTRL_`   to launch terminal, and now you're on command line on your remote machine. How incredible is that?

When someone forces you to develop in an RDP environment, you know what to do, right? Of course, if you don't want to tunnel over the web, you can simply run the following command and get a very similar experience on a local network also.

code serve-web

Running this command runs a web server on port 8000 by default, which exposes VS Code in a browser that you can access from anywhere on the local network. You can then open any file, folder, or access terminal as you please.

Developing in the browser is cool, but it isn't exactly like developing in VS Code. For instance, the shortcut keys sometimes get confused between the browser and VS Code, and ALT_TAB isn't the same when the Chrome browser is pretending to be VS Code.

Wouldn't it be cool if you could start the VS Code tunnel on a remote machine and then actually use VS Code on a different machine to do your dev work?

You can do so using the remote tunnels extension at https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-server.

You start the tunnel normally and go to the remote tunnels section on the sidebar, as shown in Figure 13.

Figure 13: Remote tunnels sidebar
Figure 13: Remote tunnels sidebar

From this sidebar, you can connect to the tunnel you'd previously created. Once connected, go ahead and open any project on that machine using the File\open folder command. What do you see? Instead of the file picker opening and prompting you to pick a local folder, now you're being asked to open a folder on the remote machine.

Go ahead and open any project. Now you're running a VS Code thick client on a remote machine, and working as if you're on the remote machine. This is 100% seamless and feels totally natural, just like developing on your local machine.

Although this is super cool, what's even more amazing is that you can replicate this on a remote container via the remote-SSH extension. You can effectively do all your dev work on a remote container while VS Code runs on your desktop. It doesn't matter if your desktop is Windows or Mac. The huge win I see here is that all your development is on a remote container that the IT department can secure at their will. This massive dev machine could be provisioned with lots of resources to make you productive. When you're done using the machine, the resources can now be released and shared with another developer in your company.

All this while having zero impact on productivity at your end or subjecting you to an awful development experience.

Try doing this with Visual Studio. This is why VS Code is the IDE that everyone's using.

Summary

I have an unhealthy level of excitement when I talk about VS Code. Having been a developer for a few decades now, I couldn't have imagined that one day we'd have an IDE that's written using JavaScript/TypeScript packaged as an electron app, that runs zippity fast, and that runs everywhere - browser, iPad, Android, Chromebook, Mac, Window. Your code can sit anywhere, you can be somewhere else, it makes IT admins happy, it makes developers happy, and it can support any development environment and programming language.

Name me one other tool that comes even close. A doc writer can use it to take notes, or a Node.js developer can use it to develop websites, or a DevOps developer can use it to orchestrate a complex infrastructure, or a data scientist can use it to sift data, or an AI developer can leverage the power of massive compute on a remote container to fine tune AI models.

I've been lucky enough to have worked personally with the developers who build VS Code. They don't get enough credit. Please give them a shout out at @code.

Until next time, happy coding.