diff --git a/config/nvim/lua/config/catppuccin_feline.lua b/config/nvim/lua/config/catppuccin_feline.lua new file mode 100644 index 00000000..884a7513 --- /dev/null +++ b/config/nvim/lua/config/catppuccin_feline.lua @@ -0,0 +1,504 @@ +local M = {} + +local C = require("catppuccin.palettes").get_palette() +local lsp = require("feline.providers.lsp") + +local assets = { + left_separator = "", + right_separator = "", + mode_icon = "", + dir = "", + file = "", + lsp = { + server = "", + error = "", + warning = "", + info = "", + hint = "", + }, + git = { + branch = "", + added = "", + changed = "", + removed = "", + }, +} + +local sett = { + text = C.surface0, + bkg = C.surface0, + diffs = C.mauve, + extras = C.overlay1, + curr_file = C.maroon, + curr_dir = C.flamingo, + show_modified = false, +} + +if require("catppuccin").flavour == "latte" then + local latte = require("catppuccin.palettes").get_palette("latte") + sett.text = latte.base + sett.bkg = latte.crust +end + +if require("catppuccin").options.transparent_background then + sett.bkg = "NONE" +end + +local mode_colors = { + ["n"] = { "NORMAL", C.lavender }, + ["no"] = { "N-PENDING", C.lavender }, + ["i"] = { "INSERT", C.green }, + ["ic"] = { "INSERT", C.green }, + ["t"] = { "TERMINAL", C.green }, + ["v"] = { "VISUAL", C.flamingo }, + ["V"] = { "V-LINE", C.flamingo }, + [""] = { "V-BLOCK", C.flamingo }, + ["R"] = { "REPLACE", C.maroon }, + ["Rv"] = { "V-REPLACE", C.maroon }, + ["s"] = { "SELECT", C.maroon }, + ["S"] = { "S-LINE", C.maroon }, + [""] = { "S-BLOCK", C.maroon }, + ["c"] = { "COMMAND", C.peach }, + ["cv"] = { "COMMAND", C.peach }, + ["ce"] = { "COMMAND", C.peach }, + ["r"] = { "PROMPT", C.teal }, + ["rm"] = { "MORE", C.teal }, + ["r?"] = { "CONFIRM", C.mauve }, + ["!"] = { "SHELL", C.green }, +} + +function M.setup(opts) + if opts then + opts.assets = opts.assets or {} + opts.sett = opts.sett or {} + opts.mode_colors = opts.mode_colors or {} + else + opts = {} + end + assets = vim.tbl_deep_extend("force", assets, opts.assets) + sett = vim.tbl_deep_extend("force", sett, opts.sett) + mode_colors = vim.tbl_deep_extend("force", mode_colors, opts.mode_colors) +end + +function M.get() + local shortline = false + + local components = { + active = { {}, {} }, -- left, right + inactive = { {} }, + } + + local function is_enabled(min_width) + if shortline then + return true + end + + return vim.api.nvim_win_get_width(0) > min_width + end + + -- global components + local invi_sep = { + str = " ", + hl = { + fg = sett.bkg, + bg = sett.bkg, + }, + } + + -- helpers + local function any_git_changes() + local gst = vim.b.gitsigns_status_dict -- git stats + if gst then + if + gst["added"] and gst["added"] > 0 + or gst["removed"] and gst["removed"] > 0 + or gst["changed"] and gst["changed"] > 0 + then + return true + end + end + return false + end + + -- #################### STATUSLINE -> + + -- ######## Left + + -- Current vi mode ------> + local vi_mode_hl = function() + return { + fg = sett.text, + bg = mode_colors[vim.fn.mode()][2], + style = "bold", + } + end + + components.active[1][1] = { + provider = " " .. assets.mode_icon .. " ", + hl = function() + return { + fg = sett.text, + bg = mode_colors[vim.fn.mode()][2], + } + end, + } + + components.active[1][2] = { + provider = function() + return mode_colors[vim.fn.mode()][1] .. " " + end, + hl = vi_mode_hl, + } + + -- there is a dilema: we need to hide Diffs if ther is no git info. We can do that, but this will + -- leave the right_separator colored with purple, and since we can't change the color conditonally + -- then the solution is to create two right_separators: one with a mauve sett.bkg and the other one normal + -- sett.bkg; both have the same fg (vi mode). The mauve one appears if there is git info, else the one with + -- the normal sett.bkg appears. Fixed :) + + -- enable if git diffs are not available + components.active[1][3] = { + provider = assets.right_separator, + hl = function() + return { + fg = mode_colors[vim.fn.mode()][2], + bg = sett.bkg, + } + end, + enabled = function() + return not any_git_changes() + end, + } + + -- enable if git diffs are available + components.active[1][4] = { + provider = assets.right_separator, + hl = function() + return { + fg = mode_colors[vim.fn.mode()][2], + bg = sett.diffs, + } + end, + enabled = function() + return any_git_changes() + end, + } + -- Current vi mode ------> + + -- Diffs ------> + components.active[1][5] = { + provider = "git_diff_added", + hl = { + fg = sett.text, + bg = sett.diffs, + }, + icon = " " .. assets.git.added .. " ", + } + + components.active[1][6] = { + provider = "git_diff_changed", + hl = { + fg = sett.text, + bg = sett.diffs, + }, + icon = " " .. assets.git.changed .. " ", + } + + components.active[1][7] = { + provider = "git_diff_removed", + hl = { + fg = sett.text, + bg = sett.diffs, + }, + icon = " " .. assets.git.removed .. " ", + } + + components.active[1][8] = { + provider = " ", + hl = { + fg = sett.bkg, + bg = sett.diffs, + }, + enabled = function() + return any_git_changes() + end, + } + + components.active[1][9] = { + provider = assets.right_separator, + hl = { + fg = sett.diffs, + bg = sett.bkg, + }, + enabled = function() + return any_git_changes() + end, + } + -- Diffs ------> + + -- Extras ------> + + -- file progess + components.active[1][10] = { + provider = function() + local current_line = vim.fn.line(".") + local total_line = vim.fn.line("$") + + if current_line == 1 then + return "Top" + elseif current_line == vim.fn.line("$") then + return "Bot" + end + local result, _ = math.modf((current_line / total_line) * 100) + return result .. "%%" + end, + -- enabled = shortline or function(winid) + -- return vim.api.nvim_win_get_width(winid) > 90 + -- end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + left_sep = invi_sep, + } + + -- position + components.active[1][11] = { + provider = "position", + -- enabled = shortline or function(winid) + -- return vim.api.nvim_win_get_width(winid) > 90 + -- end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + left_sep = invi_sep, + } + + -- macro + components.active[1][12] = { + provider = "macro", + enabled = function() + return vim.api.nvim_get_option("cmdheight") == 0 + end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + left_sep = invi_sep, + } + + -- search count + components.active[1][13] = { + provider = "search_count", + enabled = function() + return vim.api.nvim_get_option("cmdheight") == 0 + end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + left_sep = invi_sep, + } + -- Extras ------> + + -- ######## Left + -- treesitter position + components.active[1][14] = { + provider = function() + local pos = require("nvim-treesitter").statusline() + if pos and pos ~= "" then + return pos + end + return "" + end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + left_sep = invi_sep, + } + + -- ######## Right + + -- Diagnostics ------> + -- workspace loader + components.active[2][1] = { + provider = function() + local Lsp = vim.lsp.util.get_progress_messages()[1] + + if Lsp then + local msg = Lsp.message or "" + local percentage = Lsp.percentage + if not percentage then + return "" + end + local title = Lsp.title or "" + local spinners = { + "", + "", + "", + } + local success_icon = { + "", + "", + "", + } + local ms = vim.loop.hrtime() / 1000000 + local frame = math.floor(ms / 120) % #spinners + + if percentage >= 70 then + return string.format(" %%<%s %s %s (%s%%%%) ", success_icon[frame + 1], title, msg, percentage) + end + + return string.format(" %%<%s %s %s (%s%%%%) ", spinners[frame + 1], title, msg, percentage) + end + + return "" + end, + enabled = is_enabled(80), + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + right_sep = invi_sep, + } + + components.active[2][2] = { + provider = "git_branch", + enabled = is_enabled(70), + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + icon = assets.git.branch .. " ", + right_sep = invi_sep, + } + + components.active[2][3] = { + provider = function() + if next(vim.lsp.buf_get_clients()) ~= nil then + return assets.lsp.server .. " " .. "Lsp" + else + return "" + end + end, + hl = { + fg = sett.extras, + bg = sett.bkg, + }, + right_sep = invi_sep, + } + + -- genral diagnostics (errors, warnings. info and hints) + components.active[2][4] = { + provider = "diagnostic_errors", + enabled = function() + return lsp.diagnostics_exist(vim.diagnostic.severity.ERROR) + end, + + hl = { + fg = C.red, + bg = sett.bkg, + }, + icon = " " .. assets.lsp.error .. " ", + right_sep = invi_sep, + } + + components.active[2][5] = { + provider = "diagnostic_warnings", + enabled = function() + return lsp.diagnostics_exist(vim.diagnostic.severity.WARN) + end, + hl = { + fg = C.yellow, + bg = sett.bkg, + }, + icon = " " .. assets.lsp.warning .. " ", + right_sep = invi_sep, + } + + components.active[2][6] = { + provider = "diagnostic_info", + enabled = function() + return lsp.diagnostics_exist(vim.diagnostic.severity.INFO) + end, + hl = { + fg = C.sky, + bg = sett.bkg, + }, + icon = " " .. assets.lsp.info .. " ", + right_sep = invi_sep, + } + + components.active[2][7] = { + provider = "diagnostic_hints", + enabled = function() + return lsp.diagnostics_exist(vim.diagnostic.severity.HINT) + end, + hl = { + fg = C.rosewater, + bg = sett.bkg, + }, + icon = " " .. assets.lsp.hint .. " ", + right_sep = invi_sep, + } + -- Diagnostics ------> + + components.active[2][8] = { + provider = function() + local filename = vim.fn.expand("%:t") + local extension = vim.fn.expand("%:e") + local present, icons = pcall(require, "nvim-web-devicons") + local icon = present and icons.get_icon(filename, extension) or assets.file + return (sett.show_modified and "%m" or "") .. " " .. icon .. " " .. filename .. " " + end, + enabled = is_enabled(70), + hl = { + fg = sett.text, + bg = sett.curr_file, + }, + left_sep = { + str = assets.left_separator, + hl = { + fg = sett.curr_file, + bg = sett.bkg, + }, + }, + } + + components.active[2][9] = { + provider = function() + local dir_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":t") + return " " .. assets.dir .. " " .. dir_name .. " " + end, + enabled = is_enabled(80), + hl = { + fg = sett.text, + bg = sett.curr_dir, + }, + left_sep = { + str = assets.left_separator, + hl = { + fg = sett.curr_dir, + bg = sett.curr_file, + }, + }, + } + -- ######## Right + + -- Inanctive components + components.inactive[1][1] = { + provider = function() + return " " .. string.upper(vim.bo.ft) .. " " + end, + hl = { + fg = C.overlay2, + bg = C.mantle, + }, + } + + return components +end + +return M diff --git a/config/nvim/lua/config/feline.lua b/config/nvim/lua/config/feline.lua index 4eeae670..088805d9 100644 --- a/config/nvim/lua/config/feline.lua +++ b/config/nvim/lua/config/feline.lua @@ -1,28 +1,4 @@ -local components = require("catppuccin.groups.integrations.feline").get() --- local original_provider = components.active[2][1].provider --- components.active[2][1].provider = function() --- local sources = { --- original_provider(), --- require("nvim-treesitter").statusline(), --- } --- for _, message in pairs(sources) do --- if message ~= "" then --- return message --- end --- end --- return "" --- end -table.insert(components.active[1], 12, { - provider = function() - local pos = require("nvim-treesitter").statusline() - if pos and pos ~= "" then - return pos - end - return "" - end, - hl = components.active[1][11].hl, - left_sep = components.active[1][11].left_sep, -}) +local components = require("config.catppuccin_feline").get() require("feline").setup({ components = components, })