feline.lua (8789B)
1 local lsp = require("feline.providers.lsp") 2 local lsp_severity = vim.diagnostic.severity 3 local b = vim.b 4 5 local assets = { 6 left_semicircle = "", 7 right_semicircle = "", 8 right_semicircle_cut = "", 9 left_semicircle_cut = "", 10 vertical_bar_chubby = "█", 11 vertical_bar_medium = "┃", 12 vertical_bar_thin = "│", 13 left_arrow_thin = "", 14 right_arrow_thin = "", 15 left_arrow_filled = "", 16 right_arrow_filled = "", 17 slant_left = "", 18 slant_left_thin = "", 19 slant_right = "", 20 slant_right_thin = "", 21 slant_left_2 = "", 22 slant_left_2_thin = "", 23 slant_right_2 = "", 24 slant_right_2_thin = "", 25 chubby_dot = "●", 26 slim_dot = '•', 27 } 28 29 local colors = require('pywal.core').get_colors() 30 31 -- settings 32 local sett = { 33 bkg = colors.background, 34 diffs = colors.color1, 35 extras = colors.color5, 36 curr_file = colors.color4, 37 curr_dir = colors.color4, 38 } 39 40 local mode_colors = { 41 ["n"] = { "NORMAL", colors.color1 }, 42 ["no"] = { "N-PENDING", colors.color1 }, 43 ["i"] = { "INSERT", colors.color1 }, 44 ["ic"] = { "INSERT", colors.color1 }, 45 ["t"] = { "TERMINAL", colors.color1 }, 46 ["v"] = { "VISUAL", colors.color3 }, 47 ["V"] = { "V-LINE", colors.color3 }, 48 [""] = { "V-BLOCK", colors.color3 }, 49 ["R"] = { "REPLACE", colors.color4 }, 50 ["Rv"] = { "V-REPLACE", colors.color4 }, 51 ["s"] = { "SELECT", colors.color4 }, 52 ["S"] = { "S-LINE", colors.color4 }, 53 [""] = { "S-BLOCK", colors.color4 }, 54 ["c"] = { "COMMAND", colors.color6 }, 55 ["cv"] = { "COMMAND", colors.color6 }, 56 ["ce"] = { "COMMAND", colors.color6 }, 57 ["r"] = { "PROMPT", colors.color7 }, 58 ["rm"] = { "MORE", colors.color7 }, 59 ["r?"] = { "CONFIRM", colors.color2 }, 60 ["!"] = { "SHELL", colors.color1 }, 61 } 62 63 local shortline = false 64 65 -- Initialize the components table 66 local components = { 67 active = {}, 68 inactive = {}, 69 } 70 71 table.insert(components.active, {}) -- (1) left 72 table.insert(components.active, {}) -- (2) center 73 table.insert(components.active, {}) -- (3) right 74 75 -- global components 76 local invi_sep = { 77 str = " ", 78 hl = { 79 fg = sett.bkg, 80 bg = sett.bkg 81 }, 82 } 83 84 -- helpers 85 local function any_git_changes() 86 local gst = b.gitsigns_status_dict -- git stats 87 if gst then 88 if gst["added"] and gst["added"] > 0 or gst["removed"] and gst["removed"] > 0 or gst["changed"] and gst["changed"] > 0 then 89 return true 90 end 91 end 92 return false 93 end 94 95 96 -- #################### STATUSLINE -> 97 98 99 -- ######## Left 100 101 -- Current vi mode ------> 102 local vi_mode_hl = function() 103 return { 104 fg = sett.bkg, 105 bg = mode_colors[vim.fn.mode()][2], 106 style = "bold" 107 } 108 end 109 110 components.active[1][1] = { 111 provider = assets.vertical_bar_chubby, 112 hl = function() 113 return { 114 fg = mode_colors[vim.fn.mode()][2], 115 bg = sett.bkg, 116 } 117 end, 118 } 119 120 components.active[1][2] = { 121 provider = "", 122 hl = function() 123 return { 124 fg = sett.bkg, 125 bg = mode_colors[vim.fn.mode()][2], 126 } 127 end, 128 } 129 130 components.active[1][3] = { 131 provider = function() 132 return " " .. mode_colors[vim.fn.mode()][1] .. " " 133 end, 134 hl = vi_mode_hl, 135 } 136 137 -- there is a dilema: we need to hide Diffs if ther is no git info. We can do that, but this will 138 -- leave the right_semicircle colored with purple, and since we can't change the color conditonally 139 -- then the solution is to create two right_semicircles: one with a color2 sett.bkg and the other one normal 140 -- sett.bkg; both have the same fg (vi mode). The color2 one appears if there is git info, else the one with 141 -- the normal sett.bkg appears. Fixed :) 142 143 -- enable if git diffs are not available 144 components.active[1][4] = { 145 provider = assets.right_semicircle, 146 hl = function() 147 return { 148 fg = mode_colors[vim.fn.mode()][2], 149 bg = sett.bkg 150 } 151 end, 152 enabled = function() 153 return not any_git_changes() 154 end 155 } 156 157 -- enable if git diffs are available 158 components.active[1][5] = { 159 provider = assets.right_semicircle, 160 hl = function() 161 return { 162 fg = mode_colors[vim.fn.mode()][2], 163 bg = sett.diffs 164 } 165 end, 166 enabled = function() 167 return any_git_changes() 168 end 169 } 170 -- Current vi mode ------> 171 172 -- Diffs ------> 173 components.active[1][6] = { 174 provider = "git_diff_added", 175 hl = { 176 fg = sett.bkg, 177 bg = sett.diffs, 178 }, 179 icon = " ", 180 } 181 182 components.active[1][7] = { 183 provider = "git_diff_changed", 184 hl = { 185 fg = sett.bkg, 186 bg = sett.diffs, 187 }, 188 icon = " ", 189 } 190 191 components.active[1][8] = { 192 provider = "git_diff_removed", 193 hl = { 194 fg = sett.bkg, 195 bg = sett.diffs, 196 }, 197 icon = " ", 198 } 199 200 components.active[1][9] = { 201 provider = assets.right_semicircle, 202 hl = { 203 fg = sett.diffs, 204 bg = sett.bkg, 205 }, 206 enabled = function() 207 return any_git_changes() 208 end 209 } 210 -- Diffs ------> 211 212 -- Extras ------> 213 214 -- file progess 215 components.active[1][10] = { 216 provider = function() 217 local current_line = vim.fn.line(".") 218 local total_line = vim.fn.line("$") 219 220 if current_line == 1 then 221 return " Top " 222 elseif current_line == vim.fn.line("$") then 223 return " Bot " 224 end 225 local result, _ = math.modf((current_line / total_line) * 100) 226 return " " .. result .. "%% " 227 end, 228 -- enabled = shortline or function(winid) 229 -- return vim.api.nvim_win_get_width(winid) > 90 230 -- end, 231 hl = { 232 fg = sett.extras, 233 bg = sett.bkg 234 }, 235 left_sep = invi_sep, 236 } 237 238 -- position 239 components.active[1][11] = { 240 provider = "position", 241 -- enabled = shortline or function(winid) 242 -- return vim.api.nvim_win_get_width(winid) > 90 243 -- end, 244 hl = { 245 fg = sett.extras, 246 bg = sett.bkg 247 }, 248 left_sep = invi_sep, 249 } 250 -- Extras ------> 251 252 -- ######## Left 253 254 -- ######## Center 255 256 -- Diagnostics ------> 257 -- workspace loader 258 components.active[2][1] = { 259 provider = function() 260 local Lsp = vim.lsp.util.get_progress_messages()[1] 261 262 if Lsp then 263 local msg = Lsp.message or "" 264 local percentage = Lsp.percentage or 0 265 local title = Lsp.title or "" 266 local spinners = { 267 "", 268 "", 269 "", 270 } 271 local success_icon = { 272 "", 273 "", 274 "", 275 } 276 local ms = vim.loop.hrtime() / 1000000 277 local frame = math.floor(ms / 120) % #spinners 278 279 if percentage >= 70 then 280 return string.format(" %%<%s %s %s (%s%%%%) ", success_icon[frame + 1], title, msg, percentage) 281 end 282 283 return string.format(" %%<%s %s %s (%s%%%%) ", spinners[frame + 1], title, msg, percentage) 284 end 285 286 return "" 287 end, 288 enabled = shortline or function(winid) 289 return vim.api.nvim_win_get_width(winid) > 80 290 end, 291 hl = { 292 fg = colors.rosewater, 293 bg = sett.bkg 294 }, 295 } 296 297 -- genral diagnostics (errors, warnings. info and hints) 298 components.active[2][2] = { 299 provider = "diagnostic_errors", 300 enabled = function() 301 return lsp.diagnostics_exist(lsp_severity.ERROR) 302 end, 303 304 hl = { 305 fg = colors.red, 306 bg = sett.bkg, 307 }, 308 icon = " ", 309 } 310 311 components.active[2][3] = { 312 provider = "diagnostic_warnings", 313 enabled = function() 314 return lsp.diagnostics_exist(lsp_severity.WARN) 315 end, 316 hl = { 317 fg = colors.yellow, 318 bg = sett.bkg, 319 }, 320 icon = " ", 321 } 322 323 components.active[2][4] = { 324 provider = "diagnostic_info", 325 enabled = function() 326 return lsp.diagnostics_exist(lsp_severity.INFO) 327 end, 328 hl = { 329 fg = colors.sky, 330 bg = sett.bkg, 331 }, 332 icon = " ", 333 } 334 335 components.active[2][5] = { 336 provider = "diagnostic_hints", 337 enabled = function() 338 return lsp.diagnostics_exist(lsp_severity.HINT) 339 end, 340 hl = { 341 fg = colors.rosewater, 342 bg = sett.bkg, 343 }, 344 icon = " ", 345 } 346 -- Diagnostics ------> 347 348 -- ######## Center 349 350 -- ######## Right 351 352 components.active[3][1] = { 353 provider = "git_branch", 354 enabled = shortline or function(winid) 355 return vim.api.nvim_win_get_width(winid) > 70 356 end, 357 hl = { 358 fg = sett.extras, 359 bg = sett.bkg 360 }, 361 icon = " ", 362 left_sep = invi_sep, 363 right_sep = invi_sep, 364 } 365 366 components.active[3][2] = { 367 provider = function() 368 if next(vim.lsp.buf_get_clients()) ~= nil then 369 return " " 370 else 371 return "" 372 end 373 end, 374 hl = { 375 fg = sett.extras, 376 bg = sett.bkg 377 }, 378 right_sep = invi_sep, 379 } 380 381 components.active[3][3] = { 382 provider = function() 383 local filename = vim.fn.expand("%:t") 384 local extension = vim.fn.expand("%:e") 385 local icon = require("nvim-web-devicons").get_icon(filename, extension) 386 if icon == nil then 387 icon = " " 388 return icon 389 end 390 return " " .. icon .. " " .. filename .. " " 391 end, 392 enabled = shortline or function(winid) 393 return vim.api.nvim_win_get_width(winid) > 70 394 end, 395 hl = { 396 fg = sett.bkg, 397 bg = sett.curr_file, 398 }, 399 left_sep = { 400 str = assets.left_semicircle, 401 hl = { 402 fg = sett.curr_file, 403 bg = sett.bkg, 404 }, 405 }, 406 } 407 408 components.active[3][4] = { 409 provider = function() 410 local dir_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":t") 411 return " " .. dir_name .. " " 412 end, 413 414 enabled = shortline or function(winid) 415 return vim.api.nvim_win_get_width(winid) > 80 416 end, 417 418 hl = { 419 fg = sett.bkg, 420 bg = sett.curr_dir, 421 }, 422 left_sep = { 423 str = assets.left_semicircle, 424 hl = { 425 fg = sett.curr_dir, 426 bg = sett.curr_file, 427 }, 428 }, 429 } 430 -- ######## Right 431 432 return components