From 8f78c67019040ea4c173987cf2f427c9e84d7031 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 21 Sep 2026 15:14:41 -0400 Subject: [PATCH] =?UTF-8?q?feat(plugins):=20add=20URL=20picker=20and=20tod?= =?UTF-8?q?ay=E2=80=91modified=20file=20finder,=20replace=20Supermaven=20w?= =?UTF-8?q?ith=20NeoCodeium?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/plugins/astrocore.lua | 66 ++++++++++++++++++++++++++++++-- lua/plugins/blink-supermaven.lua | 26 ------------- lua/plugins/neocodeium.lua | 42 ++++++++++++++++++++ lua/plugins/supermaven.lua | 41 -------------------- 4 files changed, 105 insertions(+), 70 deletions(-) delete mode 100644 lua/plugins/blink-supermaven.lua create mode 100644 lua/plugins/neocodeium.lua delete mode 100644 lua/plugins/supermaven.lua diff --git a/lua/plugins/astrocore.lua b/lua/plugins/astrocore.lua index cdb4cb6..549daeb 100644 --- a/lua/plugins/astrocore.lua +++ b/lua/plugins/astrocore.lua @@ -54,6 +54,58 @@ local function find_files_by_extension() } end +-- x: every URL in the current buffer, in file order; confirm hands the +-- URL to vim.ui.open (xdg-open). Reuses astrocore's url_matcher so the +-- picker agrees with the highlighturl feature about what counts as a URL. +local function find_buffer_urls() + local buf = vim.api.nvim_get_current_buf() + local re = vim.regex(require("astrocore").url_matcher) + local items = {} + for lnum, line in ipairs(vim.api.nvim_buf_get_lines(buf, 0, -1, false)) do + local offset = 0 + while offset < #line do + -- match_str returns 0-indexed byte offsets relative to the substring + local s, e = re:match_str(line:sub(offset + 1)) + if not s then break end + local url = line:sub(offset + s + 1, offset + e) + items[#items + 1] = { text = url, url = url, buf = buf, pos = { lnum, offset + s }, lnum = lnum } + offset = offset + e + end + end + if #items == 0 then + vim.notify("No URLs found in buffer", vim.log.levels.WARN) + return + end + require("snacks").picker { + title = "Buffer URLs", + items = items, + format = function(item) + return { + { ("%4d "):format(item.lnum), "SnacksPickerRow" }, + { item.url, "SnacksPickerLink" }, + } + end, + confirm = function(picker, item) + picker:close() + if not item then return end + vim.ui.open(item.url) + end, + } +end + +-- m: files under the git root whose mtime is today (local midnight +-- onward). fd's --changed-within accepts a YYYY-MM-DD date as "since". +local function find_files_modified_today() + local snacks = require "snacks" + snacks.picker.files { + title = "Modified today", + cwd = snacks.git.get_root() or vim.uv.cwd(), + cmd = "fd", + args = { "--changed-within", os.date "%Y-%m-%d" }, + transform = file_filter, + } +end + return { "AstroNvim/astrocore", ---@type AstroCoreOpts @@ -323,6 +375,10 @@ return { function() require("config.templates").pick() end, desc = "Find templates", }, + -- NOTE: and are likewise the same key, so Enter in normal + -- mode runs overseer. Buffers with their own (quickfix, help, + -- neo-tree, overseer's task list) keep theirs via buffer-local maps. + [""] = { "OverseerRun", desc = "Run overseer task" }, ["w"] = { function() require("fff").live_grep() end, desc = "Live grep", @@ -340,8 +396,12 @@ return { desc = "Find files (cwd)", }, ["m"] = { - function() require("fff").find_files { title = "Git Modified", query = "git:modified " } end, - desc = "Find git-modified files", + find_files_modified_today, + desc = "Find files modified today", + }, + ["x"] = { + find_buffer_urls, + desc = "Find URLs in buffer (open in browser)", }, ["r"] = { function() require("fff").resume() end, @@ -421,7 +481,7 @@ return { function() require("config.picker").with_trouble "diagnostics" end, desc = "Search diagnostics ( sends to Trouble)", }, - [""] = { "SupermavenToggle", desc = "Toggle Supermaven" }, + [""] = { "NeoCodeium toggle", desc = "Toggle NeoCodeium" }, -- u toggles are mapped through Snacks.toggle in -- config.toggles (called from polish.lua) so which-key renders their diff --git a/lua/plugins/blink-supermaven.lua b/lua/plugins/blink-supermaven.lua deleted file mode 100644 index 33c06ef..0000000 --- a/lua/plugins/blink-supermaven.lua +++ /dev/null @@ -1,26 +0,0 @@ --- Native supermaven source for blink.cmp (mirrors the astrocommunity blink-copilot pattern). --- Inline ghost text + accept come from `astrocommunity.completion.supermaven-nvim`; --- this additionally surfaces supermaven suggestions in the blink menu so / work. -return { - "Huijiro/blink-cmp-supermaven", - lazy = true, - specs = { - { - "saghen/blink.cmp", - optional = true, - opts = { - sources = { - default = { "supermaven" }, - providers = { - supermaven = { - name = "supermaven", - module = "blink-cmp-supermaven", - score_offset = 100, - async = true, - }, - }, - }, - }, - }, - }, -} diff --git a/lua/plugins/neocodeium.lua b/lua/plugins/neocodeium.lua new file mode 100644 index 0000000..8678925 --- /dev/null +++ b/lua/plugins/neocodeium.lua @@ -0,0 +1,42 @@ +-- AI ghost-text completion via NeoCodeium (Windsurf/Codeium). Replaces +-- supermaven. Suggestions render as virtual text only; blink.cmp keeps its +-- own menu (ghost_text stays disabled in AstroNvim's blink spec). +-- +-- Disabled in python buffers and under the LeetCode work directory. Both are +-- evaluated by neocodeium on InsertEnter, and `:NeoCodeium enable_buffer` +-- still overrides them per buffer. +local leetcode_dir = vim.fn.expand "~/Developer/github.com/prdlk/leetcode/work/" + +local function is_leetcode_buffer(bufnr) + local name = vim.api.nvim_buf_get_name(bufnr) + return name:sub(1, #leetcode_dir) == leetcode_dir +end + +-- Insert-mode keys that act on a visible suggestion and otherwise keep their +-- native meaning ( backspace, delete word). +local function when_visible(action, fallback) + return function() + local neocodeium = require "neocodeium" + if neocodeium.visible() then + neocodeium[action]() + return "" + end + return fallback + end +end + +return { + "monkoose/neocodeium", + event = "VeryLazy", + cmd = "NeoCodeium", + opts = { + log_level = "warn", + filetypes = { python = false }, + filter = function(bufnr) return not is_leetcode_buffer(bufnr) end, + }, + keys = { + { "", when_visible("accept", ""), mode = "i", expr = true, desc = "Accept AI suggestion" }, + { "", when_visible("accept_word", ""), mode = "i", expr = true, desc = "Accept AI suggestion word" }, + { "", when_visible("clear", ""), mode = "i", expr = true, desc = "Clear AI suggestion" }, + }, +} diff --git a/lua/plugins/supermaven.lua b/lua/plugins/supermaven.lua deleted file mode 100644 index 46ed6ef..0000000 --- a/lua/plugins/supermaven.lua +++ /dev/null @@ -1,41 +0,0 @@ --- Disable supermaven in buffers under the LeetCode work directory, and --- re-enable it when leaving them. --- --- Note: supermaven's built-in `condition` option is one-way — its BufEnter --- listener gates the restart branch on `vim.g.SUPERMAVEN_DISABLED`, which --- `api.stop()` itself sets, so once auto-stopped it never comes back. This --- autocmd owns both directions instead. `vim.g.supermaven_leetcode_stopped` --- distinguishes our auto-stop from a manual :SupermavenStop, which stays off. -local leetcode_dir = vim.fn.expand "~/Developer/github.com/prdlk/leetcode/work/" - -local function is_leetcode_buffer() - local name = vim.api.nvim_buf_get_name(0) - return name:sub(1, #leetcode_dir) == leetcode_dir -end - -local function sync() - local api = require "supermaven-nvim.api" - if is_leetcode_buffer() then - if api.is_running() then - api.stop() - vim.g.supermaven_leetcode_stopped = true - end - elseif vim.g.supermaven_leetcode_stopped and not api.is_running() then - vim.g.supermaven_leetcode_stopped = nil - api.start() - end -end - -return { - "supermaven-inc/supermaven-nvim", - optional = true, - config = function(_, opts) - require("supermaven-nvim").setup(opts) - vim.api.nvim_create_autocmd("BufEnter", { - group = vim.api.nvim_create_augroup("supermaven_leetcode", { clear = true }), - desc = "Toggle supermaven off in LeetCode solution buffers", - callback = sync, - }) - sync() -- plugin loads on VeryLazy; cover the buffer we're already sitting in - end, -}