|
|
@@ -0,0 +1,272 @@
|
|
|
+local bitbrowser
|
|
|
+if pcall(require, "gitsigns") then
|
|
|
+ bitbrowser = require("bit-browser")
|
|
|
+else
|
|
|
+ bitbrowser = { get_target = function(_) return "NONE" end }
|
|
|
+end
|
|
|
+if not unpack then unpack = table.unpack end
|
|
|
+
|
|
|
+local setup = function()
|
|
|
+ require("status-beast.highlights").setup()
|
|
|
+ local maps = require("status-beast.maps")
|
|
|
+ -- Gutter options
|
|
|
+ vim.opt.number = true
|
|
|
+ vim.opt.relativenumber = true
|
|
|
+ vim.opt.signcolumn = "yes:1"
|
|
|
+ vim.opt.numberwidth = 3
|
|
|
+ -- Fold options
|
|
|
+ vim.opt.foldcolumn = "0"
|
|
|
+ vim.opt.foldlevel = 999
|
|
|
+ vim.opt.foldlevelstart = 999
|
|
|
+ vim.opt.foldenable = true
|
|
|
+
|
|
|
+ local get_gitsigns = function()
|
|
|
+ local found = "Empty"
|
|
|
+ local namespace = vim.api.nvim_get_namespaces()["gitsigns_signs_"]
|
|
|
+ if namespace == nil then return found end
|
|
|
+ local extmarks = vim.tbl_map(function(sign)
|
|
|
+ return sign[4]["sign_hl_group"]
|
|
|
+ end,
|
|
|
+ vim.api
|
|
|
+ .nvim_buf_get_extmarks(
|
|
|
+ vim.api
|
|
|
+ .nvim_win_get_buf(
|
|
|
+ vim.g.statusline_winid), namespace,
|
|
|
+ { vim.v.lnum - 1, 0 },
|
|
|
+ { vim.v.lnum - 1, -1 },
|
|
|
+ { details = true }))
|
|
|
+ for _, v in pairs(extmarks) do
|
|
|
+ if v == "GitSignsDelete" then
|
|
|
+ return "Delete"
|
|
|
+ elseif v == "GitSignsChange" then
|
|
|
+ found = "Change"
|
|
|
+ elseif v == "GitSignsAdd" then
|
|
|
+ found = "Add"
|
|
|
+ end
|
|
|
+ end
|
|
|
+ return found
|
|
|
+ end
|
|
|
+
|
|
|
+ local diagnostics_map = { "Error", "Warn", "Info", "Hint", "Empty" }
|
|
|
+ local get_diagnostics = function()
|
|
|
+ local diagnostics = vim.tbl_map(function(sign)
|
|
|
+ return sign.severity
|
|
|
+ end,
|
|
|
+ vim.diagnostic
|
|
|
+ .get(
|
|
|
+ vim.api
|
|
|
+ .nvim_win_get_buf(
|
|
|
+ vim.g.statusline_winid),
|
|
|
+ { lnum = vim.v.lnum - 1 }))
|
|
|
+ local index
|
|
|
+ if #diagnostics < 1 then
|
|
|
+ index = #diagnostics_map
|
|
|
+ else
|
|
|
+ index = math.min(unpack(diagnostics))
|
|
|
+ if index == nil or diagnostics_map[index] == nil then
|
|
|
+ index = #diagnostics_map
|
|
|
+ end
|
|
|
+ end
|
|
|
+ return diagnostics_map[index]
|
|
|
+ end
|
|
|
+
|
|
|
+ local get_mode = function()
|
|
|
+ local mode_code = vim.api.nvim_get_mode().mode
|
|
|
+ return maps.mode_map[mode_code] == nil and "Other" or
|
|
|
+ maps.mode_map[mode_code]
|
|
|
+ end
|
|
|
+ _G.StatusBeast = {
|
|
|
+ column = function()
|
|
|
+ local gitsign = get_gitsigns()
|
|
|
+ local diagnostic = get_diagnostics()
|
|
|
+ return table.concat({
|
|
|
+ "%#StatusBeastDiagnostic" .. diagnostic .. "#",
|
|
|
+ maps.diagnostic_icons[diagnostic] or "", "%=",
|
|
|
+ vim.v.relnum == 0 and "%#CursorLineNr#" or "%#LineNr#",
|
|
|
+ "%{&nu?(&rnu&&v:relnum?v:relnum:v:lnum):''}",
|
|
|
+ "%#StatusBeastGit" .. gitsign .. "#",
|
|
|
+ gitsign ~= "Empty" and "╏" or "¦"
|
|
|
+ }, "")
|
|
|
+ end,
|
|
|
+ line = function()
|
|
|
+ local s = {
|
|
|
+ -- Neovim icon
|
|
|
+ "%#StatusBeastBarHighlight#%#StatusBeastBarNormal#"
|
|
|
+ }
|
|
|
+ -- Mode
|
|
|
+ local mode = get_mode();
|
|
|
+ table.insert(s, "%#StatusBeastMode" .. mode .. "#" ..
|
|
|
+ string.upper(maps.mode_display_names[mode]) ..
|
|
|
+ "%#StatusBeastBarNormal#")
|
|
|
+ -- Date
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ os.date("%H:%M"))
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ os.date("%a, %b %d, W%V"))
|
|
|
+ -- Tabs
|
|
|
+ local current = vim.api.nvim_get_current_tabpage()
|
|
|
+ local tabpages = vim.api.nvim_list_tabpages()
|
|
|
+ if #tabpages > 1 then
|
|
|
+ for _, v in pairs(tabpages) do
|
|
|
+ table.insert(s,
|
|
|
+ (v == current and
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarHighlight#" or
|
|
|
+ " %#StatusBeastBarItalic#") .. v ..
|
|
|
+ "%#StatusBeastBarNormal#")
|
|
|
+ end
|
|
|
+ end
|
|
|
+ -- Directory and Position
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ "%#StatusBeastBarItalic#" .. vim.fn.getcwd() ..
|
|
|
+ "%#StatusBeastBarNormal#" .. "%=" ..
|
|
|
+ "%#StatusBeastBarIcon#%#StatusBeastBarNormal#" ..
|
|
|
+ " %l:%c (%P)")
|
|
|
+ -- Search count
|
|
|
+ if vim.v.hlsearch ~= 0 then
|
|
|
+ local ok, result = pcall(vim.fn.searchcount,
|
|
|
+ { maxcount = 998, timeout = 25 })
|
|
|
+ if ok and next(result) ~= nil then
|
|
|
+ local denominator = math.min(result.total, result.maxcount)
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ string.format("%d/%d", result.current,
|
|
|
+ denominator))
|
|
|
+ end
|
|
|
+ end
|
|
|
+ -- Selection length
|
|
|
+ if mode == "Visual" then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#L" ..
|
|
|
+ tostring(
|
|
|
+ math.abs(
|
|
|
+ vim.fn.line("v") - vim.fn.line(".")) +
|
|
|
+ 1) .. ":C" ..
|
|
|
+ tostring(
|
|
|
+ math.abs(vim.fn.col("v") - vim.fn.col(".")) +
|
|
|
+ 1))
|
|
|
+ end
|
|
|
+ -- Bitbrowser
|
|
|
+ if bitbrowser.get_target() ~= "NONE" then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ string.sub(bitbrowser.get_target(), 1, 1))
|
|
|
+ end
|
|
|
+ -- Macro
|
|
|
+ if vim.fn.reg_recording() ~= "" then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ vim.fn.reg_recording())
|
|
|
+ end
|
|
|
+ -- LSP
|
|
|
+ for _, v in pairs(vim.lsp.buf_get_clients()) do
|
|
|
+ if v["attached_buffers"][vim.api.nvim_get_current_buf()] then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ v["name"])
|
|
|
+ end
|
|
|
+ end
|
|
|
+ -- Git
|
|
|
+ local status_dict = vim.b.gitsigns_status_dict;
|
|
|
+ if (status_dict ~= nil) then
|
|
|
+ local status = vim.b.gitsigns_status
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarIcon# %#StatusBeastBarNormal#" ..
|
|
|
+ status_dict.head ..
|
|
|
+ (string.len(status) > 1 and " (" ..
|
|
|
+ vim.b.gitsigns_status .. ")" or ""))
|
|
|
+ end
|
|
|
+ return "%#StatusBeastBarNormal# " .. table.concat(s, " ¦ ") .. " "
|
|
|
+ end,
|
|
|
+ win = function()
|
|
|
+ local buffer = vim.api.nvim_win_get_buf(vim.g.statusline_winid)
|
|
|
+ local name = vim.api.nvim_buf_get_name(buffer)
|
|
|
+ -- Unnamed
|
|
|
+ if string.len(name) == 0 or vim.fn.getfsize(name) < 0 then
|
|
|
+ return
|
|
|
+ " %#StatusBeastBarIcon#%#StatusBeastBarNormal# [No File]"
|
|
|
+ end
|
|
|
+
|
|
|
+ local relativename = string.sub(name,
|
|
|
+ string.len(vim.fn.getcwd()) + 1, 999)
|
|
|
+ local s = {}
|
|
|
+ -- Diagnostics
|
|
|
+ local diagnostics = vim.diagnostic.get(buffer, {
|
|
|
+ severity = vim.diagnostic.severity.ERROR
|
|
|
+ })
|
|
|
+ if #diagnostics > 0 then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarError#" ..
|
|
|
+ maps.diagnostic_icons["Error"] ..
|
|
|
+ "%#StatusBeastBarNormal# ")
|
|
|
+ else
|
|
|
+ table.insert(s, "%#StatusBeastBarNormal# ")
|
|
|
+ end
|
|
|
+ -- Size
|
|
|
+ local filesize = vim.fn.getfsize(name)
|
|
|
+ local sizeabbrev = "B"
|
|
|
+ if filesize > 999 then
|
|
|
+ filesize = math.floor(filesize / 100)
|
|
|
+ sizeabbrev = "KB"
|
|
|
+ end
|
|
|
+ if filesize > 999 then
|
|
|
+ filesize = math.floor(filesize / 100)
|
|
|
+ sizeabbrev = "MB"
|
|
|
+ end
|
|
|
+ table.insert(s, tostring(filesize) .. sizeabbrev)
|
|
|
+ table.insert(s, " ¦ ")
|
|
|
+ -- Modified
|
|
|
+ if vim.fn.getbufinfo(buffer)[1].changed == 1 then
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarHighlight#%#StatusBeastBarNormal# ¦ ")
|
|
|
+ end
|
|
|
+ -- Icon
|
|
|
+ local fullname_icon = maps.file_node_exact_matches[vim.fn
|
|
|
+ .fnamemodify(name, ":t")]
|
|
|
+ local extension_icon = maps.file_node_extensions[vim.fn.fnamemodify(
|
|
|
+ name, ":e")]
|
|
|
+ table.insert(s, "%#StatusBeastBarIcon#")
|
|
|
+ if fullname_icon ~= nil then
|
|
|
+ table.insert(s, fullname_icon)
|
|
|
+ elseif extension_icon ~= nil then
|
|
|
+ table.insert(s, extension_icon)
|
|
|
+ else
|
|
|
+ table.insert(s, "%y")
|
|
|
+ end
|
|
|
+ table.insert(s, " %#StatusBeastBarNormal#")
|
|
|
+ -- Path
|
|
|
+ table.insert(s,
|
|
|
+ "%#StatusBeastBarHighlight#" ..
|
|
|
+ vim.fn.fnamemodify(name, ":t") ..
|
|
|
+ "%#StatusBeastBarNormal#")
|
|
|
+ local path_elements = vim.split(
|
|
|
+ vim.fn.fnamemodify(relativename, ":h"),
|
|
|
+ "/", true)
|
|
|
+ local reversed_path = {}
|
|
|
+ for i = #path_elements, 1, -1 do
|
|
|
+ reversed_path[#reversed_path + 1] = path_elements[i]
|
|
|
+ end
|
|
|
+ for _, v in pairs(reversed_path) do
|
|
|
+ if string.len(v) > 0 then
|
|
|
+ table.insert(s, " " .. v)
|
|
|
+ end
|
|
|
+ end
|
|
|
+ return "%#StatusBeastBarNormal# " .. table.concat(s) .. " "
|
|
|
+ end
|
|
|
+ }
|
|
|
+
|
|
|
+ -- Disable statusline
|
|
|
+ vim.opt.laststatus = 0
|
|
|
+ vim.opt.statusline = "%#StatusBeastStatusLine#%{repeat('-',winwidth('.'))}"
|
|
|
+ -- Set statuscolumn
|
|
|
+ vim.opt.statuscolumn = [[%!v:lua.StatusBeast.column()]]
|
|
|
+ -- Set tabline
|
|
|
+ vim.opt.showtabline = 2
|
|
|
+ vim.opt.tabline = [[%!v:lua.StatusBeast.line()]]
|
|
|
+ -- Set winbar
|
|
|
+ vim.opt.winbar = [[%!v:lua.StatusBeast.win()]]
|
|
|
+end
|
|
|
+
|
|
|
+return { setup = setup }
|