CHORE: Fixing some minor bugs
This commit is contained in:
@@ -74,10 +74,10 @@ local mode_hl_map = {
|
|||||||
i = 'StatusModeInsert',
|
i = 'StatusModeInsert',
|
||||||
v = 'StatusModeVisual',
|
v = 'StatusModeVisual',
|
||||||
V = 'StatusModeVisual',
|
V = 'StatusModeVisual',
|
||||||
['^V'] = 'StatusModeVisual',
|
['\22'] = 'StatusModeVisual',
|
||||||
s = 'StatusModeVisual',
|
s = 'StatusModeVisual',
|
||||||
S = 'StatusModeVisual',
|
S = 'StatusModeVisual',
|
||||||
['^S'] = 'StatusModeVisual',
|
['\19'] = 'StatusModeVisual',
|
||||||
R = 'StatusModeReplace',
|
R = 'StatusModeReplace',
|
||||||
c = 'StatusModeCommand',
|
c = 'StatusModeCommand',
|
||||||
r = 'StatusModeCommand',
|
r = 'StatusModeCommand',
|
||||||
@@ -85,6 +85,13 @@ local mode_hl_map = {
|
|||||||
t = 'StatusModeTerminal',
|
t = 'StatusModeTerminal',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local mode_statusline = {}
|
||||||
|
for k, v in pairs(mode_map) do
|
||||||
|
local hl = mode_hl_map[k] or 'StatusModeNormal'
|
||||||
|
mode_statusline[k] = '%#' .. hl .. '#' .. v .. '%*'
|
||||||
|
end
|
||||||
|
mode_statusline['default'] = '%#StatusModeNormal# ?? %*'
|
||||||
|
|
||||||
local function refresh_status(buf)
|
local function refresh_status(buf)
|
||||||
local b = vim.b[buf]
|
local b = vim.b[buf]
|
||||||
local left, right = {}, {}
|
local left, right = {}, {}
|
||||||
@@ -116,8 +123,14 @@ local function refresh_status(buf)
|
|||||||
.. ' %*'
|
.. ' %*'
|
||||||
end
|
end
|
||||||
|
|
||||||
b.status_left = #left > 0 and table.concat(left) or ''
|
local l = #left > 0 and table.concat(left) or ''
|
||||||
b.status_right = #right > 0 and table.concat(right) or ''
|
local r = #right > 0 and table.concat(right) or ''
|
||||||
|
if b.status_left ~= l then
|
||||||
|
b.status_left = l
|
||||||
|
end
|
||||||
|
if b.status_right ~= r then
|
||||||
|
b.status_right = r
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local lsp_icon = {
|
local lsp_icon = {
|
||||||
@@ -144,29 +157,47 @@ local function refresh_lsp(buf)
|
|||||||
local names = {}
|
local names = {}
|
||||||
for _, client in ipairs(clients) do
|
for _, client in ipairs(clients) do
|
||||||
names[#names + 1] = client.name
|
names[#names + 1] = client.name
|
||||||
local prog = active_progress[client.id]
|
local p = active_progress[client.id]
|
||||||
if prog == 'working' then
|
if p then
|
||||||
state = 'working'
|
if p.is_starting then
|
||||||
elseif prog == 'starting' and state ~= 'working' then
|
if state ~= 'working' then
|
||||||
state = 'starting'
|
state = 'starting'
|
||||||
end
|
end
|
||||||
|
elseif next(p.tokens) then
|
||||||
|
state = 'working'
|
||||||
|
end
|
||||||
|
end
|
||||||
vim.b[buf].lsp_name = table.concat(names, '/')
|
vim.b[buf].lsp_name = table.concat(names, '/')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if vim.b[buf].lsp_state == state then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
vim.b[buf].lsp_state = state
|
||||||
vim.b[buf].lsp_icon = lsp_icon[state]
|
vim.b[buf].lsp_icon = lsp_icon[state]
|
||||||
vim.b[buf].lsp_hl = lsp_hl[state]
|
vim.b[buf].lsp_hl = lsp_hl[state]
|
||||||
refresh_status(buf)
|
refresh_status(buf)
|
||||||
|
vim.cmd.redrawstatus()
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ 'LspAttach', 'LspDetach' }, {
|
vim.api.nvim_create_autocmd({ 'LspAttach', 'LspDetach' }, {
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
if ev.event == 'LspAttach' then
|
|
||||||
local cid = ev.data.client_id
|
local cid = ev.data.client_id
|
||||||
if not active_progress[cid] then
|
if ev.event == 'LspAttach' then
|
||||||
active_progress[cid] = 'starting'
|
local p = active_progress[cid] or { tokens = {} }
|
||||||
|
active_progress[cid] = p
|
||||||
|
if not p.is_starting and not next(p.tokens) then
|
||||||
|
p.is_starting = true
|
||||||
|
p.timer_id = (p.timer_id or 0) + 1
|
||||||
|
local current_id = p.timer_id
|
||||||
vim.defer_fn(function()
|
vim.defer_fn(function()
|
||||||
if active_progress[cid] == 'starting' then
|
local curr = active_progress[cid]
|
||||||
active_progress[cid] = nil
|
if
|
||||||
|
curr
|
||||||
|
and curr.is_starting
|
||||||
|
and curr.timer_id == current_id
|
||||||
|
then
|
||||||
|
curr.is_starting = nil
|
||||||
if vim.api.nvim_buf_is_valid(ev.buf) then
|
if vim.api.nvim_buf_is_valid(ev.buf) then
|
||||||
refresh_lsp(ev.buf)
|
refresh_lsp(ev.buf)
|
||||||
end
|
end
|
||||||
@@ -174,7 +205,7 @@ vim.api.nvim_create_autocmd({ 'LspAttach', 'LspDetach' }, {
|
|||||||
end, 500) -- 500ms grace period to wait for LspProgress
|
end, 500) -- 500ms grace period to wait for LspProgress
|
||||||
end
|
end
|
||||||
elseif ev.event == 'LspDetach' then
|
elseif ev.event == 'LspDetach' then
|
||||||
active_progress[ev.data.client_id] = nil
|
active_progress[cid] = nil
|
||||||
end
|
end
|
||||||
refresh_lsp(ev.buf)
|
refresh_lsp(ev.buf)
|
||||||
end,
|
end,
|
||||||
@@ -182,13 +213,27 @@ vim.api.nvim_create_autocmd({ 'LspAttach', 'LspDetach' }, {
|
|||||||
|
|
||||||
vim.api.nvim_create_autocmd('LspProgress', {
|
vim.api.nvim_create_autocmd('LspProgress', {
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
local kind = ev.data.params.value and ev.data.params.value.kind
|
local cid = ev.data.client_id
|
||||||
if kind == 'begin' or kind == 'report' then
|
local p = active_progress[cid] or { tokens = {} }
|
||||||
active_progress[ev.data.client_id] = 'working'
|
active_progress[cid] = p
|
||||||
elseif kind == 'end' then
|
|
||||||
active_progress[ev.data.client_id] = nil
|
if p.is_starting then
|
||||||
else
|
p.is_starting = nil
|
||||||
return
|
p.timer_id = (p.timer_id or 0) + 1 -- Invalidate pending start timer safely
|
||||||
|
end
|
||||||
|
|
||||||
|
local val = type(ev.data.params.value) == 'table'
|
||||||
|
and ev.data.params.value
|
||||||
|
or {}
|
||||||
|
local kind = val.kind or ev.match
|
||||||
|
local token = ev.data.params.token or 'fallback'
|
||||||
|
|
||||||
|
if kind == 'begin' or (kind == 'report' and val.percentage ~= 100) then
|
||||||
|
p.tokens[token] = true
|
||||||
|
elseif
|
||||||
|
kind == 'end' or (kind == 'report' and val.percentage == 100)
|
||||||
|
then
|
||||||
|
p.tokens[token] = nil
|
||||||
end
|
end
|
||||||
local client = vim.lsp.get_client_by_id(ev.data.client_id)
|
local client = vim.lsp.get_client_by_id(ev.data.client_id)
|
||||||
if client then
|
if client then
|
||||||
@@ -200,6 +245,18 @@ vim.api.nvim_create_autocmd('LspProgress', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
local BRANCH_ICON = ' '
|
local BRANCH_ICON = ' '
|
||||||
|
local branch_jobs = {}
|
||||||
|
local diff_jobs = {}
|
||||||
|
local git_root_cache = {}
|
||||||
|
local function get_git_root(buf, file)
|
||||||
|
local dir = vim.fs.dirname(file)
|
||||||
|
if git_root_cache[dir] ~= nil then
|
||||||
|
return git_root_cache[dir]
|
||||||
|
end
|
||||||
|
local root = vim.fs.root(buf, '.git') or dir
|
||||||
|
git_root_cache[dir] = root
|
||||||
|
return root
|
||||||
|
end
|
||||||
|
|
||||||
local function refresh_branch(buf)
|
local function refresh_branch(buf)
|
||||||
local file = vim.api.nvim_buf_get_name(buf)
|
local file = vim.api.nvim_buf_get_name(buf)
|
||||||
@@ -207,12 +264,17 @@ local function refresh_branch(buf)
|
|||||||
vim.b[buf].git_branch = ''
|
vim.b[buf].git_branch = ''
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local cwd = vim.fs.root(buf, '.git') or vim.fs.dirname(file)
|
local cwd = get_git_root(buf, file)
|
||||||
|
|
||||||
vim.system(
|
if branch_jobs[buf] then
|
||||||
|
branch_jobs[buf]:kill(9)
|
||||||
|
end
|
||||||
|
|
||||||
|
branch_jobs[buf] = vim.system(
|
||||||
{ 'git', 'branch', '--show-current' },
|
{ 'git', 'branch', '--show-current' },
|
||||||
{ text = true, cwd = cwd },
|
{ text = true, cwd = cwd },
|
||||||
vim.schedule_wrap(function(out)
|
vim.schedule_wrap(function(out)
|
||||||
|
branch_jobs[buf] = nil
|
||||||
if not vim.api.nvim_buf_is_valid(buf) then
|
if not vim.api.nvim_buf_is_valid(buf) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -220,24 +282,39 @@ local function refresh_branch(buf)
|
|||||||
vim.b[buf].git_branch = branch ~= '' and (BRANCH_ICON .. branch)
|
vim.b[buf].git_branch = branch ~= '' and (BRANCH_ICON .. branch)
|
||||||
or ''
|
or ''
|
||||||
refresh_status(buf)
|
refresh_status(buf)
|
||||||
|
vim.cmd.redrawstatus()
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function refresh_diff(buf)
|
local function refresh_diff(buf, force)
|
||||||
local file = vim.api.nvim_buf_get_name(buf)
|
local file = vim.api.nvim_buf_get_name(buf)
|
||||||
if file == '' or vim.bo[buf].buftype ~= '' then
|
if file == '' or vim.bo[buf].buftype ~= '' then
|
||||||
vim.b[buf].git_diff = nil
|
vim.b[buf].git_diff = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local cwd = vim.fs.root(buf, '.git') or vim.fs.dirname(file)
|
if
|
||||||
vim.system(
|
not force
|
||||||
|
and vim.b[buf].git_diff_fetched
|
||||||
|
and not vim.bo[buf].modified
|
||||||
|
then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local cwd = get_git_root(buf, file)
|
||||||
|
|
||||||
|
if diff_jobs[buf] then
|
||||||
|
diff_jobs[buf]:kill(9)
|
||||||
|
end
|
||||||
|
|
||||||
|
diff_jobs[buf] = vim.system(
|
||||||
{ 'git', 'diff', '--numstat', 'HEAD', '--', file },
|
{ 'git', 'diff', '--numstat', 'HEAD', '--', file },
|
||||||
{ text = true, cwd = cwd },
|
{ text = true, cwd = cwd },
|
||||||
vim.schedule_wrap(function(out)
|
vim.schedule_wrap(function(out)
|
||||||
|
diff_jobs[buf] = nil
|
||||||
if not vim.api.nvim_buf_is_valid(buf) then
|
if not vim.api.nvim_buf_is_valid(buf) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
vim.b[buf].git_diff_fetched = true
|
||||||
if out.code ~= 0 or out.stdout == '' then
|
if out.code ~= 0 or out.stdout == '' then
|
||||||
vim.b[buf].git_diff = nil
|
vim.b[buf].git_diff = nil
|
||||||
else
|
else
|
||||||
@@ -252,6 +329,7 @@ local function refresh_diff(buf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
refresh_status(buf)
|
refresh_status(buf)
|
||||||
|
vim.cmd.redrawstatus()
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -271,11 +349,13 @@ local function refresh_diag(buf)
|
|||||||
end
|
end
|
||||||
vim.b[buf].diag_str = #parts > 0 and table.concat(parts) or ''
|
vim.b[buf].diag_str = #parts > 0 and table.concat(parts) or ''
|
||||||
refresh_status(buf)
|
refresh_status(buf)
|
||||||
|
vim.cmd.redrawstatus()
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd('DiagnosticChanged', {
|
vim.api.nvim_create_autocmd('DiagnosticChanged', {
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
refresh_diag(ev.buf)
|
refresh_diag(ev.buf)
|
||||||
|
vim.cmd.redrawstatus()
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -283,7 +363,7 @@ vim.api.nvim_create_autocmd({ 'BufEnter', 'BufNewFile' }, {
|
|||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
if vim.bo[ev.buf].buftype == '' then
|
if vim.bo[ev.buf].buftype == '' then
|
||||||
refresh_branch(ev.buf)
|
refresh_branch(ev.buf)
|
||||||
refresh_diff(ev.buf)
|
refresh_diff(ev.buf, false)
|
||||||
end
|
end
|
||||||
refresh_lsp(ev.buf)
|
refresh_lsp(ev.buf)
|
||||||
refresh_diag(ev.buf)
|
refresh_diag(ev.buf)
|
||||||
@@ -299,7 +379,7 @@ vim.api.nvim_create_autocmd('FocusGained', {
|
|||||||
})
|
})
|
||||||
vim.api.nvim_create_autocmd('BufWritePost', {
|
vim.api.nvim_create_autocmd('BufWritePost', {
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
refresh_diff(ev.buf)
|
refresh_diff(ev.buf, true)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -320,18 +400,31 @@ vim.api.nvim_create_autocmd('RecordingLeave', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function _G.__statusline()
|
function _G.__statusline()
|
||||||
local m = vim.fn.mode()
|
local win_id = vim.g.statusline_winid or vim.api.nvim_get_current_win()
|
||||||
|
local is_active = win_id == vim.api.nvim_get_current_win()
|
||||||
|
local buf = vim.api.nvim_win_get_buf(win_id)
|
||||||
|
local b = vim.b[buf]
|
||||||
|
|
||||||
|
if not is_active then
|
||||||
|
return '%#StatusLineNC# '
|
||||||
|
.. (b.status_left or '')
|
||||||
|
.. '%='
|
||||||
|
.. (b.status_right or '')
|
||||||
|
.. ' %#StatusLineNC# %l:%-2c '
|
||||||
|
end
|
||||||
|
|
||||||
|
local m = vim.api.nvim_get_mode().mode
|
||||||
local key = (m == '\22' or m == '\19') and m or m:sub(1, 1)
|
local key = (m == '\22' or m == '\19') and m or m:sub(1, 1)
|
||||||
local hl = mode_hl_map[key] or 'StatusModeNormal'
|
local hl = mode_hl_map[key] or 'StatusModeNormal'
|
||||||
local b = vim.b
|
|
||||||
return table.concat({
|
return (mode_statusline[key] or mode_statusline['default'])
|
||||||
'%#' .. hl .. '#' .. (mode_map[key] or ' ?? ') .. '%*',
|
.. (b.status_left or '')
|
||||||
b.status_left or '',
|
.. '%='
|
||||||
'%=',
|
.. (b.status_right or '')
|
||||||
b.status_right or '',
|
.. '%#StatusCursor# %l:%-2c '
|
||||||
'%#StatusCursor# %l:%c ',
|
.. '%#'
|
||||||
'%#' .. hl .. '# %p%% %*',
|
.. hl
|
||||||
})
|
.. '# %p%% %*'
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.o.statusline = '%!v:lua.__statusline()'
|
vim.o.statusline = '%!v:lua.__statusline()'
|
||||||
|
|||||||
Reference in New Issue
Block a user