Skip to content

dimtion/guttermarks.nvim

Repository files navigation

GutterMarks.nvim

Lua Neovim MIT Dotfyle

A Neovim plugin that displays marks in the buffer gutter as signs. Keep track of your marks visually with customizable appearance and behavior.

Features

  • Display local marks (a-z) in the gutter
  • Display global marks (A-Z) in the gutter
  • Optional display of special marks (numbers, symbols)
  • Configurable sign text and highlight groups
  • Automatic refresh on text changes
  • Utility actions for enhanced marks workflow

Why this plugin

I've been using marks.nvim and others to display marks in the gutter, but I don't need all the extra bells and whistles that those other plugins added. This is a fast, simple implementation that doesn't get in the way, and does not change nvim default behavior. Further, I worked a bit to benchmark and make sure this plugin is fast and the implementation does not impact vim performances.

Installation

Using lazy.nvim

{
  "dimtion/guttermarks.nvim",
  event = { "BufReadPost", "BufNewFile", "BufWritePre", "FileType" },
}

Using vim-plug

Plug 'dimtion/guttermarks.nvim'

Configuration

Optionally use setup(opts) function to configure the plugin:

require("guttermarks").setup({
  global_mark = { enabled = false },
})

See full default configuration:

{
  local_mark = {
    enabled = true,
    sign = nil,
    highlight_group = "GutterMarksLocal",
    priority = 10,
  },
  global_mark = {
    enabled = true,
    sign = nil,
    highlight_group = "GutterMarksGlobal",
    priority = 11,
  },
  special_mark = {
    enabled = false,
    sign = nil,
    marks = { "'", "^", ".", "[", "]", "<", ">", '"', "`", '"', "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
    highlight_group = "GutterMarksSpecial",
    priority = 10,
  },
  excluded_filetypes = { "" },
  excluded_buftypes = {},
  -- Advanced: Customize Autocmd events that trigger a refresh
  autocmd_triggers = {
    "BufEnter",
    "BufWritePost",
    "TextChanged",
    "TextChangedI",
  },
}

Commands

Command Description
:GutterMarks toggle Toggle guttermarks display on/off
:GutterMarks enable Enable guttermarks display
:GutterMarks disable Disable guttermarks display
:GutterMarks refresh Force refresh guttermarks display

Customizing Highlights

You can customize the default highlight groups in your colorscheme or init.lua:

vim.api.nvim_set_hl(0, "GutterMarksLocal", { fg = "#ffff00" })
vim.api.nvim_set_hl(0, "GutterMarksGlobal", { fg = "#ff0000", bold = true })
vim.api.nvim_set_hl(0, "GutterMarksSpecial", { fg = "#00ff00", italic = true })

Advanced configuration

Enable Special Marks (disabled by default)

require("guttermarks").setup({
  special_mark = { enabled = true },
})

Using Custom Signs

require("guttermarks").setup({
  local_mark = { sign = "" },
  global_mark = { sign = "" },
  special_mark = {
    enabled = true,
    sign = "",
  },
})

Local Marks Only

require("guttermarks").setup({
  global_mark = { enabled = false },
  special_mark = { enabled = false },
})

Function passed for sign

require("guttermarks").setup({
  global_mark = {
    sign = function(mark)
      -- Show the mark letter with a prefix
      return "G" .. mark.mark
    end,
  },
})

GutterMarks Actions

To make marks more effective in vim, GutterMarks comes with a few actions that can be used by creating key mappings:

vim.keymap.set("n", "m;", require("guttermarks.actions").delete_mark, { desc = "Delete mark under cursor" })

vim.keymap.set("n", "]m", require("guttermarks.actions").next_buf_mark, { desc = "Next mark in current buffer" })
vim.keymap.set("n", "[m", require("guttermarks.actions").prev_buf_mark, { desc = "Previous mark in current buffer" })

vim.keymap.set("n", "<leader>mq", function()
    require("guttermarks.actions").marks_to_quickfix()
    vim.cmd("copen")
end, { desc = "Send marks to quickfix (and open it)" })

vim.keymap.set("n", "<leader>mQ", function()
    require("guttermarks.actions").marks_to_quickfix({
        special_mark = true,
    })
    vim.cmd("copen")
end, { desc = "Send marks to quickfix (include special marks)" })

Vim Marks cheat-sheet

  • Use ma to set local mark 'a', mA for global mark 'A'
  • Jump to marks with 'a (local) or 'A (global)
  • Use `a to jump to exact position (line and column) of mark 'a'
  • Delete mark 'a' with :delmarks a