Check out a free preview of the full VIM Fundamentals course

The "harpoon" Lesson is part of the full, VIM Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen discusses an ideal vim setup using harpoon and vim-fugitive as examples. An ideal vim experience should have everything one click away and flow naturally.


Transcript from the "harpoon" Lesson

>> I can't kind of came up with one idea, and I can show everyone this one. I have been working on this one for a while just kind of trying to figure out how to formalize what it is and it's called harpoon. And the general idea is that there's two things you want.

A harpoon is a very specific and very precise instrument right? You get one chance, you load it up, you shoot it, if you miss, it's completely, it's like it's worthless, right? You have to reel it back in to get the weapon. So harpoon has this notion of being very, like precise and that's kind of how I kinda came up with this is.

All right, I want to be able to go to a terminal and I want that terminal to remain in memory and I wanna be able to go to it over and over again or send commands to it. And I wanna be able to pre specify per project, the commands I want to be able to send to a terminal to go and execute, right?

Because if you're in the terminal, you can use that output and bring it back into them if it's a terminal within them. And so when I press leader tu, it will actually take me to a new terminal if I don't have one created, if I already have one created, and say I leave and go back goes phase tu, it will go back to that created terminal so I can keep things running.

If I have commands being sent, I can use things like that. I don't have any commands right now, right? And look, there's kind of like a little bit of a bug, right? I can send a list of commands off to this terminal and it will do it right in front of me.

And that's because it's just linked into this. So every one of my projects, I tend to have a build command. So I just do space cu to build it. I don't have to think about it, I already know what's gonna happen. I already know what's gonna happen correctly in the terminal.

The terminal is not created, the terminal will be created and hydrated with all the correct environment and done for me. I just don't have to think about it. I think that that's what makes ideal vim plugins are ideal vim usage. Is just stop with all this overhead processing.

So then another part about harpoon is, and I know I'm specifically talking about this one plugin, but there's a lot of plugins that do this, is that you're able to also navigate to files that you've previously marked. So I have this notion of marks, but they're living marks.

They live across sessions, and they don't actually mark a specific place, they're wherever you were at when you were last in the buffer. And so if I wanna go to there's a terminal bug, right? So I'm right here, I'm in this terminal, if I do buffer delete, it'll actually delete that terminal.

And if I try to go back to that terminal, it goes, hey, I tried to navigate there, but it's actually been deleted. So here's a bug in my program, and I want to fix it. With harpoon, I already know that if I do Ctrl first finger power finger, right I'll go to my first marked file, which is the marks actual program that I've made to do all the marking and moving.

If I do the second one, I'll go to the terminal file. So I already knew before I was ever even in here, if I jumped in here oopsies that's what I typed in the previous terminal. That's vim c then dot, there we go. If I just did Ctrl+t, I'd go right to the terminal file.

I'm already there. I am now on my way to fixing the bug, right? It's just this thing where I can have a set of marks that are the files that I'm working on. When I quit, and I go out and I go into work and I go into say the television device for Netflix, I can do any of these files, which I've just unfortunately redid on this.

Dang it, I just redid all my, redid this whole thing so now they don't work anymore. But I had all the text-to-speech things all right on my fingertips because that's been what I've been working on for the last couple of weeks. So now whenever I go in there and I had to go in there many times, I was able to just jump to the files I really needed, and the rest I just use the language server protocol cuz most of the things you do in vim you're using jump to definition, right?

So if you're in a large JavaScript project, here's one right here, and I'm looking at http2, I'm not gonna try to go and search the project for the string. Instead, I'm gonna use a language server to tell me where everything's at, right? And now I can use my quick fix navigation to walk through all the occurrences.

Notice that I'm not thinking about doing the thing, I'm doing the thing, right? That's because I've made everything be what I consider the vim way. Everything I want to do is one to two keystrokes, exactly what I want. Sometimes there are three keystrokes and I don't like that but it happens, right?

I can jump to definition. I can see where it's being used at, I can actually search the project for that string specifically by doing a project word. I can jump out of here and do a project search for whatever I want, it will come back with the list itself.

And so everything is like really tightly woven together to be able to navigate fast. But there's a few files that I'm specifically working on I can just jump to it right? I jumped right away to my frame parsing test cuz that's what I'm working on right now for HTTP2, right?

I'm gonna go in here and I'm gonna make sure that the frames all being parsed correctly. And this will always be on there, I can always jump to it. So when I go hey, what is this thing? I'm gonna jump to the definition, I'll just jump back to my work file, right?

And so that's what I kind of think is the ideal way of just working in general with vim. Is trying to get to that point where everything's one click away. Even the files you're working on, are one click away, and so let's just do a quick one. I'm gonna walk through a couple things that are pretty cool about that.

I'm gonna jump in here and jump to the file I want it to be. I know for a fact it's during the creation. And I can see right here that I grabbed the term handle, and I go, hey, if there's no term handle at this location, meaning when I try to open up a terminal at this index, yeah, then I create a terminal.

What happened if that terminal has gone bad? Well, I should probably be doing some sort of something like or vim.api.nvim_buff_is_valid, right? It's still exists. I should be checking that too cuz if I'm not doing that, then of course I ran into that bug I just showed you. Buff id there we go.

And if we do this, this technically should fix the problem. But I also can send commands right? Look, I do pretty much the exact same thing right here. If I'm sending commands I shouldn't probably make sure that we're doing that. I should do some sort of like or do this but that feels a little bit bad.

So what happen if I just delete this, right, go back up here, let's delete this thing and let's create a function, let's paste that stuff in so I don't lose it. function_find_terminal, right we can do by index, index there we go, and 11 down to that and boom.

And now I can do find terminal and I've just done it for both locations. Do that that Yep, place that go here For up, paste that in, there we go. We got everything we effectively needed. We have at all I'm now doing it right here five down, return term, handle awesome.

And then if I look at my registry history if I'm not mistaken, notice that I did have that at one point it's in register one. So I actually need to go back up here. Go here go quotes one paste. I now have that original line. Awesome, right? Like I got everything I need in here.

I believe I just live fix this. So I can just take this stage it, cc it, not even looking feature, first try right, there we go. I'm using vim fugitive, which is another one of these one press, like it just does what I want it to do. No, look at this, I just realized that I don't have these things hooked up correctly.

So I'm gonna quickly go in here, I'm gonna go up to term bug, I'm gonna rebase off that. Dang it, I have a conflict what happened in here? All right, so let's reopen up my status window. So I have a conflict, I could choose mine or choose theirs or I could just let's look at the split.

What went wrong here, right? Obviously this is very zoomed in, so it's probably pretty hard for you to be able to see these things but in the end, I can go all right, which one do I want? Well, I probably want the one that's on on my side right on, right there, the one right there.

So I already have a keyboard shortcut to go pick that side, and it will go and it will pick that side for me. I'm like, yes, that's the side I want to do. And now it looks like, all my conflicts are done, I don't need to do that anymore.

I can go there, we can go back to here, close it all down, commit it, you'll see that it's no longer there. Everything was kinda done in these one little click processes where I'm able to go through one step at a time, click a couple buttons and do large amounts of actions really quickly.

And then in the end cc feature, not this we don't wanna do that forgot about that. We wanna go Git_rebase continue. I don't have that one yet, cuz I don't do a lot of rebase is that and then conflicts and then Git_push origin since we're doing a force, let's do it.

Let's just force it right here. Boom, we have it up there, I can go make a PR. We're done, fantastic. And so I just wanted to show you some of that workflow. This is how I do a lot of my workflow. And notice I dint even have a language server set up for Lua and I was able to do a huge amount of work.

I was able to go to exactly where I wanted to go, I was able to get all the things done. And so when I'm working with things that have really nice language servers, such as C++ or TypeScript or Go, it becomes incredibly simple cuz I have a couple files that I've marked that I always wanna return to.

Plus the what 50 files I'm gonna go jump around in trying to find what I want.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now