diff options
Diffstat (limited to 'lua/config/native-statusline.lua')
| -rw-r--r-- | lua/config/native-statusline.lua | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/lua/config/native-statusline.lua b/lua/config/native-statusline.lua new file mode 100644 index 0000000..c7dea6e --- /dev/null +++ b/lua/config/native-statusline.lua @@ -0,0 +1,259 @@ +-- ===================================================== +-- Native Statusline Implementation +-- Replacement for lualine.nvim +-- ===================================================== + +local M = {} + +-- Import colors from our native colorscheme +local function get_colors() + local ok, colorscheme = pcall(require, "config.native-colorscheme") + if ok then + return colorscheme.colors + end + -- Fallback colors + return { + base03 = "#16161e", + fg = "#c0caf5", + blue100 = "#9bb3f7", + green100 = "#b3d882", + yellow100 = "#e7c664", + orange100 = "#ffad7a", + red100 = "#ff7a93", + cyan100 = "#7dd3c0", + magenta100 = "#d2a8ff", + base4 = "#c0caf5", + green300 = "#9ece6a", + yellow300 = "#e0af68", + red300 = "#f7768e", + blue300 = "#7aa2f7", + cyan300 = "#73daca", + orange300 = "#ff9e64", + } +end + +local colors = get_colors() + +-- Helper function to create highlight groups +local function create_highlight(name, fg, bg, style) + local hl = { fg = fg, bg = bg } + if style then + if style:find("bold") then hl.bold = true end + if style:find("italic") then hl.italic = true end + end + vim.api.nvim_set_hl(0, name, hl) + return "%#" .. name .. "#" +end + +-- Define statusline highlight groups +local function setup_highlights() + create_highlight("StatuslineModeNormal", colors.blue100, colors.base03, "bold") + create_highlight("StatuslineModeInsert", colors.green100, colors.base03, "bold") + create_highlight("StatuslineModeVisual", colors.magenta100, colors.base03, "bold") + create_highlight("StatuslineModeReplace", colors.red100, colors.base03, "bold") + create_highlight("StatuslineModeCommand", colors.yellow100, colors.base03, "bold") + create_highlight("StatuslineModeTerminal", colors.orange100, colors.base03, "bold") + + create_highlight("StatuslineBranch", colors.orange100, colors.base03, "bold") + create_highlight("StatuslineFilename", colors.yellow100, colors.base03, "bold") + create_highlight("StatuslineLSP", colors.base4, colors.base03, "bold") + create_highlight("StatuslineFiletype", colors.magenta100, colors.base03, "bold") + create_highlight("StatuslineProgress", colors.cyan100, colors.base03, "bold") + + create_highlight("StatuslineGitAdd", colors.green300, colors.base03, "bold") + create_highlight("StatuslineGitChange", colors.yellow300, colors.base03, "bold") + create_highlight("StatuslineGitDelete", colors.red300, colors.base03, "bold") + + create_highlight("StatuslineDiagError", colors.red300, colors.base03, "bold") + create_highlight("StatuslineDiagWarn", colors.yellow300, colors.base03, "bold") + create_highlight("StatuslineDiagInfo", colors.blue300, colors.base03, "bold") + create_highlight("StatuslineDiagHint", colors.cyan300, colors.base03, "bold") + + create_highlight("StatuslineSeparator", colors.base03, colors.base03, "") +end + +-- Get current mode +local function get_mode() + local mode_map = { + n = { "NORMAL", "StatuslineModeNormal", " " }, + i = { "INSERT", "StatuslineModeInsert", " " }, + v = { "VISUAL", "StatuslineModeVisual", " " }, + V = { "V-LINE", "StatuslineModeVisual", " " }, + [""] = { "V-BLOCK", "StatuslineModeVisual", " " }, + c = { "COMMAND", "StatuslineModeCommand", " " }, + R = { "REPLACE", "StatuslineModeReplace", " " }, + t = { "TERMINAL", "StatuslineModeTerminal", " " }, + } + + local current_mode = vim.fn.mode() + local mode_info = mode_map[current_mode] or { "UNKNOWN", "StatuslineModeNormal", " " } + + return "%#" .. mode_info[2] .. "#" .. mode_info[3] .. mode_info[1] .. " " +end + +-- Get git branch +local function get_git_branch() + local handle = io.popen("git branch --show-current 2>/dev/null") + if not handle then return "" end + + local branch = handle:read("*l") + handle:close() + + if not branch or branch == "" then + return "" + end + return "%#StatuslineBranch# " .. branch .. " " +end + +-- Get git diff stats +local function get_git_diff() + -- Check if we're in a git repository + local handle = io.popen("git rev-parse --is-inside-work-tree 2>/dev/null") + if not handle then return "" end + + local is_git = handle:read("*l") + handle:close() + + if is_git ~= "true" then return "" end + + -- Get staged changes + local staged_handle = io.popen("git diff --cached --numstat 2>/dev/null | wc -l") + local added = staged_handle and staged_handle:read("*l") or "0" + if staged_handle then staged_handle:close() end + + -- Get unstaged changes + local unstaged_handle = io.popen("git diff --numstat 2>/dev/null | wc -l") + local modified = unstaged_handle and unstaged_handle:read("*l") or "0" + if unstaged_handle then unstaged_handle:close() end + + local result = "" + if tonumber(added) and tonumber(added) > 0 then + result = result .. "%#StatuslineGitAdd# +" .. added .. " " + end + if tonumber(modified) and tonumber(modified) > 0 then + result = result .. "%#StatuslineGitChange# ~" .. modified .. " " + end + + return result +end + +-- Get filename with path +local function get_filename() + local filename = vim.fn.expand("%:t") + if filename == "" then + filename = "[No Name]" + end + return "%#StatuslineFilename# " .. filename .. " " +end + +-- Get LSP clients +local function get_lsp_clients() + local clients = vim.lsp.get_clients({ bufnr = 0 }) + if #clients == 0 then + return "%#StatuslineLSP#No LSP " + end + + local client_names = {} + for _, client in ipairs(clients) do + table.insert(client_names, client.name) + end + + return "%#StatuslineLSP#" .. table.concat(client_names, ",") .. " " +end + +-- Get diagnostics +local function get_diagnostics() + local diagnostics = vim.diagnostic.get(0) + local counts = { error = 0, warn = 0, info = 0, hint = 0 } + + for _, diagnostic in ipairs(diagnostics) do + if diagnostic.severity == vim.diagnostic.severity.ERROR then + counts.error = counts.error + 1 + elseif diagnostic.severity == vim.diagnostic.severity.WARN then + counts.warn = counts.warn + 1 + elseif diagnostic.severity == vim.diagnostic.severity.INFO then + counts.info = counts.info + 1 + elseif diagnostic.severity == vim.diagnostic.severity.HINT then + counts.hint = counts.hint + 1 + end + end + + local result = "" + if counts.error > 0 then + result = result .. "%#StatuslineDiagError# " .. counts.error .. " " + end + if counts.warn > 0 then + result = result .. "%#StatuslineDiagWarn# " .. counts.warn .. " " + end + if counts.info > 0 then + result = result .. "%#StatuslineDiagInfo# " .. counts.info .. " " + end + if counts.hint > 0 then + result = result .. "%#StatuslineDiagHint# " .. counts.hint .. " " + end + + return result +end + +-- Get filetype +local function get_filetype() + local filetype = vim.bo.filetype + if filetype == "" then + return "" + end + return "%#StatuslineFiletype#" .. filetype .. " " +end + +-- Get progress (line/total) +local function get_progress() + local current = vim.fn.line(".") + local total = vim.fn.line("$") + local percentage = math.floor((current / total) * 100) + return "%#StatuslineProgress#" .. percentage .. "%% " +end + +-- Get separator +local function separator() + return "%#StatuslineSeparator# " +end + +-- Build the statusline +function M.build_statusline() + local left = get_mode() .. separator() .. + get_git_branch() .. separator() .. + get_git_diff() .. separator() .. + get_filename() + + local right = get_diagnostics() .. separator() .. + get_lsp_clients() .. separator() .. + get_filetype() .. separator() .. + get_progress() + + return left .. "%=" .. right +end + +-- Setup function +function M.setup() + setup_highlights() + + -- Set up autocommands to refresh statusline + vim.api.nvim_create_augroup("NativeStatusline", { clear = true }) + + -- Update statusline on various events + vim.api.nvim_create_autocmd({ + "VimEnter", "WinEnter", "BufEnter", "ModeChanged", "DiagnosticChanged" + }, { + group = "NativeStatusline", + callback = function() + vim.opt.statusline = M.build_statusline() + end, + }) + + -- Set initial statusline + vim.opt.statusline = M.build_statusline() + + -- Always show statusline + vim.opt.laststatus = 2 +end + +return M |