----@type LazyPluginSpec
+local M = {}
+
+---@param component any -- actually a lualine.component
+---@param text string
+---@param hl_group? string
+---@return string
+function M.format(component, text, hl_group)
+ text = text:gsub("%%", "%%%%")
+ if not hl_group or hl_group == "" then
+ return text
+ end
+ --- hl_cache is added here, not modified
+ ---@type table<string, string>
+ component.hl_cache = component.hl_cache or {}
+ local lualine_hl_group = component.hl_cache[hl_group]
+ if not lualine_hl_group then
+ local utils = require("lualine.utils.utils")
+ ---@type string[]
+ local gui = vim.tbl_filter(function(x) return x end, {
+ utils.extract_highlight_colors(hl_group, "bold") and "bold",
+ utils.extract_highlight_colors(hl_group, "italic") and "italic",
+ })
+
+ lualine_hl_group = component:create_hl({
+ fg = utils.extract_highlight_colors(hl_group, "fg"),
+ gui = #gui > 0 and table.concat(gui, ",") or nil,
+ }, "LV_" .. hl_group) --[[@as string]]
+ component.hl_cache[hl_group] = lualine_hl_group
+ end
+ return component:format_hl(lualine_hl_group) .. text .. component:get_default_hl()
+end
+
+function M.pretty_path()
+ return function(self)
+ local opts = {
+ directory_hl = "",
+ filename_hl = "Bold",
+ length = 3,
+ modified_hl = "MatchParen", -- hl group when file is modified
+ modified_sign = "",
+ readonly_icon = " ",
+ }
+
+ local path = vim.fn.expand("%:p") --[[@as string]]
+
+ if path == "" then
+ return ""
+ end
+
+ path = require("lazy.core.util").norm(path)
+ local cwd = vim.uv.cwd()
+
+ if path:find(cwd, 1, true) == 1 then
+ path = path:sub(#cwd + 2)
+ end
+
+ local sep = package.config:sub(1, 1)
+ local parts = vim.split(path, "[\\/]")
+
+ if opts.length == 0 then
+ parts = parts
+ elseif #parts > opts.length then
+ parts = { parts[1], "…", unpack(parts, #parts - opts.length + 2, #parts) }
+ end
+
+ if vim.bo.modified then
+ parts[#parts] = parts[#parts] .. opts.modified_sign
+ parts[#parts] = M.format(self, parts[#parts], opts.modified_hl)
+ else
+ parts[#parts] = M.format(self, parts[#parts], opts.filename_hl)
+ end
+
+ local dir = ""
+ if #parts > 1 then
+ dir = table.concat({ unpack(parts, 1, #parts - 1) }, sep)
+ dir = M.format(self, dir .. sep, opts.directory_hl)
+ end
+
+ local readonly = ""
+ if vim.bo.readonly then
+ readonly = M.format(self, opts.readonly_icon, opts.modified_hl)
+ end
+ return dir .. parts[#parts] .. readonly
+ end
+end
+
+---@type LazySpec
return {
- {
- "nvim-notify",
- },
- {
- "bufferline.nvim",
- ---@type BufferlineConfig
+ { 'echasnovski/mini.clue',
+ -- NOTE: this caused some issue with unterminated mappings, i.e. <L>gc when there
+ -- is also <L>gcc. It would simply terminate early and not allow for next mapping.
+ version = '*',
opts = {
- options = {
- always_show_bufferline = false,
+ triggers = {
+ { mode = 'n', keys = '<Leader>' },
+ { mode = 'x', keys = '<Leader>' },
+ -- `g` key
+ { mode = 'n', keys = 'g' },
+ { mode = 'x', keys = 'g' },
+ -- Marks
+ { mode = 'n', keys = "'" },
+ { mode = 'n', keys = '`' },
+ { mode = 'x', keys = "'" },
+ { mode = 'x', keys = '`' },
+ -- Window commands
+ { mode = 'n', keys = '<C-w>' },
+ -- `z` key
+ { mode = 'n', keys = 'z' },
+ { mode = 'x', keys = 'z' },
+ },
+ clues = {
+ { mode = 'n', keys = '<Leader>b', desc = '+Buffers' },
+ { mode = 'n', keys = '<Leader>c', desc = '+LSP' },
},
},
},
- {
- "noice.nvim",
- ---@type NoiceConfig
+ { "akinsho/bufferline.nvim",
+ event = "VeryLazy",
+ keys = {
+ { "<leader>bp", "<Cmd>BufferLineTogglePin<CR>", desc = "Toggle Pin" },
+ { "<leader>bP", "<Cmd>BufferLineGroupClose ungrouped<CR>", desc = "Delete Non-Pinned Buffers" },
+ { "<leader>br", "<Cmd>BufferLineCloseRight<CR>", desc = "Delete Buffers to the Right" },
+ { "<leader>bl", "<Cmd>BufferLineCloseLeft<CR>", desc = "Delete Buffers to the Left" },
+ { "<S-h>", "<cmd>BufferLineCyclePrev<cr>", desc = "Prev Buffer" },
+ { "<S-l>", "<cmd>BufferLineCycleNext<cr>", desc = "Next Buffer" },
+ { "[b", "<cmd>BufferLineCyclePrev<cr>", desc = "Prev Buffer" },
+ { "]b", "<cmd>BufferLineCycleNext<cr>", desc = "Next Buffer" },
+ { "[B", "<cmd>BufferLineMovePrev<cr>", desc = "Move buffer prev" },
+ { "]B", "<cmd>BufferLineMoveNext<cr>", desc = "Move buffer next" },
+ },
+ ---@type BufferlineConfig
opts = {
- presets = {
- command_palette = false, -- don't position the cmdline and popupmenu together
- lsp_doc_border = true, -- add a border to hover docs and signature help
- },
- cmdline = {
- view = "cmdline",
- },
- routes = {
- { -- send file written messages to mini
- filter = {
- event = "msg_show",
- kind = "",
- find = "%[w%]",
+ options = {
+ close_command = function(n) Snacks.bufdelete(n) end,
+ right_mouse_command = function(n) Snacks.bufdelete(n) end,
+ diagnostics = "nvim_lsp",
+ always_show_bufferline = false,
+ diagnostics_indicator = function(_, _, diag)
+ local icons = LazyVim.config.icons.diagnostics
+ local ret = (diag.error and icons.Error .. diag.error .. " " or "")
+ .. (diag.warning and icons.Warn .. diag.warning or "")
+ return vim.trim(ret)
+ end,
+ offsets = {
+ {
+ filetype = "man",
+ text = "Man page",
+ highlight = "Directory",
+ text_align = "left",
},
- opts = { skip = true },
},
+ ---@param opts bufferline.IconFetcherOpts
+ get_element_icon = function(opts)
+ return LazyVim.config.icons.ft[opts.filetype]
+ end,
},
},
- config = function(_, opts)
- -- ensure [w] is written to msg_show so we can match it
- vim.opt.shortmess:append("w")
- vim.opt.shortmess:remove("W")
-
- require("noice").setup(opts)
- end,
},
- {
- "lualine.nvim",
- --TODO: Things that were in vim but are missing
+ { "nvim-lualine/lualine.nvim",
+ -- TODO: Things that were in vim but are missing
-- - git line add/mod/del ar next to branch name rather on right
-- - one status line per splits
-- - maybe a single one is OK too?
-- - unix/dos eof markers
-- - really I only want to know if it's not unix
-- - filetype in text form. It's quite important to glance this quickly
+ event = "VeryLazy",
+ init = function()
+ vim.g.lualine_laststatus = vim.o.laststatus
+ if vim.fn.argc(-1) > 0 then
+ -- set an empty statusline till lualine loads
+ vim.o.statusline = " "
+ else
+ -- hide the statusline on the starter page
+ vim.o.laststatus = 0
+ end
+ end,
+ opts = function()
+ -- PERF: we don't need this lualine require madness 🤷
+ local lualine_require = require("lualine_require")
+ lualine_require.require = require
+
+ local icons = LazyVim.config.icons
+
+ vim.o.laststatus = vim.g.lualine_laststatus
+
+ local opts = {
+ options = {
+ theme = "auto",
+ globalstatus = vim.o.laststatus == 3,
+ disabled_filetypes = { statusline = { "dashboard", "alpha", "ministarter", "snacks_dashboard" } },
+ },
+ sections = {
+ lualine_a = { "mode" },
+ lualine_b = { "branch" },
+
+ lualine_c = {
+ {
+ "diagnostics",
+ symbols = {
+ error = icons.diagnostics.Error,
+ warn = icons.diagnostics.Warn,
+ info = icons.diagnostics.Info,
+ hint = icons.diagnostics.Hint,
+ },
+ },
+ { "filetype", icon_only = true, separator = "", padding = { left = 1, right = 0 } },
+ { M.pretty_path() },
+ },
+ lualine_x = {
+ Snacks.profiler.status(),
+ -- stylua: ignore
+ {
+ function() return " " .. require("dap").status() end,
+ cond = function() return package.loaded["dap"] and require("dap").status() ~= "" end,
+ color = function() return { fg = Snacks.util.color("Debug") } end,
+ },
+ -- stylua: ignore
+ {
+ require("lazy.status").updates,
+ cond = require("lazy.status").has_updates,
+ color = function() return { fg = Snacks.util.color("Special") } end,
+ },
+ {
+ "diff",
+ symbols = {
+ added = icons.git.added,
+ modified = icons.git.modified,
+ removed = icons.git.removed,
+ },
+ source = function()
+ local gitsigns = vim.b.gitsigns_status_dict
+ if gitsigns then
+ return {
+ added = gitsigns.added,
+ modified = gitsigns.changed,
+ removed = gitsigns.removed,
+ }
+ end
+ end,
+ },
+ },
+ lualine_y = {
+ { "progress", separator = " ", padding = { left = 1, right = 0 } },
+ { "location", padding = { left = 0, right = 1 } },
+ },
+ lualine_z = {
+ function()
+ return " " .. os.date("%R")
+ end,
+ },
+ },
+ extensions = { "neo-tree", "lazy", "fzf" },
+ }
+
+ local trouble = require("trouble")
+ local symbols = trouble.statusline({
+ mode = "symbols",
+ groups = {},
+ title = false,
+ filter = { range = true },
+ format = "{kind_icon}{symbol.name:Normal}",
+ hl_group = "lualine_c_normal",
+ })
+ table.insert(opts.sections.lualine_c, {
+ symbols and symbols.get,
+ cond = function()
+ return vim.b.trouble_lualine ~= false and symbols.has()
+ end,
+ })
+
+ return opts
+ end,
},
{
- "indent-blankline.nvim",
+ "echasnovski/mini.icons",
+ lazy = true,
+ opts = {
+ file = {
+ [".keep"] = { glyph = "", hl = "MiniIconsGrey" },
+ ["devcontainer.json"] = { glyph = "", hl = "MiniIconsAzure" },
+ },
+ filetype = {
+ dotenv = { glyph = "", hl = "MiniIconsYellow" },
+ },
+ },
+ init = function()
+ -- TODO: try without this
+ -- see :h MiniIcons.mock_nvim_web_devicons()
+ package.preload["nvim-web-devicons"] = function()
+ require("mini.icons").mock_nvim_web_devicons()
+ return package.loaded["nvim-web-devicons"]
+ end
+ end,
},
- {
- "mini.indentscope",
+ { "MunifTanjim/nui.nvim", lazy = true },
+ { "stevearc/dressing.nvim",
+ enabled = false, -- replaced by snacks.input
+ lazy = true,
opts = {
- draw = {
- animation = require("mini.indentscope").gen_animation.linear({ duration = 10 }),
+ input = {
+ start_in_insert = false,
+ insert_only = false,
},
},
},
- {
- "alpha-nvim",
+ { "indent-blankline.nvim",
+ enabled = false, -- replaced by snacks.indent
},
- {
- "nvim-navic",
+ { "echasnovski/mini.indentscope",
+ enabled = false, -- replaced by snacks.indent
+ version = false, -- wait till new 0.7.0 release to put it back on semver
+ event = "LazyFile",
+ opts = function (_, opts)
+ return {
+ draw = {
+ animation = require("mini.indentscope").gen_animation.linear({ duration = 10 })
+ }
+ }
+ end,
},
- {
- "nvim-web-devicons",
+ { "SmiteshP/nvim-navic",
+ lazy = true,
+ init = function()
+ vim.g.navic_silence = true
+ LazyVim.lsp.on_attach(function(client, buffer)
+ if client.supports_method("textDocument/documentSymbol") then
+ require("nvim-navic").attach(client, buffer)
+ end
+ end)
+ end,
+ opts = function()
+ return {
+ separator = " ",
+ highlight = true,
+ depth_limit = 5,
+ icons = LazyVim.config.icons.kinds,
+ lazy_update_context = true,
+ }
+ end,
},
- {
- "nui.nvim",
+ { "nvim-lualine/lualine.nvim",
+ optional = true,
+ opts = function(_, opts)
+ if not vim.g.trouble_lualine then
+ table.insert(opts.sections.lualine_c, { "navic", color_correction = "dynamic" })
+ end
+ end,
},
}