mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 02:38:46 +00:00
feat: added lazygit
This commit is contained in:
parent
1abce78a8b
commit
fc32619734
2 changed files with 181 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
---@field rename snacks.rename
|
||||
---@field float snacks.float
|
||||
---@field terminal snacks.terminal
|
||||
---@field lazygit snacks.lazygit
|
||||
local M = {}
|
||||
|
||||
setmetatable(M, {
|
||||
|
@ -26,6 +27,7 @@ _G.Snacks = M
|
|||
---@field words snacks.words.Config
|
||||
---@field float snacks.float.Config
|
||||
---@field terminal snacks.terminal.Config
|
||||
---@field lazygit snacks.lazygit.Config
|
||||
local config = {
|
||||
bigfile = { enabled = true },
|
||||
quickfile = { enabled = true },
|
||||
|
|
179
lua/snacks/lazygit.lua
Normal file
179
lua/snacks/lazygit.lua
Normal file
|
@ -0,0 +1,179 @@
|
|||
---@class snacks.lazygit
|
||||
---@overload fun(opts?: snacks.lazygit.Config): snacks.float
|
||||
local M = setmetatable({}, {
|
||||
__call = function(t, ...)
|
||||
return t.open(...)
|
||||
end,
|
||||
})
|
||||
|
||||
---@alias snacks.lazygit.Color {fg?:string, bg?:string, bold?:boolean}
|
||||
|
||||
---@class snacks.lazygit.Theme: table<number, snacks.lazygit.Color>
|
||||
---@field activeBorderColor snacks.lazygit.Color
|
||||
---@field cherryPickedCommitBgColor snacks.lazygit.Color
|
||||
---@field cherryPickedCommitFgColor snacks.lazygit.Color
|
||||
---@field defaultFgColor snacks.lazygit.Color
|
||||
---@field inactiveBorderColor snacks.lazygit.Color
|
||||
---@field optionsTextColor snacks.lazygit.Color
|
||||
---@field searchingActiveBorderColor snacks.lazygit.Color
|
||||
---@field selectedLineBgColor snacks.lazygit.Color
|
||||
---@field unstagedChangesColor snacks.lazygit.Color
|
||||
|
||||
---@class snacks.lazygit.Config: snacks.terminal.Config
|
||||
---@field args? string[]
|
||||
---@field theme? snacks.lazygit.Theme
|
||||
local defaults = {
|
||||
configure = true,
|
||||
theme_path = vim.fs.normalize(vim.fn.stdpath("cache") .. "/lazygit-theme.yml"),
|
||||
theme = {
|
||||
[241] = { fg = "Special" },
|
||||
activeBorderColor = { fg = "MatchParen", bold = true },
|
||||
cherryPickedCommitBgColor = { fg = "Identifier" },
|
||||
cherryPickedCommitFgColor = { fg = "Function" },
|
||||
defaultFgColor = { fg = "Normal" },
|
||||
inactiveBorderColor = { fg = "FloatBorder" },
|
||||
optionsTextColor = { fg = "Function" },
|
||||
searchingActiveBorderColor = { fg = "MatchParen", bold = true },
|
||||
selectedLineBgColor = { bg = "Visual" }, -- set to `default` to have no background colour
|
||||
unstagedChangesColor = { fg = "DiagnosticError" },
|
||||
},
|
||||
}
|
||||
|
||||
-- re-create config file on startup
|
||||
local dirty = true
|
||||
local config_dir ---@type string?
|
||||
|
||||
-- re-create theme file on ColorScheme change
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
callback = function()
|
||||
dirty = true
|
||||
end,
|
||||
})
|
||||
|
||||
---@param opts snacks.lazygit.Config
|
||||
local function env(opts)
|
||||
if not config_dir then
|
||||
local proc = vim.system({ "lazygit", "-cd" }, { text = true }):wait()
|
||||
local lines = vim.split(proc.stdout, "\n", { plain = true })
|
||||
|
||||
if proc.code == 0 then
|
||||
config_dir = vim.split(lines[1], "\n", { plain = true })[1]
|
||||
vim.env.LG_CONFIG_FILE = vim.fs.normalize(config_dir .. "/config.yml" .. "," .. opts.theme_path)
|
||||
local custom_config = vim.fs.normalize(config_dir .. "/custom.yml")
|
||||
if vim.uv.fs_stat(custom_config) and vim.uv.fs_stat(custom_config).type == "file" then
|
||||
vim.env.LG_CONFIG_FILE = vim.env.LG_CONFIG_FILE .. "," .. custom_config
|
||||
end
|
||||
else
|
||||
local msg = {
|
||||
"Failed to get **lazygit** config directory.",
|
||||
"Will not apply **lazygit** config.",
|
||||
"",
|
||||
"# Error:",
|
||||
vim.trim(proc.stdout .. "\n" .. proc.stderr),
|
||||
}
|
||||
vim.notify(table.concat(msg, "\n"), vim.log.levels.ERROR, { title = "lazygit" })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param v snacks.lazygit.Color
|
||||
---@return string[]
|
||||
local function get_color(v)
|
||||
---@type string[]
|
||||
local color = {}
|
||||
for _, c in ipairs({ "fg", "bg" }) do
|
||||
if v[c] then
|
||||
local name = v[c]
|
||||
local hl = vim.api.nvim_get_hl and vim.api.nvim_get_hl(0, { name = name, link = false })
|
||||
or vim.api.nvim_get_hl_by_name(name, true)
|
||||
|
||||
local hl_color ---@type number?
|
||||
if c == "fg" then
|
||||
hl_color = hl and hl.fg or hl.foreground
|
||||
else
|
||||
hl_color = hl and hl.bg or hl.background
|
||||
end
|
||||
if hl_color then
|
||||
table.insert(color, string.format("#%06x", hl_color))
|
||||
end
|
||||
end
|
||||
end
|
||||
if v.bold then
|
||||
table.insert(color, "bold")
|
||||
end
|
||||
return color
|
||||
end
|
||||
|
||||
---@param opts snacks.lazygit.Config
|
||||
local function update_config(opts)
|
||||
---@type table<string, string[]>
|
||||
local theme = {}
|
||||
|
||||
for k, v in pairs(opts.theme) do
|
||||
if type(k) == "number" then
|
||||
local color = get_color(v)
|
||||
-- LazyGit uses color 241 a lot, so also set it to a nice color
|
||||
-- pcall, since some terminals don't like this
|
||||
pcall(io.write, ("\27]4;%d;%s\7"):format(k, color[1]))
|
||||
else
|
||||
theme[k] = get_color(v)
|
||||
end
|
||||
end
|
||||
|
||||
local config = [[
|
||||
os:
|
||||
editPreset: "nvim-remote"
|
||||
gui:
|
||||
nerdFontsVersion: 3
|
||||
theme:
|
||||
]]
|
||||
|
||||
---@type string[]
|
||||
local lines = {}
|
||||
for k, v in pairs(theme) do
|
||||
lines[#lines + 1] = (" %s:"):format(k)
|
||||
for _, c in ipairs(v) do
|
||||
lines[#lines + 1] = (" - %q"):format(c)
|
||||
end
|
||||
end
|
||||
config = config .. table.concat(lines, "\n")
|
||||
vim.fn.writefile(vim.split(config, "\n", { plain = true }), opts.theme_path)
|
||||
dirty = false
|
||||
end
|
||||
|
||||
-- Opens lazygit
|
||||
---@param opts? snacks.lazygit.Config
|
||||
function M.open(opts)
|
||||
---@type snacks.lazygit.Config
|
||||
opts = Snacks.config.get("lazygit", defaults, opts)
|
||||
|
||||
local cmd = { "lazygit" }
|
||||
vim.list_extend(cmd, opts.args or {})
|
||||
|
||||
if opts.configure then
|
||||
if dirty then
|
||||
update_config(opts)
|
||||
end
|
||||
env(opts)
|
||||
end
|
||||
|
||||
return Snacks.terminal(cmd, opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.lazygit.Config
|
||||
function M.log(opts)
|
||||
opts = opts or {}
|
||||
opts.args = opts.args or { "log" }
|
||||
return M.open(opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.lazygit.Config
|
||||
function M.log_file(opts)
|
||||
local file = vim.trim(vim.api.nvim_buf_get_name(0))
|
||||
opts = opts or {}
|
||||
opts.args = { "-f", file }
|
||||
opts.cwd = vim.fn.fnamemodify(file, ":h")
|
||||
return M.open(opts)
|
||||
end
|
||||
|
||||
return M
|
Loading…
Add table
Add a link
Reference in a new issue