• Stars
    star
    5,055
  • Rank 7,838 (Top 0.2 %)
  • Language
    Lua
  • License
    MIT License
  • Created over 3 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Harpoon

Getting you where you want with the fewest keystrokes.

Lua Neovim

Harpoon -- image provided by Bob Rust

โ‡ WIP

This is not fully baked, though used by several people. If you experience any issues, see some improvement you think would be amazing, or just have some feedback for harpoon (or me), make an issue!

โ‡ The Problems:

  1. You're working on a codebase. medium, large, tiny, whatever. You find yourself frequenting a small set of files and you are tired of using a fuzzy finder, :bnext & :bprev are getting too repetitive, alternate file doesn't quite cut it, etc etc.
  2. You want to execute some project specific commands or have any number of persistent terminals that can be easily navigated to.

โ‡ The Solutions:

  1. The ability to specify, or on the fly, mark and create persisting key strokes to go to the files you want.
  2. Unlimited terminals and navigation.

โ‡ Installation

  • neovim 0.5.0+ required
  • install using your favorite plugin manager (vim-plug in this example)
Plug 'nvim-lua/plenary.nvim' " don't forget to add this one if you don't have it yet!
Plug 'ThePrimeagen/harpoon'

โ‡ Harpooning

here we'll explain how to wield the power of the harpoon:

Marks

you mark files you want to revisit later on

:lua require("harpoon.mark").add_file()

File Navigation

view all project marks with:

:lua require("harpoon.ui").toggle_quick_menu()

you can go up and down the list, enter, delete or reorder. q and <ESC> exit and save the menu

you also can switch to any mark without bringing up the menu, use the below with the desired mark index

:lua require("harpoon.ui").nav_file(3)                  -- navigates to file 3

you can also cycle the list in both directions

:lua require("harpoon.ui").nav_next()                   -- navigates to next mark
:lua require("harpoon.ui").nav_prev()                   -- navigates to previous mark

from the quickmenu, open a file in: a vertical split with control+v, a horizontal split with control+x, a new tab with control+t

Terminal Navigation

this works like file navigation except that if there is no terminal at the specified index a new terminal is created.

lua require("harpoon.term").gotoTerminal(1)             -- navigates to term 1

Commands to Terminals

commands can be sent to any terminal

lua require("harpoon.term").sendCommand(1, "ls -La")    -- sends ls -La to tmux window 1

further more commands can be stored for later quick

lua require('harpoon.cmd-ui').toggle_quick_menu()       -- shows the commands menu
lua require("harpoon.term").sendCommand(1, 1)           -- sends command 1 to term 1

Tmux Support

tmux is supported out of the box and can be used as a drop-in replacement to normal terminals by simply switching 'term' with 'tmux' like so

lua require("harpoon.tmux").gotoTerminal(1)             -- goes to the first tmux window
lua require("harpoon.tmux").sendCommand(1, "ls -La")    -- sends ls -La to tmux window 1
lua require("harpoon.tmux").sendCommand(1, 1)           -- sends command 1 to tmux window 1

sendCommand and goToTerminal also accept any valid tmux pane identifier.

lua require("harpoon.tmux").gotoTerminal("{down-of}")   -- focus the pane directly below
lua require("harpoon.tmux").sendCommand("%3", "ls")     -- send a command to the pane with id '%3'

Once you switch to a tmux window you can always switch back to neovim, this is a little bash script that will switch to the window which is running neovim.

In your tmux.conf (or anywhere you have keybinds), add this

bind-key -r G run-shell "path-to-harpoon/harpoon/scripts/tmux/switch-back-to-nvim"

Telescope Support

1st register harpoon as a telescope extension

require("telescope").load_extension('harpoon')

currently only marks are supported in telescope

:Telescope harpoon marks

โ‡ Configuration

if configuring harpoon is desired it must be done through harpoons setup function

require("harpoon").setup({ ... })

Global Settings

here are all the available global settings with their default values

global_settings = {
    -- sets the marks upon calling `toggle` on the ui, instead of require `:w`.
    save_on_toggle = false,

    -- saves the harpoon file upon every change. disabling is unrecommended.
    save_on_change = true,

    -- sets harpoon to run the command immediately as it's passed to the terminal when calling `sendCommand`.
    enter_on_sendcmd = false,

    -- closes any tmux windows harpoon that harpoon creates when you close Neovim.
    tmux_autoclose_windows = false,

    -- filetypes that you want to prevent from adding to the harpoon list menu.
    excluded_filetypes = { "harpoon" },

    -- set marks specific to each git branch inside git repository
    mark_branch = false,

    -- enable tabline with harpoon marks
    tabline = false,
    tabline_prefix = "   ",
    tabline_suffix = "   ",
}

Preconfigured Terminal Commands

to preconfigure terminal commands for later use

projects = {
    -- Yes $HOME works
    ["$HOME/personal/vim-with-me/server"] = {
        term = {
            cmds = {
                "./env && npx ts-node src/index.ts"
            }
        }
    }
}

โ‡ Logging

  • logs are written to harpoon.log within the nvim cache path (:echo stdpath("cache"))
  • available log levels are trace, debug, info, warn, error, or fatal. warn is default
  • log level can be set with vim.g.harpoon_log_level (must be before setup())
  • launching nvim with HARPOON_LOG=debug nvim takes precedence over vim.g.harpoon_log_level.
  • invalid values default back to warn.

โ‡ Others

How do Harpoon marks differ from vim global marks

they serve a similar purpose however harpoon marks differ in a few key ways:

  1. They auto update their position within the file
  2. They are saved per project.
  3. They can be hand edited vs replaced (swapping is easier)

The Motivation behind Harpoon terminals

  1. I want to use the terminal since I can gF and gF to any errors arising from execution that are within the terminal that are not appropriate for something like dispatch. (not just running tests but perhaps a server that runs for X amount of time before crashing).
  2. I want the terminal to be persistent and I can return to one of many terminals with some finger wizardry and reparse any of the execution information that was not necessarily error related.
  3. I would like to have commands that can be tied to terminals and sent them without much thinking. Some sort of middle ground between vim-test and just typing them into a terminal (configuring netflix's television project isn't quite building and there are tons of ways to configure).

Use a dynamic width for the Harpoon popup menu

Sometimes the default width of 60 is not wide enough. The following example demonstrates how to configure a custom width by setting the menu's width relative to the current window's width.

require("harpoon").setup({
    menu = {
        width = vim.api.nvim_win_get_width(0) - 4,
    }
})

Tabline

By default, the tabline will use the default theme of your theme. You can customize by editing the following highlights:

  • HarpoonInactive
  • HarpoonActive
  • HarpoonNumberActive
  • HarpoonNumberInactive

Example to make it cleaner:

vim.cmd('highlight! HarpoonInactive guibg=NONE guifg=#63698c')
vim.cmd('highlight! HarpoonActive guibg=NONE guifg=white')
vim.cmd('highlight! HarpoonNumberActive guibg=NONE guifg=#7aa2f7')
vim.cmd('highlight! HarpoonNumberInactive guibg=NONE guifg=#7aa2f7')
vim.cmd('highlight! TabLineFill guibg=NONE guifg=white')

Result: tabline

โ‡ Social

For questions about Harpoon, there's a #harpoon channel on the Primagen's Discord server.

More Repositories

1

init.lua

Lua
2,727
star
2

vim-be-good

vim-be-good is a nvim plugin designed to make you better at Vim Movements.
Lua
2,692
star
3

.dotfiles

Perl
2,611
star
4

refactoring.nvim

The Refactoring library based off the Refactoring book by Martin Fowler
Lua
2,465
star
5

kata-machine

TypeScript
1,041
star
6

git-worktree.nvim

Lua
613
star
7

ts-rust-zig-deez

Java
520
star
8

htmx-lsp

its so over
Rust
454
star
9

tyrone-biggums

Clearly a repo about websockets and their comparison...
ReScript
450
star
10

anime

The repo that everyone deserves
448
star
11

vim-royale

Because Nano sucks
Rust
406
star
12

vim-apm

Vim APM, Actions per minute, is the greatest plugin since vim-slicedbread
Lua
282
star
13

neovimrc

Lua
261
star
14

CHADstack

Dockerfile
252
star
15

keyboards

239
star
16

fem-algos

FrontEnd Master algorithms!
JavaScript
237
star
17

undefined

A project to turn a file of JSON responses into TypeScript types
TypeScript
231
star
18

rust-for-typescript-devs

JavaScript
207
star
19

ansible

Dockerfile
203
star
20

primestack

Rust
135
star
21

ThePrimeagen

109
star
22

vmrss

Shell
83
star
23

web3-smart-contracts

JavaScript
82
star
24

BunSpreader

We spread the buns
Zig
74
star
25

vim-with-me

Rust
73
star
26

fem-algos-2

The Last Algorithm Class You Want
JavaScript
68
star
27

jvim.nvim

A simple json traverser for NeoVim
Lua
67
star
28

aoc

2020
Rust
63
star
29

vimrc

62
star
30

yew-have-ligma

Elixir
61
star
31

htmx_golang

Go
57
star
32

orgwasm

CSS
55
star
33

2-simple-steps

Its literally that simple
TypeScript
54
star
34

fem-htmx-proj

Go
47
star
35

coin-toss-me-daddy

Rust
44
star
36

js-perf-example

TypeScript
40
star
37

vim-nav-playground

C
39
star
38

htmx-class-template

The starter template with server in go or rust
Rust
39
star
39

lsp-debug-tools.nvim

this probably isn't the droid you are looking for
OCaml
35
star
40

neural-js

A kick-ass neural network for javascript
JavaScript
34
star
41

leftPadDeez

nuts
JavaScript
34
star
42

yt

All my yt videos that require to have some codes.
TypeScript
32
star
43

rusty-arduino

Rust
31
star
44

titty-sprinkles

Yes... This is the name for my NodeConfEU project
TypeScript
30
star
45

htmx-subscribe

HTML
28
star
46

htmx

Rust
27
star
47

public-edging

Rust
26
star
48

jpegdegens

TypeScript
26
star
49

beat-me-daddy

I put my sonic in my pi
Rust
26
star
50

ts-go-rust

JavaScript
26
star
51

go-vs-rust

The greatest cli comparison ever created
Elixir
26
star
52

uhh

When you keep forgetting those sweet sweet sweet sweet commands.
Go
25
star
53

best-of-stackoverflow

A DRAMATIC READING OF STACK OVERFLOW
23
star
54

objects-to-buffer

TypeScript
23
star
55

bun-vs-node

TypeScript
22
star
56

fem-htmx

JavaScript
22
star
57

rust-wasm-serverless

Rust
21
star
58

json-vs-proto

TypeScript
20
star
59

no-flap-november

the greatest
Go
19
star
60

gspot

Rust
18
star
61

fem-jsperf

JavaScript
18
star
62

ts-go-rust-projector

TypeScript
17
star
63

ocaml-aoc

OCaml
16
star
64

i-fixed

16
star
65

shooter-js

TypeScript
15
star
66

vim-deathmatch

Rust
15
star
67

milo

TypeScript
15
star
68

zig-deez-structures

Zig
14
star
69

big-chungus

is amungus
TypeScript
13
star
70

this-isnt-rust

There is no rust in this suppository
TypeScript
13
star
71

your-first-plugin

Example NeoVim Lua Plugin
Lua
12
star
72

tree-navigation

Lua
12
star
73

more-htmx-eploration

Rust
12
star
74

javascwipt-performance

suck it piq
TypeScript
12
star
75

why-are-promises-slow

they are
11
star
76

real-prog-dvorak-zmk

Rust
11
star
77

tier-list

HTML
11
star
78

projector

Project my config into your prebuild
Go
10
star
79

dev

my next gen build for starting my system
Shell
10
star
80

cargo-chadr

Rust
10
star
81

test-these-besties

Go
10
star
82

chat-js

Rust
9
star
83

he-uses-tabs

Rust
8
star
84

neovim-irc

C
8
star
85

git-bisect

JavaScript
8
star
86

rxjs-examples

JavaScript
7
star
87

jest-mem-test

JavaScript
7
star
88

todo

yes
C++
6
star
89

first-deno-project

JavaScript
6
star
90

fizzbuzz

A real programmers fizzbuzz
JavaScript
6
star
91

ansible-dev-prod

Dockerfile
6
star
92

99-ocaml-problems

6
star
93

neovim-irc-ui

Lua
5
star
94

first-nvim-plugin

The template for writing your first nvim plugin
5
star
95

the-hoff

9000
TypeScript
5
star
96

mini-wasm-env

When full wasms just wont due
C
4
star
97

crypto-legends

Like Apex Legends. Just more, better, faster, and less recoil
Go
4
star
98

keyboard

Simple keyboard
JavaScript
4
star
99

fem-vim

Vim Script
4
star
100

flatbuffers-benchmarks

The hello server that will take in either flatbuffs or json and add one to the `count` field, then resend the data back through the socket connection.
JavaScript
4
star