return { { "folke/snacks.nvim", priority = 1000, lazy = false, ---@type snacks.Config opts = { animate = { enabled = false, duration = { step = 1, total = 1 }, easing = "linear", }, bigfile = { enabled = true }, dashboard = { enabled = false }, explorer = { enabled = false }, image = { enabled = true, inline = false, scale = 3, -- nil | 1 (default) | 2 | 3 | ... doc = { inline = true, enabled = true, max_width = nil, max_height = nil, conceal = true, }, math = { enabled = true, } }, terminal = { bo = { filetype = "snacks_terminal", }, win = { style = "terminal" }, wo = {}, keys = { q = "hide", gf = function(self) local f = vim.fn.findfile(vim.fn.expand(""), "**") if f == "" then Snacks.notify.warn("No file under cursor") else self:hide() vim.schedule(function() vim.cmd("e " .. f) end) end end, term_normal = { "", function(self) self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer() if self.esc_timer:is_active() then self.esc_timer:stop() vim.cmd("stopinsert") else self.esc_timer:start(250, 0, function() end) return "" end end, mode = "t", expr = true, desc = "Double escape to normal mode", }, }, }, indent = { enabled = false }, notifier = { enabled = true, timeout = 1000, }, picker = { enabled = true, layout = { preset = "ivy", layout = { position = "bottom" } }, frecency = true, history_bonus = true, projects = { dev = { "~/Projects", }, }, win = { input = { keys = { [''] = { 'layout_right', mode = { 'i', 'n' } }, }, }, }, sources = { files = { -- add a custom action actions = { create_if_missing = function(picker, item) -- When typing in the input, item may be nil. -- We'll use the input text as the intended file path. local input = picker.input and picker.input:get() or "" if input == "" then return end -- Make it relative to picker cwd if it’s not absolute local cwd = picker.opts.cwd or vim.loop.cwd() local path = input if not path:match("^/") and not path:match("^%a:[/\\]") then path = cwd .. "/" .. path end -- Normalize path (optional) path = vim.fn.fnamemodify(path, ":p") -- If file exists, just open it if vim.loop.fs_stat(path) then picker:close() vim.cmd.edit(path) return end -- Ensure parent dirs exist (optional but nice) vim.fn.mkdir(vim.fn.fnamemodify(path, ":h"), "p") -- Open a new buffer at that path (creates buffer even if file missing) picker:close() vim.cmd.edit(path) -- At this point buffer is new + unnamed-on-disk until you :w end, }, -- bind the action to a key in the picker UI win = { input = { keys = { [""] = { "create_if_missing", mode = { "i", "n" }, desc = "Create file from input" }, }, }, list = { keys = { [""] = { "create_if_missing", mode = { "n" }, desc = "Create file from input" }, }, }, }, }, }, }, scope = { enabled = false }, scratch = { ft = "markdown", }, statuscolumn = { enabled = true }, styles = { notification = { -- wo = { wrap = true } -- Wrap notifications } } }, keys = { -- Org Search { "o/", function() Snacks.picker.grep({dirs = { os.getenv("HOME") .. "/Documents/notes" }}) end, desc = "Search Org Files" }, -- { "o/", function() Snacks.picker.files({ cwd = os.getenv("HOME") .. "/Documents/notes" }) end, desc = "Find Document" }, -- Top Pickers & Explorer { "", function() Snacks.picker.smart() end, desc = "Smart Find Files" }, { "j", function() Snacks.picker.files({args = { "--no-require-git" }}) end, desc = "Find Files" }, { ",", function() Snacks.picker.buffers() end, desc = "Buffers" }, { "/", function() Snacks.picker.grep() end, desc = "Grep" }, { ":", function() Snacks.picker.command_history() end, desc = "Command History" }, { "n", function() Snacks.picker.notifications() end, desc = "Notification History" }, { "i", function() Snacks.picker.lsp_symbols() end, desc = "Symbols" }, { "I", function() Snacks.picker.lsp_workspace_symbols() end, desc = "LSP Workspace Symbols" }, -- { "e", function() Snacks.explorer() end, desc = "File Explorer" }, -- find { "fb", function() Snacks.picker.buffers() end, desc = "Buffers" }, { "fc", function() Snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, desc = "Find Config File" }, { "ff", function() Snacks.picker.files() end, desc = "Find Files" }, { "fg", function() Snacks.picker.git_files() end, desc = "Find Git Files" }, { "fp", function() Snacks.picker.projects() end, desc = "Projects" }, { "fr", function() Snacks.picker.recent() end, desc = "Recent" }, -- git { "gb", function() Snacks.picker.git_branches() end, desc = "Git Branches" }, { "gl", function() Snacks.picker.git_log() end, desc = "Git Log" }, { "gL", function() Snacks.picker.git_log_line() end, desc = "Git Log Line" }, { "gs", function() Snacks.picker.git_status() end, desc = "Git Status" }, { "gS", function() Snacks.picker.git_stash() end, desc = "Git Stash" }, { "gd", function() Snacks.picker.git_diff() end, desc = "Git Diff (Hunks)" }, { "gf", function() Snacks.picker.git_log_file() end, desc = "Git Log File" }, -- Grep { "sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" }, { "sB", function() Snacks.picker.grep_buffers() end, desc = "Grep Open Buffers" }, { "sg", function() Snacks.picker.grep() end, desc = "Grep" }, { "sw", function() Snacks.picker.grep_word() end, desc = "Visual selection or word", mode = { "n", "x" } }, -- search { 's"', function() Snacks.picker.registers() end, desc = "Registers" }, { 's/', function() Snacks.picker.search_history() end, desc = "Search History" }, { "sa", function() Snacks.picker.autocmds() end, desc = "Autocmds" }, { "sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" }, { "sc", function() Snacks.picker.command_history() end, desc = "Command History" }, { "sC", function() Snacks.picker.commands() end, desc = "Commands" }, { "sd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" }, { "sD", function() Snacks.picker.diagnostics_buffer() end, desc = "Buffer Diagnostics" }, { "sh", function() Snacks.picker.help() end, desc = "Help Pages" }, { "sH", function() Snacks.picker.highlights() end, desc = "Highlights" }, { "si", function() Snacks.picker.icons() end, desc = "Icons" }, { "sj", function() Snacks.picker.jumps() end, desc = "Jumps" }, { "sk", function() Snacks.picker.keymaps() end, desc = "Keymaps" }, { "sl", function() Snacks.picker.loclist() end, desc = "Location List" }, { "sm", function() Snacks.picker.marks() end, desc = "Marks" }, { "sM", function() Snacks.picker.man() end, desc = "Man Pages" }, { "sp", function() Snacks.picker.lazy() end, desc = "Search for Plugin Spec" }, { "sq", function() Snacks.picker.qflist() end, desc = "Quickfix List" }, { "sR", function() Snacks.picker.resume() end, desc = "Resume" }, { "su", function() Snacks.picker.undo() end, desc = "Undo History" }, { "sz", function() Snacks.picker.zoxide() end, desc = "Zoxide" }, { "uC", function() Snacks.picker.colorschemes() end, desc = "Colorschemes" }, -- LSP { "gd", function() Snacks.picker.lsp_definitions() end, desc = "Goto Definition" }, { "gD", function() Snacks.picker.lsp_declarations() end, desc = "Goto Declaration" }, { "grr", function() Snacks.picker.lsp_references() end, nowait = true, desc = "References" }, { "gri", function() Snacks.picker.lsp_implementations() end, desc = "Goto Implementation" }, { "gy", function() Snacks.picker.lsp_type_definitions() end, desc = "Goto T[y]pe Definition" }, { "ss", function() Snacks.picker.lsp_symbols() end, desc = "LSP Symbols" }, { "sS", function() Snacks.picker.lsp_workspace_symbols() end, desc = "LSP Workspace Symbols" }, -- Other { "Z", function() Snacks.zen() end, desc = "Toggle Zen Mode" }, { "z", function() Snacks.zen.zoom() end, desc = "Toggle Zoom" }, { ".", function() Snacks.scratch() end, desc = "Toggle Scratch Buffer" }, { "S", function() Snacks.scratch.select() end, desc = "Select Scratch Buffer" }, -- { "n", function() Snacks.notifier.show_history() end, desc = "Notification History" }, { "bd", function() Snacks.bufdelete() end, desc = "Delete Buffer" }, { "bR", function() Snacks.rename.rename_file() end, desc = "Rename File" }, { "gB", function() Snacks.gitbrowse() end, desc = "Git Browse", mode = { "n", "v" } }, { "gg", function() Snacks.lazygit() end, desc = "Lazygit" }, { "un", function() Snacks.notifier.hide() end, desc = "Dismiss All Notifications" }, { "", function() Snacks.terminal.toggle() end, desc = "Toggle Terminal", mode = { "n", "t" } }, -- { "", "", desc = "Exit Terminal Mode", mode = { "t" } }, { "]]", function() Snacks.words.jump(vim.v.count1) end, desc = "Next Reference", mode = { "n", "t" } }, { "[[", function() Snacks.words.jump(-vim.v.count1) end, desc = "Prev Reference", mode = { "n", "t" } }, { "xN", desc = "Neovim News", function() Snacks.win({ file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1], width = 0.6, height = 0.6, wo = { spell = false, wrap = false, signcolumn = "yes", statuscolumn = " ", conceallevel = 3, }, }) end, } }, init = function() vim.api.nvim_create_autocmd("User", { pattern = "VeryLazy", callback = function() -- Setup some globals for debugging (lazy-loaded) _G.dd = function(...) Snacks.debug.inspect(...) end _G.bt = function() Snacks.debug.backtrace() end vim.print = _G.dd -- Override print to use snacks for `:=` command -- Create some toggle mappings Snacks.toggle.option("spell", { name = "Spelling" }):map("us") Snacks.toggle.option("wrap", { name = "Wrap" }):map("uw") Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("uL") Snacks.toggle.diagnostics():map("ud") Snacks.toggle.line_number():map("ul") Snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }):map("uc") Snacks.toggle.treesitter():map("uT") Snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map("ub") Snacks.toggle.inlay_hints():map("uh") Snacks.toggle.indent():map("ug") Snacks.toggle.dim():map("uD") end, }) end, }, { "folke/todo-comments.nvim", lazy = true, keys = { { "st", function() Snacks.picker.todo_comments() end, desc = "Todo" }, { "sT", function() Snacks.picker.todo_comments({ keywords = { "TODO", "FIX", "FIXME", "NOTE" } }) end, desc = "Todo/Fix/Fixme/Note" }, }, opts = {}, }, { 'L3MON4D3/LuaSnip', dependencies = { 'rafamadriz/friendly-snippets', }, version = "v2.*", build = "make install_jsregexp", config = function() require('luasnip.loaders.from_vscode').lazy_load() require('luasnip.loaders.from_vscode').lazy_load({ paths = "./json_snippets" }) local luasnip = require("luasnip") luasnip.add_snippets("zig", require("snippets.zig")) end, }, { 'saghen/blink.cmp', lazy = false, -- lazy loading handled internally -- optional: provides snippets for the snippet source dependencies = { 'L3MON4D3/LuaSnip', 'moyiz/blink-emoji.nvim', 'MeanderingProgrammer/render-markdown.nvim', 'fang2hou/blink-copilot', --'giuxtaposition/blink-cmp-copilot', }, version = '1.*', config = function() -- NOTE: Specify the trigger character(s) used for luasnip -- local trigger_text = ";" require('blink.cmp').setup({ enabled = function() local filetype = vim.bo[0].filetype if filetype == "TelescopePrompt" or filetype == "minifiles" or filetype == "snacks_picker_input" then return false end return true end, snippets = { preset = 'luasnip' }, completion = { -- keyword = { -- -- 'prefix' will fuzzy match on the text before the cursor -- -- 'full' will fuzzy match on the text before *and* after the cursor -- -- example: 'foo_|_bar' will match 'foo_' for 'prefix' and 'foo__bar' for 'full' -- range = "full", -- }, menu = { draw = { treesitter = { 'lsp' } } -- border = "single", }, list = { selection = { preselect = false, auto_insert = false, } }, documentation = { auto_show = true, auto_show_delay_ms = 500, -- window = { -- border = "single", -- }, }, ghost_text = { enabled = false }, }, cmdline = { enabled = true, }, signature = { enabled = true }, sources = { per_filetype = { org = {'orgmode'} }, default = { 'orgmode', 'lsp', 'copilot', 'snippets', 'path', 'omni', 'buffer', 'codecompanion', 'markdown' }, providers = { codecompanion = { name = "CodeCompanion" , module = "codecompanion.providers.completion.blink", enabled = true, }, orgmode = { name = 'Orgmode', module = 'orgmode.org.autocompletion.blink', fallbacks = { 'buffer' }, }, copilot = { name = 'copilot', module = 'blink-copilot', score_offset = 100, async = true, }, markdown = { name = 'RenderMarkdown', module = 'render-markdown.integ.blink', score_offset = 80, }, lsp = { name = 'lsp', -- IMPORTANT: use the same name as you would for nvim-cmp enabled = true, module = 'blink.cmp.sources.lsp', -- fallbacks = { 'snippets', 'buffer', 'path' }, score_offset = 100, }, path = { name = 'path', -- IMPORTANT: use the same name as you would for nvim-cmp module = 'blink.cmp.sources.path', score_offset = 50, fallbacks = { 'snippets', 'buffer' }, opts = { trailing_slash = false, label_trailing_slash = true, get_cwd = function(context) return vim.fn.expand(("#%d:p:h"):format(context.bufnr)) end, show_hidden_files_by_default = true, }, }, buffer = { name = "Buffer", enabled = true, max_items = 3, module = "blink.cmp.sources.buffer", min_keyword_length = 4, score_offset = 15, -- the higher the number, the higher the priority }, snippets = { name = "snippets", enabled = true, max_items = 15, min_keyword_length = 2, module = "blink.cmp.sources.snippets", score_offset = 90, -- the higher the number, the higher the priority }, emoji = { module = "blink-emoji", name = "Emoji", score_offset = 0, -- the higher the number, the higher the priority opts = { insert = true }, -- Insert emoji (default) or complete its name }, }, }, appearance = { -- Blink does not expose its default kind icons so you must copy them all (or set your custom ones) and add Copilot kind_icons = { Copilot = "", Text = '󰉿', Method = '󰊕', Function = '󰊕', Constructor = '󰒓', Field = '󰜢', Variable = '󰆦', Property = '󰖷', Class = '󱡠', Interface = '󱡠', Struct = '󱡠', Module = '󰅩', Unit = '󰪚', Value = '󰦨', Enum = '󰦨', EnumMember = '󰦨', Keyword = '󰻾', Constant = '󰏿', Snippet = '󱄽', Color = '󰏘', File = '󰈔', Reference = '󰬲', Folder = '󰉋', Event = '󱐋', Operator = '󰪚', TypeParameter = '󰬛', }, }, }) end }, { 'stevearc/conform.nvim', event = { 'BufWritePre' }, cmd = { 'ConformInfo' }, keys = { { 'bf', function() require('conform').format { async = true, lsp_format = 'fallback' } end, mode = { 'n', 'v' }, desc = 'Format buffer', }, }, opts = { notify_on_error = false, formatters = { shfmt = { prepend_args = { "-i", "2", "-ci" }, }, dprint = { condition = function(ctx) return vim.fs.find({ "dprint.json" }, { path = ctx.filename, upward = true })[1] end, }, }, formatters_by_ft = { c = { "clang_format" }, cpp = { "clang_format" }, lua = { 'stylua' }, go = { "goimports", "gofmt" }, rust = { "dprint", "rustfmt", lsp_format = "fallback" }, python = { "isort", "black", stop_after_first = true }, javascript = { "dprint", "prettier", stop_after_first = true }, markdown = { "dprint", "prettier", stop_after_first = true }, javascriptreact = { "dprint", "prettier", stop_after_first = true }, typescript = { "dprint", "prettier", stop_after_first = true }, typescriptreact = { "dprint", "prettier", stop_after_first = true }, svelte = { "dprint", "prettier", stop_after_first = true }, html = { "dprint", "prettier", stop_after_first = true }, }, }, }, { 'lewis6991/gitsigns.nvim', event = "VimEnter", keys = { { 'uG', "Gitsigns toggle_signs", mode = { 'n' }, desc = 'Gitsigns toggle', }, }, opts = { auto_attach = true, signs_staged_enable = true, signcolumn = true, current_line_blame_opts = { delay = 50 }, on_attach = function(bufnr) local gitsigns = require('gitsigns') local function map(mode, l, r, opts) opts = opts or {} opts.buffer = bufnr vim.keymap.set(mode, l, r, opts) end -- Actions -- visual mode map('v', 'vs', function() gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'stage git hunk' }) map('v', 'vr', function() gitsigns.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'reset git hunk' }) -- normal mode map('n', '[v', function() gitsigns.nav_hunk 'prev' end, { desc = 'git previous hunk' }) map('n', ']v', function() gitsigns.nav_hunk 'next' end, { desc = 'git next hunk' }) map('n', 'vs', gitsigns.stage_hunk, { desc = 'git stage hunk' }) map('n', 'vr', gitsigns.reset_hunk, { desc = 'git reset hunk' }) map('n', 'vS', gitsigns.stage_buffer, { desc = 'git stage buffer' }) map('n', 'vu', gitsigns.undo_stage_hunk, { desc = 'git undo stage hunk' }) map('n', 'vR', gitsigns.reset_buffer, { desc = 'git reset buffer' }) map('n', 'vP', gitsigns.preview_hunk, { desc = 'git preview hunk' }) map('n', 'vb', gitsigns.blame_line, { desc = 'git blame line' }) map('n', 'vP', gitsigns.diffthis, { desc = 'git diff against index' }) map('n', 'vD', function() gitsigns.diffthis '@' end, { desc = 'git [D]iff against last commit' }) -- Toggles map('n', 'uvb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' }) map('n', 'uvd', gitsigns.toggle_deleted, { desc = '[T]oggle git show [D]eleted' }) end, } }, { "dlyongemallo/diffview.nvim", --"sindrets/diffview.nvim", }, { "NicolasGB/jj.nvim", version = "*", -- Use latest stable release -- Or from the main branch (uncomment the branch line and comment the version line) -- branch = "main", keys = function() local cmd = require("jj.cmd") local annotate = require("jj.annotate") vim.keymap.set("n", "va", annotate.file, { desc = "JJ annotate file" }) vim.keymap.set("n", "vA", annotate.line, { desc = "JJ annotate line" }) vim.keymap.set("n", "vbc", cmd.bookmark_create, { desc = "JJ bookmark create" }) vim.keymap.set("n", "vbd", cmd.bookmark_delete, { desc = "JJ bookmark delete" }) vim.keymap.set("n", "vbm", cmd.bookmark_move, { desc = "JJ bookmark move" }) vim.keymap.set("n", "vd", cmd.describe, { desc = "JJ describe" }) vim.keymap.set("n", "vl", cmd.log, { desc = "JJ log" }) vim.keymap.set("n", "ve", cmd.edit, { desc = "JJ edit" }) vim.keymap.set("n", "vn", cmd.new, { desc = "JJ new" }) vim.keymap.set("n", "vs", cmd.status, { desc = "JJ status" }) vim.keymap.set("n", "vS", cmd.squash, { desc = "JJ squash" }) vim.keymap.set("n", "vju", cmd.undo, { desc = "JJ undo" }) vim.keymap.set("n", "vjr", cmd.redo, { desc = "JJ redo" }) vim.keymap.set("n", "vr", cmd.rebase, { desc = "JJ rebase" }) vim.keymap.set("n", "vf", cmd.fetch, { desc = "JJ fetch" }) vim.keymap.set("n", "vx", cmd.abandon, { desc = "JJ abandon" }) vim.keymap.set("n", "vp", cmd.push, { desc = "JJ push" }) vim.keymap.set("n", "vpr", cmd.open_pr, { desc = "JJ open PR from bookmark in current revision or parent" }) vim.keymap.set("n", "vpl", function() cmd.open_pr { list_bookmarks = true } end, { desc = "JJ open PR listing available bookmarks" }) -- Diff commands local diff = require("jj.diff") vim.keymap.set("n", "vjd", function() diff.open_vdiff() end, { desc = "JJ diff current buffer" }) vim.keymap.set("n", "vjD", function() diff.open_hsplit() end, { desc = "JJ hdiff current buffer" }) -- Pickers local picker = require("jj.picker") vim.keymap.set("n", "vjs", function() picker.status() end, { desc = "JJ Picker status" }) vim.keymap.set("n", "vjh", function() picker.file_history() end, { desc = "JJ Picker history" }) -- Some functions like `log` can take parameters vim.keymap.set("n", "vL", function() cmd.log { revisions = "all()", -- equivalent to jj log -r :: } end, { desc = "JJ log all" }) -- This is an alias i use for moving bookmarks its so good vim.keymap.set("n", "vt", function() cmd.j "tug" cmd.log {} end, { desc = "JJ tug" }) end, config = function() require("jj").setup({ diff = { backend = "native", }, cmd = { describe = { editor = { type = "buffer", } } }, describe = { editor = { type = "buffer", } } }) end, }, { "julienvincent/hunk.nvim", cmd = { "DiffEditor" }, config = function() require("hunk").setup() end, }, { -- "PrayagS/jj-diffconflicts", -- branch = 'fix-for-jj-v0_37_0', "rafikdraoui/jj-diffconflicts" }, { 'Glhou/jjsigns.nvim', branch = 'fix/skip-extra-lines', config = function() require('jjsigns').setup({ enabled = true, attach = { auto = false, } }) end, }, { 'williamboman/mason.nvim', lazy = true, opts = {} }, { 'williamboman/mason-lspconfig.nvim', lazy = true }, { 'WhoIsSethDaniel/mason-tool-installer.nvim', lazy = true }, { 'neovim/nvim-lspconfig', lazy = false, dependencies = { { 'SmiteshP/nvim-navic', lazy = true }, }, keys = function() vim.keymap.set("i", "", function() if not vim.lsp.inline_completion.get() then return "" end end, { expr = true, desc = "Accept the current inline completion" }) end, config = function() vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) local function client_supports_method(client, method, bufnr) return client:supports_method(method, bufnr) end local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_completion, event.buf) then vim.lsp.completion.enable(true, client.id, event.buf, { autotrigger = true }) end end, }) -- Diagnostic Config -- See :help vim.diagnostic.Opts vim.diagnostic.config({ severity_sort = true, float = { border = 'rounded', source = 'if_many' }, underline = { severity = vim.diagnostic.severity.ERROR }, signs = vim.g.have_nerd_font and { text = { [vim.diagnostic.severity.ERROR] = '󰅚 ', [vim.diagnostic.severity.WARN] = '󰀪 ', [vim.diagnostic.severity.INFO] = '󰋽 ', [vim.diagnostic.severity.HINT] = '󰌶 ', }, } or {}, virtual_text = { source = 'if_many', spacing = 2, format = function(diagnostic) local diagnostic_message = { [vim.diagnostic.severity.ERROR] = diagnostic.message, [vim.diagnostic.severity.WARN] = diagnostic.message, [vim.diagnostic.severity.INFO] = diagnostic.message, [vim.diagnostic.severity.HINT] = diagnostic.message, } return diagnostic_message[diagnostic.severity] end, }, }) local servers = { lua_ls = { settings = { Lua = { runtime = { version = 'LuaJIT', }, workspace = { library = vim.api.nvim_get_runtime_file("", true), checkThirdParty = false, }, completion = { callSnippet = "Replace", }, diagnostics = { disable = { 'missing-fields' }, globals = { 'vim', 'require' }, }, }, } }, gopls = { settings = { gopls = { experimentalPostfixCompletions = true, analyses = { unusedparams = true, shadow = true, }, staticcheck = true, hints = { enabled = true, rangeVariableTypes = true, prameterNames = true, functionTypeParameters = true, constantValues = true, compositeLiteralTypes = true, compositeLiteralFields = true, assignVariableTypes = true, }, }, }, }, harper_ls = { settings = { ["harper-ls"] = { linters = { SentenceCapitalization = true, SpellCheck = true }, dialect = "Canadian" } } }, -- csharp_ls = {}, zls = {}, clangd = { settings = { ["clang"] = { cmd = { "clangd", "--background-index", "--compile-commands-dir=" .. vim.loop.cwd() .. "/build" }, } } }, rust_analyzer= { settings = { ['rust-analyzer'] = { cargo = { allFeatures = true, }, checkOnSave = true, check = { command = "clippy", }, procMacro = { enable = true, }, lens = { debug = { enable = true }, enable = true, implementations = { enable = true }, references = { adt = { enable = true }, enumVariant = { enable = true }, method = { enable = true }, trait = { enable = true }, }, run = { enable = true }, updateTest = { enable = true }, }, }, } }, ts_ls= {}, html= {}, eslint= {}, jsonls= {}, jdtls= {}, copilot = { -- settings = { -- ['copilot'] = { -- cmd = { "copilot-language-server", "--stdio" }, -- init_options = { -- name = "Neovim", -- version = tostring(vim.version()), -- }, -- editorPluginInfo = { -- name = "Neovim", -- version = tostring(vim.version()), -- }, -- }, -- }, }, } local ensure_installed = vim.tbl_keys(servers or {}) require('mason-tool-installer').setup ({ ensure_installed = ensure_installed }) local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = vim.tbl_deep_extend('force', capabilities, require('blink.cmp').get_lsp_capabilities({}, false)) capabilities = vim.tbl_deep_extend('force', capabilities, { general = { -- dynamicRegistration = false, positionEncodings = { "utf-16" }, }, textDocument = { foldingRange = { dynamicRegistration = false, lineFoldingOnly = true } } }) for server, cfg in pairs(servers) do cfg.capabilities = vim.tbl_deep_extend('force', {}, capabilities, cfg.capabilities or {}) vim.lsp.config(server, cfg) vim.lsp.enable(server) end vim.lsp.inline_completion.enable(); -- vim.lsp.enable("rust-analyzer", false) end }, { "rcarriga/nvim-dap-ui", dependencies = { "mfussenegger/nvim-dap", "nvim-neotest/nvim-nio" }, config = function() local dapui = require("dapui") local dap = require("dap") dapui.setup() vim.fn.sign_define("DapBreakpoint", { text = "🐞" }) dap.listeners.before.attach.dapui_config = function() dapui.open() end dap.listeners.before.launch.dapui_config = function() dapui.open() end dap.listeners.before.event_terminated.dapui_config = function() dapui.close() end dap.listeners.before.event_exited.dapui_config = function() dapui.close() end end }, { "jay-babu/mason-nvim-dap.nvim", config = function() require ('mason-nvim-dap').setup({ handlers = { function(config) -- all sources with no handler get passed here -- Keep original functionality require('mason-nvim-dap').default_setup(config) end, }, }) end, }, { "Saecki/crates.nvim", lazy = true, keys = function() local crates = require("crates") local opts = { silent = true } vim.keymap.set("n", "cct", crates.toggle, { desc = 'toggle' }) vim.keymap.set("n", "ccr", crates.reload, { desc = 'reload' }) vim.keymap.set("n", "ccv", crates.show_versions_popup, { desc = 'show versions' }) vim.keymap.set("n", "ccf", crates.show_features_popup, { desc = 'show features' }) vim.keymap.set("n", "ccd", crates.show_dependencies_popup, { desc = 'show dependencies' }) vim.keymap.set("n", "ccu", crates.update_crate, { desc = 'update' }) vim.keymap.set("v", "ccu", crates.update_crates, { desc = 'update' }) vim.keymap.set("n", "cca", crates.update_all_crates, { desc = 'update all' }) vim.keymap.set("n", "ccU", crates.upgrade_crate, { desc = 'upgrade' }) vim.keymap.set("v", "ccU", crates.upgrade_crates, { desc = 'upgrade' }) vim.keymap.set("n", "ccA", crates.upgrade_all_crates, { desc = 'upgrade all' }) vim.keymap.set("n", "ccx", crates.expand_plain_crate_to_inline_table, { desc = 'expand' }) vim.keymap.set("n", "ccX", crates.extract_crate_into_table, { desc = 'extract' }) vim.keymap.set("n", "ccH", crates.open_homepage, { desc = 'open homepage' }) vim.keymap.set("n", "ccR", crates.open_repository, { desc = 'open repository' }) vim.keymap.set("n", "ccD", crates.open_documentation, { desc = 'open documents' }) vim.keymap.set("n", "ccC", crates.open_crates_io, { desc = 'open crates.io' }) vim.keymap.set("n", "ccL", crates.open_lib_rs, { desc = 'open lib.rs' }) end, opts = { completion = { crates = { enabled = true, }, }, lsp = { enabled = true, actions = true, completion = true, hover = true, }, }, }, -- { -- 'mrcjkb/rustaceanvim', -- -- version = '^6', -- Recommended -- lazy = true, -- ft = {'rust'}, -- opts = { -- server = { -- default_settings = { -- cargo = { -- allFeatures = false, -- loadOutDirsFromCheck = true, -- buildScripts = { enable = true }, -- }, -- }, -- on_attach = function(_, bufnr) -- vim.keymap.set("n", "lr", function() -- vim.cmd.RustLsp("codeAction") -- end, { desc = "Code Action", buffer = bufnr }) -- vim.keymap.set("n", "ld", function() -- vim.cmd.RustLsp("debuggables") -- end, { desc = "Rust Debuggables", buffer = bufnr }) -- vim.keymap.set("n", "lD", function() -- vim.cmd.RustLsp("openDocs") -- end, { desc = "Open Documents", buffer = bufnr }) -- vim.keymap.set("n", "lc", function() -- vim.cmd.RustLsp("openCargo") -- end, { desc = "Open Documents", buffer = bufnr }) -- end, -- }, -- }, -- config = function(_, opts) -- vim.g.rustaceanvim = vim.tbl_deep_extend("keep", vim.g.rustaceanvim or {}, opts or {}) -- end, -- }, { -- Highlight, edit, and navigate code 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', branch = 'main', dependencies = { -- 'p00f/nvim-ts-rainbow', }, config = function() local ts_parsers = { "bash", "dockerfile", "git_config", "git_rebase", "gitattributes", "gitcommit", "gitignore", "go", "gomod", "gosum", "json", "toml", "yaml", "lua", "make", "markdown", "python", "terraform", "vim", "vimdoc", 'c', "lua", "markdown", "markdown_inline", "query", "html", "xml", "zig", "typescript", "javascript", "svelte", "regex", "rust", "http", } local nts = require("nvim-treesitter") nts.install(ts_parsers) -- vim.api.nvim_create_autocmd('PackChanged', { -- callback = function() -- nts.update() -- end -- }) vim.api.nvim_create_autocmd("FileType", { -- enable treesitter highlighting and indents callback = function(args) local filetype = args.match local lang = vim.treesitter.language.get_lang(filetype) if vim.treesitter.language.add(lang) then vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" vim.treesitter.start() end end }) -- vim.api.nvim_create_autocmd('FileType', { -- pattern = ts_parsers, -- callback = function() -- vim.treesitter.start() -- end, -- }) end, }, { 'nvim-treesitter/nvim-treesitter-textobjects', branch = "main", init = function() vim.g.no_plugin_maps = true end, }, { 'JoosepAlviste/nvim-ts-context-commentstring', lazy = true, opts = { enable_autocmd = false, } }, { 'nvim-treesitter/nvim-treesitter-context', enabled = true, config = function () require("treesitter-context").setup({ mode = "cursor", max_lines = 3, multiline_threshold = 1, separator = '-', min_window_height = 20, line_numbers = true, }) end, }, { "mbbill/undotree", lazy = true, keys = { { 'uu', vim.cmd.UndotreeToggle, desc = 'Format buffer' } }, }, { 'Civitasv/cmake-tools.nvim', lazy = true, config = function () local osys = require("cmake-tools.osys") require("cmake-tools").setup { cmake_command = "cmake", -- this is used to specify cmake command path ctest_command = "ctest", -- this is used to specify ctest command path cmake_use_preset = true, cmake_regenerate_on_save = true, -- auto generate when save CMakeLists.txt cmake_generate_options = { "-DCMAKE_EXPORT_COMPILE_COMMANDS=1" }, -- this will be passed when invoke `CMakeGenerate` cmake_build_options = {}, -- this will be passed when invoke `CMakeBuild` -- support macro expansion: -- ${kit} -- ${kitGenerator} -- ${variant:xx} cmake_build_directory = function() if osys.iswin32 then return "out\\${variant:buildType}" end return "out/${variant:buildType}" end, -- this is used to specify generate directory for cmake, allows macro expansion, can be a string or a function returning the string, relative to cwd. cmake_soft_link_compile_commands = true, -- this will automatically make a soft link from compile commands file to project root dir cmake_compile_commands_from_lsp = false, -- this will automatically set compile commands file location using lsp, to use it, please set `cmake_soft_link_compile_commands` to false cmake_kits_path = nil, -- this is used to specify global cmake kits path, see CMakeKits for detailed usage cmake_variants_message = { short = { show = true }, -- whether to show short message long = { show = true, max_length = 40 }, -- whether to show long message }, cmake_dap_configuration = { -- debug settings for cmake name = "cpp", type = "codelldb", request = "launch", stopOnEntry = false, runInTerminal = true, console = "integratedTerminal", }, cmake_executor = { -- executor to use name = "quickfix", -- name of the executor opts = {}, -- the options the executor will get, possible values depend on the executor type. See `default_opts` for possible values. default_opts = { -- a list of default and possible values for executors quickfix = { show = "always", -- "always", "only_on_error" position = "belowright", -- "vertical", "horizontal", "leftabove", "aboveleft", "rightbelow", "belowright", "topleft", "botright", use `:h vertical` for example to see help on them size = 10, encoding = "utf-8", -- if encoding is not "utf-8", it will be converted to "utf-8" using `vim.fn.iconv` auto_close_when_success = true, -- typically, you can use it with the "always" option; it will auto-close the quickfix buffer if the execution is successful. }, toggleterm = { direction = "float", -- 'vertical' | 'horizontal' | 'tab' | 'float' close_on_exit = false, -- whether close the terminal when exit auto_scroll = true, -- whether auto scroll to the bottom singleton = true, -- single instance, autocloses the opened one, if present }, overseer = { new_task_opts = { strategy = { "toggleterm", direction = "horizontal", autos_croll = true, quit_on_exit = "success" } }, -- options to pass into the `overseer.new_task` command on_new_task = function(task) require("overseer").open( { enter = false, direction = "right" } ) end, -- a function that gets overseer.Task when it is created, before calling `task:start` }, terminal = { name = "Main Terminal", prefix_name = "[CMakeTools]: ", -- This must be included and must be unique, otherwise the terminals will not work. Do not use a simple spacebar " ", or any generic name split_direction = "horizontal", -- "horizontal", "vertical" split_size = 11, -- Window handling single_terminal_per_instance = true, -- Single viewport, multiple windows single_terminal_per_tab = true, -- Single viewport per tab keep_terminal_static_location = true, -- Static location of the viewport if avialable auto_resize = true, -- Resize the terminal if it already exists -- Running Tasks start_insert = false, -- If you want to enter terminal with :startinsert upon using :CMakeRun focus = false, -- Focus on terminal when cmake task is launched. do_not_add_newline = false, -- Do not hit enter on the command inserted when using :CMakeRun, allowing a chance to review or modify the command before hitting enter. }, -- terminal executor uses the values in cmake_terminal }, }, cmake_runner = { -- runner to use name = "terminal", -- name of the runner opts = {}, -- the options the runner will get, possible values depend on the runner type. See `default_opts` for possible values. default_opts = { -- a list of default and possible values for runners quickfix = { show = "always", -- "always", "only_on_error" position = "belowright", -- "bottom", "top" size = 10, encoding = "utf-8", auto_close_when_success = true, -- typically, you can use it with the "always" option; it will auto-close the quickfix buffer if the execution is successful. }, toggleterm = { direction = "float", -- 'vertical' | 'horizontal' | 'tab' | 'float' close_on_exit = false, -- whether close the terminal when exit auto_scroll = true, -- whether auto scroll to the bottom singleton = true, -- single instance, autocloses the opened one, if present }, overseer = { new_task_opts = { strategy = { "toggleterm", direction = "horizontal", autos_croll = true, quit_on_exit = "success" } }, -- options to pass into the `overseer.new_task` command on_new_task = function(task) end, -- a function that gets overseer.Task when it is created, before calling `task:start` }, terminal = { name = "Main Terminal", prefix_name = "[CMakeTools]: ", -- This must be included and must be unique, otherwise the terminals will not work. Do not use a simple spacebar " ", or any generic name split_direction = "horizontal", -- "horizontal", "vertical" split_size = 11, -- Window handling single_terminal_per_instance = true, -- Single viewport, multiple windows single_terminal_per_tab = true, -- Single viewport per tab keep_terminal_static_location = true, -- Static location of the viewport if avialable auto_resize = true, -- Resize the terminal if it already exists -- Running Tasks start_insert = false, -- If you want to enter terminal with :startinsert upon using :CMakeRun focus = false, -- Focus on terminal when cmake task is launched. do_not_add_newline = false, -- Do not hit enter on the command inserted when using :CMakeRun, allowing a chance to review or modify the command before hitting enter. }, }, }, cmake_notifications = { runner = { enabled = true }, executor = { enabled = true }, spinner = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }, -- icons used for progress display refresh_rate_ms = 100, -- how often to iterate icons }, cmake_virtual_text_support = true, -- Show the target related to current file using virtual text (at right corner) } end, }, { "folke/persistence.nvim", event = "BufReadPre", opts = { options = { "buffers", "curdir", "tabpages", "winsize", "help", "globals", "skiprtp" } }, -- stylua: ignore keys = { { "xr", function() require("persistence").load() end, desc = "Restore Session" }, { "xs", function() require("persistence").save() end, desc = "Save Session" }, { "xl", function() require("persistence").load({ last = true }) end, desc = "Restore Last Session" }, { "xd", function() require("persistence").stop() end, desc = "Don't Save Current Session" }, }, }, { "otavioschwanck/arrow.nvim", dependencies = { { "nvim-tree/nvim-web-devicons" }, -- or if using `mini.icons` -- { "echasnovski/mini.icons" }, }, opts = { show_icons = true, leader_key = ';', -- Recommended to be a single key buffer_leader_key = ';', -- Per Buffer Mappings } }, { "nvim-pack/nvim-spectre", lazy = true, cmd = { "Spectre" }, keys = { { "sr", function() require("spectre").open() end, desc = "Replace in files (Spectre)" }, }, opts = { open_cmd = "noswapfile vnew", highlight = { search = "SpectreSearch", replace = "SpectreReplace", }, mapping = { ["send_to_qf"] = { map = "", cmd = "lua require('spectre.actions').send_to_qf()", desc = "send all items to quickfix", }, }, } }, { 'stevearc/overseer.nvim', keys = { { "xo", "OverseerOpen", desc = "Open Overseer" }, { "to", "OverseerToggle", desc = "Overseer Toggle" }, { "", "OverseerRun", desc = "Run Overseer" }, { "", "OverseerToggle", desc = "Overseer Toggle" }, }, config = function() require("overseer").setup({ templates = { "builtin", "user" }, component_aliases = { default = { { 'display_duration', detail_level = 2 }, 'on_output_summarize', 'on_exit_set_status', 'on_result_diagnostics_quickfix', 'on_complete_notify', { "on_complete_dispose", require_view = { "SUCCESS", "FAILURE" } }, }, default_vscode = { 'default', 'on_result_diagnostics', 'on_result_diagnostics_quickfix', 'on_complete_notify', }, } }) -- local pm = require("overseer.template.vscode.problem_matcher") -- pm.register_problem_matcher("$rustc", { -- fileLocation = { "autoDetect", "${cwd}" }, -- pattern = { -- --regexp = "^(.*?)-->\\s+(.*?):(\\d+):(\\d+)$", -- -- vim_regexp = "\\v^(.*?)-->\\s+(.*?):(\\d+):(\\d+)$", -- regexp = "^\\s+-->\\s*([^:]*):(\\d+):(\\d+)$", -- vim_regexp = "\\v^\\s+-->\\s*([^:]*):(\\d+):(\\d+)$", -- file = 1, -- line = 2, -- column = 3, -- } -- }) end, }, }