馃 a tiny, customizable statusline for neovim
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 2d41df65f2ea311423f0d4eff8e217387ac4cbec 157 lines 4.1 kB view raw
1local utils = require("lylla.utils") 2 3---@class lylla.proto 4---@field wins table<integer, table> 5---@field win integer 6---@field modules any[] 7---@field winbar any[] 8---@field timer uv.uv_timer_t 9---@field refreshau integer 10local statusline = {} 11 12statusline.wins = {} 13 14---@class lylla.proto 15---@field new fun(self, win): lylla.proto 16function statusline:new(win) 17 if statusline.wins[win] then 18 statusline.wins[win]:close() 19 end 20 local stl = setmetatable({ 21 win = win, 22 modules = vim.deepcopy(require("lylla.config").get().modules, true), 23 winbar = vim.deepcopy(require("lylla.config").get().winbar, true), 24 }, { __index = statusline }) 25 statusline.wins[win] = stl 26 return stl 27end 28 29---@class lylla.proto 30---@field init fun(self) 31function statusline:init() 32 local err, err_kind 33 ---@diagnostic disable-next-line: assign-type-mismatch 34 self.timer, err, err_kind = vim.uv.new_timer() 35 if not self.timer or err then 36 vim.api.nvim_echo({ { err_kind }, { "\n\t" }, { err } }, true, { err = true }) 37 return 38 end 39 40 local refresh = require("lylla.config").get().refresh_rate 41 self.timer:start(0, refresh, function() 42 self:refresh() 43 end) 44 45 self.refreshau = vim.api.nvim_create_autocmd(require("lylla.config").get().events, { 46 group = vim.api.nvim_create_augroup("lylla:refresh", { clear = false }), 47 callback = function(ev) 48 self:refresh(ev) 49 end, 50 }) 51end 52 53---@class lylla.proto 54---@field close fun(self) 55function statusline:close() 56 self.timer:stop() 57 self.timer:close() 58 vim.api.nvim_del_autocmd(self.refreshau) 59 statusline.wins[self.win] = nil 60end 61 62---@class lylla.proto 63---@field refresh fun(self, ev?: vim.api.keyset.create_autocmd.callback_args) 64function statusline:refresh(ev) 65 vim.schedule(function() 66 if not vim.api.nvim_win_is_valid(self.win) then 67 return 68 end 69 70 self:set(ev) 71 self:setwinbar(ev) 72 end) 73end 74 75---@class lylla.proto 76---@field fold fun(self, ev?: vim.api.keyset.create_autocmd.callback_args, modules: any[]): string 77function statusline:fold(ev, modules) 78 local lst = vim 79 .iter(ipairs(modules)) 80 :map(function(_, module) 81 if type(module) == "table" and module._type == "component" then 82 if module.opts and module.opts.events then 83 -- refresh from timer 84 if not ev and module.prev then 85 return module.prev 86 end 87 -- refresh from non-match event 88 if ev and not vim.tbl_contains(module.opts.events, ev.event) and module.prev then 89 return module.prev 90 end 91 end 92 module.prev = module.fn() 93 return module.prev 94 end 95 if type(module) == "function" then 96 module = module() 97 end 98 return module 99 end) 100 :totable() 101 lst = utils.flatten(lst, 1) 102 return vim.iter(lst):fold("", function(str, module) 103 if type(module) ~= "table" or #module == 0 then 104 return str 105 end 106 local text = module[1] 107 if #module > 1 then 108 return str .. "%#" .. module[2] .. "#" .. text .. "%*" 109 end 110 return str .. "%*" .. text 111 end) 112end 113 114---@class lylla.proto 115---@field get fun(self, ev?: vim.api.keyset.create_autocmd.callback_args) 116function statusline:get(ev) 117 return self:fold(ev, self.modules) 118end 119 120---@class lylla.proto 121---@field getwinbar fun(self, ev?: vim.api.keyset.create_autocmd.callback_args) 122function statusline:getwinbar(ev) 123 return self:fold(ev, self.winbar) 124end 125 126---@class lylla.proto 127---@field setwinbar fun(self, ev?: vim.api.keyset.create_autocmd.callback_args) 128function statusline:setwinbar(ev) 129 local buf = vim.api.nvim_win_get_buf(self.win) 130 if vim.bo[buf].buftype ~= "" then 131 return 132 end 133 134 local ok, result = pcall(vim.api.nvim_win_call, self.win, function() 135 return self:getwinbar(ev) 136 end) 137 if not ok then 138 return 139 end 140 141 vim.wo[self.win].winbar = result 142end 143 144---@class lylla.proto 145---@field set fun(self, ev?: vim.api.keyset.create_autocmd.callback_args) 146function statusline:set(ev) 147 local ok, result = pcall(vim.api.nvim_win_call, self.win, function() 148 return self:get(ev) 149 end) 150 if not ok then 151 return 152 end 153 154 vim.wo[self.win].statusline = result 155end 156 157return statusline