summary refs log tree commit diff
path: root/.vim/lua/internal/statusline.lua
blob: 1c09271603299236ae3a1918977d2cb1e0b7538c (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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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 .. statusline_append(statusline_lightbulb(), 'StatusLineLightbulb', hi)

  sl = sl .. statusline_append(statusline_ts(), 'StatusLineTreesitter', hi)

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

  sl = sl .. statusline_append(statusline_lspstatus(), 'StatusLineLsp', hi)

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

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

  sl = sl .. statusline_append(statusline_notify(hi), 'StatusLineNotify', hi)

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

  sl = sl .. statusline_append([[ %l:%v --%p%%-- %y]], hi, hi)

  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_by_id(vim.api.nvim_get_hl_id_by_name(outer_name), true)
  local inner = vim.api.nvim_get_hl_by_id(vim.api.nvim_get_hl_id_by_name(inner_name), true)
  local hi = 'auto' .. outer_name .. inner_name
  if pcall(vim.api.nvim_get_hl_by_name, hi, true) then
    return hi
  end
  local gui
  gui = inner.bold and 'bold'
  gui = inner.italic and 'italic'
  gui = inner.underline and 'underline'
  vim.api.nvim_set_hl(0, hi, { bg = outer.background, fg = inner.foreground, gui = gui })
  return hi
end

function _G.statusline_lsp_diagnostics(bufnr, default_hi)
  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 = vim.fn.sign_getdefined('DiagnosticSignError')[1].text .. #error_num
    s = s
      .. statusline_append(
        errs,
        statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticError'),
        default_hi
      )
  end
  if #warn_num > 0 then
    local warns = vim.fn.sign_getdefined('DiagnosticSignWarn')[1].text .. #warn_num
    s = s
      .. statusline_append(
        warns,
        statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticWarn'),
        default_hi
      )
  end
  return vim.trim(s)
end
function _G.statusline_ts()
  local navic = package.loaded['nvim-navic']
  if not navic then
    return ''
  end
  local data = navic.get_data()
  if not data then
    return ''
  end
  local s = {}
  for i = 1, #data do
    table.insert(
      s,
      string.format(
        '%%#CmpItemKind%s#%s%%* %%#StatusLine#%s%%*',
        data[i].type,
        data[i].icon,
        data[i].name
      )
    )
  end
  return table.concat(s, ' > ')
end
function _G.statusline_lspstatus()
  local lst = package.loaded['lsp-status']
  if not lst then
    return ''
  end
  return vim.trim(lst.status())
end
function _G.statusline_lightbulb()
  local lb = package.loaded['nvim-lightbulb']
  if not lb then
    return ''
  end
  return lb.get_status_text()
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

function _G.statusline_notify(default_hi)
  if not _G.statusline_notifications or #_G.statusline_notifications == 0 then
    return ''
  end
  local n = _G.statusline_notifications[1]
  local timeout = (n.options and n.options.timeout) or 2000
  -- pop message after <timeout> and move to archive
  vim.defer_fn(function()
    local n = table.remove(_G.statusline_notifications, 1)
    table.insert(_G.statusline_notifications_archive, n)
    -- make sure archive is never longer than 20 notifications
    if #_G.statusline_notifications_archive > 20 then
      table.remove(_G.statusline_notifications_archive, 1)
    end
  end, timeout)

  local s = ''
  if n.hi then
    s = s
      .. statusline_append(
        n.lvl_string .. ' ',
        statusline_combine_hi('StatusLineNotify', n.hi),
        default_hi,
        { append_space = false }
      )
  end
  s = s .. statusline_append(vim.inspect(n.message), 'StatusLineNotify', default_hi)
  return vim.trim(s)
end

-- vim.opt.statusline = '%!luaeval("statusline()")'
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()%}'