Menu
About me Kontakt

Ben Awad is a huge fan of the VS Code editor and has been using its Vim extension for a while. Recently, he noticed considerable lag when working on large TypeScript projects. To resolve this issue, he decided to configure Vim to include some of his favorite features from VS Code. After experimenting for three days, he settled on using NeoVim, which he found to be a better option than the traditional Vim. This blog post dives into his setup and the improvements he managed to implement in his Vim configuration while making it feel closer to VS Code.

To start off, Ben chose to utilize NeoVim and installed a variety of plugins through the VimPlug manager. He switched between applications easily using tmux for managing multiple terminal windows. One key aspect of his configuration is the use of hotkeys that mimic those in VS Code, allowing him to move seamlessly between both environments. This decision remarkably enhanced his productivity, especially with features such as go to definition, auto-completion, and renaming variables.

Another focal point in Ben's setup is the integration of TypeScript through the COC plugin, which provides language server support. However, he realized that as his project size increased, the lag issues persisted. This problem prompted him to consider how language servers operate in larger systems, as they do tend to slow down with more extensive and complex projects. Despite starting with promising performance, Ben found dealing with larger projects brought similar frustrations as when using VS Code.

In terms of user experience, Ben opted for the grovbox theme, which enhances syntax highlighting, and he also deployed NerdTree for file navigation. He made admirable strides in creating a user-friendly setup while working to achieve the same level of visual cues as VS Code, such as highlighting modified files based on their status. This unique hybrid approach has allowed him to create a cohesive environment that balances the Vim experience with the capabilities he appreciates in VS Code.

Ultimately, Ben concludes that while his Vim configuration has its strengths, it struggles with performance lag in large projects, driving him to reconsider a return to VS Code. The video showcasing his experience, at the time of writing this article, has reached 757,355 views with 12,622 likes, reflecting a substantial amount of interest in the topic. Developers facing similar challenges may find that blending Vim's efficiency with VS Code's complete features can be a double-edged sword, leaving them to navigate potential frustrations consciously.

Toggle timeline summary

  • 00:00 Introduction to using VS Code and Vim extension, mentioning lag issues in large TypeScript projects.
  • 00:24 Author discusses attempts to configure Vim to incorporate VS Code features.
  • 01:08 Choosing NeoVim over Vim 8 for the configuration.
  • 01:22 Introduction of VimPlug for managing plugins.
  • 02:36 Installation of the 'coc.nvim' plugin to enhance completion features.
  • 03:03 Demonstration of auto-completion enabled by the COC plugin.
  • 03:24 Features like automatic imports and function definition integrations showcased.
  • 03:56 Explanation of needing a language server to run the COC plugin effectively.
  • 04:20 Description of additional extensions for TypeScript and formatting.
  • 04:38 Custom snippet creation for quick console logging.
  • 05:27 Using 'GD' command to navigate to function definitions.
  • 06:32 Hotkey configurations to keep consistent with VS Code.
  • 07:06 Integration of Prettier for auto-formatting code on save.
  • 08:57 Discussion on tmux for managing terminal splits effectively.
  • 10:35 Setting up NerdTree for file navigation.
  • 13:16 Installation of Git integration features for file tracking in NerdTree.
  • 18:01 Commenting functionality modeled after VS Code.
  • 19:16 Implementation of a gutter plugin to highlight modified lines.
  • 20:57 Concluding thoughts on performance issues with the TypeScript server.
  • 22:47 Final reflections on the transition back to VS Code due to configuration challenges.
  • 23:06 Thanking viewers and signing off.

Transcription

I'm a big fan of VS Code and have been using the Vim extension with it, but lately I've noticed specifically in large TypeScript projects that it's been really laggy and really slow and the Vim emulation is kind of just meh overall. So what I wanted to try to figure out is if I could set up Vim in a way that used some of my favorite VS Code features. And so what I did is over the past three days or so, I've tried configuring Vim to use some of VS Code's features. Now it doesn't cover all of them. I selectively picked some of the most important ones to me. So I'm going to be showing you this setup that I got working that I'm actually pretty happy with. And I'll show you everything that I installed and how I set it up. And I'm going to be walking through that here. If you prefer just to just see the end results and look at the dot files for this, I'll put in the description the configuration file for Vim. All right, so to start off with, what I decided was to go with NeoVim over Vim. That seems just the, or at least Vim 8, that seems to be the way to go for Vim these days and this seems to be a better option overall. And then the next thing that I decided to go with this was to start installing some plugins to set stuff up. I went with VimPlug. I was very happy with it. I've used it before and it was overall really solid. And so what I'm going to be doing is kind of switching back and forth between Notion where I have some notes of kind of what I set up. And then also I have here my init.vim, which is just the NeoVim config file. And then you can see over here, over here, look at that, I have basically the keys that I'm typing. So you can see the hotkeys that I'm using for this. I'm also using tmux that I'm going to be just like switching between the two files here. So if you see control B here, this is my leader to switch between just emulators or terminals. So that's tmux if you're wondering what that is and why I'm pressing control B to switch back and forth. Alright, so this is the start of my configuration file where I just declare all the plugins. So this is what VimPlug does or how the syntax for it works. And here you can see these are each plugins that I have added. Now the most important one to get started with to start getting some of the VS Code features is this one called conquer of completion or just COC.inVim. So I have him added right here. And once you install this guy, he's pretty neat. So let's hop on over to the code and I can show you some of the stuff we can get with this. So you can see right here I'm importing a function called create tokens. I'm just going to delete that. And then I'm going to start typing and notice I'm getting some auto completion here. So this is thanks to that particular plugin. And I can also see on the right over here some definition of, for example, that this is a prompt. It returns a promise. This create connection function. So it's integrating nicely with TypeScript too. But anyway, I can type my create tokens and I can hit enter. You're going to see it finishes the word for me. It also automatically imports it, which is super sweet. And you can see here, I can see just definition as well that it takes a user as a parameter. So I can pass in a user, whatever I want. So this detection also we can see right here that a little pop-up telling me that I don't have a user defined. So this is all using that particular plugin. Now how this plugin works is you actually need to get a language server or it's running a language server in the background. And if I just search him and hop over here, we'll talk about Prettier in a second. These are the extensions that I'm using with it. So you install that base plugin and then it comes with other extensions that you can add into it. So I here have a JSON configuration, Prettier, ESLint, TypeScript server, pairs and snippets. Pairs, this is, it's going to complete my paren there, my parenthesis. Snippets, I'll show that real quick, is for example, if I do CL, you can see this is a custom snippet I did to do console log. And how I did that is if I say, actually forget what the command for this is, I think I have it right here. Yeah. Let's copy this. Oops. So if I run this command here, install snippets, actually I don't want to install it. I want to run this one. That command that I just ran there is how you can individually install extensions. The one that I want is this one right here. So this is the edit snippets. I can see this is my snippets file and this is how you add a snippet using it. So I gave it the prefix CL and then I can use it in my code using auto-completion. Close out. There we go. So that's pretty nifty. Another thing that I use with this is GD, which is go to definition. So I'm hovering over this function here and you can see it actually took me to a separate file here. This is where the create tokens function came from. If I press control O, I hop back here. I'm still kind of getting used to all the different hotkeys that I'm pressing in now. So that's a bear with me there. But there you go. So that's go definition. Also if I press command K, I can bring up my definition here for the particular function. I can also do it for whatever I want. And let's see, was there anything else I want to show with this? I showed go to, I showed these two, and control space is what I actually bound. Actually I think it came by default. So like for example here, you see how the auto-completion window is not open? Control space will open this for me. Alright, so I'm going to just press GD here, go to here, and I'm going to press F2 to rename this. So another thing that I did is I tried to keep the hotkeys the same as VS Code. That way I could switch between them if I needed to. So F2 is rename in VS Code as well. So I'm going to rename create tokens to create tokens 2. I'm going to hit save, and now if I go back, control O, you can see it actually renamed this everywhere. So you get that same cool effect where you get auto-completion, auto-imports, rename everywhere, all that fun stuff you get in VS Code with this function. So it's super powerful and super nifty. I really like it. The other thing that I have integrated with it is prettier. So that's an extension that I add to it. So you can see here I can make it ugly. And I have it running on save. So when I hit W, it'll actually format everything for me. Just to show you how I have that, all the stuff that I have here, this is a whole bunch of configuration that I just copy and pasted. There's actually a lot of it copy and pasted from the README. All this stuff is from that. And I think I had to do a particular thing for prettier if I go up here. I don't remember. Yeah, I actually need to put it down there. I don't know why I have it all the way up here. But I had to define a command here called prettier. That way when I automatically save the file, it'll run this command. And there's actually this other thing. I haven't actually mentioned this yet, but let's open up just a separate terminal here. And this is using tmux, by the way, so that's not a Vim thing. So we'll just open up config slash nvim slash preferences. Actually there we go. So this is another file that you can create to kind of give settings for the language server. So you can see I have no select set to false. This one is, I actually don't even remember what no select does, but I just remembered that was one of the settings that I liked to match with VS Code. And this one you can see I set prettier to format on save for these file types. So those are the things I'm doing. And you can see that I can actually switch between these two tmux windows. That's using a plugin, this one, vim tmux navigator. It's pretty sweet. I can push control L to go to the, actually, yeah, to go to the right and control H to go to the left. I was confused for a second. I was like, why is control L to the right? But that is how it works. All right, we'll close that and we'll close that. I just remapped, I had to change my leader for tmux. That's why I like, it feels a little awkward to push control B right now. So yeah, so this is really the main plugin that's going to give you like that awesome VS Code auto completion and just auto everything. That is super fun about it. So I showed you, I think, everything related to that and the preferences and all that. The next thing is my theme. So this is really just a small thing. I actually really liked the VS Code default dark plus theme. And unfortunately, I couldn't get like a similar one that worked nicely, where it actually colored things the same. So what I did instead was went with grovbox. This is another favorite of mine. And so that's this plugin. And this is what it looks like. You saw the syntax highlighting for this. This is another one. But one thing I noticed when I add this plugin, it actually looks super ugly by default. I need to add a language syntax plugin. So I installed this TypeScript syntax plugin, YATS, and it's been working great. It's been syntax highlighting stuff correctly. So that's the combination I'm using for just the color and what it looks like. Next up is NerdTree. So this is how I got files to show up, or a file tree. So let's go back to my structure here. So I have it Control N, and you can see here's my file tree. Now I have a few extra things going on besides just like a default NerdTree configuration, which we're going to get to in a second. I think it's a default bind, either Control N is, or they had me, yeah. Right here I added a bind Control N opens up, or toggles the tree. Okay, so the other things that I installed, so what this comes with is just a basic tree where you can click files. So I can click this, open up the file. Now the way I actually navigate between these two trees is actually with the vim-tmux-navigator. So I'll actually push Control L to go to the right and Control H to hop back and forth. So that's how I hop between the tree. So yeah, I can press these to open and close files and whatnot, and you can do all your file tree related stuff in here, I'm not going to go through all that stuff. Now one of the nice things that I really like about the file tree in VS Code is that they color code it. So you can see here that I've made a change in index, and so I can see that it's red, and I can also see that it basically has some errors in it with the TypeScript compiler, and that's why it's red too. Now if I make a change in auth, for example, and it's a good change, like we'll just console.log hi, and I go to another file, it's going to turn, I don't know what color this is, like an orange-yellow thing, tan. So that's really nice. And basically in my mind I have this color association where I know whether a file is modified, deleted, new, that sort of thing, and it's super handy. So it integrates with Git. So I wanted to see if I could get a similar thing going, and I could get kind of a similar thing going. So there's this plugin called, not this one, well it kind of integrates with this, but it's called a NerdTree Git plugin. There's two of them. So there's this one by this dude, let's put them together, and let's bring this guy down here. All right, so these are the three plugins, well these four that really kind of go together with NerdTree here. So these two you can see are doing the exact same thing. This one I could not get working properly. And this one actually maps colors to the files, but for a reason it never looked correctly on mine. I don't know if it's because I have grovbox, didn't conflict with that theme, I tried disabling it, I tried a whole bunch of stuff, couldn't get it working, so I just settled for this one. And so what this one does is it does little icons next to it. So you can see I have actually touched the index file, and I have touched the auth file, and you just see these modified, and we can see these X's up here for the folder tree. So they have these little symbols. I don't like the symbols quite as much as the color coding, but I'll compromise there. So that is what this plugin here is doing, is it checks a git, and it basically sets an icon next to the folder tree. And for this to work, it also uses this syntax highlighting one, well actually, the syntax highlighting one I installed with this, so maybe I don't need this one. We'll see. And you can see here I have a thing to comment stuff out, we'll talk about him in a second. And then there's this plugin called dev icons. That's where you can see I have like TS and these sort of things going. Now to get that working was kind of interesting, because my font wasn't supported by default, so I had to go to, I'm using iTerm2, so I went to my preferences, and I actually installed a new font specifically for, let's go to this, specifically for this, it's a nerd font. So I installed this font here, tying out ligatures, I'm not sure if I actually like them or not, but I am trying them out. But yeah, so I had to actually install a separate font, and if you go to the readme of this guy, of dev icons, you can read about where you go to actually install the font. But after I installed the font, it worked correctly, and I can see these little extensions here now. So that's what these do. So I got like a decent file tree going on there with NerdTree, it's quite nice. But that's not the only way that I actually, oops, I kind of, I just reopened that, I was like what did I just do? That's not the only way that I actually like to navigate. So I also like to navigate, well actually I'll show that in VS Code first. Command P opens up this little window here, where I can like, you know, go to different files, and it's a fuzzy finder of files. So for that, there is this plugin that I got called Control P, and so it works the same way. So I hit, I actually did a special binding to Command P as well so it matches, and so I can type a file in here, auth, and then I can switch to it, it's been changed, yeah it's fine. And I can switch to the file. And I noticed one thing that I did is I have my NerdTree highlight the file that I have open here, that actually took a special configuration as well. So that's what this, I did like a little bit of code here, where did I put it? I haven't organized this quite too well yet. While I'm at it though, this is one thing I added, I had NerdTree ignore node modules, and I also had my fuzzy finder of files ignore all files that are ignored by git, and that's what this command does. Ignores stuff in gitignore. I think I put it down here, yeah here it is. So I have this two functions, isNerdTreeOpen and syncTree in this buffer inner theme of Aubur. What they do is whenever I switch files using Command P and I type resolver, you'll see it highlights it here on the left automatically. So that is what that's doing. So that's pretty nice, this is the way I like to navigate. Now getting Command P to work was actually kind of interesting. So if I go to, and this is just kind of an iTerm2 thing and a Mac specific thing, because the command keys doesn't really bind well. So what I actually do is when I hit Command P, it actually sends colon control P, so it actually basically hits colon here and actually types out control P and launches it like that. So that's how it actually got, I map Command P, I actually did it through iTerm and not through them. And I did basically a similar thing with my commenting out stuff, which we're going to talk about in a second. But yeah, so that's fuzzy finding files, so that's pretty handy, and this is just a fun way that I like to navigate, similar to how you could do it in VS Code. Okay, so that is how I find files and stuff. Let's talk about this guy, I haven't talked about my commenter out yet. So I bound this to Command Slash, this is the same way you do it in VS Code. So I can select files and it comments them out. It's this plugin right here, Nerd Commenter, and to get him working, I mapped plus plus, I just picked an arbitrary keystroke that I was never going to use. And it calls this function, and then my iTerm2Preferences, profiles, no, keys, key bindings, I have Command Slash send plus plus, and it triggers that. And so I can select groups of code and Command Slash to do that. And we can hop over here and we can do it with a real piece of code if we want to. Command Slash, comment it all out. File has changed since reading it, do you really want to write it? Yeah, I do. Alright, so that's handy. What else do I have? I talked about that, and okay, so this is pretty much the last thing, is the gutter. So in VS Code, I can know where in my file I've changed stuff with this little gutter here. So I can see I've added these lines here, I can see I modified this line because it's blue, it's color coded and stuff, go to my resolvers. I thought maybe there was a red one, maybe red only shows up on the right over here, it's quite small too. But there you go, it color codes it. So this gutter plugin, where is it here, this one here, gets the same effect. So here, you can see it's a little squiggly, and if I go to my index, you can see it's squiggly here. And how it works is, I think my leader is this, slash, I actually forgot, I think it's HP maybe, no, I actually totally forgot what my key for this is. Basically there's some key combination that I can press to get this effect. Same as clicking here, and I can see the diff. I forget what my key combination is, I haven't memorized it yet for that. But yes, so I was able to get that with the gutter, that's pretty sweet, so I like that a lot. So this one I do remember, I can actually go to the next one by pressing the little bracket there, so bracket, actually I press bracket once, and then I press C, and it'll take me, well bracket C, bracket C, bracket C, and what it does is it just takes me to the next modified line, so that's a pretty handy one. So this gutter was pretty nice, and again that's another one that integrates with git and tells me which line has changed. So there you go, that is my configuration with all the plugins that I end up installing to get this working. I'm going to put this entire file again in the description if you want to check out any of it. I think we went over most of it that was of relevance, besides just a bunch of junk in there. And really the conclusion I came down to playing around with this is, it was actually really nice at first, and I forgot how nice it is to just type without lag. So like the Vim stuff is really snappy, and when I press stuff and move around it's really responsive, which was just quite a nice change from using VS Code Vim emulation for a while. And so I like that a lot, but everything else just feels like slightly worse than the VS Code version, which I'm kind of like eh about, but like I'm okay with. But I think the biggest thing that I ran into is the server, or the TypeScript server, language server works great with small stuff at first, like this, but I found when I tried doing this in a large project, and maybe I just need to configure the language server, is it was lagging just as bad as VS Code was. So I think the real problem I'm running into is these language servers don't work well for large projects, or at least I'm not configuring them well, or I'm doing something wrong that makes them really slow and really unresponsive, because I was getting problems with Vim just as bad too, which was unfortunate because it was working really nice at first. So yeah, I'm basically running into the same problem with basically the language server does not work as well as I'd like it to, at least the TypeScript one. So I'm not sure if I'm going to continue using this Vim setup, although it is pretty sweet. But yeah, that's pretty much it. I'll probably be switching back to VS Code still, but this is what I would do if I was going to be using Vim today. But I'm getting the same lag, I might as well try to fix it in VS Code. But yeah, that's pretty much where I'm at with it. Thanks for watching. See you next time.