This commit is contained in:
Daniel Winkler 2026-07-24 15:04:12 +10:00
commit 5269e76608
20 changed files with 604 additions and 349 deletions

View file

@ -128,27 +128,20 @@ local diagnostic_opts = {
-- Don't update diagnostics when typing
update_in_insert = false,
}
later(function() vim.diagnostic.config(diagnostic_opts) end)
later(function()
vim.diagnostic.config(diagnostic_opts)
-- Custom autocommands ========================================================
local augroup = vim.api.nvim_create_augroup('CustomSettings', {})
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'markdown' },
group = augroup,
callback = function()
vim.diagnostic.config({
signs = {
severity = { min = 'WARN', max = 'ERROR' }
},
virtual_text = {
current_line = false,
severity = { min = 'HINT', max = 'ERROR' }
}
})
end
})
-- Relax diagnostics for markdown (many false positives)
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'markdown' },
callback = function()
vim.diagnostic.config({
signs = { severity = { min = 'WARN', max = 'ERROR' } },
virtual_text = { severity = { min = 'HINT', max = 'ERROR' }, current_line = false },
})
end,
})
end)
vim.api.nvim_create_autocmd("FileType", {
desc = "remove formatoptions",
@ -157,17 +150,6 @@ vim.api.nvim_create_autocmd("FileType", {
vim.b.minitrailspace_disable = true -- Don't highlight trailing space by default
end,
})
vim.api.nvim_create_autocmd('FileType', {
group = augroup,
callback = function()
-- Don't auto-wrap comments and don't insert comment leader after hitting 'o'
-- If don't do this on `FileType`, this keeps reappearing due to being set in
-- filetype plugins.
vim.cmd('setlocal formatoptions-=r formatoptions-=o')
end,
desc = [[Ensure proper 'formatoptions']],
})
-- Neovide ==============================================
if vim.g.neovide then
vim.g.neovide_cursor_vfx_mode = "pixiedust"
@ -176,7 +158,7 @@ if vim.g.neovide then
vim.g.neovide_cursor_short_animation_length = 0
vim.g.neovide_font_hinting = 'none'
vim.g.neovide_font_edging = 'subpixelantialias'
vim.o.guifont = 'JetBrainsMono Nerd Font,Symbols Nerd Font:h14:#e-subpixelantialias:#h-none'
vim.o.guifont = 'JetBrainsMono Nerd Font:h14:#e-subpixelantialias:#h-none'
vim.g.neovide_floating_corner_radius = 0.35
vim.keymap.set("n", "<leader>nf", "<cmd>NeovideFullscreen<CR>", { desc = "Toggle Neovide Fullscreen" })
end

View file

@ -12,7 +12,7 @@ end
Config.log = {}
Config.log_buf_id = Config.log_buf_id or nil
Config.start_hrtime = Config.start_hrtime or vim.loop.hrtime()
Config.start_hrtime = Config.start_hrtime or vim.uv.hrtime()
Config.log_print = function()
if Config.log_buf_id == nil or not vim.api.nvim_buf_is_valid(Config.log_buf_id) then
@ -24,7 +24,7 @@ end
Config.log_clear = function()
Config.log = {}
Config.start_hrtime = vim.loop.hrtime()
Config.start_hrtime = vim.uv.hrtime()
vim.cmd('echo "Cleared log"')
end

View file

@ -66,21 +66,28 @@ nmap_leader('<Tab>', '<Cmd>bnext<CR>', 'Next buffer')
nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer')
-- a is for 'AI'
nmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent chat (@{agent} tools)")
nmap_leader("ac", "<cmd>CodeCompanionChat Toggle<CR>", "Chat Toggle")
-- nmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
-- nmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
nmap_leader("aC", function()
local chat = require("codecompanion").last_chat()
if not chat then
return vim.notify("No CodeCompanion chat to compact", vim.log.levels.WARN)
end
require("codecompanion.interactions.chat.context_management.compaction").compact(chat, { min_token_savings = 0 })
end, "Compact chat")
nmap_leader("ag", "<cmd>CodeCompanion /commit<CR>", "Generate commit message")
nmap_leader("ai", "<cmd>CodeCompanionActions<CR>", "Chat Action")
nmap_leader("al", "<cmd>CodeCompanion /lsp<CR>", "Explain LSP Diagnostics")
nmap_leader("an", "<cmd>CodeCompanionChat Add<CR>", "Chat New")
nmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
--nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
nmap_leader("aw", "<cmd>CodeCompanion /tdd<CR>", "Workflow: plan, implement, test")
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
xmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent on selection")
xmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
xmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
--xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Expert")
xmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
nmap_leader("ak", "<cmd>CodeCompanionChat adapter=codex<CR>", "Chat with Codex")
-- b is for 'buffer'
nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate')
@ -123,7 +130,7 @@ nmap_leader('fm', '<Cmd>Pick marks<CR>', 'Marks')
nmap_leader('fn', '<cmd>ZkNotes<CR>', "Notes")
nmap_leader('fk', '<Cmd>Pick keymaps<CR>', 'Keymaps')
nmap_leader('fR', '<Cmd>Pick resume<CR>', 'Resume')
nmap_leader('fp', '<Cmd>Pick projects<CR>', 'Projects')
nmap_leader('fp', '<Cmd>Pick files<CR>', 'Files')
nmap_leader('fq', '<Cmd>Pick list scope="quickfix"<CR>', 'Quickfix')
nmap_leader('fr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
nmap_leader('flr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
@ -164,7 +171,7 @@ vim.keymap.set({ 'n' }, 'grk', '<Cmd>lua vim.lsp.buf.hover()<CR>', { desc = 'Doc
vim.keymap.set({ 'n' }, 'gre', '<Cmd>lua vim.diagnostic.open_float()<CR>', { desc = 'Diagnostics' })
nmap_lsp("K", '<Cmd>lua vim.lsp.buf.hover()<CR>', "Documentation")
local formatting_cmd = '<Cmd>lua require("conform").format({ lsp_fallback = true })<CR>'
local formatting_cmd = '<Cmd>lua require("conform").format({ lsp_format = "fallback" })<CR>'
nmap_leader('la', '<Cmd>lua vim.lsp.buf.code_action()<CR>', 'Actions')
nmap_leader('le', '<Cmd>lua vim.diagnostic.open_float()<CR>', 'Diagnostics popup')
nmap_leader('lf', formatting_cmd, 'Format')
@ -189,11 +196,9 @@ nmap_leader('Lx', '<Cmd>lua Config.execute_lua_line()<CR>', 'Execute `lua` line'
-- o is for 'other'
local trailspace_toggle_command = '<Cmd>lua vim.b.minitrailspace_disable = not vim.b.minitrailspace_disable<CR>'
nmap_leader('od', '<Cmd>Neogen<CR>', 'Document')
nmap_leader('oh', '<Cmd>normal gxiagxila<CR>', 'Move arg left')
nmap_leader('ol', '<Cmd>normal gxiagxina<CR>', 'Move arg right')
nmap_leader('or', '<Cmd>lua MiniMisc.resize_window()<CR>', 'Resize to default width')
nmap_leader('oS', '<Cmd>lua Config.insert_section()<CR>', 'Section insert')
nmap_leader('ot', '<Cmd>lua MiniTrailspace.trim()<CR>', 'Trim trailspace')
nmap_leader('oT', trailspace_toggle_command, 'Trailspace hl toggle')
nmap_leader('oz', '<Cmd>lua MiniMisc.zoom()<CR>', 'Zoom toggle')

View file

@ -208,112 +208,31 @@ now_if_args(function()
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
local ok_configs, configs = pcall(require, "nvim-treesitter.configs")
if ok_configs and configs.setup then
local opts = {
highlight = { enable = true },
indent = { enable = false },
textobjects = {
move = {
enable = true,
set_jumps = true,
goto_next_start = {
["]a"] = "@parameter.inner", -- fixed typo
["]f"] = "@function.outer",
["]o"] = "@loop.*",
["]s"] = { query = "@local.scope", desc = "Next scope" },
["]z"] = { query = "@fold", desc = "Next fold" },
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[a"] = "@parameter.inner",
["[f"] = "@function.outer",
["[o"] = "@loop.*",
["[s"] = { query = "@local.scope", query_group = "locals", desc = "Prev. scope" },
["[z"] = { query = "@fold", query_group = "folds", desc = "Prev. fold" },
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
goto_next = {
["]e"] = "@conditional.outer",
},
goto_previous = {
["[e"] = "@conditional.outer",
},
},
swap = {
enable = true,
swap_next = {
["<leader>x"] = "@parameter.inner",
},
swap_previous = {
["<leader>X"] = "@parameter.inner",
},
},
lsp_interop = {
enable = true,
border = "none",
floating_preview_opts = {},
peek_definition_code = {
["<leader>lm"] = "@function.outer",
["<leader>lM"] = "@class.outer",
},
},
},
}
-- Manual parser check for non-Nix users
if not Config.isNixCats then
local installed_check = function(lang)
return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0
end
local to_install = vim.tbl_filter(installed_check, opts.ensure_installed)
if #to_install > 0 then
require("nvim-treesitter").install(to_install)
end
end
-- Environment-specific Overrides
if not Config.isNixCats then
opts.auto_install = true
opts.ensure_installed = Config.treesitter_helpers.default_parsers
else
opts.auto_install = false
-- Nix handles installation, so ensure_installed is skipped/empty
end
configs.setup(opts)
return
end
local ts_filetypes = {
"c", "cpp", "lua", "nix", "python", "r", "markdown", "query",
"vim", "vimdoc", "yaml", "json", "toml", "rust", "go",
"javascript", "typescript", "tsx", "html", "css", "sql",
"julia", "rnoweb", "latex", "gitcommit", "gitignore",
"git_config", "git_rebase", "diff", "dockerfile",
"make", "xml", "zig", "regex", "csv", "bash",
"markdown_inline", "quarto", "rmd", "codecompanion",
}
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function(args)
-- Use explicit buffer + filetype to avoid any ambiguity
local ok = pcall(vim.treesitter.start, args.buf, args.match)
vim.bo.syntax = 'on'
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
vim.wo[0][0].foldexpr = 'v:lua.vim.treesitter.foldexpr()'
vim.wo[0][0].foldmethod = 'expr'
pattern = ts_filetypes,
callback = function(ev)
local lang = ev.match
if vim.treesitter.language.get_lang then
lang = vim.treesitter.language.get_lang(lang) or lang
end
if #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0 then
return
end
vim.treesitter.start(ev.buf, lang)
vim.bo[ev.buf].indentexpr = "v:lua.require('nvim-treesitter').indentexpr()"
end,
})
-- Textobjects: require plugin and bail out quietly if missing
local ok_nto, nto = pcall(require, "nvim-treesitter-textobjects")
if not ok_nto then
return
end
vim.g.no_plugin_maps = true
nto.setup({
require("nvim-treesitter-textobjects").setup({
move = {
set_jumps = true,
},
@ -322,70 +241,36 @@ now_if_args(function()
local move = require("nvim-treesitter-textobjects.move")
local swap = require("nvim-treesitter-textobjects.swap")
-- Map motion function names to actual functions
local move_fns = {
goto_next_start = move.goto_next_start,
goto_next_end = move.goto_next_end,
goto_previous_start = move.goto_previous_start,
goto_previous_end = move.goto_previous_end,
goto_next = move.goto_next,
goto_previous = move.goto_previous,
}
vim.keymap.set("n", "]a", function() move.goto_next_start("@parameter.inner", "textobjects") end, { desc = "Next parameter" })
vim.keymap.set("n", "[a", function() move.goto_previous_start("@parameter.inner", "textobjects") end, { desc = "Prev parameter" })
vim.keymap.set("n", "]f", function() move.goto_next_start("@function.outer", "textobjects") end, { desc = "Next function" })
vim.keymap.set("n", "[f", function() move.goto_previous_start("@function.outer", "textobjects") end, { desc = "Prev function" })
vim.keymap.set("n", "]o", function() move.goto_next_start("@loop.*", "textobjects") end, { desc = "Next loop" })
vim.keymap.set("n", "[o", function() move.goto_previous_start("@loop.*", "textobjects") end, { desc = "Prev loop" })
vim.keymap.set("n", "]s", function() move.goto_next_start("@local.scope", "textobjects") end, { desc = "Next scope" })
vim.keymap.set("n", "[s", function() move.goto_previous_start("@local.scope", "locals") end, { desc = "Prev scope" })
vim.keymap.set("n", "]z", function() move.goto_next_start("@fold", "folds") end, { desc = "Next fold" })
vim.keymap.set("n", "[z", function() move.goto_previous_start("@fold", "folds") end, { desc = "Prev fold" })
vim.keymap.set("n", "]M", function() move.goto_next_end("@function.outer", "textobjects") end, { desc = "Next function end" })
vim.keymap.set("n", "][", function() move.goto_next_end("@class.outer", "textobjects") end, { desc = "Next class end" })
vim.keymap.set("n", "[M", function() move.goto_previous_end("@function.outer", "textobjects") end, { desc = "Prev function end" })
vim.keymap.set("n", "[]", function() move.goto_previous_end("@class.outer", "textobjects") end, { desc = "Prev class end" })
vim.keymap.set("n", "]e", function() move.goto_next("@conditional.outer", "textobjects") end, { desc = "Next conditional" })
vim.keymap.set("n", "[e", function() move.goto_previous("@conditional.outer", "textobjects") end, { desc = "Prev conditional" })
-- All motions defined in one place
-- spec = { query_or_list, query_group, desc }
local move_maps = {
goto_next_start = {
["]a"] = { "@parameter.inner", "textobjects", "Next parameter" },
["]f"] = { "@function.outer", "textobjects", "Next function start" },
["]o"] = { { "@loop.inner", "@loop.outer" }, "textobjects", "Next loop" },
["]s"] = { "@local.scope", "locals", "Next scope" },
["]z"] = { "@fold", "folds", "Next fold" },
},
goto_next_end = {
["]M"] = { "@function.outer", "textobjects", "Next function end" },
["]["] = { "@class.outer", "textobjects", "Next class end" },
},
goto_previous_start = {
["[a"] = { "@parameter.inner", "textobjects", "Previous parameter" },
["[f"] = { "@function.outer", "textobjects", "Previous function start" },
["[o"] = { { "@loop.inner", "@loop.outer" }, "textobjects", "Previous loop" },
["[s"] = { "@local.scope", "locals", "Previous scope" },
["[z"] = { "@fold", "folds", "Previous fold" },
},
goto_previous_end = {
["[M"] = { "@function.outer", "textobjects", "Previous function end" },
["[]"] = { "@class.outer", "textobjects", "Previous class end" },
},
goto_next = {
["]e"] = { "@conditional.outer", "textobjects", "Next conditional" },
},
goto_previous = {
["[e"] = { "@conditional.outer", "textobjects", "Previous conditional" },
},
}
vim.keymap.set("n", "<leader>x", function() swap.swap_next("@parameter.inner", "textobjects") end, { desc = "Swap parameter next" })
vim.keymap.set("n", "<leader>X", function() swap.swap_previous("@parameter.inner", "textobjects") end, { desc = "Swap parameter prev" })
-- Generate motion keymaps
for fn_name, maps in pairs(move_maps) do
local fn = move_fns[fn_name]
if fn then
for lhs, spec in pairs(maps) do
local query_or_list, group, desc = spec[1], spec[2], spec[3]
vim.keymap.set({ "n", "x", "o" }, lhs, function()
fn(query_or_list, group)
end, { desc = desc })
end
if not Config.isNixCats then
local installed_check = function(lang)
return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0
end
local default_parsers = Config.treesitter_helpers.default_parsers
local to_install = vim.tbl_filter(installed_check, default_parsers)
if #to_install > 0 then
require("nvim-treesitter").install(to_install)
end
end
-- Swap keymaps (unchanged, but minimal)
vim.keymap.set("n", "<leader>x", function()
swap.swap_next("@parameter.inner")
end, { desc = "Swap with next parameter" })
vim.keymap.set("n", "<leader>X", function()
swap.swap_previous("@parameter.inner")
end, { desc = "Swap with previous parameter" })
end)
-- zk

View file

@ -5,18 +5,18 @@ local add = Config.add
local nix = require('config.nix')
if not Config.isNixCats then
local m_add = MiniDeps.add
local add = MiniDeps.add
now(function()
m_add({ source = "R-nvim/R.nvim" })
add({ source = "R-nvim/R.nvim" })
end)
now_if_args(function()
m_add({ source = "jmbuhr/otter.nvim" })
add({ source = "jmbuhr/otter.nvim" })
end)
later(function()
m_add({ source = "jpalardy/vim-slime" })
add({ source = "jpalardy/vim-slime" })
end)
end
@ -44,12 +44,6 @@ end)
-- r
now(function()
if nix.get_cat("r", false) then
local cwd = vim.fn.getcwd(-1)
vim.env.RNVIM_COMPLDIR = cwd .. "/.r-compl"
vim.env.R_LIBS_USER = (vim.env.R_LIBS_USER or ""):gsub("%$PWD", cwd)
vim.env.TMPDIR = cwd .. "/.r-tmp"
vim.fn.mkdir(vim.env.RNVIM_COMPLDIR, "p")
vim.fn.mkdir(vim.env.TMPDIR, "p")
vim.g.rout_follow_colorscheme = true
require("r").setup({
-- Create a table with the options to be passed to setup()
@ -62,6 +56,20 @@ now(function()
rconsole_height = 20,
nvimpager = "split_h",
pdfviewer = "",
-- Use R.nvim's built-in rnvimserver-backed language server. Do not
-- configure the external R languageserver through plugin/25_lsp.lua.
r_ls = {
completion = true,
hover = true,
signature = true,
definition = true,
references = true,
implementation = true,
document_symbol = true,
workspace_symbol = true,
document_highlight = true,
rename = true,
},
})
end
end)
@ -69,8 +77,6 @@ end)
-- Quarto
now(function()
vim.treesitter.language.register("markdown", { "quarto", "rmd" })
if nix.get_cat({ "r", "markdown" }, false) then
vim.api.nvim_create_autocmd("FileType", {
pattern = { "quarto" },

View file

@ -4,10 +4,10 @@ local later = MiniDeps.later
local nix = require('config.nix')
if not Config.isNixCats then
local m_add = MiniDeps.add
local add = MiniDeps.add
later(function()
m_add({ source = "Bilal2453/luvit-meta" })
m_add({ source = "folke/lazydev.nvim" })
add({ source = "Bilal2453/luvit-meta" })
add({ source = "folke/lazydev.nvim" })
end)
end

View file

@ -2,10 +2,10 @@ local later = MiniDeps.later
local add = Config.add
if not Config.isNixCats then
local m_add = MiniDeps.add
local add = MiniDeps.add
later(function()
m_add("stevearc/conform.nvim")
add("stevearc/conform.nvim")
end)
end
@ -23,20 +23,6 @@ later(function()
rmd = { "injected" },
quarto = { "injected" },
},
default_format_opts = {
lsp_format = "fallback",
},
formatters = {
my_styler = {
command = "R",
-- A list of strings, or a function that returns a list of strings
-- Return a single string instead of a list to run the command in a shell
args = { "-s", "-e", "styler::style_file(commandArgs(TRUE)[1])", "--args", "$FILENAME" },
stdin = false,
},
},
})
end)

View file

@ -4,7 +4,7 @@ local now = MiniDeps.now
local now_if_args = Config.now_if_args
-- Constants
local BLINK_VERSION = "v1.4.1"
local BLINK_VERSION = "v1.10.2"
-- Plugin sources configuration
local PLUGIN_SOURCES = {
@ -26,26 +26,16 @@ local PLUGIN_ADDS = {
-- Helper functions
local function create_system_prompt(role_description)
return function(context)
return "I want you to act as a senior " .. context.filetype .. " developer. " .. role_description
local lang = context.filetype or "programmer"
return "I want you to act as a senior " .. lang .. " developer. " .. role_description
end
end
local function get_code_block(context)
local text = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
local text = require("codecompanion.helpers.code").get_code(context.start_line, context.end_line)
return "```" .. context.filetype .. "\n" .. text .. "\n```"
end
local function create_common_opts(mapping, short_name)
return {
mapping = mapping,
modes = { "v" },
short_name = short_name,
auto_submit = true,
stop_context_insertion = true,
user_prompt = true,
}
end
local function get_mini_icons_highlight(ctx)
local _, hl, _ = require("mini.icons").get("lsp", ctx.kind)
return hl
@ -57,7 +47,7 @@ local function get_blink_fuzzy_setting()
}
if not Config.isNixCats then
setting.prebuilt_binary = { force_version = BLINK_VERSION }
setting.prebuilt_binaries = { force_version = BLINK_VERSION }
end
return setting
@ -65,10 +55,10 @@ end
-- Plugin loading
if not Config.isNixCats then
local m_add = MiniDeps.add
local add = MiniDeps.add
now_if_args(function()
m_add({
add({
source = "saghen/blink.cmp",
depends = { "rafamadriz/friendly-snippets" },
checkout = BLINK_VERSION,
@ -77,38 +67,91 @@ if not Config.isNixCats then
later(function()
for _, source in ipairs(PLUGIN_SOURCES) do
m_add({ source = source })
add({ source = source })
end
end)
end
local function get_codecompanion_config()
return {
adapters = {
acp = {
-- Codex = heavy agent lane (ChatGPT Edu login via `codex login`; ~/.codex/auth.json).
-- Requires `codex-acp` on PATH (~/.nix-profile/bin). ACP-only slash commands in the
-- chat buffer: /resume (restore a past session, fresh chat only), /mode (switch agent
-- mode), /command, /acp_session_options (e.g. model per session); `\` triggers ACP
-- command completion (1-5s delay after chat open).
codex = function()
return require("codecompanion.adapters").extend("codex", {
defaults = {
auth_method = "chatgpt",
},
})
end,
},
},
interactions = {
chat = {
adapter = {
name = "copilot",
model = "gemini-3.1-pro-preview",
model = "claude-sonnet-5",
},
slash_commands = {
["share"] = {
opts = {
token = os.getenv("GITHUB_GIST_TOKEN"),
},
},
},
opts = {
completion_provider = "blink",
context_management = {
editing = {
trigger = 0.65,
keep_cycles = 3,
exclude_tools = { "memory" },
},
compaction = {
trigger = 0.85,
min_token_savings = 10000,
},
},
},
},
inline = {
adapter = {
name = "copilot",
model = "gemini-3.1-pro-preview",
}
},
keymaps = {
accept_change = {
modes = { n = "ga" },
description = "Accept the suggested change",
model = "gpt-5-mini",
},
reject_change = {
modes = { n = "gr" },
opts = { nowait = true },
description = "Reject the suggested change",
},
shared = {
keymaps = {
accept_change = {
modes = { n = "ga" },
description = "Accept the suggested change",
},
reject_change = {
modes = { n = "gr" },
opts = { nowait = true },
description = "Reject the suggested change",
},
},
},
background = {
adapter = {
name = "copilot",
model = "gpt-5-mini",
},
chat = {
callbacks = {
["on_ready"] = {
actions = { "interactions.background.builtin.chat_make_title" },
enabled = true,
},
},
opts = {
enabled = true,
},
},
},
},
@ -121,12 +164,38 @@ local function get_codecompanion_config()
height = 0.33,
},
},
diff = {
enabled = true,
threshold_for_chat = 6,
},
},
rules = {
default = {
description = "Collection of common files for all projects",
files = {
".clinerules",
".cursorrules",
".rules",
".github/copilot-instructions.md",
"AGENT.md",
"AGENTS.md",
{ path = "CLAUDE.md", parser = "claude" },
{ path = "CLAUDE.local.md", parser = "claude" },
{ path = "~/.claude/CLAUDE.md", parser = "claude" },
},
},
opts = {
chat = {
autoload = "default",
enabled = true,
},
},
},
prompt_library = {
["expert"] = {
interaction = "chat",
description = "Get expert advice from an LLM",
--opts = create_common_opts("<localleader>ae", "expert"),
opts = { alias = "expert" },
prompts = {
{
role = "system",
@ -146,7 +215,7 @@ local function get_codecompanion_config()
["fixer"] = {
interaction = "chat",
description = "Fix code errors with expert guidance",
--opts = create_common_opts("<localleader>af", "afixer"),
opts = { alias = "fixer" },
prompts = {
{
role = "system",
@ -166,7 +235,7 @@ local function get_codecompanion_config()
["suggest"] = {
interaction = "chat",
description = "Suggest improvements to the buffer",
--opts = create_common_opts("<localleader>as", "suggest"),
opts = { alias = "suggest" },
prompts = {
{
role = "system",
@ -188,7 +257,53 @@ local function get_codecompanion_config()
},
},
},
}
["agent"] = {
interaction = "chat",
description = "Agentic coding with the @{agent} tool group (read/edit/grep/run)",
opts = { alias = "agent" },
prompts = {
{
role = "user",
content = function(context)
return "@{agent} Work on the following code:\n\n" .. get_code_block(context) .. "\n\n"
end,
opts = { contains_code = true },
},
},
},
["tdd"] = {
interaction = "chat",
description = "Workflow: plan the buffer change, implement it, run the tests",
opts = { alias = "tdd", is_workflow = true },
prompts = {
{
{
role = "user",
content = function(context)
return "Let's work test-driven. First, study #buffer and the relevant parts of the codebase, then propose a concise implementation plan (no code yet).\n\nThe code under discussion:\n\n"
.. get_code_block(context)
.. "\n\nThe task: "
end,
opts = { contains_code = true },
},
},
{
{
role = "user",
content = "Implement the plan now, writing or updating tests alongside the code. @{agent}",
opts = { auto_submit = true },
},
},
{
{
role = "user",
content = "Run the project's test suite with @{run_command} and fix any failures until it passes.",
opts = { auto_submit = true },
},
},
},
},
},
}
end
@ -244,6 +359,13 @@ later(function()
end)
-- CodeCompanion habit notes (chat buffer unless stated):
-- /compact compact history, keep summary /fork fork the conversation
-- /symbols insert symbols for a file /share export chat to a GitHub gist
-- gm toggle "btw" ephemeral message gty YOLO: approve all tool calls
-- gba/gbd buffer sync add/drop gd debug window (adapter/tools info)
-- Codex (ACP) lane: /resume (fresh chat only), /mode, /command, /acp_session_options,
-- `\` ACP command completion. Prompt library: /expert /fixer /suggest /agent /tdd (workflow).
later(function()
add("codecompanion.nvim")
@ -316,7 +438,10 @@ now_if_args(function()
},
snippets = { preset = "mini_snippets" },
sources = {
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot", "codecompanion" },
per_filetype = {
codecompanion = { "codecompanion" },
},
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot" },
providers = {
path = {
score_offset = 50,
@ -335,10 +460,6 @@ now_if_args(function()
score_offset = 10,
opts = { cmp_name = "cmdline" }
},
cmp_r = {
name = "cmp_r",
module = "blink.compat.source",
},
copilot = {
name = "copilot",
module = "blink-copilot",

View file

@ -8,24 +8,14 @@ if not Config.isNixCats then
end
now_if_args(function()
-- R.nvim owns the R `r_ls` client and starts its bundled rnvimserver from
-- its own plugin directory. Keep R out of this generic server registry.
local servers = {
clangd = {},
basedpyright = {},
ruff = {},
marksman = {
filetypes = { "markdown", "markdown_inline", "codecompanion" },
},
r_ls = {
filetypes = { 'r', 'rmd', 'rmarkdown' },
settings = {
['r_ls'] = {
lsp = {
rich_documentation = true,
enable = true,
},
},
}
},
julials = {
settings = {
julia = {