Something went wrong. Try again.
🪴 a tiny, customizable statusline for neovim
Something went wrong. Try again.
6.7 kB · 256 lines
Lua
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257local utils = {}
--- flatten list so all children have level of depth---@param lst table---@param maxdepth integerfunction utils.flatten(lst, maxdepth) vim.validate("lst", lst, "table") vim.validate("maxdepth", maxdepth, "number")
---@param _t any[] ---@return integer local function _depth(_t) return vim.iter(ipairs(_t)):fold(1, function(maxd, _, v) if type(v) == "table" and vim.islist(v) then local d = 1 + _depth(v) if d > maxd then return d end end return maxd end) end
local result = {} ---@param _t any[] local function _flatten(_t) local n = #_t for i = 1, n do local v = _t[i] if type(v) ~= "table" or (not vim.islist(v)) or _depth(v) <= maxdepth then table.insert(result, v) else _flatten(v) end end end _flatten(lst) return resultend
local sfmt = "%%*%s"local sfmt_inherit = "%s"-- str, hl_name, textlocal hlfmt = "%%#%s#%s"local hlfmt_inherit = "%%$%s$%s%%#%s#"
---@param text string---@param inherit string|false---@param hl? string---@return stringlocal function strfmt(text, inherit, hl) if hl then return string.format( inherit and hlfmt_inherit or hlfmt, hl, text, inherit or nil ) end return string.format(inherit and sfmt_inherit or sfmt, text)end
---@param lst any[]---@return stringfunction utils.fold(lst) vim.validate("lst", lst, "table")
lst = utils.flatten(lst, 1) ---@type string|false local section = false local l = vim .iter(ipairs(lst)) :map(function(_, module) if type(module) == "string" and #module > 0 then return strfmt(module, section) end if type(module) ~= "table" then return end if module.section ~= nil and (type(module.section) == "string" or module.section == false) then section = module.section if section then return string.format("%%#%s#", module.section) end return end local text = module[1] if text == nil or type(text) ~= "string" or #text == 0 then return end local hl = module[2] if not hl then return strfmt(text, section) end if type(hl) == "string" and #hl > 0 then return strfmt(text, section, hl) elseif type(hl) == "table" and (hl.fg or hl.bg or hl.link) then local inherit = section or hl.inherit hl.inherit = nil local hl_name = hl.link or utils.create_hl(hl) return strfmt(text, inherit, hl_name) elseif type(hl) == "table" and hl.inherit then return strfmt(text, hl.inherit) end
return strfmt(text, section) end) :totable()
return table.concat(l)end
---@param hl string|vim.api.keyset.highlight|vim.api.keyset.get_hl_info name or keyset---@return vim.api.keyset.highlightfunction utils.reverse_hl(hl) if type(hl) == "string" then ---@diagnostic disable-next-line: cast-local-type hl = vim.api.nvim_get_hl(0, { name = hl, link = false }) end
if vim.tbl_isempty(hl) or (not hl.fg and not hl.bg and not hl.link) then return {} end if hl.link then return utils.reverse_hl(hl.link --[[@as string]]) end local rev = vim.deepcopy(hl) rev.fg = hl.bg rev.bg = hl.fg ---@diagnostic disable-next-line: return-type-mismatch return revend
---@param hl vim.api.keyset.highlightfunction utils.create_hl(hl) local hl_name = string.format("@lylla.%s", vim.fn.sha256(vim.inspect(hl))) vim.schedule(function() vim.api.nvim_set_hl(0, hl_name, hl) end) return hl_nameend
function utils.getfilename() local _, default_file_hl = require("mini.icons").get("default", "file")
local bufname = vim.api.nvim_buf_get_name(0) local name = vim.fs.basename(bufname)
local file_icon_raw, file_icon_hl
local buftype = vim.bo.buftype if buftype == "" or buftype == "nowrite" then local stat = vim.uv.fs_stat(bufname) local type_ = stat and stat.type == "directory" and "directory" or "file" file_icon_raw, file_icon_hl = require("mini.icons").get(type_, name) elseif buftype == "nofile" or buftype == "acwrite" then local filetype = vim.bo.filetype file_icon_raw, file_icon_hl = require("mini.icons").get("filetype", filetype) name = string.format("(%s)", filetype) else name = string.format("(%s)", buftype) return { { name, default_file_hl } } end
return { { name, default_file_hl }, { " " }, { file_icon_raw, file_icon_hl } }end
function utils.getfilepath() if vim.bo.buftype ~= "" and vim.bo.buftype ~= "nowrite" then return {} end
local bufname = vim.api.nvim_buf_get_name(0) local path = vim.fn.fnamemodify(bufname, ":p:~:.")
local file_path_list = {} local _ = string.gsub(path, "[^/]+", function(w) table.insert(file_path_list, w) end)
local filepath = vim .iter(ipairs(file_path_list)) :fold("", function(acc, i, fragment) if i == #file_path_list then return acc end acc = acc .. fragment .. "/" return acc end)
return { filepath, "Directory" }end
function utils.get_searchcount() local result = vim.fn.searchcount({ recompute = 1 }) if vim.v.hlsearch ~= 1 then return "" end if vim.tbl_isempty(result) then return "" end local term = vim.fn.getreg("/") local display if result.incomplete == 1 then -- timed out display = "[?/??]" elseif result.incomplete == 2 then -- max count exceeded if result.total > result.maxcount and result.current > result.maxcount then display = string.format("[>%d/>%d]", result.current, result.total) elseif result.total > result.maxcount then display = string.format("[%d/>%d]", result.current, result.total) end end display = display or string.format("[%d/%d]", result.current, result.total)
return { { string.format("/%s", term), "IncSearch" }, { " " }, { display, "MsgSeparator" }, }end
---@param mode string---@return string---@return stringfunction utils.get_modehl_name(mode) return "@lylla." .. mode, string.format("@lylla.%s.rev", mode)end
---@return string---@return stringfunction utils.get_modehl() local mode = vim.api.nvim_get_mode().mode local modename = "normal"
if string.match(mode, "^[vVs]") then modename = "visual" elseif string.match(mode, "^c") then modename = "command" elseif string.match(mode, "^[it]") then modename = "insert" elseif string.match(mode, "^[rR]") then modename = "replace" elseif string.match(mode, "^%ao") then modename = "operator" end
return utils.get_modehl_name(modename)end
return utils