### Configure blame.nvim with Options Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md Install blame.nvim and configure it with specific blame options, such as '-w' to ignore whitespace changes. This is done within the plugin's setup configuration. ```lua return { { "FabijanZulj/blame.nvim", lazy = false, config = function() require('blame').setup {} end, opts = { blame_options = { '-w' }, }, }, } ``` -------------------------------- ### Install blame.nvim Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md Basic installation of the blame.nvim plugin using a Lua configuration. Ensure this is placed within your Neovim configuration's plugin management section. ```lua return { { "FabijanZulj/blame.nvim", lazy = false, config = function() require('blame').setup {} end, }, } ``` -------------------------------- ### Minimal setup with lazy.nvim Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt This snippet shows the basic configuration for blame.nvim using lazy.nvim. Ensure this is called once during Neovim startup. ```lua -- Minimal setup (lazy.nvim) { "FabijanZulj/blame.nvim", lazy = false, config = function() require('blame').setup({}) end, } ``` -------------------------------- ### Full configuration for blame.nvim Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt This example demonstrates the extensive configuration options available for blame.nvim. Customize date formats, view styles, highlight colors, and key mappings. ```lua -- Full configuration with all options require('blame').setup({ -- Date format passed to os.date(); use "%r" for relative time date_format = "%Y-%m-%d", -- Show relative date ("3 days ago") for commits < 30 days old relative_date_if_recent = true, -- "right_align" | "float" – only used by virtual view virtual_style = "right_align", -- Which view opens for :BlameToggle with no argument views = { window = require("blame.views.window_view"), virtual = require("blame.views.virtual_view"), default = require("blame.views.window_view"), }, -- Move cursor into the blame window on open focus_blame = true, -- Collapse consecutive lines with the same commit hash merge_consecutive = false, -- Truncate commit summary after this many characters (date_message format) max_summary_width = 30, -- Fixed color palette (list of "#RRGGBB" strings); nil = random RGB per commit colors = { "#e06c75", "#98c379", "#e5c07b", "#61afef", "#c678dd", "#56b6c2" }, -- Extra flags forwarded to git blame (e.g. ignore whitespace) blame_options = { "-w" }, -- Where to open full commit details: "tab" | "vsplit" | "split" | "current" -- Or a function: function(hash, row, file_path) ... end commit_detail_view = "vsplit", -- Built-in format functions (swap to change blame line appearance): -- formats.commit_date_author_fn → "a1b2c3d 2024-05-01 Jane Doe" -- formats.date_message → "2024-05-01 Fix null pointer dereference..." format_fn = require("blame.formats.default_formats").commit_date_author_fn, -- Key mappings – each value can be a string or a list of strings mappings = { commit_info = "i", stack_push = "", stack_pop = "", show_commit = "", close = { "", "q" }, copy_hash = "y", open_in_browser = "o", }, }) ``` -------------------------------- ### Handle BlameViewOpened Event Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md Example of creating a user autocommand to react when a blame view is opened. This specific example toggles off the 'barbecue' UI plugin when a 'window' blame view is opened. ```lua vim.api.nvim_create_autocmd("User", { pattern = "BlameViewOpened", callback = function(event) local blame_type = event.data if blame_type == "window" then require("barbecue.ui").toggle(false) end end, }) ``` -------------------------------- ### Handle BlameViewClosed Event Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md Example of creating a user autocommand to react when a blame view is closed. This specific example toggles the 'barbecue' UI plugin back on when a 'window' blame view is closed. ```lua vim.api.nvim_create_autocmd("User", { pattern = "BlameViewClosed", callback = function(event) local blame_type = event.data if blame_type == "window" then require("barbecue.ui").toggle(true) end end, }) ``` -------------------------------- ### User command to open/close blame view Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt These Vimscript examples show how to use the `:BlameToggle` user command to open and close blame views. You can specify the view type and pass git blame flags. ```vim " Open the default window view :BlameToggle " Open virtual text view :BlameToggle virtual " Open window view, ignoring whitespace changes :BlameToggle window -w " Toggle off (same command closes if already open) :BlameToggle ``` -------------------------------- ### Default blame.nvim Configuration Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md The default configuration settings for blame.nvim, covering date formatting, virtual text alignment, merge strategies, and custom key mappings. These can be overridden in your setup. ```lua { date_format = "%d.%m.%Y", virtual_style = "right_align", relative_date_if_recent = true -- this is relative only for the latest month views = { window = window_view, virtual = virtual_view, default = window_view, }, focus_blame = true, merge_consecutive = false, max_summary_width = 30, colors = nil, blame_options = nil, commit_detail_view = "vsplit", format_fn = formats.commit_date_author_fn, mappings = { commit_info = "i", stack_push = "", stack_pop = "", show_commit = "", close = { "", "q" }, copy_hash = "y", open_in_browser = "o", } } ``` -------------------------------- ### BlameToggle [view] [git-options] Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt A user command to open or close a blame view. When called without arguments, it opens the default window view. A registered view name can be provided to select a specific view. Any argument starting with a hyphen (`-`) is passed directly to the `git blame` command. ```APIDOC ## `BlameToggle [view] [git-options]` — User command to open/close a blame view The primary entry point for end-users. With no arguments it opens the default (window) view. Passing a registered view name selects that view. Any token starting with `-` is forwarded verbatim to `git blame`. ```vim " Open the default window view :BlameToggle " Open virtual text view :BlameToggle virtual " Open window view, ignoring whitespace changes :BlameToggle window -w " Toggle off (same command closes if already open) :BlameToggle ``` ``` -------------------------------- ### require('blame').setup(config) Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Initializes the blame.nvim plugin and registers the BlameToggle command. This function should be called once during Neovim startup. It merges provided configuration with defaults and sets up the plugin's core components. ```APIDOC ## `require('blame').setup(config)` — Plugin initialization and `BlameToggle` command registration Merges the supplied table with the default configuration using `vim.tbl_deep_extend`, creates the default view instance, and registers the `BlameToggle` user command. Must be called once during Neovim startup. The command accepts an optional view name and any number of `git blame` flag arguments. ```lua -- Minimal setup (lazy.nvim) { "FabijanZulj/blame.nvim", lazy = false, config = function() require('blame').setup({}) end, } -- Full configuration with all options require('blame').setup({ -- Date format passed to os.date(); use "%r" for relative time date_format = "%Y-%m-%d", -- Show relative date ("3 days ago") for commits < 30 days old relative_date_if_recent = true, -- "right_align" | "float" – only used by virtual view virtual_style = "right_align", -- Which view opens for :BlameToggle with no argument views = { window = require("blame.views.window_view"), virtual = require("blame.views.virtual_view"), default = require("blame.views.window_view"), }, -- Move cursor into the blame window on open focus_blame = true, -- Collapse consecutive lines with the same commit hash merge_consecutive = false, -- Truncate commit summary after this many characters (date_message format) max_summary_width = 30, -- Fixed color palette (list of "#RRGGBB" strings); nil = random RGB per commit colors = { "#e06c75", "#98c379", "#e5c07b", "#61afef", "#c678dd", "#56b6c2" }, -- Extra flags forwarded to git blame (e.g. ignore whitespace) blame_options = { "-w" }, -- Where to open full commit details: "tab" | "vsplit" | "split" | "current" -- Or a function: function(hash, row, file_path) ... end commit_detail_view = "vsplit", -- Built-in format functions (swap to change blame line appearance): -- formats.commit_date_author_fn → "a1b2c3d 2024-05-01 Jane Doe" -- formats.date_message → "2024-05-01 Fix null pointer dereference..." format_fn = require("blame.formats.default_formats").commit_date_author_fn, -- Key mappings – each value can be a string or a list of strings mappings = { commit_info = "i", stack_push = "", stack_pop = "", show_commit = "", close = { "", "q" }, copy_hash = "y", open_in_browser = "o", }, }) ``` ``` -------------------------------- ### Implement Custom Quickfix BlameView Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt This minimal custom view logs blame data to a quickfix list. It requires the `BlameView` interface methods: `new`, `open`, `is_open`, and `close`. The `open` method populates the quickfix list with blame details. ```lua -- Minimal custom view that logs blame data to a quickfix list local QuickfixView = {} function QuickfixView:new(config) local o = setmetatable({}, { __index = self }) o.config = config o.opened = false return o end function QuickfixView:open(lines) local qf_items = {} for _, p in ipairs(lines) do table.insert(qf_items, { text = string.sub(p.hash, 1, 7) .. " " .. p.author .. " " .. p.summary, lnum = p.original_line, filename = p.filename, }) end vim.fn.setqflist(qf_items, "r") vim.cmd("copen") self.opened = true end function QuickfixView:is_open() return self.opened end function QuickfixView:close(_) vim.cmd("cclose") self.opened = false end -- Register and use: require("blame").setup({ views = { window = require("blame.views.window_view"), virtual = require("blame.views.virtual_view"), quickfix = QuickfixView, default = require("blame.views.window_view"), }, }) -- :BlameToggle quickfix ``` -------------------------------- ### Configure blame.nvim line formats Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Demonstrates how to switch between built-in line formats or define a custom format function at runtime. Ensure the format function signature matches the expected `FormatFn` type. ```lua local formats = require("blame.formats.default_formats") -- commit_date_author_fn produces: "a1b2c3d 2024-05-01 Jane Doe" -- date_message produces: "2024-05-01 Fix null pointer dereference..." -- Switch to date+summary format at runtime: require("blame").setup({ format_fn = formats.date_message, max_summary_width = 40, -- summaries longer than 40 chars are truncated with "..." }) ``` ```lua -- Custom format function (same signature): -- FormatFn = fun(line_porcelain: Porcelain, config: Config, idx: integer): LineWithHl require("blame").setup({ format_fn = function(porcelain, config, idx) local hash = string.sub(porcelain.hash, 0, 7) return { idx = idx, values = { { textValue = hash, hl = "Comment" }, { textValue = porcelain.author, hl = hash }, }, format = "% -8s %s", } end, }) ``` -------------------------------- ### Async Git Command Wrapper Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Provides non-blocking wrappers for git commands like blame, show, diff, and rev-parse. All methods require success and error callback functions. ```lua local Git = require("blame.git") local config = { blame_options = { "-w" } } local g = Git:new(config) -- Run git blame --line-porcelain on the current file g:blame( "/home/user/project/src/main.lua", -- absolute filename "/home/user/project/src", -- cwd nil, -- commit (nil = HEAD) nil, -- per-call opts (overrides config.blame_options) function(data) -- data: string[] of raw porcelain lines vim.notify("Blame lines received: " .. #data) end, function(err) vim.notify("git blame failed: " .. err, vim.log.levels.ERROR) end ) -- Show file content at a specific commit g:show( "src/main.lua", -- relative path from repo root "/home/user/project", -- cwd / repo root "a1b2c3d", -- commit hash function(content) end, function(err) end ) -- Get unified diff between two commits (used by blame stack) g:diff( "src/main.lua", "/home/user/project", "a1b2c3d^", -- parent "a1b2c3d", -- child function(diff_lines) end, function(err) end ) -- Get repository root g:git_root( "/home/user/project/src", function(root) vim.notify("Root: " .. root[1]) end, function(err) vim.notify(err, vim.log.levels.WARN) end ) ``` -------------------------------- ### Convert Porcelain to Render-Ready Lines Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Applies formatting functions to porcelain lines and normalizes column widths for aligned output. Requires `blame.highlights`, `blame.porcelain_parser`, and `blame.formats` modules. ```lua local highlights = require("blame.highlights") local parser = require("blame.porcelain_parser") local formats = require("blame.formats.default_formats") local config = { format_fn = formats.commit_date_author_fn, date_format = "%d.%m.%Y", relative_date_if_recent = true, merge_consecutive = true, -- blank out repeated consecutive commits max_summary_width = 30, ns_id = vim.api.nvim_create_namespace("blame_ns"), } local porcelain = parser.parse_porcelain(raw_blame_data) local lines_with_hl = highlights.get_hld_lines_from_porcelain(porcelain, config) -- lines_with_hl[1] example: -- { -- idx = 1, -- values = { -- { textValue = "a1b2c3d", hl = "Comment" }, -- { textValue = "01.05.2024", hl = "a1b2c3d" }, -- { textValue = "Jane Doe", hl = "a1b2c3d" }, -- }, -- format = "% -7s %-10s %s", -- columns left-padded to max width -- } ``` -------------------------------- ### Configure Default Virtual View Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Set up blame.nvim to use the virtual text view as the default for displaying blame information. This view attaches blame details as virtual text on the right side of each line. ```lua local VirtualView = require("blame.views.virtual_view") require("blame").setup({ -- Use virtual view as the default views = { window = require("blame.views.window_view"), virtual = VirtualView, default = VirtualView, -- :BlameToggle opens virtual text by default }, virtual_style = "float", -- "right_align" | "float" }) -- Toggle virtual blame: -- :BlameToggle → uses default (VirtualView) -- :BlameToggle virtual → explicit ``` -------------------------------- ### blame.git Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Provides asynchronous wrappers for common Git commands like `blame`, `show`, `diff`, and `rev-parse`. All methods support callbacks for handling successful data retrieval and error reporting. ```APIDOC ## `blame.git` — Async git command wrapper A class providing non-blocking wrappers around `git blame`, `git show`, `git diff`, and `git rev-parse`. All methods accept a `callback(data: string[])` and an `err_cb(err: string)`. ### Methods - **`blame(filename, cwd, commit, opts, callback, err_cb)`**: Executes `git blame` on the specified file. - `filename` (string): Absolute path to the file. - `cwd` (string): The current working directory. - `commit` (string | nil): The commit hash to blame (nil for HEAD). - `opts` (table | nil): Per-call options, overrides `config.blame_options`. - `callback` (function): Called with `string[]` of raw porcelain lines on success. - `err_cb` (function): Called with an error string on failure. - **`show(path, cwd, commit, callback, err_cb)`**: Shows the content of a file at a specific commit. - `path` (string): Relative path from the repository root. - `cwd` (string): The current working directory / repository root. - `commit` (string): The commit hash. - `callback` (function): Called with file content on success. - `err_cb` (function): Called with an error string on failure. - **`diff(path, cwd, commit1, commit2, callback, err_cb)`**: Gets the unified diff between two commits for a file. - `path` (string): Relative path from the repository root. - `cwd` (string): The current working directory / repository root. - `commit1` (string): The parent commit hash. - `commit2` (string): The child commit hash. - `callback` (function): Called with `string[]` of diff lines on success. - `err_cb` (function): Called with an error string on failure. - **`git_root(cwd, callback, err_cb)`**: Retrieves the root directory of the Git repository. - `cwd` (string): The current working directory. - `callback` (function): Called with `string[]` containing the root path on success. - `err_cb` (function): Called with an error string on failure. ``` -------------------------------- ### Configure Open in Browser Mapping Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Customize the key mapping for the 'open in browser' feature, which opens the current commit in a web browser. This uses the `open_commit_in_browser` function from `blame.git_browser`. ```lua -- To remap the key: require("blame").setup({ mappings = { open_in_browser = "gB" }, }) ``` -------------------------------- ### Fugitive-style Side Window View Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Implements a blame view that opens a scratch buffer, synchronizes scrolling and cursor movement, and manages keymaps. Fires `User BlameViewOpened` and `User BlameViewClosed` events. ```lua local WindowView = require("blame.views.window_view") -- Instantiate manually (blame.setup() does this internally) local config = { -- full Config table focus_blame = true, format_fn = require("blame.formats.default_formats").commit_date_author_fn, date_format = "%d.%m.%Y", relative_date_if_recent = true, merge_consecutive = false, max_summary_width = 30, colors = nil, commit_detail_view = "vsplit", ns_id = vim.api.nvim_create_namespace("blame_ns"), mappings = { commit_info = "i", stack_push = "", stack_pop = "", show_commit = "", close = { "", "q" }, copy_hash = "y", open_in_browser = "o", }, } local wv = WindowView:new(config) -- wv:open(porcelain_lines) -- render blame -- wv:close(false) -- close and clean up -- wv:is_open() -- boolean -- React to view events: vim.api.nvim_create_autocmd("User", { pattern = "BlameViewOpened", callback = function(event) -- event.data == "window" | "virtual" if event.data == "window" then require("barbecue.ui").toggle(false) end end, }) vim.api.nvim_create_autocmd("User", { pattern = "BlameViewClosed", callback = function(event) if event.data == "window" then require("barbecue.ui").toggle(true) end end, }) ``` -------------------------------- ### Configure Blame History Navigation Mappings Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Customize key mappings for navigating through the Git blame history. This allows you to step backward through commits for a file. ```lua -- Navigation is triggered via keymaps set in the blame window. -- Default bindings: -- → stack_push (go back in history for line under cursor) -- → stack_pop (return to the next commit) -- To remap: require("blame").setup({ mappings = { stack_push = "", stack_pop = "", }, }) ``` -------------------------------- ### Parse raw git blame --line-porcelain output Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Converts raw git blame output into structured `Porcelain` tables. Each table represents a source line and includes standard porcelain fields plus the original line number at the blamed commit. ```lua local parser = require("blame.porcelain_parser") -- Simulated raw porcelain input (normally produced by git.blame()) local raw = { "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 1 1 1", "author Jane Doe", "author-mail ", "author-time 1714521600", "author-tz +0200", "committer Jane Doe", "committer-mail ", "committer-time 1714521600", "committer-tz +0200", "summary Fix null pointer dereference in parser", "filename src/parser.lua", "\tlocal result = parse(input)", } local lines = parser.parse_porcelain(raw) -- lines[1] = { -- hash = "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", -- original_line = 1, -- author = "Jane Doe", -- author_email = "", -- author_time = 1714521600, -- author_tz = "+0200", -- committer = "Jane Doe", -- committer_mail = "", -- committer_time = 1714521600, -- committer_tz = "+0200", -- summary = "Fix null pointer dereference in parser", -- filename = "src/parser.lua", -- content = "\tlocal result = parse(input)", -- } ``` -------------------------------- ### require('blame').is_open() Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Queries whether a blame view is currently visible in the Neovim instance. Returns `true` if a blame view is open, and `false` or `nil` otherwise. This is useful for implementing conditional logic in custom keymaps or autocommands. ```APIDOC ## `require('blame').is_open()` — Query whether a blame view is currently visible Returns `true` when a blame view is open, `false` or `nil` otherwise. Useful for conditional logic in custom keymaps or autocommands. ```lua -- Toggle blame only when not already open, otherwise print a message vim.keymap.set("n", "gb", function() if require("blame").is_open() then vim.notify("blame.nvim: view already open", vim.log.levels.INFO) else vim.cmd("BlameToggle") end end, { desc = "Open git blame" }) ``` ``` -------------------------------- ### blame.views.window_view Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Implements the `BlameView` interface for displaying blame information in a Fugitive-style side window. It synchronizes scrolling, manages keymaps, and handles UI events. ```APIDOC ## `blame.views.window_view` — Fugitive-style side window view Implements `BlameView`. Opens a `nofile` scratch buffer to the left of the current window, synchronises scrolling and cursor movement (`scrollbind`/`cursorbind`), sets up all keymaps, and manages the blame stack. Fires `User BlameViewOpened` / `User BlameViewClosed` autocmd events. ### Methods - **`WindowView:new(config)`**: Instantiates a new `WindowView`. - `config` (table): A configuration table including `focus_blame`, `format_fn`, `date_format`, `relative_date_if_recent`, `merge_consecutive`, `max_summary_width`, `colors`, `commit_detail_view`, `ns_id`, and `mappings`. - **`wv:open(porcelain_lines)`**: Renders the blame information in the window. - `porcelain_lines` (any): The blame data to display. - **`wv:close(false)`**: Closes the blame window and cleans up resources. - **`wv:is_open()`**: Returns a boolean indicating if the blame window is currently open. ### Events - **`User BlameViewOpened`**: Fired when the blame view is opened. `event.data` can be "window" or "virtual". - **`User BlameViewClosed`**: Fired when the blame view is closed. `event.data` can be "window" or "virtual". ``` -------------------------------- ### Format UNIX Timestamps with blame.utils Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Utilize helper functions from `blame.utils` to format UNIX timestamps into human-readable dates using `os.date` format strings or display relative times. ```lua local utils = require("blame.utils") -- Absolute date using os.date format string utils.format_time("%d.%m.%Y", 1714521600) -- "01.05.2024" utils.format_time("%Y-%m-%d", 1714521600) -- "2024-05-01" -- Use "%r" as a token for inline relative time utils.format_time("Committed %r", 1714521600) -- "Committed 3 days ago" utils.format_time("%r", 1714521600) -- "3 days ago" -- Relative if < 30 days old, else absolute utils.format_recent_date("%d.%m.%Y", os.time() - 86400) -- "1 day ago" utils.format_recent_date("%d.%m.%Y", os.time() - 3000000) -- "01.01.2024" -- Width of widest string in an array (display-safe, handles multibyte) utils.longest_string_in_array({ "abc", "de", "fghij" }) -- 5 ``` -------------------------------- ### blame.commit_info Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Opens a read-only floating window near the cursor showing all porcelain fields for the commit on the current blame line. Closes automatically when the cursor moves; can also be focused ('i' key) to scroll the popup. ```APIDOC ## `blame.commit_info` — Floating commit metadata popup Opens a read-only floating window near the cursor showing all porcelain fields for the commit on the current blame line. Closes automatically when the cursor moves; can also be focused (`i` key) to scroll the popup. ```lua -- Triggered by the commit_info mapping (default: "i") in the blame window. -- To change: require("blame").setup({ mappings = { commit_info = "K" }, -- use "K" like hover docs }) -- The popup displays all Porcelain fields (except "content"), e.g.: -- author: Jane Doe -- author_email: -- author_time: 1714521600 -- committer: Jane Doe -- committer_time: 1714521600 -- filename: src/parser.lua -- hash: a1b2c3d4e5f6... -- summary: Fix null pointer dereference in parser ``` ``` -------------------------------- ### Open Commit in Browser Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Directly call the function to open a specific Git commit in the system's default web browser. The function detects the hosting provider (GitHub, GitLab, Bitbucket) from the remote URL. ```lua local browser = require("blame.git_browser") -- Triggered by the open_in_browser mapping (default: "o") in the blame window. -- Can also be called directly: browser.open_commit_in_browser( "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", vim.fn.expand("%:p:h") ) -- GitHub → https://github.com/owner/repo/commit/ -- GitLab → https://gitlab.com/owner/repo/-/commit/ -- Bitbucket → https://bitbucket.org/owner/repo/commits/ ``` -------------------------------- ### blame.git_browser.open_commit_in_browser Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Opens the commit in the system's default web browser on platforms like GitHub, GitLab, or Bitbucket. It reads the 'origin' remote URL, detects the provider, and constructs the commit URL. ```APIDOC ## `blame.git_browser.open_commit_in_browser(hash, cwd)` — Open commit on GitHub / GitLab / Bitbucket Reads the `origin` remote URL via `git remote get-url origin`, detects the hosting provider, constructs the commit URL, and opens it with the system browser (`open` / `xdg-open` / `cmd.exe`). ```lua local browser = require("blame.git_browser") -- Triggered by the open_in_browser mapping (default: "o") in the blame window. -- Can also be called directly: browser.open_commit_in_browser( "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", vim.fn.expand("%:p:h") ) -- GitHub → https://github.com/owner/repo/commit/ -- GitLab → https://gitlab.com/owner/repo/-/commit/ -- Bitbucket → https://bitbucket.org/owner/repo/commits/ -- To remap the key: require("blame").setup({ mappings = { open_in_browser = "gB" }, }) ``` ``` -------------------------------- ### blame.utils Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Provides helper functions for date formatting and string manipulation, including formatting UNIX timestamps, calculating relative times, and measuring string display widths. ```APIDOC ## `blame.utils` — Date formatting utilities Helper functions for formatting UNIX timestamps, computing relative times ("3 days ago"), and measuring string display widths for column alignment. ```lua local utils = require("blame.utils") -- Absolute date using os.date format string utils.format_time("%d.%m.%Y", 1714521600) -- "01.05.2024" utils.format_time("%Y-%m-%d", 1714521600) -- "2024-05-01" -- Use "%r" as a token for inline relative time utils.format_time("Committed %r", 1714521600) -- "Committed 3 days ago" utils.format_time("%r", 1714521600) -- "3 days ago" -- Relative if < 30 days old, else absolute utils.format_recent_date("%d.%m.%Y", os.time() - 86400) -- "1 day ago" utils.format_recent_date("%d.%m.%Y", os.time() - 3000000) -- "01.01.2024" -- Width of widest string in an array (display-safe, handles multibyte) utils.longest_string_in_array({ "abc", "de", "fghij" }) -- 5 ``` ``` -------------------------------- ### blame.formats.default_formats Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Provides built-in line format functions that can be used with the blame.nvim plugin. These functions take a Porcelain object, Config, and line index to return a LineWithHl table for rendering. ```APIDOC ## `blame.formats.default_formats` — Built-in line format functions Two `FormatFn` implementations ship with the plugin. Each receives a `Porcelain` object, the active `Config`, and the 1-based line index, and returns a `LineWithHl` table that the view renders. ```lua local formats = require("blame.formats.default_formats") -- commit_date_author_fn produces: "a1b2c3d 2024-05-01 Jane Doe" -- date_message produces: "2024-05-01 Fix null pointer dereference..." -- Switch to date+summary format at runtime: require("blame").setup({ format_fn = formats.date_message, max_summary_width = 40, -- summaries longer than 40 chars are truncated with "..." }) -- Custom format function (same signature): -- FormatFn = fun(line_porcelain: Porcelain, config: Config, idx: integer): LineWithHl require("blame").setup({ format_fn = function(porcelain, config, idx) local hash = string.sub(porcelain.hash, 0, 7) return { idx = idx, values = { { textValue = hash, hl = "Comment" }, { textValue = porcelain.author, hl = hash }, }, format = "% -8s %s", } end, }) ``` ``` -------------------------------- ### blame.views.virtual_view Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Implements BlameView using nvim_buf_set_extmark to attach blame information as virtual text. Supports 'right_align' and 'float' positioning. Closing clears all extmarks. ```APIDOC ## `blame.views.virtual_view` — Inline virtual text view Implements `BlameView` using `nvim_buf_set_extmark` to attach blame information as virtual text on the right side of each line. Supports `right_align` (default) and `float` positioning. Closing clears all extmarks via `nvim_buf_clear_namespace`. ```lua local VirtualView = require("blame.views.virtual_view") require("blame").setup({ -- Use virtual view as the default views = { window = require("blame.views.window_view"), virtual = VirtualView, default = VirtualView, -- :BlameToggle opens virtual text by default }, virtual_style = "float", -- "right_align" | "float" }) -- Toggle virtual blame: -- :BlameToggle → uses default (VirtualView) -- :BlameToggle virtual → explicit ``` ``` -------------------------------- ### Configure Commit Info Popup Mapping Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Change the key mapping used to trigger the floating commit metadata popup. This popup displays detailed information about the commit associated with a blame line. ```lua -- Triggered by the commit_info mapping (default: "i") in the blame window. -- To change: require("blame").setup({ mappings = { commit_info = "K" }, -- use "K" like hover docs }) ``` -------------------------------- ### blame.highlights.get_hld_lines_from_porcelain Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Converts raw porcelain blame lines into a structured format (`LineWithHl[]`) suitable for rendering. It applies formatting functions and normalizes column widths for alignment. This function is essential for displaying blame information in a user-friendly way. ```APIDOC ## `blame.highlights.get_hld_lines_from_porcelain(lines, config)` — Convert porcelain to render-ready `LineWithHl[]` Applies `config.format_fn` to each porcelain line (with `merge_consecutive` support) and then normalises column widths so all rows align. Returns a `LineWithHl[]` array consumed by both `WindowView` and `VirtualView`. ### Parameters - **lines**: The raw porcelain blame data. - **config**: A table containing configuration options such as `format_fn`, `date_format`, `relative_date_if_recent`, `merge_consecutive`, `max_summary_width`, and `ns_id`. ### Returns - `LineWithHl[]`: An array of lines formatted for display, with each line containing text and highlight information. ``` -------------------------------- ### blame.porcelain_parser.parse_porcelain Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Parses raw `git blame --line-porcelain` output into an array of `Porcelain` tables. Each table includes standard porcelain fields and the original line number from the commit. ```APIDOC ## `blame.porcelain_parser.parse_porcelain(data)` — Parse raw `git blame --line-porcelain` output Converts the raw string-array produced by `git blame --line-porcelain` into an array of `Porcelain` tables, one per source line. Each table contains all standard porcelain fields plus `original_line` (the source line number at the blamed commit). ```lua local parser = require("blame.porcelain_parser") -- Simulated raw porcelain input (normally produced by git.blame()) local raw = { "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 1 1 1", "author Jane Doe", "author-mail ", "author-time 1714521600", "author-tz +0200", "committer Jane Doe", "committer-mail ", "committer-time 1714521600", "committer-tz +0200", "summary Fix null pointer dereference in parser", "filename src/parser.lua", "\tlocal result = parse(input)", } local lines = parser.parse_porcelain(raw) -- lines[1] = { -- hash = "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", -- original_line = 1, -- author = "Jane Doe", -- author_email = "", -- author_time = 1714521600, -- author_tz = "+0200", -- committer = "Jane Doe", -- committer_mail = "", -- committer_time = 1714521600, -- committer_tz = "+0200", -- summary = "Fix null pointer dereference in parser", -- filename = "src/parser.lua", -- content = "\tlocal result = parse(input)", -- } ``` ``` -------------------------------- ### Custom Blame View Interface Definition Source: https://github.com/fabijanzulj/blame.nvim/blob/main/README.md Defines the interface for creating custom blame views. Implement this to add new ways of displaying blame information. ```lua ---@class BlameView ---@field new fun(self, config: Config) : BlameView ---@field open fun(self, lines: Porcelain[]) ---@field is_open fun(): boolean ---@field close fun(cleanup: boolean) ``` -------------------------------- ### blame.highlights.create_highlights_per_hash Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Assigns per-commit highlight groups by sorting unique commit hashes and assigning a highlight group named by the short hash. Colors can be customized via configuration. ```APIDOC ## `blame.highlights.create_highlights_per_hash(lines, config)` — Assign per-commit highlight groups Iterates all unique commit hashes in the parsed blame data, sorts them by author timestamp (oldest → newest), then assigns each a highlight group named by the short hash (7 chars). Colors are either picked from `config.colors` using a spread algorithm or generated randomly. ```lua local highlights = require("blame.highlights") -- Using a custom fixed palette (6 colors, evenly spread across N unique commits) require("blame").setup({ colors = { "#e06c75", -- red "#d19a66", -- orange "#e5c07b", -- yellow "#98c379", -- green "#61afef", -- blue "#c678dd", -- purple }, }) -- Internally, create_highlights_per_hash() calls: -- vim.api.nvim_set_hl(0, "a1b2c3d", { fg = "#98c379", ctermfg = }) -- The short hash "a1b2c3d" is then used as a highlight group name in extmarks/buf_add_highlight. ``` ``` -------------------------------- ### blame.blame_stack Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Allows stepping backwards through the history of a file commit-by-commit. 'push(commit)' loads the file content at the parent commit and re-runs blame there; 'pop()' reverses the operation. A floating window shows the current stack of visited commits. ```APIDOC ## `blame.blame_stack` — Navigable blame history (time-travel) Allows stepping backwards through the history of a file commit-by-commit. `push(commit)` loads the file content at the parent commit and re-runs blame there; `pop()` reverses the operation. A floating window shows the current stack of visited commits. ```lua -- Navigation is triggered via keymaps set in the blame window. -- Default bindings: -- → stack_push (go back in history for line under cursor) -- → stack_pop (return to the next commit) -- To remap: require("blame").setup({ mappings = { stack_push = "", stack_pop = "", }, }) -- The stack float window shows entries like: -- a1b2c3d Jane Doe 01.05.2024 -- e5f6a7b Alice 15.03.2024 ← current position (highlighted with commit color) ``` ``` -------------------------------- ### Assign per-commit highlight groups Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt Assigns highlight groups to unique commit hashes, sorted by author timestamp. Colors are either from a custom palette or generated randomly, and are applied using `vim.api.nvim_set_hl`. ```lua local highlights = require("blame.highlights") -- Using a custom fixed palette (6 colors, evenly spread across N unique commits) require("blame").setup({ colors = { "#e06c75", -- red "#d19a66", -- orange "#e5c07b", -- yellow "#98c379", -- green "#61afef", -- blue "#c678dd", -- purple }, }) -- Internally, create_highlights_per_hash() calls: -- vim.api.nvim_set_hl(0, "a1b2c3d", { fg = "#98c379", ctermfg = }) -- The short hash "a1b2c3d" is then used as a highlight group name in extmarks/buf_add_highlight. ``` -------------------------------- ### Conditional blame toggle with keymap Source: https://context7.com/fabijanzulj/blame.nvim/llms.txt This Lua code snippet defines a keymap that toggles the blame view. It checks if the blame view is already open and displays a message if it is, otherwise it opens the view. ```lua -- Toggle blame only when not already open, otherwise print a message vim.keymap.set("n", "gb", function() if require("blame").is_open() then vim.notify("blame.nvim: view already open", vim.log.levels.INFO) else vim.cmd("BlameToggle") end end, { desc = "Open git blame" }) ```