Skip to main content
The mark API provides functions for managing file marks in Harpoon. Marks are bookmarks to specific files with saved cursor positions.

add_file

Add a file to the mark list.
require("harpoon.mark").add_file(file_name_or_buf_id)
file_name_or_buf_id
string | number | nil
File path (string), buffer ID (number), or nil for current buffer

Behavior

  • If the file is already marked, does nothing (preserves existing position)
  • Adds the mark to the first empty slot in the list
  • Saves current cursor position with the mark
  • Throws error if filetype is in excluded_filetypes config
  • Throws error if trying to mark the Harpoon UI itself

Example

local mark = require("harpoon.mark")

-- Add current buffer
mark.add_file()

-- Add specific file by path
mark.add_file("/path/to/file.lua")

-- Add by buffer ID
mark.add_file(5)

rm_file

Remove a file from the mark list.
require("harpoon.mark").rm_file(file_name_or_buf_id)
file_name_or_buf_id
string | number | nil
File path (string), buffer ID (number), or nil for current buffer

Behavior

  • Removes the mark if it exists
  • Does nothing if the file is not marked
  • Removes empty tail entries from the mark list

Example

local mark = require("harpoon.mark")

-- Remove current buffer
mark.rm_file()

-- Remove specific file
mark.rm_file("/path/to/file.lua")

toggle_file

Toggle a file in the mark list (add if not present, remove if present).
require("harpoon.mark").toggle_file(file_name_or_buf_id)
file_name_or_buf_id
string | number | nil
File path (string), buffer ID (number), or nil for current buffer

Behavior

  • Adds the file if not marked
  • Removes the file if already marked
  • Prints “Mark added” or “Mark removed” message

Example

local mark = require("harpoon.mark")

-- Toggle current buffer
mark.toggle_file()

-- Toggle specific file
mark.toggle_file("/path/to/file.lua")

clear_all

Remove all marks from the list.
require("harpoon.mark").clear_all()

Behavior

  • Clears all marks immediately
  • Triggers save if save_on_change is enabled

Example

local mark = require("harpoon.mark")

-- Clear all marks
mark.clear_all()

get_marked_file

Get the mark object at a specific index or by filename.
require("harpoon.mark").get_marked_file(idxOrName)
idxOrName
number | string
required
Mark index (number) or filename (string)
return
table | nil
Mark object with fields:
  • filename (string): File path
  • row (number): Cursor row position
  • col (number): Cursor column position

Example

local mark = require("harpoon.mark")

-- Get mark by index
local m1 = mark.get_marked_file(1)
print(m1.filename, m1.row, m1.col)

-- Get mark by filename
local m2 = mark.get_marked_file("/path/to/file.lua")

get_marked_file_name

Get the filename of a mark at a specific index.
require("harpoon.mark").get_marked_file_name(idx)
idx
number
required
Mark index (1-based)
return
string | nil
Filename at the index, or nil if no mark exists

Example

local mark = require("harpoon.mark")

-- Get filename at index 1
local filename = mark.get_marked_file_name(1)
print(filename)

get_current_index

Get the mark index of the current buffer.
require("harpoon.mark").get_current_index()
return
number | nil
Index of current buffer in mark list, or nil if not marked

Example

local mark = require("harpoon.mark")

local idx = mark.get_current_index()
if idx then
    print("Current file is mark #" .. idx)
else
    print("Current file is not marked")
end

set_current_at

Set the current buffer as a mark at a specific index.
require("harpoon.mark").set_current_at(idx)
idx
number
required
Target index for the mark (1-based)

Behavior

  • Removes the current file from its existing position (if marked)
  • Places the current file at the specified index
  • Fills any gaps with empty marks
  • Saves current cursor position

Example

local mark = require("harpoon.mark")

-- Set current file as mark #3
mark.set_current_at(3)

to_quickfix_list

Populate Vim’s quickfix list with all marks.
require("harpoon.mark").to_quickfix_list()

Behavior

  • Creates quickfix entries for all non-empty marks
  • Each entry includes filename, row, and column position
  • Opens the quickfix list for easy navigation

Example

local mark = require("harpoon.mark")

-- Send all marks to quickfix
mark.to_quickfix_list()

-- Navigate with :cnext and :cprev

status

Get the mark status string for a buffer (useful for statusline).
require("harpoon.mark").status(bufnr)
bufnr
number
Buffer number to check (defaults to current buffer)
return
string
Returns “M1”, “M2”, etc. if marked, or empty string if not marked

Example

local mark = require("harpoon.mark")

-- In statusline configuration
local status = mark.status()
if status ~= "" then
    -- Display status in statusline
    print("Mark: " .. status)
end

Additional Functions

get_index_of

Get the index of a file in the mark list.
local idx = require("harpoon.mark").get_index_of(item)
item
string | number
required
Filename (string) or index (number)
return
number | nil
Index if found, nil otherwise

valid_index

Check if an index is valid and has a mark.
local is_valid = require("harpoon.mark").valid_index(idx)
idx
number
required
Index to validate
return
boolean
True if index has a valid mark, false otherwise

get_length

Get the total number of marks.
local count = require("harpoon.mark").get_length()
return
number
Number of marks in the list

set_mark_list

Replace the entire mark list with a new list.
require("harpoon.mark").set_mark_list(new_list)
new_list
table
required
Array of mark objects or filenames. Can be strings (filenames) or mark objects with filename, row, and col fields
-- Example: Set marks from a list of filenames
local mark = require("harpoon.mark")
mark.set_mark_list({
  "src/index.js",
  "src/components/App.jsx",
  "README.md"
})

-- Example: Set marks with cursor positions
mark.set_mark_list({
  { filename = "src/index.js", row = 10, col = 5 },
  { filename = "src/App.jsx", row = 25, col = 0 }
})

on

Register a callback function that runs when marks change.
require("harpoon.mark").on(event, callback)
event
string
required
Event name. Currently only "changed" is supported
callback
function
required
Function to call when the event occurs
-- Example: Log when marks change
local mark = require("harpoon.mark")
mark.on("changed", function()
  print("Harpoon marks have been updated!")
end)

-- Example: Update statusline when marks change
mark.on("changed", function()
  vim.cmd("redrawstatus")
end)

store_offset

Manually store the current cursor position for the current file’s mark (if it exists).
require("harpoon.mark").store_offset()
This function is called automatically when leaving a buffer, but you can call it manually if needed.
-- Example: Force save cursor position before an operation
local mark = require("harpoon.mark")
mark.store_offset()
-- Do something that might change cursor position

remove_empty_tail

Remove empty marks from the end of the mark list.
require("harpoon.mark").remove_empty_tail()
This is called automatically after removing marks. You typically don’t need to call it directly.

Build docs developers (and LLMs) love