1
0
Fork 0
dotfiles/home/config/nvim/nifoc/statuscolumn.fnl

170 lines
8 KiB
Plaintext
Raw Normal View History

2023-01-11 21:45:22 +00:00
(let [mod {}
2023-07-05 21:55:20 +00:00
cache {:diagnostics {} :gitsigns {}}
2023-01-11 21:45:22 +00:00
api vim.api
o vim.opt
2023-04-03 09:01:19 +00:00
b vim.b
v vim.v
2023-01-14 16:07:11 +00:00
statusline (require :nifoc.statusline)
2023-01-14 21:45:23 +00:00
diagnostic vim.diagnostic
gitsigns (require :gitsigns)
2023-10-22 00:00:49 +00:00
gitsigns-ns (api.nvim_create_namespace :gitsigns_extmark_signs_)
2023-01-14 21:45:23 +00:00
augroup (vim.api.nvim_create_augroup :NifocStatuscolumn {:clear true})
aucmd vim.api.nvim_create_autocmd]
;; Cache
2023-07-05 21:55:20 +00:00
(fn cached-sign [key bufnr lnum]
(?. cache key bufnr lnum))
2023-01-22 12:47:36 +00:00
2023-07-05 21:55:20 +00:00
(fn maybe-setup-buffer-cache! [key bufnr]
(when (= (. cache key bufnr) nil)
(tset cache key bufnr {})))
(fn clear-cache! [key bufnr]
(tset cache key bufnr {}))
2023-01-14 21:45:23 +00:00
2023-04-03 09:01:19 +00:00
(fn cache-filter [func t]
(let [ret-tab {}]
(each [k v (pairs t)] (when (func v k) (tset ret-tab k v)))
ret-tab))
2023-01-22 12:47:36 +00:00
(fn clear-diagnostics-cache! [bufnr diagnostics]
2023-10-22 00:00:49 +00:00
(if (vim.tbl_isempty diagnostics) (tset cache :diagnostics bufnr nil)
(let [namespaces (vim.tbl_map #$1.namespace diagnostics)
current-cache (. cache :diagnostics bufnr)
new-cache (cache-filter #(not (vim.tbl_contains namespaces $1.ns))
current-cache)]
(tset cache :diagnostics bufnr new-cache))))
2023-01-22 12:47:36 +00:00
2023-01-14 21:45:23 +00:00
(fn update-cache-diagnostics [bufnr diagnostics]
2023-07-05 21:55:20 +00:00
(maybe-setup-buffer-cache! :diagnostics bufnr)
2023-01-22 12:47:36 +00:00
(clear-diagnostics-cache! bufnr diagnostics)
2023-01-14 21:45:23 +00:00
(each [_ diagnostic (pairs diagnostics)]
(let [lnum (+ diagnostic.lnum 1)
2023-07-05 21:55:20 +00:00
current (cached-sign :diagnostics bufnr lnum)]
2023-04-03 09:01:19 +00:00
(when (or (= current nil) (> diagnostic.severity current.severity))
2023-07-05 21:55:20 +00:00
(tset cache :diagnostics bufnr lnum
2023-01-22 12:47:36 +00:00
{:severity diagnostic.severity
:col diagnostic.col
:ns diagnostic.namespace})))))
2023-01-14 21:45:23 +00:00
(fn update-cache-gitsigns [bufnr]
2023-07-05 21:55:20 +00:00
(maybe-setup-buffer-cache! :gitsigns bufnr)
(clear-cache! :gitsigns bufnr)
2023-10-22 00:00:49 +00:00
(let [signs (api.nvim_buf_get_extmarks bufnr gitsigns-ns 0 -1
{:details true})]
(when (not (vim.tbl_isempty signs))
(each [_ [_id row _col details] (pairs signs)]
(let [lnum (+ row 1)
2023-07-05 21:55:20 +00:00
current (cached-sign :gitsigns bufnr lnum)]
2023-01-14 21:45:23 +00:00
(when (= current nil)
2023-10-22 00:00:49 +00:00
(tset cache :gitsigns bufnr lnum {:name details.sign_hl_group})))))))
2023-01-14 21:45:23 +00:00
(aucmd :DiagnosticChanged
2023-10-22 00:00:49 +00:00
{:callback #(let [full-mode (. (api.nvim_get_mode) :mode)
mode (full-mode:sub 1 1)]
(when (not= mode :i)
(update-cache-diagnostics $1.buf $1.data.diagnostics)))
2023-01-14 21:45:23 +00:00
:group augroup
:desc "Update cached diagnostic signs"})
2023-10-22 00:00:49 +00:00
(aucmd :CursorHold
{:callback #(update-cache-diagnostics $1.buf
(vim.diagnostic.get $1.buf))
:group augroup
:desc "Periodically update cached diagnostics"})
(aucmd :InsertLeave
{:callback (fn [args]
(vim.defer_fn #(update-cache-diagnostics args.buf
(vim.diagnostic.get args.buf))
1000))
:group augroup
:desc "Update diagnostics after leaving insert mode"})
2023-01-14 21:45:23 +00:00
(aucmd :User {:pattern :GitSignsUpdate
:callback #(update-cache-gitsigns $1.buf)
:group augroup
:desc "Update cached gitsigns signs"})
2023-07-07 17:57:55 +00:00
(aucmd :BufWipeout
2023-07-05 21:55:20 +00:00
{:callback (fn [args]
(tset cache :diagnostics args.buf nil)
(tset cache :gitsigns args.buf nil))
2023-01-14 21:45:23 +00:00
:group augroup
:desc "Clear sign cache for current buffer"})
2023-07-07 17:57:55 +00:00
(aucmd :BufWritePre
{:callback #(tset cache :diagnostics $1.buf nil)
:group augroup
:desc "Reset diagnostic signs on save"})
2023-01-11 21:45:22 +00:00
;; Line Number
2023-04-03 09:01:19 +00:00
(set mod.line-number {:condition #(or (o.number:get) (o.relativenumber:get))
1 statusline.push-right
2 {:provider (fn []
(let [relnum-opt (o.relativenumber:get)
relnum v.relnum
virtnum v.virtnum]
(if (not= virtnum 0) ""
(and relnum-opt (= relnum 0)) "%l"
relnum-opt (tostring relnum)
"%l")))}})
2023-01-11 21:45:22 +00:00
;; Signs
(set mod.signs {:provider "%s" :hl {:bold true}})
;; gitsigns
2023-04-03 09:01:19 +00:00
(set mod.gitsigns {:condition #(= b.nifoc_gitsigns_enabled 1)
:init (fn [self]
(let [bufnr (api.nvim_get_current_buf)
2023-07-05 21:55:20 +00:00
sign (cached-sign :gitsigns bufnr v.lnum)]
2023-04-03 09:01:19 +00:00
(set self.sign sign)
(set self.has_sign (not= sign nil))))
:provider " ▏"
:hl #(if $1.has_sign $1.sign.name :StatusLineNC)
:on_click {:name :heirline_statuscolumn_gitsigns
2023-10-22 00:00:49 +00:00
:callback (fn [_self]
2023-04-03 09:01:19 +00:00
(let [mouse (vim.fn.getmousepos)
cursor-pos [mouse.line 0]]
(api.nvim_win_set_cursor mouse.winid
cursor-pos)
(vim.defer_fn #(gitsigns.blame_line {:full true})
100)))}})
(set mod.gitsigns-or-bar [{:condition #(and (not= b.nifoc_gitsigns_enabled 1)
2023-01-14 16:07:11 +00:00
(or (o.number:get)
(o.relativenumber:get)))
:provider " ▏"
2023-01-12 09:59:15 +00:00
:hl :StatusLineNC}
mod.gitsigns])
2023-01-11 21:45:22 +00:00
;; Diagnostic signs
(set mod.diagnostic-signs
2023-10-22 00:00:49 +00:00
{:condition #(let [bufnr (api.nvim_get_current_buf)
buf-diagnostics (. cache :diagnostics bufnr)]
(and (= b.nifoc_diagnostics_enabled 1)
(not= buf-diagnostics nil)
(not (vim.tbl_isempty buf-diagnostics))))
2023-01-14 21:45:23 +00:00
:static {:sign-text {diagnostic.severity.ERROR " "
diagnostic.severity.WARN " "
diagnostic.severity.INFO " "
diagnostic.severity.HINT " "}
:sign-hl {diagnostic.severity.ERROR :DiagnosticSignError
diagnostic.severity.WARN :DiagnosticSignWarn
diagnostic.severity.INFO :DiagnosticSignInfo
diagnostic.severity.HINT :DiagnosticSignHint}}
2023-01-11 21:45:22 +00:00
:init (fn [self]
(let [bufnr (api.nvim_get_current_buf)
2023-07-05 21:55:20 +00:00
sign (cached-sign :diagnostics bufnr v.lnum)]
2023-01-11 21:45:22 +00:00
(set self.sign sign)
(set self.has_sign (not= sign nil))))
:provider #(if $1.has_sign
2023-01-14 21:45:23 +00:00
(. $1.sign-text $1.sign.severity)
2023-01-11 21:45:22 +00:00
" ")
:hl #(when $1.has_sign
2023-01-14 21:45:23 +00:00
(. $1.sign-hl $1.sign.severity))
2023-01-11 21:45:22 +00:00
:on_click {:name :heirline_statuscolumn_diagnostic
:callback (fn [self]
2023-01-11 22:48:51 +00:00
(let [mouse (vim.fn.getmousepos)
line (- mouse.line 1)
cursor-pos [mouse.line 0]]
(api.nvim_win_set_cursor mouse.winid
cursor-pos)
(vim.defer_fn #(vim.diagnostic.open_float {:bufnr self.bufnr
:pos line
:scope :line})
2023-04-03 09:01:19 +00:00
100)))}})
;; Debug
2023-10-22 00:00:49 +00:00
(set mod._debug_cache #{: cache})
2023-01-11 21:45:22 +00:00
mod)