From 9b700ce8692f77da617d293301c2f0259a5be641 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Mon, 2 Feb 2026 16:37:51 -0500 Subject: [PATCH] feat: diffsplit support --- lua/fugitive-ts/init.lua | 79 ++++++++++++++++++++++++++++++++++++++++ plugin/fugitive-ts.lua | 11 ++++++ 2 files changed, 90 insertions(+) diff --git a/lua/fugitive-ts/init.lua b/lua/fugitive-ts/init.lua index 5a2d064..0f42e7e 100644 --- a/lua/fugitive-ts/init.lua +++ b/lua/fugitive-ts/init.lua @@ -10,6 +10,9 @@ ---@field enabled boolean ---@field max_lines integer +---@class fugitive-ts.DiffsplitConfig +---@field enabled boolean + ---@class fugitive-ts.Config ---@field enabled boolean ---@field debug boolean @@ -18,6 +21,7 @@ ---@field treesitter fugitive-ts.TreesitterConfig ---@field vim fugitive-ts.VimConfig ---@field highlights fugitive-ts.Highlights +---@field diffsplit fugitive-ts.DiffsplitConfig ---@class fugitive-ts ---@field attach fun(bufnr?: integer) @@ -80,6 +84,9 @@ local default_config = { background = true, gutter = true, }, + diffsplit = { + enabled = true, + }, } ---@type fugitive-ts.Config @@ -88,6 +95,15 @@ local config = vim.deepcopy(default_config) ---@type table local attached_buffers = {} +---@type table +local diff_windows = {} + +---@param bufnr integer +---@return boolean +local function is_fugitive_buffer(bufnr) + return vim.api.nvim_buf_get_name(bufnr):match('^fugitive://') ~= nil +end + ---@param msg string ---@param ... any local function dbg(msg, ...) @@ -222,6 +238,62 @@ local function compute_highlight_groups() vim.api.nvim_set_hl(0, 'FugitiveTsDelete', { bg = blended_del }) vim.api.nvim_set_hl(0, 'FugitiveTsAddNr', { fg = add_fg, bg = blended_add }) vim.api.nvim_set_hl(0, 'FugitiveTsDeleteNr', { fg = del_fg, bg = blended_del }) + + local diff_change = resolve_hl('DiffChange') + local diff_text = resolve_hl('DiffText') + + vim.api.nvim_set_hl(0, 'FugitiveTsDiffAdd', { bg = diff_add.bg }) + vim.api.nvim_set_hl(0, 'FugitiveTsDiffDelete', { bg = diff_delete.bg }) + vim.api.nvim_set_hl(0, 'FugitiveTsDiffChange', { bg = diff_change.bg }) + vim.api.nvim_set_hl(0, 'FugitiveTsDiffText', { bg = diff_text.bg }) +end + +local DIFF_WINHIGHLIGHT = table.concat({ + 'DiffAdd:FugitiveTsDiffAdd', + 'DiffDelete:FugitiveTsDiffDelete', + 'DiffChange:FugitiveTsDiffChange', + 'DiffText:FugitiveTsDiffText', +}, ',') + +function M.attach_diff() + if not config.enabled or not config.diffsplit.enabled then + return + end + + local tabpage = vim.api.nvim_get_current_tabpage() + local wins = vim.api.nvim_tabpage_list_wins(tabpage) + + local has_fugitive = false + local diff_wins = {} + + for _, win in ipairs(wins) do + if vim.api.nvim_win_is_valid(win) and vim.wo[win].diff then + table.insert(diff_wins, win) + local bufnr = vim.api.nvim_win_get_buf(win) + if is_fugitive_buffer(bufnr) then + has_fugitive = true + end + end + end + + if not has_fugitive then + return + end + + for _, win in ipairs(diff_wins) do + vim.api.nvim_set_option_value('winhighlight', DIFF_WINHIGHLIGHT, { win = win }) + diff_windows[win] = true + dbg('applied diff winhighlight to window %d', win) + end +end + +function M.detach_diff() + for win, _ in pairs(diff_windows) do + if vim.api.nvim_win_is_valid(win) then + vim.api.nvim_set_option_value('winhighlight', '', { win = win }) + end + diff_windows[win] = nil + end end ---@param opts? fugitive-ts.Config @@ -236,8 +308,15 @@ function M.setup(opts) treesitter = { opts.treesitter, 'table', true }, vim = { opts.vim, 'table', true }, highlights = { opts.highlights, 'table', true }, + diffsplit = { opts.diffsplit, 'table', true }, }) + if opts.diffsplit then + vim.validate({ + ['diffsplit.enabled'] = { opts.diffsplit.enabled, 'boolean', true }, + }) + end + if opts.treesitter then vim.validate({ ['treesitter.enabled'] = { opts.treesitter.enabled, 'boolean', true }, diff --git a/plugin/fugitive-ts.lua b/plugin/fugitive-ts.lua index cfe7a03..6b815ce 100644 --- a/plugin/fugitive-ts.lua +++ b/plugin/fugitive-ts.lua @@ -9,3 +9,14 @@ vim.api.nvim_create_autocmd('FileType', { require('fugitive-ts').attach(args.buf) end, }) + +vim.api.nvim_create_autocmd('OptionSet', { + pattern = 'diff', + callback = function() + if vim.wo.diff then + require('fugitive-ts').attach_diff() + else + require('fugitive-ts').detach_diff() + end + end, +})