Skip to content

Commit

Permalink
refactor(neovim): statuscolumn via heirline
Browse files Browse the repository at this point in the history
  • Loading branch information
olimorris committed Dec 8, 2023
1 parent 5aebea3 commit a99b6b5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 242 deletions.
17 changes: 0 additions & 17 deletions .config/nvim/lua/plugins/heirline/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,6 @@ return {
local align = { provider = "%=" }
local spacer = { provider = " " }

statuscolumn = {
condition = function()
return not conditions.buffer_matches({
buftype = buftypes,
filetype = force_inactive_filetypes,
})
end,
static = statuscolumn.static,
init = statuscolumn.init,
statuscolumn.signs,
align,
statuscolumn.line_numbers,
spacer,
statuscolumn.folds,
statuscolumn.git_signs,
-- statuscolumn.line,
},
heirline.setup({
statusline = {
static = {
Expand Down
300 changes: 75 additions & 225 deletions .config/nvim/lua/plugins/heirline/statuscolumn.lua
Original file line number Diff line number Diff line change
@@ -1,238 +1,88 @@
local M = {}

local conditions = require("heirline.conditions")
local gitsigns_avail, gitsigns = pcall(require, "gitsigns")

M.static = {
click_args = function(self, minwid, clicks, button, mods)
local args = {
minwid = minwid,
clicks = clicks,
button = button,
mods = mods,
mousepos = vim.fn.getmousepos(),
}
local sign = vim.fn.screenstring(args.mousepos.screenrow, args.mousepos.screencol)
if sign == " " then
sign = vim.fn.screenstring(args.mousepos.screenrow, args.mousepos.screencol - 1)
end
args.sign = self.signs[sign]
vim.api.nvim_set_current_win(args.mousepos.winid)
vim.api.nvim_win_set_cursor(0, { args.mousepos.line, 0 })

return args
end,
handlers = {},
}

M.init = function(self)
self.signs = {}

self.handlers.signs = function(args)
return vim.schedule(vim.diagnostic.open_float)
end

self.handlers.line_number = function(args)
local dap_avail, dap = pcall(require, "dap")
if dap_avail then
vim.schedule(dap.toggle_breakpoint)
end
end

self.handlers.git_signs = function(args)
if gitsigns_avail then
vim.schedule(gitsigns.preview_hunk)
end
end

self.handlers.fold = function(args)
local lnum = args.mousepos.line
if vim.fn.foldlevel(lnum) <= vim.fn.foldlevel(lnum - 1) then
return
end
vim.cmd.execute("'" .. lnum .. "fold" .. (vim.fn.foldclosed(lnum) == -1 and "close" or "open") .. "'")
end
end

M.signs = {
-- condition = function() return conditions.has_diagnostics() end,
init = function(self)
local signs = vim.fn.sign_getplaced(vim.api.nvim_get_current_buf(), {
group = "*",
lnum = vim.v.lnum,
})

if #signs == 0 or signs[1].signs == nil then
self.sign = nil
self.has_sign = false
return
end

-- Filter out git signs
signs = vim.tbl_filter(function(sign)
return not vim.startswith(sign.group, "gitsigns")
end, signs[1].signs)

if #signs == 0 then
self.sign = nil
else
self.sign = signs[1]
end

self.has_sign = self.sign ~= nil
end,
provider = function(self)
if self.has_sign then
return vim.fn.sign_getdefined(self.sign.name)[1].text
end
return " "
end,
hl = function(self)
if self.has_sign then
-- Neotest signs
if self.sign.group == "neotest-status" then
if self.sign.name == "neotest_running" then
return "NeotestRunning"
end
if self.sign.name == "neotest_failed" then
return "NeotestFailed"
end
if self.sign.name == "neotest_passed" then
return "NeotestPassed"
return {
{
-- Signs
{
init = function(self)
local signs = {}

local extmarks = vim.api.nvim_buf_get_extmarks(
0,
-1,
{ vim.v.lnum - 1, 0 },
{ vim.v.lnum - 1, -1 },
{ details = true, type = "sign" }
)

for _, extmark in pairs(extmarks) do
if extmark[4].ns_id ~= vim.api.nvim_get_namespaces()["gitsigns_extmark_signs_"] then
signs[#signs + 1] = {
name = extmark[4].sign_hl_group or "",
text = extmark[4].sign_text,
sign_hl_group = extmark[4].sign_hl_group,
priority = extmark[4].priority,
}
end
end
return "NeotestSkipped"
end

-- Everything else
local hl = self.sign.name
return (vim.fn.hlexists(hl) ~= 0 and hl)
end
end,
on_click = {
name = "sign_click",
callback = function(self, ...)
if self.handlers.signs then
self.handlers.signs(self.click_args(self, ...))
end
end,
},
}

M.line_numbers = {
provider = function()
if vim.v.virtnum ~= 0 then
return ""
end
-- Sort by priority
table.sort(signs, function(a, b)
return (a.priority or 0) < (b.priority or 0)
end)

if vim.v.relnum == 0 then
return vim.v.lnum
end

return vim.v.relnum
end,
on_click = {
name = "line_number_click",
callback = function(self, ...)
if self.handlers.line_number then
self.handlers.line_number(self.click_args(self, ...))
end
end,
},
}

M.folds = {
condition = function()
return vim.v.virtnum == 0
end,
init = function(self)
self.lnum = vim.v.lnum
self.folded = vim.fn.foldlevel(self.lnum) > vim.fn.foldlevel(self.lnum - 1)
end,
{
condition = function(self)
return self.folded
end,
{
self.sign = signs[1]
end,
provider = function(self)
if vim.fn.foldclosed(self.lnum) == -1 then
return ""
end
return self.sign and self.sign.text or ""
end,
hl = function(self)
return self.sign and self.sign.sign_hl_group
end,
},
-- Line Numbers
{
provider = function(self)
if vim.fn.foldclosed(self.lnum) ~= -1 then
return ""
end
end,
hl = { fg = "yellow" },
provider = "%=%4{v:virtnum ? '' : &nu ? (&rnu && v:relnum ? v:relnum : v:lnum) . ' ' : ''}",
},
},
{
condition = function(self)
return not self.folded
end,
provider = " ",
},
on_click = {
name = "fold_click",
callback = function(self, ...)
if self.handlers.fold then
self.handlers.fold(self.click_args(self, ...))
end
end,
},
}

M.git_signs = {
{
condition = function()
return not conditions.is_git_repo() or vim.v.virtnum ~= 0
end,
provider = "",
hl = "HeirlineStatusColumn",
},
{
condition = function()
return conditions.is_git_repo() and vim.v.virtnum == 0
end,
init = function(self)
local signs = vim.fn.sign_getplaced(vim.api.nvim_get_current_buf(), {
group = "gitsigns_vimfn_signs_",
lnum = vim.v.lnum,
})

if #signs == 0 or signs[1].signs == nil or #signs[1].signs == 0 or signs[1].signs[1].name == nil then
self.sign = nil
else
self.sign = signs[1].signs[1]
end

self.has_sign = self.sign ~= nil
end,
provider = "",
hl = function(self)
if self.has_sign then
return self.sign.name
end
return "HeirlineStatusColumn"
end,
on_click = {
name = "gitsigns_click",
callback = function(self, ...)
if self.handlers.git_signs then
self.handlers.git_signs(self.click_args(self, ...))
end
end,
-- Git Signs
{
{
condition = function()
return conditions.is_git_repo() and vim.v.virtnum == 0
end,
init = function(self)
local ns_id = vim.api.nvim_get_namespaces()["gitsigns_extmark_signs_"]

if ns_id then
local extmark = vim.api.nvim_buf_get_extmarks(
0,
ns_id,
{ vim.v.lnum - 1, 0 },
{ vim.v.lnum, 0 },
{ limit = 1, details = true }
)[1]

self.sign = extmark and extmark[4]["sign_hl_group"]
end
end,
{
provider = "",
hl = function(self)
return self.sign or { fg = "bg" }
end,
on_click = {
name = "heirline_statuscolumn_gitsigns",
callback = function(_self)
local mouse = vim.fn.getmousepos()
local cursor_pos = { mouse.line, 0 }
vim.api.nvim_win_set_cursor(mouse.winid, cursor_pos)
vim.defer_fn(function()
require("gitsigns").blame_line({ full = true })
end, 100)
end,
},
},
},
},
},
}

M.line = {
{
provider = "",
hl = "HeirlineStatusColumn",
},
}

return M

0 comments on commit a99b6b5

Please sign in to comment.