return { -- Seamless navigation between nvim splits and tmux panes { "mrjones2014/smart-splits.nvim", lazy = false, opts = { multiplexer_integration = "tmux", cursor_follows_swapped_panes = false, }, keys = { -- Navigate { "", function() require("smart-splits").move_cursor_left() end, mode = { "n", "t" }, desc = "Move to left split/pane" }, { "", function() require("smart-splits").move_cursor_down() end, mode = { "n", "t" }, desc = "Move to lower split/pane" }, { "", function() require("smart-splits").move_cursor_up() end, mode = { "n", "t" }, desc = "Move to upper split/pane" }, { "", function() require("smart-splits").move_cursor_right() end, mode = { "n", "t" }, desc = "Move to right split/pane" }, -- Resize { "", function() require("smart-splits").resize_left() end, desc = "Resize left" }, { "", function() require("smart-splits").resize_down() end, desc = "Resize down" }, { "", function() require("smart-splits").resize_up() end, desc = "Resize up" }, { "", function() require("smart-splits").resize_right() end, desc = "Resize right" }, }, }, -- Breadcrumbs: current file > class > method via LSP { "SmiteshP/nvim-navic", lazy = true, -- attached via LspAttach in autocmds.lua opts = { icons = { File = "󰈙 ", Module = " ", Namespace = "󰌗 ", Package = " ", Class = "󰌗 ", Method = "󰆧 ", Property = " ", Field = " ", Constructor = " ", Enum = "󰕘", Interface = "󰕘", Function = "󰊕 ", Variable = "󰆧 ", Constant = "󰏿 ", String = "󰀬 ", Number = "󰎠 ", Boolean = "◩ ", Array = "󰅪 ", Object = "󰅩 ", Key = "󰌋 ", Null = "󰟢 ", EnumMember = " ", Struct = "󰌗 ", Event = " ", Operator = "󰆕 ", TypeParameter = "󰊄 ", }, lsp = { auto_attach = false }, -- we attach manually in autocmds.lua highlight = true, separator = " › ", }, }, -- Statusline { "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons", "SmiteshP/nvim-navic" }, event = "VeryLazy", config = function() local navic = require("nvim-navic") require("lualine").setup({ options = { theme = require("apex-neon").lualine, globalstatus = true, component_separators = { left = "", right = "" }, section_separators = { left = "", right = "" }, }, sections = { lualine_a = { "mode" }, lualine_b = { "branch", "diff", "diagnostics" }, lualine_c = { { "filename", path = 1 } }, lualine_x = { { -- Show recording macro indicator function() local reg = vim.fn.reg_recording() return reg ~= "" and "Recording @" .. reg or "" end, color = { fg = "#ffb700" }, }, "encoding", "fileformat", "filetype", }, lualine_y = { "progress" }, lualine_z = { "location" }, }, winbar = { lualine_c = { { function() return navic.is_available() and navic.get_location() or "" end, }, }, }, inactive_winbar = { lualine_c = { { "filename", path = 1 } }, }, }) end, }, -- Buffer tabs at top { "akinsho/bufferline.nvim", version = "*", dependencies = "nvim-tree/nvim-web-devicons", event = "VeryLazy", opts = { options = { mode = "buffers", separator_style = "slant", show_buffer_close_icons = true, show_close_icon = false, color_icons = true, diagnostics = "nvim_lsp", offsets = { { filetype = "aerial", text = "Symbols", text_align = "center", separator = true }, }, }, }, }, -- Scoped buffers per tab { "tiagovla/scope.nvim", event = "VeryLazy", opts = {}, }, -- Keymap discovery { "folke/which-key.nvim", event = "VeryLazy", opts = { preset = "modern", icons = { mappings = false }, }, config = function(_, opts) local wk = require("which-key") wk.setup(opts) wk.add({ { "f", group = "Find / Telescope" }, { "g", group = "Git" }, { "l", group = "LSP" }, { "r", group = "Refactor" }, { "x", group = "Diagnostics / Trouble" }, { "d", group = "Debug (DAP)" }, { "t", group = "Test" }, { "u", group = "UI Toggles" }, { "S", group = "Sessions" }, { "j", group = "Java" }, { "c", group = "AI / Claude" }, { "h", group = "Git Hunks" }, }) -- UI toggle keymaps (no plugin dependency) local map = vim.keymap.set map("n", "uw", function() vim.opt.wrap = not vim.wo.wrap end, { desc = "Toggle wrap" }) map("n", "uf", "zA", { desc = "Toggle all folds" }) end, }, -- Indentation guides { "lukas-reineke/indent-blankline.nvim", main = "ibl", event = { "BufReadPost", "BufNewFile" }, keys = { { "ui", "IBLToggle", desc = "Toggle indent guides" }, }, opts = { indent = { char = "│" }, scope = { enabled = true }, }, }, -- Rendered markdown in buffer { "MeanderingProgrammer/render-markdown.nvim", ft = { "markdown" }, dependencies = { "nvim-tree/nvim-web-devicons" }, opts = { heading = { enabled = true }, code = { enabled = true, style = "full" }, bullet = { enabled = true }, }, }, -- File explorer as buffer { "stevearc/oil.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, cmd = "Oil", keys = { { "-", "Oil --float", desc = "Open oil (float)" }, }, opts = { default_file_explorer = true, float = { padding = 2 }, view_options = { show_hidden = true }, }, }, -- Symbols outline panel { "stevearc/aerial.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, keys = { { "uo", "AerialToggle!", desc = "Symbols outline" }, }, opts = { attach_mode = "global", backends = { "lsp", "treesitter", "markdown", "man" }, layout = { min_width = 28 }, show_guides = true, }, }, -- Diagnostics list { "folke/trouble.nvim", version = "v3.*", cmd = "Trouble", keys = { { "xx", "Trouble diagnostics toggle", desc = "Workspace diagnostics" }, { "xd", "Trouble diagnostics toggle filter.buf=0", desc = "Document diagnostics" }, { "xq", "Trouble qflist toggle", desc = "Quickfix list" }, { "xl", "Trouble loclist toggle", desc = "Location list" }, { "xs", "Trouble lsp toggle focus=false win.position=right", desc = "LSP definitions" }, }, opts = { use_diagnostic_signs = true }, }, -- Better notifications { "rcarriga/nvim-notify", lazy = false, priority = 1000, config = function() local notify = require("notify") notify.setup({ timeout = 3000, max_width = 80, stages = "fade_in_slide_out", render = "default", background_colour = "#050505", }) vim.notify = notify end, keys = { { "un", function() require("notify").dismiss({ silent = true, pending = true }) end, desc = "Dismiss notifications" }, }, }, -- Sign column + fold gutter management { "luukvbaal/statuscol.nvim", event = "BufReadPost", config = function() local builtin = require("statuscol.builtin") require("statuscol").setup({ relculright = true, segments = { { text = { builtin.foldfunc }, click = "v:lua.ScFa" }, { text = { "%s" }, click = "v:lua.ScSa" }, { text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" }, }, }) end, }, -- Scrollbar with diagnostic + git marks { "lewis6991/satellite.nvim", event = "BufReadPost", opts = { current_only = false, winblend = 50, handlers = { cursor = { enable = true }, search = { enable = true }, marks = { enable = true }, quickfix = { enable = false }, gitsigns = { enable = true }, diagnostics = { enable = true, min_severity = vim.diagnostic.severity.WARN }, }, }, }, -- Session save/restore per directory { "folke/persistence.nvim", event = "BufReadPre", opts = { dir = vim.fn.stdpath("state") .. "/sessions/" }, keys = { { "Ss", function() require("persistence").save() end, desc = "Save session" }, { "Sr", function() require("persistence").load() end, desc = "Restore session" }, { "Sl", function() require("persistence").load({ last = true }) end, desc = "Last session" }, }, }, -- Project-wide search and replace { "MagicDuck/grug-far.nvim", cmd = "GrugFar", keys = { { "sr", "GrugFar", desc = "Search & replace" }, { "rs", "GrugFar", desc = "Search & replace" }, { "sw", function() require("grug-far").open({ prefills = { search = vim.fn.expand("") } }) end, desc = "Search word" }, }, opts = { headerMaxWidth = 80 }, }, -- Code action preview (diff before applying) { "aznhe21/actions-preview.nvim", event = "LspAttach", keys = { { "la", function() require("actions-preview").code_actions() end, mode = { "n", "v" }, desc = "Code actions (preview)" }, }, opts = {}, }, -- Multi-cursor (Ctrl+N equivalent) { "mg979/vim-visual-multi", event = "VeryLazy", init = function() vim.g.VM_maps = { ["Find Under"] = "", ["Find Subword Under"] = "", } end, }, -- Project switcher (auto-detect project root) { "ahmedkhalf/project.nvim", lazy = false, config = function() require("project_nvim").setup({ detection_methods = { "lsp", "pattern" }, patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "Cargo.toml" }, silent_chdir = true, }) end, }, -- UI Toggles -- (wrap, fold, spell are just keymap + vim.opt calls — no plugin needed) }