diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index 9f7f572..820e5fc 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -1,5 +1,5 @@ require("config.options") require("config.lsp") -require("config.lazy") require("config.keymaps") require("config.autocmds") +require("config.lazy") diff --git a/.config/nvim/lazy-lock.json b/.config/nvim/lazy-lock.json index 72d72d5..e9bab02 100644 --- a/.config/nvim/lazy-lock.json +++ b/.config/nvim/lazy-lock.json @@ -1,7 +1,6 @@ { - "99": { "branch": "master", "commit": "0172d3caae2d8b967c9d47aa7557295f1481e5df" }, "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, - "blink.cmp": { "branch": "main", "commit": "451168851e8e2466bc97ee3e026c3dcb9141ce07" }, + "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, "blink.compat": { "branch": "main", "commit": "2ed6d9a28b07fa6f3bface818470605f8896408c" }, "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, "claudecode.nvim": { "branch": "main", "commit": "432121f0f5b9bda041030d1e9e83b7ba3a93dd8f" }, @@ -9,15 +8,16 @@ "dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" }, "flutter-tools.nvim": { "branch": "main", "commit": "677cc07c16e8b89999108d2ebeefcfc5f539b73c" }, "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitsigns.nvim": { "branch": "main", "commit": "944ef13cc8d8fe8b846c91f36041c8dfb85ca000" }, + "gitsigns.nvim": { "branch": "main", "commit": "8d82c240f190fc33723d48c308ccc1ed8baad69d" }, "harpoon": { "branch": "master", "commit": "1bc17e3e42ea3c46b33c0bbad6a880792692a1b3" }, "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "lualine.nvim": { "branch": "master", "commit": "8811f3f3f4dc09d740c67e9ce399e7a541e2e5b2" }, - "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, + "lualine.nvim": { "branch": "master", "commit": "a905eeebc4e63fdc48b5135d3bf8aea5618fb21c" }, + "mason.nvim": { "branch": "main", "commit": "b03fb0f20bc1d43daf558cda981a2be22e73ac42" }, + "mcphub.nvim": { "branch": "main", "commit": "7cd5db330f41b7bae02b2d6202218a061c3ebc1f" }, "mini.indentscope": { "branch": "main", "commit": "e0601f75aa5137a5a13bb92a988c9a300f5bd3de" }, - "mini.nvim": { "branch": "main", "commit": "402ee6c6ec8ea44b22330446c8fb4e615fd3953e" }, - "neo-tree.nvim": { "branch": "main", "commit": "b48ed11632c8208ffb27dab6acfbf16e4f9e3376" }, + "mini.nvim": { "branch": "main", "commit": "efa5cf403cf8b438c8171b4234b77e40b213e117" }, + "neo-tree.nvim": { "branch": "main", "commit": "aa3500f7038a32ed4b0b765cd458b9c429062cac" }, "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" }, @@ -25,13 +25,13 @@ "nvim-notify": { "branch": "master", "commit": "8701bece920b38ea289b457f902e2ad184131a5d" }, "nvim-treesitter": { "branch": "master", "commit": "cf12346a3414fa1b06af75c79faebe7f76df080a" }, "nvim-treesitter-context": { "branch": "master", "commit": "b0c45cefe2c8f7b55fc46f34e563bc428ef99636" }, - "nvim-treesitter-textobjects": { "branch": "master", "commit": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef" }, - "nvim-web-devicons": { "branch": "master", "commit": "40e9d5a6cc3db11b309e39593fc7ac03bb844e38" }, - "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, + "nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" }, + "nvim-web-devicons": { "branch": "master", "commit": "c72328a5494b4502947a022fe69c0c47e53b6aa6" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, "snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" }, "symbols-outline.nvim": { "branch": "master", "commit": "564ee65dfc9024bdde73a6621820866987cbb256" }, "telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" }, - "telescope.nvim": { "branch": "master", "commit": "cfb85dcf7f822b79224e9e6aef9e8c794211b20b" }, + "telescope.nvim": { "branch": "master", "commit": "3ab376cfae65b921dda454df5967f8df673effc6" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, "transparent.nvim": { "branch": "main", "commit": "8ac59883de84e9cd1850ea25cf087031c5ba7d54" }, "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, diff --git a/.config/nvim/lua/config/autocmds.lua b/.config/nvim/lua/config/autocmds.lua index e197b3d..f8c79a2 100644 --- a/.config/nvim/lua/config/autocmds.lua +++ b/.config/nvim/lua/config/autocmds.lua @@ -1,3 +1,14 @@ +-- Per-session socket; symlink /tmp/nvim.sock → latest instance for MCP +local sock = "/tmp/nvim-" .. vim.fn.getpid() .. ".sock" +vim.fn.serverstart(sock) +vim.fn.system("ln -sf " .. sock .. " /tmp/nvim.sock") +vim.api.nvim_create_autocmd("VimLeave", { + callback = function() + vim.fn.system("rm -f " .. vim.fn.shellescape(sock)) + vim.fn.system("[ \"$(readlink /tmp/nvim.sock)\" = " .. vim.fn.shellescape(sock) .. " ] && rm -f /tmp/nvim.sock || true") + end, +}) + vim.o.updatetime = 250 vim.cmd [[autocmd CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]] diff --git a/.config/nvim/lua/plugins/ai.lua b/.config/nvim/lua/plugins/ai.lua index 0950525..20b8685 100644 --- a/.config/nvim/lua/plugins/ai.lua +++ b/.config/nvim/lua/plugins/ai.lua @@ -1,18 +1,16 @@ return { - -- { - -- 'Exafunction/windsurf.vim', - -- event = 'BufEnter', - -- config = function() - -- -- Change '' here to any keycode you like. - -- vim.keymap.set('i', '', function() return vim.fn['codeium#Accept']() end, { expr = true, silent = true }) - -- vim.keymap.set('i', '', function() return vim.fn['codeium#CycleCompletions'](1) end, - -- { expr = true, silent = true }) - -- vim.keymap.set('i', '', function() return vim.fn['codeium#CycleCompletions'](-1) end, - -- { expr = true, silent = true }) - -- vim.keymap.set('i', '', function() return vim.fn['codeium#Clear']() end, { expr = true, silent = true }) - -- vim.keymap.set('i', '', function() return vim.fn['codeium#Toggle']() end, { expr = true, silent = true }) - -- end - -- }, + { + "ravitemer/mcphub.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + build = "npm install -g mcp-hub@latest", + opts = { + auto_approve = true, + extensions = { + avante = { enabled = false }, + codecompanion = { enabled = false }, + }, + }, + }, { "coder/claudecode.nvim", dependencies = { "folke/snacks.nvim" }, @@ -37,48 +35,4 @@ return { { "ad", "ClaudeCodeDiffDeny", desc = "Deny diff" }, }, }, - { - "ThePrimeagen/99", - config = function() - local _99 = require("99") - local cwd = vim.uv.cwd() - local basename = vim.fs.basename(cwd) - - _99.setup({ - provider = _99.Providers.ClaudeCodeProvider, - -- provider = _99.Providers.OpenCodeProvider, - logger = { - level = _99.DEBUG, - path = "/tmp/" .. basename .. ".99.debug", - print_on_error = true, - }, - tmp_dir = "/tmp", - completion = { - custom_rules = { - "scratch/custom_rules/", - }, - files = { - enabled = true, - max_file_size = 102400, -- bytes, skip files larger than this - max_files = 5000, -- cap on total discovered files - exclude = { ".env", ".env.*", "node_modules", ".git", ".venv" }, - }, - source = "blink", - }, - md_files = { - "AGENT.md", - "CLAUDE.md", - }, - }) - vim.keymap.set("v", "9v", function() - _99.visual() - end) - vim.keymap.set("n", "9x", function() - _99.stop_all_requests() - end) - vim.keymap.set("n", "9s", function() - _99.search() - end) - end, - }, } diff --git a/.config/nvim/lua/plugins/treesitter.lua b/.config/nvim/lua/plugins/treesitter.lua index 18f2485..6ba5375 100644 --- a/.config/nvim/lua/plugins/treesitter.lua +++ b/.config/nvim/lua/plugins/treesitter.lua @@ -1,113 +1,130 @@ return { { "nvim-treesitter/nvim-treesitter", - build = ":TSUpdate", + -- Load on these events for a snappier startup event = { "BufReadPost", "BufNewFile" }, - dependencies = { - { - "nvim-treesitter/nvim-treesitter-textobjects", - init = function() - -- disable rtp plugin, as we only need its queries for mini.ai - -- In case other textobject modules are enabled, we will load them - -- once nvim-treesitter is loaded - require("lazy.core.loader").disable_rtp_plugin("nvim-treesitter-textobjects") - load_textobjects = true - end, - }, - }, - cmd = { "TSUpdateSync" }, - keys = { - { "", desc = "Increment selection" }, - { "", desc = "Decrement selection", mode = "x" }, - }, - opts = { - highlight = { enable = true }, - indent = { enable = true }, - ensure_installed = { - "bash", - "c", - "html", - "javascript", - "jsdoc", - "json", - "lua", - "luadoc", - "luap", - "markdown", - "markdown_inline", - "python", - "query", - "regex", - "tsx", - "typescript", - "svelte", - "vim", - "vimdoc", - "yaml", - "kotlin", - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "", - node_incremental = "", - scope_incremental = false, - node_decremental = "", - }, - }, - }, - config = function(_, opts) - if type(opts.ensure_installed) == "table" then - local added = {} - opts.ensure_installed = vim.tbl_filter(function(lang) - if added[lang] then - return false - end - added[lang] = true - return true - end, opts.ensure_installed) - end - require("nvim-treesitter.configs").setup(opts) + -- Keep the build command to update parsers automatically + build = ":TSUpdate", + config = function() + local configs = require("nvim-treesitter.configs") - if load_textobjects then - if opts.textobjects then - for _, mod in ipairs({ "move", "select", "swap", "lsp_interop" }) do - if opts.textobjects[mod] and opts.textobjects[mod].enable then - local Loader = require("lazy.core.loader") - Loader.disabled_rtp_plugins["nvim-treesitter-textobjects"] = nil - local plugin = require("lazy.core.config").plugins["nvim-treesitter-textobjects"] - require("lazy.core.loader").source_runtime(plugin.dir, "plugin") - break - end - end - end - end + configs.setup({ + -- Automatically install missing parsers + ensure_installed = { + "bash", "c", "comment", "css", "diff", "dockerfile", "git_config", + "gitcommit", "gitignore", "go", "html", "http", "java", "javascript", + "jsdoc", "json", "json5", "kotlin", "lua", "luadoc", "luap", "make", + "markdown", "markdown_inline", "python", "query", "regex", "rst", + "sql", "ssh_config", "svelte", "terraform", "toml", "tsx", + "typescript", "typst", "vim", "vimdoc", "yaml", "groovy" + }, + -- Enable syntax highlighting + highlight = { + enable = true, + -- Setting this to true will run `:h syntax` and Tree-sitter at the same time. + -- Set to `false` if you want Treesitter to handle everything. + additional_vim_regex_highlighting = false, + }, + -- Enable indentation based on treesitter + indent = { + enable = true + }, + }) + + -- Register custom filetypes for Treesitter + vim.treesitter.language.register("groovy", "Jenkinsfile") + + -- Treesitter-based folding + vim.opt.foldmethod = "expr" + vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" + vim.opt.foldlevel = 99 -- Prevents files from being folded by default end, }, + { "nvim-treesitter/nvim-treesitter-context", dependencies = { "nvim-treesitter/nvim-treesitter" }, - event = { "VeryLazy" }, + -- Context is only useful once you're actually inside a buffer + event = "BufReadPost", opts = { - enable = true, -- Enable this plugin (Can be enabled/disabled later via commands) - max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit. - min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit. + enable = true, + max_lines = 0, + min_window_height = 0, line_numbers = true, - multiline_threshold = 10, -- Maximum number of lines to show for a single context - trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' - mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' - -- Separator between context and content. Should be a single character string, like '-'. - -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. - separator = nil, - zindex = 20, -- The Z-index of the context window - on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching + multiline_threshold = 10, + trim_scope = "outer", + mode = "cursor", + zindex = 20, }, config = function(_, opts) - print() + -- If the window is small, limit context to 1 line to save screen real estate if vim.api.nvim_win_get_height(0) < 50 then opts.multiline_threshold = 1 end require("treesitter-context").setup(opts) - end + end, + }, + { + "nvim-treesitter/nvim-treesitter-textobjects", + lazy = true, + config = function() + require("nvim-treesitter.configs").setup({ + textobjects = { + select = { + enable = true, + lookahead = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + ["ac"] = "@class.outer", + ["ic"] = "@class.inner", + ["as"] = { query = "@local.scope", query_group = "locals" }, + }, + selection_modes = { + ['@parameter.outer'] = 'v', + ['@function.outer'] = 'V', + ['@class.outer'] = '', + }, + }, + move = { + enable = true, + set_jumps = true, + goto_next_start = { + ["]m"] = "@function.outer", + ["]]"] = "@class.outer", + ["]o"] = { query = { "@loop.inner", "@loop.outer" } }, + ["]s"] = { query = "@local.scope", query_group = "locals" }, + ["]z"] = { query = "@fold", query_group = "folds" }, + }, + goto_next_end = { + ["]M"] = "@function.outer", + ["]["] = "@class.outer", + }, + goto_previous_start = { + ["[m"] = "@function.outer", + ["[["] = "@class.outer", + }, + goto_previous_end = { + ["[M"] = "@function.outer", + ["[]"] = "@class.outer", + }, + }, + swap = { + enable = true, + swap_next = { ["a"] = "@parameter.inner" }, + swap_previous = { ["A"] = "@parameter.inner" }, + }, + }, + }) + + -- Repeatable moves logic (keeps ; and , functionality) + local ts_repeat_move = require("nvim-treesitter-textobjects.repeatable_move") + vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_next) + vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous) + vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, { expr = true }) + vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, { expr = true }) + vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, { expr = true }) + vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, { expr = true }) + end, } }