vimtricks.wiki Concise Vim tricks, one at a time.

How do I use Harpoon to bookmark project files and jump between them instantly?

Answer

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

Explanation

Harpoon by ThePrimeagen is a Neovim plugin that maintains a small, numbered list of the files you're actively working on. Unlike buffers or marks, Harpoon gives you a persistent, project-aware shortlist — you can jump to file 1, 2, 3, or 4 with a single keystroke, no matter what buffer you're currently in.

How it works

Harpoon stores a per-project list in your Neovim data directory. The core workflow is:

  1. Mark a file — add the current file to the Harpoon list:
    :lua require('harpoon.mark').add_file()
    
  2. Open the quick menu — view and reorder the list:
    :lua require('harpoon.ui').toggle_quick_menu()
    
  3. Jump to a specific file by index:
    :lua require('harpoon.ui').nav_file(1)  " jump to file 1
    :lua require('harpoon.ui').nav_file(2)  " jump to file 2
    

The quick menu is a regular Neovim buffer — you can reorder lines, delete entries with dd, and save with :w.

Example

You're refactoring an API and bounce between four files constantly. Add each to Harpoon:

" In routes.lua
:lua require('harpoon.mark').add_file()
" In handler.lua
:lua require('harpoon.mark').add_file()
" In schema.lua
:lua require('harpoon.mark').add_file()

Now map the jumps in your config:

local mark = require('harpoon.mark')
local ui = require('harpoon.ui')
vim.keymap.set('n', '<leader>a', mark.add_file)
vim.keymap.set('n', '<C-e>', ui.toggle_quick_menu)
vim.keymap.set('n', '<C-1>', function() ui.nav_file(1) end)
vim.keymap.set('n', '<C-2>', function() ui.nav_file(2) end)

Jumping between files is now instant — no :buffer, no fuzzy search, no delay.

Tips

  • The list is project-specific: Harpoon detects the project root (via git) and maintains separate lists per project
  • Use nav_next() and nav_prev() to cycle through the list in order
  • Harpoon v2 has a revised API; the concepts are identical but the require paths differ (harpoon:list() instead of harpoon.mark)
  • Pairs naturally with a fuzzy finder (like Telescope) for broad file search, while Harpoon handles your hot files

Next

How do I show both the absolute line number on the current line and relative numbers on all other lines?