Skip to main content

Overview

Harpoon is a lightning-fast file navigation plugin that lets you mark important files and quickly jump between them. Think of it as bookmarks for your most frequently accessed files in a project. Plugin: ThePrimeagen/harpoon (branch: harpoon2)

Features

  • Mark/bookmark important files for quick access
  • Toggle quick menu to see all marked files
  • Navigate forward and backward through marked files
  • Remove files from the mark list
  • Lightning-fast file switching
  • Per-project mark lists

Configuration

Harpoon is configured in lua/magictt/plugins/harpoon.lua:
return {
  "ThePrimeagen/harpoon",
  branch = "harpoon2",
  dependencies = { "nvim-lua/plenary.nvim" },

  config = function()
    local harpoon = require("harpoon")
    harpoon:setup()
    
    -- Register with which-key
    require("which-key").add({
      { "<leader>h", group = "Harpoon" },
    })

    -- Add file to Harpoon list
    vim.keymap.set("n", "<leader>ha", function()
      harpoon:list():add()
    end, { desc = "Harpoon: Add file" })
    
    -- Toggle quick menu
    vim.keymap.set("n", "<C-e>", function()
      harpoon.ui:toggle_quick_menu(harpoon:list())
    end, { desc = "Harpoon: Toggle menu" })
    
    -- Navigate to previous file
    vim.keymap.set("n", "<C-p>", function()
      harpoon:list():prev()
    end, { desc = "Harpoon: Previous file" })
    
    -- Navigate to next file
    vim.keymap.set("n", "<C-n>", function()
      harpoon:list():next()
    end, { desc = "Harpoon: Next file" })

    -- Remove current file from list
    vim.keymap.set("n", "<leader>hr", function()
      harpoon:list():remove()
    end, { desc = "Harpoon: Remove current file" })
  end,
}

Keybindings

Primary Keymaps

KeymapActionDescription
<leader>haAdd fileAdd current file to Harpoon list
<C-e>Toggle menuOpen/close Harpoon quick menu
<C-p>PreviousNavigate to previous marked file
<C-n>NextNavigate to next marked file
<leader>hrRemoveRemove current file from Harpoon list

Inside Harpoon Menu

When the quick menu is open:
KeyAction
<CR>Open selected file
ddDelete entry from list
j/kNavigate up/down
q or <Esc>Close menu

Usage Examples

Basic Workflow

  1. Mark your important files:
    • Open a file you want to bookmark
    • Press <leader>ha to add it to Harpoon
    • Repeat for 3-5 files you frequently switch between
  2. View your marks:
    • Press <C-e> to see all marked files
    • The quick menu shows file names and paths
  3. Navigate between marks:
    • Press <C-n> to go to the next file
    • Press <C-p> to go to the previous file
    • Or use <C-e> to open the menu and select directly

Add Current File

vim.keymap.set("n", "<leader>ha", function()
  harpoon:list():add()
end, { desc = "Harpoon: Add file" })
Open a file and press <leader>ha to add it to your Harpoon list.

Quick Menu Navigation

vim.keymap.set("n", "<C-e>", function()
  harpoon.ui:toggle_quick_menu(harpoon:list())
end, { desc = "Harpoon: Toggle menu" })
Press <C-e> to see all your marked files and select one to open.

Cycle Through Files

-- Next file
vim.keymap.set("n", "<C-n>", function()
  harpoon:list():next()
end, { desc = "Harpoon: Next file" })

-- Previous file
vim.keymap.set("n", "<C-p>", function()
  harpoon:list():prev()
end, { desc = "Harpoon: Previous file" })
Quickly cycle through your marked files without opening the menu.

Remove Files

vim.keymap.set("n", "<leader>hr", function()
  harpoon:list():remove()
end, { desc = "Harpoon: Remove current file" })
Press <leader>hr while in a marked file to remove it from the list.

Tips and Tricks

When to Use Harpoon

Harpoon is perfect for:
  • Switching between a controller, service, and test file
  • Navigating between frontend component and its styles
  • Jumping between related configuration files
  • Working on a feature spanning multiple files

Harpoon vs Telescope

  • Telescope (<leader>ff): Use when exploring or searching for files
  • Harpoon: Use when rapidly switching between known files
Harpoon is faster because there’s no fuzzy finding - just direct navigation.

Typical Marking Strategy

Mark 3-5 files you’re actively working on:
  1. Main implementation file
  2. Test file
  3. Related component/module
  4. Configuration file
  5. Documentation
Update marks as your focus shifts to different parts of the codebase.

Per-Project Marks

Harpoon maintains separate mark lists for each project directory. When you switch projects, you’ll see different marks. This makes it perfect for working on multiple projects.

Quick Menu Editing

In the quick menu (<C-e>):
  • Reorder files by cutting (dd) and pasting (p)
  • Delete marks you no longer need
  • See file paths to avoid confusion

Keyboard-Centric Workflow

Harpoon encourages a keyboard-only workflow:
  1. Open files with Telescope once
  2. Mark them with Harpoon
  3. Navigate with <C-n> and <C-p> without leaving home row

Integration with Which-Key

The config registers Harpoon with which-key:
require("which-key").add({
  { "<leader>h", group = "Harpoon" },
})
Press <leader>h and wait to see all Harpoon keybindings.

Advanced Usage

Clear All Marks

To start fresh, open the quick menu (<C-e>) and delete all entries with dd.

Check Current Mark Position

The quick menu shows which file is currently open (highlighted).

Muscle Memory

After a few days of use, you’ll develop muscle memory:
  • File 1: <C-e> then 1
  • File 2: <C-e> then 2
  • Or cycle with <C-n> repeatedly

Harpoon 2

This config uses Harpoon 2 (branch: harpoon2), which features:
  • Improved API and performance
  • Better list management
  • More reliable persistence
  • Enhanced UI
If you see references to Harpoon 1 in other tutorials, note that the API has changed.

Workflow Example

# Working on a feature
1. Open UserController.ts    -> <leader>ha (mark it)
2. Open UserService.ts        -> <leader>ha (mark it)
3. Open user.test.ts          -> <leader>ha (mark it)
4. Open types.ts              -> <leader>ha (mark it)

# Now rapidly switch:
<C-n>  # Jump to next file in cycle
<C-p>  # Jump back
<C-e>  # See all marks, select specific file

# Done with feature:
<leader>hr  # Remove current file from marks
# Or clear all from menu with dd
  • Telescope - Complementary file finding tool
  • NvimTree - File explorer for project overview

Troubleshooting

Marks don’t persist
  • Harpoon 2 stores marks per project directory
  • Ensure you’re in the same working directory
  • Check :pwd to see current directory
Quick menu doesn’t open
  • Verify <C-e> isn’t mapped by another plugin: :map <C-e>
  • Check for errors: :messages
Can’t navigate with Ctrl+n/Ctrl+p
  • These may conflict with other plugins
  • Check mappings: :map <C-n> and :map <C-p>
  • Consider remapping if needed
Which-key not showing Harpoon group
  • Ensure which-key is loaded before Harpoon
  • Check :Lazy plugin load order

Build docs developers (and LLMs) love