mirror of
https://github.com/jdhao/nvim-config.git
synced 2025-06-08 14:14:33 +02:00
I guess it is due to the reason that we are doing constant git fetch, and somehow gitsigns word diff is affected. Changing the gitsigns debounce or changing lualine refresh rate do not seem to help. So gitsigns word diff is disabled.
311 lines
7.3 KiB
Lua
311 lines
7.3 KiB
Lua
local fn = vim.fn
|
||
|
||
local git_status_cache = {}
|
||
|
||
local on_exit_fetch = function(result)
|
||
if result.code == 0 then
|
||
git_status_cache.fetch_success = true
|
||
end
|
||
end
|
||
|
||
local function handle_numeric_result(cache_key)
|
||
return function(result)
|
||
if result.code == 0 then
|
||
git_status_cache[cache_key] = tonumber(result.stdout:match("(%d+)")) or 0
|
||
end
|
||
end
|
||
end
|
||
|
||
local async_cmd = function(cmd_str, on_exit)
|
||
local cmd = vim.tbl_filter(function(element)
|
||
return element ~= ""
|
||
end, vim.split(cmd_str, " "))
|
||
|
||
vim.system(cmd, { text = true }, on_exit)
|
||
end
|
||
|
||
local async_git_status_update = function()
|
||
-- Fetch the latest changes from the remote repository (replace 'origin' if needed)
|
||
async_cmd("git fetch origin", on_exit_fetch)
|
||
if not git_status_cache.fetch_success then
|
||
return
|
||
end
|
||
|
||
-- Get the number of commits behind
|
||
-- the @{upstream} notation is inspired by post: https://www.reddit.com/r/neovim/comments/t48x5i/git_branch_aheadbehind_info_status_line_component/
|
||
-- note that here we should use double dots instead of triple dots
|
||
local behind_cmd_str = "git rev-list --count HEAD..@{upstream}"
|
||
async_cmd(behind_cmd_str, handle_numeric_result("behind_count"))
|
||
|
||
-- Get the number of commits ahead
|
||
local ahead_cmd_str = "git rev-list --count @{upstream}..HEAD"
|
||
async_cmd(ahead_cmd_str, handle_numeric_result("ahead_count"))
|
||
end
|
||
|
||
local function get_git_ahead_behind_info()
|
||
async_git_status_update()
|
||
|
||
local status = git_status_cache
|
||
if not status then
|
||
return ""
|
||
end
|
||
|
||
local msg = ""
|
||
|
||
if type(status.ahead_count) == "number" and status.ahead_count > 0 then
|
||
local ahead_str = string.format("↑[%d] ", status.ahead_count)
|
||
msg = msg .. ahead_str
|
||
end
|
||
|
||
if type(status.behind_count) == "number" and status.behind_count > 0 then
|
||
local behind_str = string.format("↓[%d] ", status.behind_count)
|
||
msg = msg .. behind_str
|
||
end
|
||
|
||
return msg
|
||
end
|
||
|
||
local function spell()
|
||
if vim.o.spell then
|
||
return string.format("[SPELL]")
|
||
end
|
||
|
||
return ""
|
||
end
|
||
|
||
--- show indicator for Chinese IME
|
||
local function ime_state()
|
||
if vim.g.is_mac then
|
||
-- ref: https://github.com/vim-airline/vim-airline/blob/master/autoload/airline/extensions/xkblayout.vim#L11
|
||
local layout = fn.libcall(vim.g.XkbSwitchLib, "Xkb_Switch_getXkbLayout", "")
|
||
|
||
-- We can use `xkbswitch -g` on the command line to get current mode.
|
||
-- mode for macOS builtin pinyin IME: com.apple.inputmethod.SCIM.ITABC
|
||
-- mode for Rime: im.rime.inputmethod.Squirrel.Rime
|
||
local res = fn.match(layout, [[\v(Squirrel\.Rime|SCIM.ITABC)]])
|
||
if res ~= -1 then
|
||
return "[CN]"
|
||
end
|
||
end
|
||
|
||
return ""
|
||
end
|
||
|
||
local function trailing_space()
|
||
if not vim.o.modifiable then
|
||
return ""
|
||
end
|
||
|
||
local line_num = nil
|
||
|
||
for i = 1, fn.line("$") do
|
||
local linetext = fn.getline(i)
|
||
-- To prevent invalid escape error, we wrap the regex string with `[[]]`.
|
||
local idx = fn.match(linetext, [[\v\s+$]])
|
||
|
||
if idx ~= -1 then
|
||
line_num = i
|
||
break
|
||
end
|
||
end
|
||
|
||
local msg = ""
|
||
if line_num ~= nil then
|
||
msg = string.format("[%d]trailing", line_num)
|
||
end
|
||
|
||
return msg
|
||
end
|
||
|
||
local function mixed_indent()
|
||
if not vim.o.modifiable then
|
||
return ""
|
||
end
|
||
|
||
local space_pat = [[\v^ +]]
|
||
local tab_pat = [[\v^\t+]]
|
||
local space_indent = fn.search(space_pat, "nwc")
|
||
local tab_indent = fn.search(tab_pat, "nwc")
|
||
local mixed = (space_indent > 0 and tab_indent > 0)
|
||
local mixed_same_line
|
||
if not mixed then
|
||
mixed_same_line = fn.search([[\v^(\t+ | +\t)]], "nwc")
|
||
mixed = mixed_same_line > 0
|
||
end
|
||
if not mixed then
|
||
return ""
|
||
end
|
||
if mixed_same_line ~= nil and mixed_same_line > 0 then
|
||
return "MI:" .. mixed_same_line
|
||
end
|
||
local space_indent_cnt = fn.searchcount({ pattern = space_pat, max_count = 1e3 }).total
|
||
local tab_indent_cnt = fn.searchcount({ pattern = tab_pat, max_count = 1e3 }).total
|
||
if space_indent_cnt > tab_indent_cnt then
|
||
return "MI:" .. tab_indent
|
||
else
|
||
return "MI:" .. space_indent
|
||
end
|
||
end
|
||
|
||
local diff = function()
|
||
local git_status = vim.b.gitsigns_status_dict
|
||
if git_status == nil then
|
||
return
|
||
end
|
||
|
||
local modify_num = git_status.changed
|
||
local remove_num = git_status.removed
|
||
local add_num = git_status.added
|
||
|
||
local info = { added = add_num, modified = modify_num, removed = remove_num }
|
||
-- vim.print(info)
|
||
return info
|
||
end
|
||
|
||
local virtual_env = function()
|
||
-- only show virtual env for Python
|
||
if vim.bo.filetype ~= "python" then
|
||
return ""
|
||
end
|
||
|
||
local conda_env = os.getenv("CONDA_DEFAULT_ENV")
|
||
local venv_path = os.getenv("VIRTUAL_ENV")
|
||
|
||
if venv_path == nil then
|
||
if conda_env == nil then
|
||
return ""
|
||
else
|
||
return string.format(" %s (conda)", conda_env)
|
||
end
|
||
else
|
||
local venv_name = vim.fn.fnamemodify(venv_path, ":t")
|
||
return string.format(" %s (venv)", venv_name)
|
||
end
|
||
end
|
||
|
||
local get_active_lsp = function()
|
||
local msg = "🚫"
|
||
local buf_ft = vim.api.nvim_get_option_value("filetype", {})
|
||
local clients = vim.lsp.get_clients { bufnr = 0 }
|
||
if next(clients) == nil then
|
||
return msg
|
||
end
|
||
|
||
for _, client in ipairs(clients) do
|
||
---@diagnostic disable-next-line: undefined-field
|
||
local filetypes = client.config.filetypes
|
||
if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then
|
||
return client.name
|
||
end
|
||
end
|
||
return msg
|
||
end
|
||
|
||
require("lualine").setup {
|
||
options = {
|
||
icons_enabled = true,
|
||
theme = "auto",
|
||
component_separators = { left = "⏐", right = "⏐" },
|
||
section_separators = "",
|
||
disabled_filetypes = {},
|
||
always_divide_middle = true,
|
||
refresh = {
|
||
statusline = 500,
|
||
},
|
||
},
|
||
sections = {
|
||
lualine_a = {
|
||
{
|
||
"filename",
|
||
symbols = {
|
||
readonly = "[🔒]",
|
||
},
|
||
},
|
||
},
|
||
lualine_b = {
|
||
{
|
||
"branch",
|
||
fmt = function(name, _)
|
||
-- truncate branch name in case the name is too long
|
||
return string.sub(name, 1, 20)
|
||
end,
|
||
color = { gui = "italic,bold" },
|
||
},
|
||
{
|
||
get_git_ahead_behind_info,
|
||
color = { fg = "#E0C479" },
|
||
},
|
||
{
|
||
"diff",
|
||
source = diff,
|
||
},
|
||
{
|
||
virtual_env,
|
||
color = { fg = "black", bg = "#F1CA81" },
|
||
},
|
||
},
|
||
lualine_c = {
|
||
{
|
||
"%S",
|
||
color = { gui = "bold", fg = "cyan" },
|
||
},
|
||
{
|
||
spell,
|
||
color = { fg = "black", bg = "#a7c080" },
|
||
},
|
||
},
|
||
lualine_x = {
|
||
{
|
||
get_active_lsp,
|
||
icon = "📡",
|
||
},
|
||
{
|
||
"diagnostics",
|
||
sources = { "nvim_diagnostic" },
|
||
symbols = { error = "🆇 ", warn = "⚠️ ", info = "ℹ️ ", hint = " " },
|
||
},
|
||
{
|
||
trailing_space,
|
||
color = "WarningMsg",
|
||
},
|
||
{
|
||
mixed_indent,
|
||
color = "WarningMsg",
|
||
},
|
||
},
|
||
lualine_y = {
|
||
{
|
||
"encoding",
|
||
fmt = string.upper,
|
||
},
|
||
{
|
||
"fileformat",
|
||
symbols = {
|
||
unix = "unix",
|
||
dos = "win",
|
||
mac = "mac",
|
||
},
|
||
},
|
||
"filetype",
|
||
{
|
||
ime_state,
|
||
color = { fg = "black", bg = "#f46868" },
|
||
},
|
||
},
|
||
lualine_z = {
|
||
"location",
|
||
"progress",
|
||
},
|
||
},
|
||
inactive_sections = {
|
||
lualine_a = {},
|
||
lualine_b = {},
|
||
lualine_c = { "filename" },
|
||
lualine_x = { "location" },
|
||
lualine_y = {},
|
||
lualine_z = {},
|
||
},
|
||
tabline = {},
|
||
extensions = { "quickfix", "fugitive", "nvim-tree" },
|
||
}
|