Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

LuaintermediatedevopsAI generated

Custom Neovim Plugin for Git Blame Inline Annotations

Build a Neovim plugin in Lua that shows who last changed the current line and when, as faded text at the end of the line (like GitLens in VS Code): Ana Pop, 3 days ago: fix login redirect. It runs git blame in the background without ever freezing the editor, caches the results per file, updates as the cursor moves, handles lines you've edited but not committed, and can be configured and turned off per buffer. You'll learn the Neovim Lua API, running external commands asynchronously (with vim.system, or the libuv bindings exposed as vim.uv, formerly vim.loop), extmarks and virtual text, autocommands, debouncing, plugin structure and configuration, and testing Neovim plugins.

Estimate
~8.5h
Steps
6
Completed by
0
Proposed by
codeseed.app

Neovim Lua API · vim.system / vim.uv

Project roadmap

  1. 01

    Set up the plugin

    ~1h

    Create the plugin folder structure (lua/inline_blame/init.lua and a plugin/ file registering user commands), with a setup(opts) function that merges user options with defaults using vim.tbl_deep_extend, and commands InlineBlameToggle and InlineBlameRefresh. Load it locally in your Neovim config (for example with lazy.nvim's dir option). Done when: :InlineBlameToggle runs and prints a message.

  2. 02

    Run git blame asynchronously

    ~2h

    For the current buffer's file, run git blame --porcelain on the whole file with vim.system (or vim.uv.spawn), in the file's folder, without blocking, and parse the output into a table per line: commit hash, author, author time and summary. Handle files outside a Git repository and untracked files quietly. Cache results per buffer. Done when: blame data for a file is parsed and cached without the editor pausing.

  3. 03

    Show virtual text

    ~1.5h

    Create a namespace with nvim_create_namespace and show the current line's blame as virtual text at the end of the line with nvim_buf_set_extmark (virt_text and virt_text_pos = "eol"), using a highlight group linked to Comment. Format dates as relative time (such as 3 days ago), and show You for your own commits (from git config user.name). Clear the previous mark before showing a new one. Done when: moving to a line shows its author, date and summary at the end.

  4. 04

    Update as the cursor moves

    ~1.5h

    Use nvim_create_autocmd for CursorMoved (debounced with a timer, so moving quickly doesn't cause work on every line), BufEnter to load blame for new buffers, and BufWritePost to refresh the cache after saving. Show Not committed yet for lines changed since the last commit (git blame reports them with a zero hash). Done when: the annotation follows the cursor smoothly and refreshes after saving.

  5. 05

    Add configuration options

    ~1h

    Support options for the date format (relative or absolute), the text template (such as {author}, {date}: {summary}), the highlight group, a delay, excluded file types, and turning it off for large files. Add :InlineBlameToggle per buffer and a command showing the full commit (git show) in a split for the current line. Done when: every option changes the behavior as documented in README.md.

  6. 06

    Test it

    ~1.5h

    Write tests with a Lua test runner for Neovim (such as plenary.nvim's busted-style tests, or mini.test) that create a temporary Git repository with commits by different authors, open a file and check the parsed blame, the virtual text for a line, uncommitted lines and non-Git files. Done when: the tests pass in a headless Neovim (nvim --headless).

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~8.5h · 6 steps

Tech stack

Neovim Lua APIvim.system / vim.uv