I'm a huge fan of VS Code, and I suspect I'm not the only one. We've emerged from a world of very heavy IDEs (Integrated Development Environments). Many of them are still around. They're specialized IDEs that do some things very well, and a very popular one is Visual Studio. Visual Studio has been around for quite some time. When Microsoft entered the IDE game around C++ and there were things like Microsoft Foundation Classes (MFC), that's when Visual Studio started taking off. Before that, we had IDEs built into DOS. They would take over your entire screen and they were text-based. IDEs such as Turbo C++, or Turbo, by a company called Borland, were the rage. Visual Studio has gone through some twists and turns as well. We've had specialized IDEs, such as Visual Interdev for web-based scenarios or FrontPage Express for lightweight web page editing. There was a time when a VB programmer had a different IDE than a C++ programmer.

It wasn't until we had VS Code that we had an IDE that works with nearly every language, every platform, and yet is fast, efficient, and super customizable. It runs on Mac, Linux, Windows - it even runs in a browser. It works on Python node.js, .NET, and anything else you can imagine. I'll go so far as saying that I'm hard-pressed to think of another application as good as VS Code. VS Code is built on Electron and a lot of people like to complain about Electron being heavy, yet we all use VS Code. That alone is a testament to how well VS Code is built.

In this article, I'm going to talk about some of my favorite tips and tricks about my favorite IDE, VS Code. Although I'm writing this on a Mac, many of these concepts will port to Windows, so you may have to replace COMMAND key, WIN key, etc.

What Is VS Code?

VS Code is a free application, built on open source by Microsoft, that you can download from https://code.visualstudio.com. It's designed to be a code editor, but honestly, it's so much more than that. It's definitely developer-centric. I've personally used VS Code with .NET, client- and server-side JavaScript projects, Python, and GoLang. I wouldn't trade it for anything else. Okay perhaps .NET and Visual Studio are a good combination, but Visual Studio non-community edition can get expensive. Speaking of developer-centric, although the canonical use of VS Code is to fire up a code development project in your language of choice, I find myself using VS Code for taking quick notes as an alternative to a tabbed notepad, quick debugging, etc. It's a really flexible application with many uses.

VS Code Extensions

The first tip I have for you is that VS Code, when downloaded, is bare bones. That's a good thing. When I'm writing code as a Python developer, I have zero use for Node.js-related paraphernalia loaded in memory bogging my computer down. There are some common things that are applicable to every language, such as Git support, that are built right inside of VS Code. You can go far beyond that by customizing VS Code further. VS Code is extremely customizable. You can grab extensions to improve and customize your dev experience from https://marketplace.visualstudio.com/search?target=VSCode or right within VS Code by looking for the extensions button that's shown in Figure 1.

Figure 1: Extensions
Figure 1: Extensions

The process of writing your own extensions is also well documented, but 99 out of 100 times, I can find some really well-written extensions for my needs in the marketplace.

There Are Two VS Codes

Love it or hate it, in this internet-connected world, things change all the time. The application VS Code changes quite often. It has a vibrant community and dedicated product managers who constantly look for ways to make VS Code better. As a result, roughly once a month, VS Code updates itself. Something I've found very valuable is to keep up with the changes at https://code.visualstudio.com/updates/. You know that life gets busy, and the app updates and project deadlines mean that we can't visit a website to keep up with these changes.

Right inside of VS Code, press COMMAND_P press the “greater than” sign (>) and type “Release notes”, which will show you the release notes. Ensure that you check the checkbox for “Show release notes after an update” and get in the habit of periodically reading these release notes for fun ‘n’ learnin'. In fact, you can click the “gear” icon, as shown in Figure 2, to create a shortcut for viewing release notes. I really appreciate how the VS Code team creates purposeful meaningful documentation that's easy to grok with my very limited attention span.

Figure 2: Release notes
Figure 2: Release notes

Although a monthly release is frequent enough for my liking, sometimes I can't wait to try out new features. VS Code also has an insiders build that you can grab from https://code.visualstudio.com/insiders/ that updates every day.

Keyboard Shortcuts

I'll say one thing about creating shortcuts: VS Code is very customizable, so don't go nuts with shortcuts. Use it for a while, see what you must have as a shortcut, see that it doesn't interfere with your OS or other applications, and then go ahead and create a shortcut for what you find valuable. Even if you don't create shortcuts, many actions are just a few key presses away. And, frequently, if you just hover over an action item, it reveals what shortcut activates an action. I'll talk more about keyboard sleuthing shortly, but here are some invaluable shortcuts that you must know.

To go back and forward, use CTRL_MINUS or CTRL_SHIFT_MINUS within your code. When you're dealing with a complex project and jumping from place to place, it's nice to be able to go back to where you were.

Another shortcut is F12, which is Go to Definition, but if you want to just peek into the definition without losing your place in code, you can press OPT_F12. The Go to Definition is incredibly useful when consuming libraries because frequently a lot of documentation is embedded as comments in the library. Try SHIFT_F12 to find all references for any symbol in your code. You can simply hover your mouse on a symbol to see documentation in a nice large tooltip.

F2 is for renaming across your project. Honestly, I don't want to go through listing every key shortcut, so the best thing I can say is, as you use VS Code, watch out for these shortcuts. If there's an action you find yourself doing often, building the muscle memory for the shortcut is going to make you more productive.

In fact, Microsoft has put together a commonly used shortcuts reference you can find right from within VS Code using CMD_K, CMD_R (also, see the next section about COMMAND_P and search for “Shortcuts reference”). This launches a PDF that's specific to your OS and shows the most commonly used shortcuts at http://aka.ms/vscodekeybindings.

On Mac specifically, one shortcut I'd like to discuss is F11. F11 is STEP_INTO when it comes to debugging. But MacOS also likes to use F11 for spaces. Personally, I still switch between Mac and Windows enough that I remapped F11 at the operating system level. Of course, this really messes me up when I use XCode. Ugh, why can't we just agree on shortcuts? Let me know if you have a better suggestion.

COMMAND_P and SHIFT_COMMAND_P

This is a shortcut so valuable that it deserves its own section. This is the shortcut that discovers everything you care for.

At any point, you can press COMMAND_P, and it shows a searchable list of all files in your current project. This makes it super easy to jump from file to file in a large project. Many route-based applications tend to use the same filenames over and over again, such as index.js or index.html. You can search for the containing folder name that coincides with your route and narrow down the file you care for. This is pretty much how I navigate my project most of the time. Very rarely do I use the tree view-based navigation on the left.

Speaking of that tree view-based navigation on the left, you can put it on the right. This is controlled by a setting:

"workbench.sideBar.location": "left"

My eyes aren't all they used to be, so I like to work in larger fonts. But the huge downside is that I see less code on the screen. What I do is I move the sidebar to the right and press COMMAND_B to hide or show it as needed. Frankly, COMMAND_P pretty much removes my dependence on the sidebar anyway, but in case I need it, it's there, and every time I hide or show it, it doesn't move my code. And I have the whole screen width for code. Yay!

It would be nice if you could just remember all this, but you don't need to. This is where the SHIFT_COMMAND_P comes in. You can either press COMMAND_P and type “>” to discover all the commands VS Code supports, or you can press SHIFT_COMMAND_P to land there directly. Here, you'll find a treasure trove of commands.

One that I really like is COMMAND_K_Z, or Zen mode, which removes all distractions and full-screens my application, so I can actually get some work done.

You'll also notice that many of these commands don't have assigned shortcuts. You can click the gear next to any command, as shown back in Figure 2, and create a shortcut key if you desire.

Here's another really nice power tip. You can press COMMAND_P and press # to do an exact search for a symbol. Or try my preference: press COMMAND_P and type @ to do a fuzzy symbol search. For instance, in my recent CODE Magazine article around passkeys (https://www.codemag.com/Article/2403031/Passkey-Authentication), I wish to see where I'm using “user.” I can simply do a search like that shown in Figure 3.

Figure 3: Searching for symbols
Figure 3: Searching for symbols

I highly recommend opening your complex production project and trying this out. You'll be amazed at how useful this is.

Settings and Preferences

VS Code is extremely customizable. I'm not sure if I mentioned that yet. Many of these customizations land in your preferences. My preferences may not be the same as my teammate's preferences, so VS Code allows me to have preferences at two levels, at the workspace level that I intend to share with my team, and those that are specific to the project. For instance, maybe I want to customize F5 to not just run, but do some action like spin up a remote container and then run and attach, or maybe we use spaces and not tabs and want to enforce three spaces, etc. I could put that in workspace preferences.

But there are preferences that are unique to me. For instance, I like working on a Mac and the F11 key really messes me up. So I customized the F11 key behavior and kept that in user preferences. I set up a few shortcuts I like to use often, and that also goes in my user preferences.

Such preferences are stored in a settings.json file. Workspace preferences reside in a .vscode folder, so they get checked in with your code. User preferences are in your ~/.vscode folder. You can choose to synch them across your computers by signing in with GitHub.

You can also launch VS Code with the –user-code-dir commandline option to load settings on the fly if you wish, or pair it with symlinks to be as fancy as you like.

Hiding Files

There are many project types that create temporary or interstitial files. A good example is TypeScript or any Node.js project. TypeScript doesn't run directly; it runs through transpilation, so you usually generate JavaScript files ahead of time. As your project gets bigger, you don't want everything to get transpiled every time you wish to debug. Inevitably, your view gets cluttered with a filename.js and a corresponding filename.ts. Sure, there are workarounds like bundling, etc., but they create their own set of problems.

A rather easy answer here is that, in addition to excluding those files from being checked in via .gitignore, you can also hide such files via a setting. For instance, the setting below in your .vscode\settings.json folder hides the node_modules folder from your view, even though it may exist on the disk.

{
    "files.exclude": {
        "node_modules": true
    }
}

Multiple Cursors and Other Editing Hacks

Okay, this next tip, if you master it, is going to make you really productive. You probably frequently end up writing repetitive code. For instance, let's say that you want to create an HTML ULI element with five Lis. You can simply type this out like so:

<ul>
    <li></li>
</ul>

Now try and follow these keyboard shortcuts carefully. Go ahead and select the <li></li> line. You can easily move this line up or down using OPTION_CURSORUP/DOWN keys. To duplicate this line, you simply do SHIFT_OPTION_CURSORUP/DOWN. Go ahead and try it, and create five <li> elements.

Actually, this was too complex a way of creating five lis. VS Code supports something called Emmet, which allows you to speedily hack up commonly used HTML and CSS structures. For instance, to generate exactly the same code in an HTML file, type exactly this:

ul>li*5

It should look like Figure 4.

Figure 4: Emmet in action
Figure 4: Emmet in action

Now when you hit enter, you get a ul with five lis inside.

Now, let's say that you wish to add some text into these five <li> elements. Carefully place your cursor in the middle of the first <li></li> element, and press OPTION_COMMAND_CURSORDOWN. You should now see multiple cursors, as shown in Figure 5.

Figure 5: Multiple cursors
Figure 5: Multiple cursors

Now any text you write will appear in all five places. You can super charge this with text replacement and regex to do some really amazing things.

What if I didn't want to type exactly the same text in all five places. Instead, I wanted to incrementally type 1, 2, 3, 4, 5? You can use the following Emmet expansion.

ul>li{$}*5

I know this Emmet syntax feels a bit weird and alien. Once you get used to it, it's not so bad. In fact, it feels quite logical. So here's a link that's a great Emmet cheat sheet https://docs.emmet.io/cheat-sheet/. Of course, there's an extension that makes this even easier. It's called Text Pastry and lets you do ranges, text, etc.

Selecting Text Like a Pro

I just talked about multiple cursors. That's very cool, but sometimes you want to visually select a random column of text. You can see Figure 6 for what I mean. The way to do this is to press OPTION_SHIFT and drag your mouse cursor across whatever you wish to select. This can be useful when you want to cross edit or paste a vertical line of text.

Figure 6: Selecting a column of text
Figure 6: Selecting a column of text

Selecting code is also an art. I can't tell you how many times I've seen people just place their cursor somewhere, hold the shift key down and press LEFT ARROW multiple times to select a whole line. Just do COMMAND_L to select a whole line. Now pair that with move line up or down as I talked about earlier. You can certainly use all Mac or Windows OS shortcuts to move between lines or words easily.

However, here's a nice tip. Sometimes you want your selection to be code aware. For example, you might want to select this “if” block or select this method. In fact, let's say that you want to place your cursor somewhere, select an if block, and maybe move it a few lines up.

Here's how you do it. You use an ability to call an expand or collapse selection. You can do so using CTRL_SHIFT_OPTION_RIGHT/LEFT_Arrow keys. With the text selected, you can move the whole section up, smartly, respecting all the code logic and boundaries using OPTION_UP/DOWN arrows.

Collapse Expand on Steroids

Remember, I mentioned that VS Code is incredible for developers, but I use it for other purposes, like taking meeting notes. You can enable Emmet in any language you wish.

For instance, I love taking notes in markdown. I don't know why we all don't do that. It's simple, fast, and can be version controlled and compared. In fact, my editor insists that I write this article in MS Word, but you know what? I first write it in markdown, and then copy paste it in Word. It's just more productive.

Anyway, here's how you can enable Emmet in VS Code. In your settings (either user or workspace), add the following:

{
    "emmet.excludeLanguages": [],
    "emmet.includeLanguages": {"markdown": "html"},
}

Now, open a markdown file, and try out an Emmet expansion. For instance, let's say that you want to quickly create a list of five items. Try this:

{ $.}*5

You can start typing notes. For instance, Figure 7 shows my to-dos for the weekend. Note that I have my mouse cursor positioned in the left gutter. Just by indenting things in a certain way, I can collapse or expand sections in my notes. Good luck doing that with Notepad. This collapse or expand works in any language that VS Code understands, including text.

Figure 7: Collapse and expand works in any file type
Figure 7: Collapse and expand works in any file type

The Outline View

Collapse and expand is nice, but it's sometimes very nice to view a top-down outline view of your code. For example, what routes do I have configured in a long file? I've found this to be especially useful in languages that tend to get very verbose, such as Golang. Press COMMAND_P and look for “Focus on outline view”. You should see something similar to Figure 8. Please feel free to try this with your incredibly complicated unwieldy long file with lots of code.

Figure       8      : The outline view
Figure 8 : The outline view

The outline view is really useful because the overall structure of the code is now super clear. Now I can tell that I have four routes and a few global variables. Hmm, maybe I should restructure them into a const or something to clean up my code. Or maybe put them in their own scope. I'll get back to refactoring later.

The Timeline View

I mentally fought Git for many years. I felt it was overbearing and over-complex for simple things. I'm almost at a point now where I've seen the light. Even for simple stuff, you can make Git as complex or as simple as you'd like. Even when I'm taking notes, I like to Git init\commit simply because it gives me reference points when I'm doing complex refactoring.

We all have those days where we make some changes, mess up everything, and wish we had a commit. If we knew we were walking toward a trap… Well, VS Code has your back. This is a nifty trick hidden by default. Use COMMAND_P and find Focus on timeline view. Now open any file and you'll see that VS Code has been monitoring the work you've been doing in that file. This will work whether or not you did a commit. You can see this in action in Figure 9. You can select any previous version, and it shows you a diff view of the changes between your current version and the version from however long back.

Figure 9: The timeline view has my back.
Figure 9: The timeline view has my back.

Sticky Headers

A really nice feature of VS Code is sticky headers. Frequently, as I'm scrolling through code, the methods become really long and I tend to lose context of where I was.

Sticky headers solve this problem for me. As I scroll, sticky headers lock the scope I'm in at the top. If you pay close attention to Figure 10, you'll see that line #51 is my scope, and line #52, 53, and 54 are scrolling underneath it. This also works in other scopes such as if/while, etc. This way, when I'm in the middle of a long method in line #8848, I can easily reference what the input parameters of my scope were.

Figure 10: Sticky headers
Figure 10: Sticky headers

Extensions

VS Code has a vibrant extensions marketplace. Nearly every platform or language has its unique needs. VS Code out of the box remains fairly bare bones, but you can add whatever you wish to it via extensions. There are UI themes that are more suitable to HTML, for instance. But it's also true that a color picker, although incredibly useful in CSS, has little use in Python. This is where profiles come in.

If you click on the gear icon in the activity bar, you can create profiles. In a profile, you can capture extensions, UI state, keyboard shortcuts, and settings. You can import/export profiles, and you can create profiles unique to dev scenarios.

For instance, at a place I used to work, all development was done in a remote container. I wanted to try things out locally as well. I just set up different profiles for those. One profile had the extension that made the remote container work seamless. Another didn't.

Extensions can also get heavy. Some extensions do too much. A perfect example is the “import cost” extension at https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost. For Node.js projects, this extension is incredible. As soon as you import something, it'll let you know exactly how big the dependency is. The problem is that the extension that lets you know how heavy a dependency is, is itself quite heavy.

How do you know which extension is slowing you down? Periodically, it's a good idea to view how much time your extensions are taking. Press COMMAND_P, and type “>Developer: Show running extensions”. This gives you a clear idea of which extensions are killing your battery life. Remember, you can set up profiles to selectively load extensions. This little bit of homework keeps your IDE zippity fast.

Search Like a Pro

VS Code can search through your code. That's not a big deal: Just type in a search term and hit enter, right? VS Code's search is quite powerful and all these nifty things are right under your nose. For instance, you can do “match case” or “match whole word” in search. You can even make search case specific. The best part is that you can use regex expressions to search to make it truly powerful.

Sometimes you need to search text that spans multiple lines. It's easy. You just hit SHIFT_ENTER to make your search box multiline.

Sometimes you want to narrow your search down by file types. You can easily click the triple dot below the search box and pick files to exclude or include, as shown in Figure 11.

Figure 11: File customization in search
Figure 11: File customization in search

These textboxes are deceptively powerful. They allow you to use glob pattern syntax in searches. For example, you can use an asterisk (*) to match zero or more characters in a path segment. Or you can use a question mark (?) to match against one character in a path segment. You may use double asterisks (**) to match any number of path segments, including none.

You can make your combine conditions using {}. For instance {**/*.html,**/*.txt} matches all HTML and text files. You can use [] to declare a range of characters to match. For example, use .[0-9] to match on example.0, example.1, ...). You can even negate criteria using !. For example, use [!...] to negate a range of characters to match (example.[!0-9] to match on example.a, example.b, but not example.0).

Here's another neat tip regarding searching your codebase. You're not limited to using the sidebar for searches. Just press COMMAND_P and open search editor. Now you have a full screen window for searches. Once you see your search results, you can use CMD_CLICK to navigate to the code occurrence without losing the search results.

This window even maintains your search history and you can have multiple search editors open. The red arrow allows you to see lines of code around the matched search result. For instance, clicking on that allows me to see the line before and after the matched search result within the search results. This can be seen in Figure 12.

Figure 12: The search editor
Figure 12: The search editor

Summary

Sometimes you take things for granted. I use VS Code every day, including weekends. I seldom realize how amazing this tool is and how much muscle memory I take for granted. When I started writing this article, I was debating whether I had enough tips. But as I started verbalizing my thoughts with VS Code open on the side, I came up with one tip and then another.

Believe me when I say this: I'm not done. Some of the super-charging tips are a bit complex and require me to describe my workflow and OS setup. Some of them are specific to Git and certain extensions that really simplify my Git life. Some of them are all about terminals hosted inside VS Code so I don't have to leave VS Code for common tasks. Some are around debugging and logging tricks. And there are many more.

What code editor do you use? Do you have any favorite tips? Give a shout out to me on X or Twitter or wherever you feel.

Until next time, happy coding in VS Code, or whatever you prefer.