Compare commits

..
Author SHA1 Message Date
25a88599c1 bloocky config and fixes 2026-08-07 14:35:17 +10:00
92729cff56 added bloocky and dooing 2026-08-07 14:35:17 +10:00
17 changed files with 257 additions and 341 deletions

View file

@ -0,0 +1,17 @@
{
"lastAgent": "agent-local-096f2785-09c8-4487-b71b-f8ac2b81aaaf",
"sessionsByServer": {
"api.letta.com": {
"agentId": "agent-21b21fd6-49e4-4d5c-a1b7-1c6dcd8dacc9",
"conversationId": "default"
},
"local:/Users/daniel/.letta/lc-local-backend": {
"agentId": "agent-local-096f2785-09c8-4487-b71b-f8ac2b81aaaf",
"conversationId": "default"
}
},
"lastSession": {
"agentId": "agent-local-096f2785-09c8-4487-b71b-f8ac2b81aaaf",
"conversationId": "default"
}
}

46
flake.lock generated
View file

@ -22,11 +22,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1784796856, "lastModified": 1785967620,
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=", "narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d", "rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -36,6 +36,22 @@
"type": "github" "type": "github"
} }
}, },
"plugins-bloocky": {
"flake": false,
"locked": {
"lastModified": 1786042339,
"narHash": "sha256-8QcoC1bS8pRcwBkW3mqD2vgP9Mu0aCdIy6umZO6mUGM=",
"owner": "atiladefreitas",
"repo": "bloocky",
"rev": "a052c3b1a8126e04b194bb3db3c4c6ca641c0e4e",
"type": "github"
},
"original": {
"owner": "atiladefreitas",
"repo": "bloocky",
"type": "github"
}
},
"plugins-cmp-pandoc-references": { "plugins-cmp-pandoc-references": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -52,6 +68,22 @@
"type": "github" "type": "github"
} }
}, },
"plugins-dooing": {
"flake": false,
"locked": {
"lastModified": 1785971574,
"narHash": "sha256-GtEC5kWcH0DmiYXkzxzNjjfYLfyEb7zpTLQWdi7n3zs=",
"owner": "atiladefreitas",
"repo": "dooing",
"rev": "6748316bc6b4601797fb952a83694cc0a5ef6da2",
"type": "github"
},
"original": {
"owner": "atiladefreitas",
"repo": "dooing",
"type": "github"
}
},
"r-nvim-nix": { "r-nvim-nix": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -76,11 +108,11 @@
}, },
"rixpkgs": { "rixpkgs": {
"locked": { "locked": {
"lastModified": 1782576256, "lastModified": 1785776890,
"narHash": "sha256-KOvpL9DJJmShb64mX9QTjhxHaxE8MizQIqNUAniuJ2E=", "narHash": "sha256-CzzgB1teVbroR/QhGAnsQToUYCDXEZZtFTcISAooASM=",
"owner": "dwinkler1", "owner": "dwinkler1",
"repo": "rixpkgs", "repo": "rixpkgs",
"rev": "815afc01bc0cc9a2eba80906645bd08f976a4401", "rev": "a54080a58b57d5785dc85901850b817bef2aaf83",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -111,7 +143,9 @@
"inputs": { "inputs": {
"fran": "fran", "fran": "fran",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"plugins-bloocky": "plugins-bloocky",
"plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references", "plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references",
"plugins-dooing": "plugins-dooing",
"r-nvim-nix": "r-nvim-nix", "r-nvim-nix": "r-nvim-nix",
"rixpkgs": "rixpkgs", "rixpkgs": "rixpkgs",
"wrappers": "wrappers" "wrappers": "wrappers"

View file

@ -29,6 +29,16 @@
url = "github:jmbuhr/cmp-pandoc-references"; url = "github:jmbuhr/cmp-pandoc-references";
flake = false; flake = false;
}; };
"plugins-bloocky" = {
url = "github:atiladefreitas/bloocky";
flake = false;
};
"plugins-dooing" = {
url = "github:atiladefreitas/dooing";
flake = false;
};
}; };
outputs = { outputs = {
@ -232,6 +242,12 @@
''; '';
smoke-test = pkgs.runCommand "smoke-test" {} '' smoke-test = pkgs.runCommand "smoke-test" {} ''
# The Nix build sandbox has a read-only HOME; point XDG dirs at a
# writable location so vim.lsp/shaDa can write state headlessly.
export XDG_CONFIG_HOME=$TMPDIR/xdg-config
export XDG_STATE_HOME=$TMPDIR/xdg-state
export XDG_CACHE_HOME=$TMPDIR/xdg-cache
export XDG_DATA_HOME=$TMPDIR/xdg-data
BINARY_PATH="${defaultNvimPkg}/bin/vv" BINARY_PATH="${defaultNvimPkg}/bin/vv"
"$BINARY_PATH" --headless -c "luafile ${./tests/smoke.lua}" -c "qa!" "$BINARY_PATH" --headless -c "luafile ${./tests/smoke.lua}" -c "qa!"
touch $out touch $out

View file

@ -11,28 +11,39 @@ nmap_leader('<Tab>', '<Cmd>bnext<CR>', 'Next buffer')
nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer') nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer')
-- a is for 'AI' -- a is for 'AI'
nmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent chat (@{agent} tools)") nmap_leader("aa", function()
nmap_leader("ac", "<cmd>CodeCompanionChat Toggle<CR>", "Chat Toggle") require("opencode").ask("@this: ")
nmap_leader("aC", function() end, "Ask OpenCode about this")
local chat = require("codecompanion").last_chat() nmap_leader("ab", function()
if not chat then require("opencode").prompt("Analyse @buffer")
return vim.notify("No CodeCompanion chat to compact", vim.log.levels.WARN) end, "Analyse buffer")
end nmap_leader("aB", function()
require("codecompanion.interactions.chat.context_management.compaction").compact(chat, { min_token_savings = 0 }) require("opencode").prompt("Analyse @buffers")
end, "Compact chat") end, "Analyse open buffers")
nmap_leader("ag", "<cmd>CodeCompanion /commit<CR>", "Generate commit message") nmap_leader("ad", function()
nmap_leader("ai", "<cmd>CodeCompanionActions<CR>", "Chat Action") require("opencode").prompt("Explain @diagnostics and fix the underlying issue")
nmap_leader("al", "<cmd>CodeCompanion /lsp<CR>", "Explain LSP Diagnostics") end, "Explain/fix diagnostics")
nmap_leader("an", "<cmd>CodeCompanionChat Add<CR>", "Chat New") nmap_leader("an", function()
nmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements") require("opencode").command("session.new")
nmap_leader("aw", "<cmd>CodeCompanion /tdd<CR>", "Workflow: plan, implement, test") end, "New OpenCode session")
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer") nmap_leader("ap", function()
xmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent on selection") require("opencode").ask("@")
xmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code") end, "Ask OpenCode with context")
xmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code") nmap_leader("as", function()
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Expert") require("opencode").select()
xmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements") end, "Select OpenCode action")
nmap_leader("ak", "<cmd>CodeCompanionChat adapter=codex<CR>", "Chat with Codex") xmap_leader("aa", function()
require("opencode").ask("@this: ")
end, "Ask OpenCode about selection")
xmap_leader("af", function()
require("opencode").prompt("Fix the selected code and preserve its surrounding API:\n@this")
end, "Fix selection")
xmap_leader("ap", function()
require("opencode").ask("@")
end, "Ask OpenCode with context")
xmap_leader("as", function()
require("opencode").select()
end, "Select OpenCode action")
-- b is for 'buffer' -- b is for 'buffer'
nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate') nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate')
@ -214,6 +225,24 @@ nmap_leader("wh", "<C-w>h", "Go to Left Window", { remap = true })
nmap_leader("wj", "<C-w>j", "Go to Lower Window", { remap = true }) nmap_leader("wj", "<C-w>j", "Go to Lower Window", { remap = true })
nmap_leader("wk", "<C-w>k", "Go to Upper Window", { remap = true }) nmap_leader("wk", "<C-w>k", "Go to Upper Window", { remap = true })
nmap_leader("wl", "<C-w>l", "Go to Right Window", { remap = true }) nmap_leader("wl", "<C-w>l", "Go to Right Window", { remap = true })
nmap_leader("w>", "<Cmd>vertical resize +5<CR>", "Increase Window Width")
nmap_leader("w<lt>", "<Cmd>vertical resize -5<CR>", "Decrease Window Width")
local function set_window_width_percent(percent)
return function()
local target_width = math.max(1, math.floor(vim.o.columns * percent / 100 + 0.5))
vim.api.nvim_win_set_width(0, target_width)
end
end
for i = 1, 9 do
local percent = i * 10
nmap_leader(
"w" .. i,
set_window_width_percent(percent),
string.format("Set Window Width to %d%%", percent)
)
end
nmap_leader("_", "<C-W>s", "Split Window Below", { remap = true }) nmap_leader("_", "<C-W>s", "Split Window Below", { remap = true })
nmap_leader("|", "<C-W>v", "Split Window Right", { remap = true }) nmap_leader("|", "<C-W>v", "Split Window Right", { remap = true })

View file

@ -80,6 +80,8 @@ in {
plenary-nvim plenary-nvim
vimtex vimtex
neogit neogit
config.nvim-lib.neovimPlugins.bloocky
config.nvim-lib.neovimPlugins.dooing
{ {
data = mini-nvim; data = mini-nvim;
pname = "mini.nvim"; pname = "mini.nvim";
@ -163,10 +165,8 @@ in {
pname = "nvim-treesitter"; pname = "nvim-treesitter";
} }
{ {
data = pkgs.codecompanion-nvim.overrideAttrs (old: { data = pkgs.vimPlugins.opencode-nvim;
doCheck = false; pname = "opencode.nvim";
});
pname = "codecompanion";
} }
] ++ builtins.attrValues pkgs.vimPlugins.nvim-treesitter.queries; ] ++ builtins.attrValues pkgs.vimPlugins.nvim-treesitter.queries;
}; };

13
nvim.log Normal file
View file

@ -0,0 +1,13 @@
WRN 2026-07-31T16:36:01.037 ?.50508 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/TN25Kv/nvim.50508.0
WRN 2026-07-31T16:36:38.634 ?.50644 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/6jT8As/nvim.50644.0
WRN 2026-07-31T16:46:12.752 ?.54395 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/zY36Oi/nvim.54395.0
WRN 2026-07-31T17:01:43.138 ?.58656 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/nDisRA/nvim.58656.0
WRN 2026-07-31T17:01:50.641 ?.58696 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/okDyqb/nvim.58696.0
WRN 2026-07-31T17:02:04.773 ?.58741 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/5wxfRu/nvim.58741.0
WRN 2026-07-31T17:02:29.644 ?.58854 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/OMTfpB/nvim.58854.0
WRN 2026-07-31T17:02:29.644 ?.58852 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/QZvLy2/nvim.58852.0
WRN 2026-07-31T17:14:31.289 ?.64329 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/zh9tLm/nvim.64329.0
WRN 2026-07-31T17:14:40.017 ?.64399 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/pGaDez/nvim.64399.0
WRN 2026-07-31T17:17:48.228 ?.64921 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/ryMpX0/nvim.64921.0
WRN 2026-07-31T17:17:52.664 ?.64953 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/X7RmXh/nvim.64953.0
WRN 2026-07-31T17:18:00.691 ?.64989 server_start:197: Failed to start server: operation not permitted: /tmp/nvim.daniel/C6njjq/nvim.64989.0

View file

@ -1,22 +1,6 @@
{ ... }: { ... }:
final: prev: final: prev:
{ {
codecompanion-nvim = prev.vimPlugins.codecompanion-nvim.overrideAttrs {
checkInputs = with prev.vimPlugins; [
blink-cmp
mini-nvim
];
dependencies = [ prev.vimPlugins.plenary-nvim ];
nvimSkipModules = [
"codecompanion.actions.static"
"codecompanion.actions.init"
"minimal"
"codecompanion.providers.actions.fzf_lua"
"codecompanion.providers.completion.cmp.setup"
"codecompanion.providers.actions.telescope"
"codecompanion.providers.actions.snacks"
];
};
zk-nvim = prev.vimPlugins.zk-nvim.overrideAttrs { zk-nvim = prev.vimPlugins.zk-nvim.overrideAttrs {
nvimSkipModules = [ nvimSkipModules = [
"zk.pickers.fzf_lua" "zk.pickers.fzf_lua"

View file

@ -5,7 +5,7 @@
}; };
in { in {
inherit rpkgs; inherit rpkgs;
baseRPackages = [rpkgs.nvimcom]; baseRPackages = [rpkgs.nvimcom rpkgs.rPackages.btw];
rWrapper = rpkgs.rWrapper.override {packages = [];}; rWrapper = rpkgs.rWrapper.override {packages = [];};
quarto = rpkgs.quarto.override {extraRPackages = [];}; quarto = rpkgs.quarto.override {extraRPackages = [];};
} }

View file

@ -18,7 +18,7 @@ local defaults = {
duckdb = "duckdb", duckdb = "duckdb",
julia = "julia", julia = "julia",
python = "ipython", python = "ipython",
shell = "echo 'Hello " .. vim.env.USER .. "!'", shell = "echo 'Hello " .. (vim.env.USER or "user") .. "!'",
} }
-- Registry of terminal commands -- Registry of terminal commands

View file

@ -191,7 +191,7 @@ end)
-- Treesitter -- Treesitter
now_if_args(function() now_if_args(function()
vim.treesitter.language.register("markdown", { "markdown", "codecompanion", "rmd", "quarto" }) vim.treesitter.language.register("markdown", { "markdown", "rmd", "quarto" })
require 'treesitter-context'.setup { require 'treesitter-context'.setup {
enable = true, enable = true,
@ -216,7 +216,7 @@ now_if_args(function()
"julia", "rnoweb", "latex", "gitcommit", "gitignore", "julia", "rnoweb", "latex", "gitcommit", "gitignore",
"git_config", "git_rebase", "diff", "dockerfile", "git_config", "git_rebase", "diff", "dockerfile",
"make", "xml", "zig", "regex", "csv", "bash", "make", "xml", "zig", "regex", "csv", "bash",
"markdown_inline", "quarto", "rmd", "codecompanion", "markdown_inline", "quarto", "rmd",
} }
local function start_treesitter(buf, filetype) local function start_treesitter(buf, filetype)
local lang = vim.treesitter.language.get_lang(filetype) or filetype local lang = vim.treesitter.language.get_lang(filetype) or filetype

View file

@ -102,7 +102,7 @@ now_if_args(function()
add("render-markdown.nvim") add("render-markdown.nvim")
require('render-markdown').setup({ require('render-markdown').setup({
-- completions = { blink = { enabled = true } }, -- completions = { blink = { enabled = true } },
file_types = { 'markdown', 'codecompanion', }, file_types = { 'markdown', },
link = { link = {
wiki = { wiki = {
body = function(ctx) body = function(ctx)

View file

@ -37,7 +37,6 @@ later(function()
end) end)
later(function() later(function()
-- Keep `ga` free for CodeCompanion's "accept change" mapping.
require("mini.align").setup({ require("mini.align").setup({
mappings = { mappings = {
start = "gA", start = "gA",
@ -219,6 +218,8 @@ later(function()
local minikeymap = require("mini.keymap") local minikeymap = require("mini.keymap")
minikeymap.setup() minikeymap.setup()
local map_multistep = minikeymap.map_multistep local map_multistep = minikeymap.map_multistep
-- blink_next/blink_prev/blink_accept are blink.cmp actions.
-- Direct blink keymaps (C-space/C-l) are set in 24_completion.lua.
local tab_steps = { local tab_steps = {
"blink_next", "blink_next",
"pmenu_next", "pmenu_next",

View file

@ -4,9 +4,6 @@ local later = MiniDeps.later
local now = MiniDeps.now local now = MiniDeps.now
local now_if_args = Config.now_if_args local now_if_args = Config.now_if_args
-- Constants
local BLINK_VERSION = "v1.10.2"
-- Plugin sources configuration -- Plugin sources configuration
local PLUGIN_SOURCES = { local PLUGIN_SOURCES = {
"hrsh7th/cmp-cmdline", "hrsh7th/cmp-cmdline",
@ -14,7 +11,7 @@ local PLUGIN_SOURCES = {
"zbirenbaum/copilot.lua", "zbirenbaum/copilot.lua",
"jmbuhr/cmp-pandoc-references", "jmbuhr/cmp-pandoc-references",
"fang2hou/blink-copilot", "fang2hou/blink-copilot",
"olimorris/codecompanion.nvim" "nickjvandyke/opencode.nvim",
} }
local PLUGIN_ADDS = { local PLUGIN_ADDS = {
@ -24,34 +21,16 @@ local PLUGIN_ADDS = {
"cmp-pandoc-references", "cmp-pandoc-references",
} }
-- Helper functions
local function create_system_prompt(role_description)
return function(context)
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.code").get_code(context.start_line, context.end_line)
return "```" .. context.filetype .. "\n" .. text .. "\n```"
end
local function get_mini_icons_highlight(ctx) local function get_mini_icons_highlight(ctx)
local _, hl, _ = require("mini.icons").get("lsp", ctx.kind) local _, hl, _ = require("mini.icons").get("lsp", ctx.kind)
return hl return hl
end end
local function get_blink_fuzzy_setting() local function get_blink_fuzzy_setting()
local setting = { return {
sorts = { "exact", "score", "sort_text" } sorts = { "exact", "score", "sort_text" },
use_proximity = true,
} }
if not Config.isNixCats then
setting.prebuilt_binaries = { force_version = BLINK_VERSION }
end
return setting
end end
-- Plugin loading -- Plugin loading
@ -62,7 +41,6 @@ if not Config.isNixCats then
add({ add({
source = "saghen/blink.cmp", source = "saghen/blink.cmp",
depends = { "rafamadriz/friendly-snippets" }, depends = { "rafamadriz/friendly-snippets" },
checkout = BLINK_VERSION,
}) })
end) end)
@ -73,241 +51,6 @@ if not Config.isNixCats then
end) 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 = "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 = "gpt-5-mini",
},
},
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,
},
},
},
},
display = {
chat = {
show_settings = false,
window = {
layout = "horizontal",
position = "bottom",
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 = { alias = "expert" },
prompts = {
{
role = "system",
content = create_system_prompt(
"I will ask you specific questions and I want you to return concise explanations and codeblock examples."
),
},
{
role = "user",
content = function(context)
return "I have the following code:\n\n" .. get_code_block(context) .. "\n\n"
end,
opts = { contains_code = true },
},
},
},
["fixer"] = {
interaction = "chat",
description = "Fix code errors with expert guidance",
opts = { alias = "fixer" },
prompts = {
{
role = "system",
content = create_system_prompt(
"I have a block of code that is not working and will give you a hint about the error. I want you to return the corrected code and a concise explanation of the corrections."
),
},
{
role = "user",
content = function(context)
return "The following code has an error:\n\n" .. get_code_block(context) .. "\n\nThe error is:"
end,
opts = { contains_code = true },
},
},
},
["suggest"] = {
interaction = "chat",
description = "Suggest improvements to the buffer",
opts = { alias = "suggest" },
prompts = {
{
role = "system",
content = create_system_prompt(
"When asked to improve code, follow these steps:\n" ..
"1. Identify the programming language.\n" ..
"2. Think separately for each function or significant block of code and think about possible improvements (e.g., for better readability or speed) in the context of the language.\n" ..
"3. Think about the whole document and think about possible improvements.\n" ..
"4. Provide the improved code.\n" ..
"5. Provide a concise explanation of the improvements."
),
},
{
role = "user",
content = function(context)
return "Please improve the following code:\n\n" .. get_code_block(context)
end,
opts = { contains_code = true },
},
},
},
["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
-- Batch add simple plugins -- Batch add simple plugins
later(function() later(function()
for _, plugin in ipairs(PLUGIN_ADDS) do for _, plugin in ipairs(PLUGIN_ADDS) do
@ -359,26 +102,33 @@ later(function()
}) })
end) 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() later(function()
add("codecompanion.nvim") vim.g.opencode_opts = {
events = {
-- now use function reload = true,
require("codecompanion").setup(get_codecompanion_config()) permissions = {
vim.cmd([[cab cc CodeCompanion]]) enabled = true,
edits = { enabled = true },
},
},
server = {
start = function()
vim.cmd("vsplit term://opencode --port")
vim.cmd("vertical resize " .. math.floor(vim.o.columns * 0.4))
vim.cmd("wincmd p")
end
},
}
add("opencode.nvim")
end) end)
now_if_args(function() now_if_args(function()
add("blink.cmp") add("blink.cmp")
require("blink.cmp").setup({ require("blink.cmp").setup({
-- Direct blink keymaps (C-space/C-l).
-- Tab/Enter/Up/Down are handled via multistep chains in 23_editor.lua,
-- which chain blink_next/blink_prev/blink_accept with other editor actions.
keymap = { keymap = {
preset = "default", preset = "default",
["<C-space>"] = { "show", "select_next" }, ["<C-space>"] = { "show", "select_next" },
@ -415,6 +165,7 @@ now_if_args(function()
}, },
completion = { completion = {
menu = { menu = {
border = "rounded",
draw = { draw = {
treesitter = { "lsp" }, treesitter = { "lsp" },
components = { components = {
@ -434,14 +185,12 @@ now_if_args(function()
list = { list = {
selection = { preselect = false, auto_insert = true } selection = { preselect = false, auto_insert = true }
}, },
documentation = { auto_show = true }, ghost_text = { enabled = true, show_with_menu = true },
documentation = { auto_show = true, window = { border = "rounded" } },
trigger = { show_in_snippet = false }, trigger = { show_in_snippet = false },
}, },
snippets = { preset = "mini_snippets" }, snippets = { preset = "mini_snippets" },
sources = { sources = {
per_filetype = {
codecompanion = { "codecompanion" },
},
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot" }, default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot" },
providers = { providers = {
path = { path = {
@ -467,12 +216,6 @@ now_if_args(function()
score_offset = 45, score_offset = 45,
async = true, async = true,
}, },
codecompanion = {
name = "CodeCompanion",
module = "codecompanion.providers.completion.blink",
score_offset = 45,
async = true,
},
references = { references = {
name = "pandoc_references", name = "pandoc_references",
module = "cmp-pandoc-references.blink", module = "cmp-pandoc-references.blink",

View file

@ -15,7 +15,7 @@ now_if_args(function()
basedpyright = {}, basedpyright = {},
ruff = {}, ruff = {},
marksman = { marksman = {
filetypes = { "markdown", "markdown_inline", "codecompanion" }, filetypes = { "markdown", "markdown_inline" },
}, },
harper_ls = { harper_ls = {
cmd = { "harper-ls", "--stdio" }, cmd = { "harper-ls", "--stdio" },

43
plugin/29_bloocky.lua Normal file
View file

@ -0,0 +1,43 @@
-- Bloocky: timeblocking calendar (day/week/month views), persisted to JSON.
-- Loaded via the `general` cat spec (nix mode) or MiniDeps (non-nix).
-- Default global toggle is <leader>tb, which collides with the terminal map
-- (toggle bracketed paste), so it is moved to the calendar/tasks group <leader>c.
local Config = require('config')
if not Config.isNixCats then
local later = MiniDeps.later
later(function()
MiniDeps.add({ source = 'atiladefreitas/bloocky' })
end)
end
local nix = require('config.nix')
local later = MiniDeps.later
later(function()
if not nix.get_cat('general', false) then
return
end
require('bloocky').setup({
week_start = "monday",
window = {
-- Width per view: fraction of the editor width (or absolute columns if > 1).
-- A single number applies to every view.
width = {
month = 0.99,
week = 0.99,
day = 0.8,
},
border = "rounded",
},
integrations = {
dooing = {
enabled = true, -- show Dooing todos on their due date
show_done = false, -- also show completed todos
},
},
keymaps = {
toggle = '<leader>cb',
},
})
end)

28
plugin/30_dooing.lua Normal file
View file

@ -0,0 +1,28 @@
-- Dooing: minimalist todo list manager with a floating window, persisted to JSON.
-- Loaded via the `general` cat spec (nix mode) or MiniDeps (non-nix).
-- Default globals <leader>td / <leader>tN occupy the terminal group, so the
-- todo toggles are moved to the calendar/tasks group <leader>c.
local Config = require('config')
if not Config.isNixCats then
local later = MiniDeps.later
later(function()
MiniDeps.add({ source = 'atiladefreitas/dooing' })
end)
end
local nix = require('config.nix')
local later = MiniDeps.later
later(function()
if not nix.get_cat('general', false) then
return
end
require('dooing').setup({
keymaps = {
toggle_window = '<leader>cd',
open_project_todo = '<leader>cD',
show_due_notification = '<leader>cN',
},
})
end)

View file

@ -55,6 +55,10 @@ local function wait_for_deferred(timeout_ms)
-- Fire VimEnter so startup autocmds run, then drain the event loop so -- Fire VimEnter so startup autocmds run, then drain the event loop so
-- mini.deps' deferred setup closures have a chance to execute before we -- mini.deps' deferred setup closures have a chance to execute before we
-- assert anything. -- assert anything.
-- The headless smoke run has no start screen to display. Disabling
-- mini.starter also prevents it from replacing the current buffer and
-- trying to create a swap file in the read-only Nix sandbox.
vim.g.ministarter_disable = true
vim.cmd('doautocmd VimEnter') vim.cmd('doautocmd VimEnter')
vim.wait(timeout_ms, function() return false end, 50) vim.wait(timeout_ms, function() return false end, 50)
end end
@ -91,8 +95,12 @@ end
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
local function has_lsp_config(name) local function has_lsp_config(name)
if vim.lsp and vim.lsp.config then if vim.lsp and vim.lsp.config then
-- vim.lsp.config(name) returns the merged config or {} if none registered. -- Neovim 0.12 exposes configs through the callable `vim.lsp.config`
local ok, cfg = pcall(vim.lsp.config, name) -- table; older versions expose a function-like API.
local ok, cfg = pcall(function() return vim.lsp.config[name] end)
if not ok or type(cfg) ~= 'table' or next(cfg) == nil then
ok, cfg = pcall(vim.lsp.config, name)
end
if ok and cfg and next(cfg) ~= nil then if ok and cfg and next(cfg) ~= nil then
return true return true
end end