Files
dmtrkovalenko--fff/lua/fff/git_utils.lua
T
Dmitriy Kovalenko c3ed9fb17b fix: Binary download integrity issues (#260)
* feat: cleanup hl groups resolution (#259)

* feat: cleanup hl groups resolution

* chore: Update docs for - feat: cleanup hl groups resolution

* chore: Update docs for - feat: cleanup hl groups resolution (#259)

* feat: cleanup hl groups resolution (#259)

* feat: cleanup hl groups resolution

* chore: Update docs for - feat: cleanup hl groups resolution
2026-02-24 17:32:10 -08:00

197 lines
6.9 KiB
Lua

local M = {}
-- git signs like borders
M.border_chars = {
untracked = '┆', -- Dotted vertical line
ignored = '┆', -- Dotted vertical line
unknown = '┆',
modified = '┃', -- Vertical line
deleted = '▁', -- Bottom horizontal line
renamed = '┃', -- Vertical line
staged_new = '┃', -- Vertical line
staged_modified = '┃', -- Vertical line
staged_deleted = '▁', -- Bottom horizontal line
clean = '',
clear = '',
}
-- Cache for config-based highlight mappings
local highlights_cache = nil
local border_highlights_cache = nil
local border_highlights_selected_cache = nil
--- Build and cache highlight mappings from config
local function ensure_cache()
if highlights_cache then return end
local config = require('fff.conf').get()
highlights_cache = {
untracked = config.hl.git_untracked,
modified = config.hl.git_modified,
deleted = config.hl.git_deleted,
renamed = config.hl.git_renamed,
staged_new = config.hl.git_staged,
staged_modified = config.hl.git_staged,
staged_deleted = config.hl.git_staged,
ignored = config.hl.git_ignored,
clean = '',
clear = '',
unknown = config.hl.git_untracked,
}
border_highlights_cache = {
untracked = config.hl.git_sign_untracked,
modified = config.hl.git_sign_modified,
deleted = config.hl.git_sign_deleted,
renamed = config.hl.git_sign_renamed,
staged_new = config.hl.git_sign_staged,
staged_modified = config.hl.git_sign_staged,
staged_deleted = config.hl.git_sign_staged,
ignored = config.hl.git_sign_ignored,
clean = '',
clear = '',
unknown = config.hl.git_sign_untracked,
}
border_highlights_selected_cache = {
untracked = config.hl.git_sign_untracked_selected,
modified = config.hl.git_sign_modified_selected,
deleted = config.hl.git_sign_deleted_selected,
renamed = config.hl.git_sign_renamed_selected,
staged_new = config.hl.git_sign_staged_selected,
staged_modified = config.hl.git_sign_staged_selected,
staged_deleted = config.hl.git_sign_staged_selected,
ignored = config.hl.git_sign_ignored_selected,
clean = '',
clear = '',
unknown = config.hl.git_sign_untracked_selected,
}
end
--- Get highlight group for git status text
--- @param git_status string Git status
--- @return string Highlight group name
function M.get_text_highlight(git_status)
ensure_cache()
return highlights_cache and highlights_cache[git_status] or ''
end
--- Get border highlight group for git status
--- @param git_status string Git status
--- @return string Highlight group name
function M.get_border_highlight(git_status)
ensure_cache()
return border_highlights_cache and border_highlights_cache[git_status] or ''
end
--- Get selected border highlight group for git status
--- @param git_status string Git status
--- @return string Highlight group name
function M.get_border_highlight_selected(git_status)
ensure_cache()
return border_highlights_selected_cache and border_highlights_selected_cache[git_status] or ''
end
function M.get_border_char(git_status) return M.border_chars[git_status] or '' end
function M.should_show_border(git_status)
return git_status == 'untracked'
or git_status == 'modified'
or git_status == 'staged_new'
or git_status == 'staged_modified'
or git_status == 'deleted'
or git_status == 'staged_deleted'
or git_status == 'renamed'
end
function M.setup_highlights()
vim.cmd([[
" Symbol highlights
highlight default FFFGitStaged guifg=#10B981 ctermfg=2
highlight default FFFGitModified guifg=#F59E0B ctermfg=3
highlight default FFFGitDeleted guifg=#EF4444 ctermfg=1
highlight default FFFGitRenamed guifg=#8B5CF6 ctermfg=5
highlight default FFFGitUntracked guifg=#10B981 ctermfg=2
highlight default FFFGitIgnored guifg=#4B5563 ctermfg=8
" Thin border highlights
highlight default FFFGitSignStaged guifg=#10B981 ctermfg=2
highlight default FFFGitSignModified guifg=#F59E0B ctermfg=3
highlight default FFFGitSignDeleted guifg=#EF4444 ctermfg=1
highlight default FFFGitSignRenamed guifg=#8B5CF6 ctermfg=5
highlight default FFFGitSignUntracked guifg=#10B981 ctermfg=2
highlight default FFFGitSignIgnored guifg=#4B5563 ctermfg=8
" Fallback to GitSigns highlights if they exist
highlight default link FFFGitSignStaged GitSignsAdd
highlight default link FFFGitSignModified GitSignsChange
highlight default link FFFGitSignDeleted GitSignsDelete
highlight default link FFFGitSignUntracked GitSignsAdd
]])
-- Highlighes for git signs both for selected and normal states
local git_highlights = {
{ 'FFFGitSignStaged', 'FFFGitSignStagedSelected', '#10B981', 2 },
{ 'FFFGitSignModified', 'FFFGitSignModifiedSelected', '#F59E0B', 3 },
{ 'FFFGitSignDeleted', 'FFFGitSignDeletedSelected', '#EF4444', 1 },
{ 'FFFGitSignRenamed', 'FFFGitSignRenamedSelected', '#8B5CF6', 5 },
{ 'FFFGitSignUntracked', 'FFFGitSignUntrackedSelected', '#10B981', 2 },
{ 'FFFGitSignIgnored', 'FFFGitSignIgnoredSelected', '#4B5563', 8 },
}
local visual_bg_gui = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Visual')), 'bg', 'gui')
local visual_bg_cterm = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Visual')), 'bg', 'cterm')
for _, hl in ipairs(git_highlights) do
local _, selected_hl, gui_fg, cterm_fg = hl[1], hl[2], hl[3], hl[4]
local gui_bg = visual_bg_gui ~= '' and visual_bg_gui or 'NONE'
local cterm_bg = visual_bg_cterm ~= '' and visual_bg_cterm or 'NONE'
vim.cmd(
string.format(
'highlight default %s guifg=%s guibg=%s ctermfg=%d ctermbg=%s',
selected_hl,
gui_fg,
gui_bg,
cterm_fg,
cterm_bg
)
)
end
-- Selection highlight - use Directory/Number colors (better than green 'Added')
vim.cmd('highlight default link FFFSelected Directory')
local dir_fg_gui = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Directory')), 'fg', 'gui')
local dir_fg_cterm = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Directory')), 'fg', 'cterm')
if dir_fg_gui == '' or dir_fg_gui == '-1' then
-- Directory not defined, try Number
dir_fg_gui = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Number')), 'fg', 'gui')
dir_fg_cterm = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Number')), 'fg', 'cterm')
end
-- Fallback to blue if neither Directory nor Number have colors
local is_dark_bg = vim.o.background == 'dark'
local gui_fg = dir_fg_gui ~= '' and dir_fg_gui or (is_dark_bg and '#60A5FA' or '#0369A1')
local cterm_fg = dir_fg_cterm ~= '' and dir_fg_cterm or (is_dark_bg and '12' or '4')
local gui_bg = visual_bg_gui ~= '' and visual_bg_gui or 'NONE'
local cterm_bg = visual_bg_cterm ~= '' and visual_bg_cterm or 'NONE'
-- Create combined highlight: Directory/Number foreground + Visual background
vim.cmd(
string.format(
'highlight default FFFSelectedActive guifg=%s guibg=%s ctermfg=%s ctermbg=%s',
gui_fg,
gui_bg,
cterm_fg,
cterm_bg
)
)
end
return M