summary refs log tree commit diff
path: root/.config/nvim/lua/config/statusline.lua
blob: fed6d338c2966e3108b7fafb745d49b9cad3d32d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function _G.statusline()
  local bufnr = vim.fn.bufnr() or 0
  local hi = statusline_color(vim.fn.mode())

  local sl = hi
  -- sl = sl .. statusline_append([[ ⢷]], 'StatusLineIcon', hi)

  sl = sl .. [[%-h%-w%-q%-f %-m%-r]]

  sl = sl .. statusline_append(statusline_git(bufnr, hi), 'StatusLineGit', hi)

  sl = sl .. statusline_append(statusline_grapple(bufnr, hi), 'StatusLineGrapple', hi)

  sl = sl .. [[ %= ]] -- spacer

  sl = sl .. statusline_append(statusline_lsp_diagnostics(bufnr, hi), 'StatusLineDiagnostics', hi)

  sl = sl .. statusline_append(statusline_dap(bufnr, hi), 'StatusLineDap', hi)

  -- sl = sl .. [[ %= ]] -- spacer

  sl = sl .. statusline_append(statusline_spinner(bufnr, hi), 'StatusLineJobs', hi)

  sl = sl .. [[%-l:%-v --%p%%-- %-Y]]

  return sl
end

function _G.statusline_color(mode)
  local hi = '%*'
  if mode == 'i' then
    -- hi = '%#StatusLineInsert#'
  elseif mode == 'c' then
    -- hi = '%#StatusLineCommand#'
  elseif mode == 'v' or mode == 'V' or mode == '' then
    hi = '%#StatusLineVisual#'
  elseif mode == 'R' or mode == 'Rv' then
    hi = '%#StatusLineReplace#'
  end
  -- return '%{g:actual_curwin==win_getid()?'.. hi ..':%#StatusLineNC#}'
  return hi
end

-- does item highlighting and conditionnal spacing
function _G.statusline_append(element, hi, default_hi, opts)
  if not element or element == '' then
    return ''
  end
  opts = opts or { append_space = true }

  if hi ~= nil then
    hi = '%#' .. hi .. '#'
  end
  if not (default_hi == '%*') then
    hi = default_hi
  end
  local el = hi .. element .. default_hi
  if opts.append_space then
    el = el .. ' '
  end
  return el
end

function _G.statusline_combine_hi(outer_name, inner_name)
  local outer = vim.api.nvim_get_hl(0, { name = outer_name, create = false })
  local inner = vim.api.nvim_get_hl(0, { name = inner_name, create = false })
  -- try to find a predefined hl
  local name = (outer_name .. inner_name)
  if vim.api.nvim_get_hl(0, { name = name, create = false }) then
    return name
  end
  -- generate one new one automatically
  name = ('autohi_' .. outer_name .. inner_name)
  vim.api.nvim_get_hl(0, { name = name, create = true })
  local hi = vim.tbl_extend('force', inner, { bg = inner.fg }, { fg = outer.bg })
  vim.api.nvim_set_hl(0, name, hi)
  return name
end

function _G.statusline_lsp_diagnostics(bufnr, default_hi)
  local signs = vim.diagnostic.config().signs.text or {}
  local error_num = vim.diagnostic.get(bufnr, { severity = vim.diagnostic.severity.ERROR })
  local warn_num = vim.diagnostic.get(bufnr, { severity = vim.diagnostic.severity.WARN })

  local s = ''
  if #error_num > 0 then
    local errs = signs[vim.diagnostic.severity.ERROR] .. ' ' .. #error_num
    s = s
      .. statusline_append(errs, statusline_combine_hi('StatusLine', 'DiagnosticError'), default_hi)
  end
  if #warn_num > 0 then
    local warns = signs[vim.diagnostic.severity.WARN] .. ' ' .. #warn_num
    s = s
      .. statusline_append(warns, statusline_combine_hi('StatusLine', 'DiagnosticWarn'), default_hi)
  end
  return vim.trim(s)
end

function _G.statusline_git(_, hi)
  if vim.b.gitsigns_status and vim.b.gitsigns_status ~= '' then
    return statusline_append('[' .. vim.b.gitsigns_status .. ']', 'StatusLineGitChanges', hi)
  end
end

function _G.statusline_grapple(_, _)
  local g = package.loaded.grapple
  if not g then
    return ''
  end
  return g.statusline()
  -- if not g or not g.exists({ buffer = bufnr }) then
  --   return ''
  -- end
  -- return '➥ ' .. g.key({ buffer = bufnr })
end

function _G.statusline_spinner(bufnr, _)
  local sp = package.loaded.spinner
  if not sp then
    return ''
  end
  return sp.status(bufnr)
end

function _G.statusline_dap(_, _)
  local dap = package.loaded.dap
  if not dap then
    return ''
  end
  local s = dap.status()
  if s == '' then
    return s
  end
  return '[DAP: ' .. s .. ']'
end

local hi = function(name, opts)
  vim.api.nvim_set_hl(0, name, opts)
end

local statusline = vim.api.nvim_get_hl(0, { name = 'StatusLine', create = false })
hi('StatusLineDiagnosticError', { fg = 'NvimDarkRed', bg = statusline.bg, bold = true })
hi('StatusLineDiagnosticWarn', { fg = 'NvimDarkYellow', bg = statusline.bg, bold = true })

vim.opt.statusline = '%{%v:lua.statusline()%}'

-- WINBAR --
-- vim.opt.winbar = [[%h%w%q%f %-m %-r %= %#WinBarCwd#%{%getcwd()%}%*]] -- keep it simple
-- function _G.winbar()
--   return [[%<%F %-m %-r]]
-- end
-- vim.opt.winbar = '%{%v:lua.winbar()%}'