🪴 a tiny, customizable statusline for neovim
at main 287 lines 5.9 kB view raw view rendered
1# lylla.nvim 2 3a minimal statusline plugin for neovim with extensive configuration; simple by default, flexible if needed. 4 5## features 6 7- minimal default look, based on neovim default statusline implementation 8- flexible configuration; define your own components 9- lightweight design; no required dependencies 10 11## goals 12 13lylla is designed to be: 14 15- minimal in features (no clutter) 16- maximal in configuration 17- stable and predictable; i wanted to prevent any hidden logic that i got 18 annoyed by in other statusline plugins 19 20## installation 21 22###### `vim.pack` 23 24```lua 25vim.pack.add({ src = "comfysage/lylla.nvim" }) 26``` 27 28###### `lazy.nvim` 29 30```lua 31{ 32 "comfysage/lylla.nvim", lazy = false, 33} 34``` 35 36### dependencies 37 38some of the utilities included in lylla use 39[mini.nvim](https://github.com/mini-nvim/mini.nvim) but these are not required 40in the default implementation. 41 42## configuration 43 44the default configuration is as follows: 45 46```lua 47require("lylla").setup({ 48 refresh_rate = 300, 49 hls = {}, 50 modules = { 51 "%<%f %h%w%m%r", 52 "%=", 53 { 54 fn = function() 55 if vim.o.showcmdloc == "statusline" then 56 return "%-10.S" 57 end 58 return "" 59 end, 60 }, 61 { " " }, 62 { 63 fn = function() 64 if not vim.b.keymap_name then 65 return "" 66 end 67 return "<" .. vim.b.keymap_name .. ">" 68 end, 69 }, 70 { " " }, 71 { 72 fn = function() 73 if vim.bo.busy > 0 then 74 return "" 75 end 76 return "" 77 end, 78 }, 79 { " " }, 80 { 81 fn = function() 82 if not package.loaded["vim.diagnostic"] then 83 return "" 84 end 85 return vim.diagnostic.status() 86 end, 87 opts = { 88 events = { "DiagnosticChanged" }, 89 }, 90 }, 91 { " " }, 92 { 93 fn = function() 94 if not vim.o.ruler then 95 return "" 96 end 97 if vim.o.rulerformat == "" then 98 return "%-14.(%l,%c%V%) %P" 99 end 100 return vim.o.rulerformat 101 end, 102 }, 103 }, 104 winbar = {}, 105}) 106``` 107 108### example configuration 109 110for a fully fletched example, look at my personal config: [`config/lylla.lua`](https://codeberg.org/comfysage/ivy/src/commit/bf572e5b6c73d6f0021956b28ec55667c272f6fa/config/config/lylla.lua). 111 112#### use `mini.icons` for colors 113 114some nice highlights that i personally use: 115 116```lua 117 hls = { 118 normal = { link = "MiniIconsAzure" }, 119 visual = { link = "MiniIconsPurple" }, 120 command = { link = "MiniIconsOrange" }, 121 insert = { link = "MiniIconsGrey" }, 122 replace = { link = "MiniIconsGrey" }, 123 operator = { link = "NonText" }, 124 }, 125``` 126 127### example components 128 129you can define custom components by passing lua functions: 130 131```lua 132local lylla = require("lylla") 133 134lylla.setup({ 135 modules = { 136 lylla.component(function() 137 return "hi " .. vim.env.USER 138 end, { events = { "VimEnter" } }), 139 }, 140}) 141``` 142 143components return strings to be shown in the statusline and can register 144autocmds to refresh them. 145 146components can also return a tuple combining text with a highlight group: 147 148```lua 149{ 150 { 151 { "meow", "ModeMsg" }, 152 { " | ", "WinSeparator" }, 153 }, 154 { fn = function() return { vim.bo.filetype, "MsgArea" } end }, 155} 156``` 157 158these tables can be nested to any amount; they all get folded down on refresh. 159 160### change refresh rate and events 161 162```lua 163require("lylla").setup { 164 refresh_rate = 100, -- update faster 165 events = { "WinEnter", "BufEnter", "CursorMoved" }, -- only update on these 166} 167``` 168 169(events control when the statusline is redrawn) 170 171### add a custom module 172 173modules are just tables that return strings. 174this example shows your current working directory: 175 176```lua 177local lylla = require("lylla") 178 179lylla.setup { 180 modules = { 181 "%<%f %h%w%m%r", -- filename etc 182 "%=", -- spacer 183 { 184 fn = function() 185 return vim.fn.fnamemodify(vim.fn.getcwd(), ":t") 186 end, opts = { 187 events = { "DirChanged" }, 188 }, 189 }, 190 }, 191} 192``` 193 194### conditional modules 195 196modules can react to options, buffers, or plugins. 197example: only show diagnostics if `vim.diagnostic` is loaded: 198 199```lua 200{ 201 lylla.component(function() 202 if not package.loaded["vim.diagnostic"] then 203 return "" 204 end 205 return vim.diagnostic.status() 206 end, { events = { "DiagnosticChanged" } }), 207} 208``` 209 210### sections 211 212modules can handle different highlights for a section. ~ highlights inside will inherit the background color. 213 214```lua 215{ 216 lylla.component(function() 217 return { 218 { section = "CursorLine" }, -- highlights after this will inherit the CursorLine bg 219 { "meow", "Title" }, 220 { " :3", "Constant" }, 221 { section = false }, -- denotes the end of a section 222 } 223 end) 224} 225``` 226 227### lsp information 228 229lylla components has a builtin helper for getting the current lsp client. 230 231```lua 232local components = require("lylla.components") 233 234{ 235 lylla.component(function() 236 local clients = components.lsp_clients() 237 return clients and { 238 { { "lsp :: " }, { client } }, 239 } 240 end, { events = { "FileType", "LspAttach" } }), 241} 242``` 243 244### winbar 245 246the winbar can be configured in the same way as the statusline: 247 248```lua 249winbar = { 250 lylla.component(function() 251 return { 252 utils.getfilepath(), 253 utils.getfilename(), 254 { " " }, 255 "%h%w%m%r", 256 } 257 end, { 258 events = { 259 "WinEnter", 260 "BufEnter", 261 "BufWritePost", 262 "FileChangedShellPost", 263 "Filetype", 264 }, 265 }), 266 { " " }, 267 lylla.component(function() 268 return utils.get_searchcount() 269 end), 270}, 271``` 272 273### tabline 274 275similarly, the tabline can be configured with the help of the `lylla.tabline` module: 276 277```lua 278local H = require('lylla.tabline') 279 280tabline = function() 281 return H.fortabs(function(tabidx, t_iscurrent) 282 return { 283 { string.format(" %d "), t_iscurrent and "TabLineSel" or "TabLine" }, 284 } 285 end) 286end 287```