Remove all org files using a new script to more config over, The old org file configuaration were great but required org. This new version only requires the scripts that is included in the repo. The configuration are all done but have not ported the theming system yet. Signed-off-by: Steve Beaulac <steve@sagacity.ca> Change-Id: I14cd7fe058a71c8ba9d6d35397dc8d7e6a6a6964
1559 lines
72 KiB
Lua
1559 lines
72 KiB
Lua
return {
|
|
|
|
{
|
|
"Davidyz/VectorCode",
|
|
version = "*",
|
|
build = "uv tool upgrade vectorcode", -- This helps keeping the CLI up-to-date
|
|
-- build = "pipx upgrade vectorcode", -- If you used pipx to install the CLI
|
|
dependencies = { "nvim-lua/plenary.nvim" },
|
|
},
|
|
{ 'j-hui/fidget.nvim', lazy = true },
|
|
{
|
|
"olimorris/codecompanion.nvim",
|
|
version = "^18.0.0",
|
|
opts = {},
|
|
dependencies = {
|
|
"nvim-lua/plenary.nvim",
|
|
"nvim-treesitter/nvim-treesitter",
|
|
"franco-ruggeri/codecompanion-spinner.nvim",
|
|
"ravitemer/codecompanion-history.nvim",
|
|
"cairijun/codecompanion-agentskills.nvim",
|
|
"ttgrules/cc-adapter-copilot-cli-acp",
|
|
-- { "stevearc/dressing.nvim", opts = {} },
|
|
},
|
|
event = "VeryLazy",
|
|
keys = {
|
|
{ "<leader>rc", "<cmd>CodeCompanionChat Toggle<cr>", mode = {'n', 'v'}, { noremap = true, silent = true }, desc = "CC Toggle" },
|
|
{ "<leader>ra", "<cmd>CodeCompanionActions<cr>", mode = { 'n', 'v' }, { noremap = true, silent = true }, desc = "CC Action" },
|
|
{ "<leader>ri", "<cmd>CodeCompanionChat Add<cr>", mode = { 'v' }, { noremap = true, silent = true }, desc = "CC Add" },
|
|
{ "<leader>re", "<cmd>CodeCompanion Explain<cr>", mode = { 'n' }, desc = "CC Explain" },
|
|
{ "<leader>rf", "<cmd>CodeCompanion Fix code<cr>", mode = { 'n' }, desc = "CC fix" },
|
|
{ '<leader>cr', '<cmd>CodeCompanion Code Review<cr>', mode = { 'v' }, desc = 'Code Review' },
|
|
{ '<leader>co', '<cmd>CodeCompanion Optimize Performance<cr>', mode = { 'v' }, desc = 'Optimize Code' },
|
|
{ '<leader>ce', '<cmd>CodeCompanion Explain Code<cr>', mode = { 'v' }, desc = 'Explain Code' },
|
|
{ '<leader>cg', '<cmd>CodeCompanion Generate Tests<cr>', mode = { 'v' }, desc = 'Generate Tests' },
|
|
{ '<leader>cd', '<cmd>CodeCompanion Debug Analysis<cr>', mode = { 'v' }, desc = 'Debug Analysis' },
|
|
},
|
|
config = function()
|
|
local function get_abacus_key()
|
|
local handle = io.popen("pass show abacus.ai-api")
|
|
if not handle then return "" end
|
|
local result = handle:read("*a")
|
|
handle:close()
|
|
-- Remove trailing newline that 'pass' often adds
|
|
return result:gsub("%s+", "")
|
|
end
|
|
|
|
local codecompanion = require("codecompanion")
|
|
codecompanion.setup({
|
|
adapters = {
|
|
http = {
|
|
opts = {
|
|
show_presets = true,
|
|
show_model_choices = true,
|
|
},
|
|
-- openai = function()
|
|
-- return require("codecompanion.adapters").extend("openai", {
|
|
-- env = { api_key = "cmd:pass show api.openai.com" }
|
|
-- })
|
|
-- end,
|
|
openrouter = function()
|
|
return require("codecompanion.adapters").extend("openai_compatible", {
|
|
env = {
|
|
url = "https://openrouter.ai/api",
|
|
api_key = "OPENROUTER_API_KEY",
|
|
chat_url = "/v1/chat/completions",
|
|
},
|
|
schema = {
|
|
model = {
|
|
default = "anthropic/claude-3.7-sonnet",
|
|
},
|
|
},
|
|
})
|
|
end,
|
|
abacus = function()
|
|
return require("codecompanion.adapters").extend("openai_compatible", {
|
|
name = "abacus",
|
|
formatted_name = "Abacus.AI",
|
|
env = {
|
|
url = "https://routellm.abacus.ai/v1",
|
|
-- IMPORTANT: include /v1 in the base url
|
|
api_key = get_abacus_key(),
|
|
chat_url = "/chat/completions"
|
|
},
|
|
headers = {
|
|
["Content-Type"] = "application/json",
|
|
["Authorization"] = "Bearer ${api_key}",
|
|
},
|
|
schema = {
|
|
model = {
|
|
order = 1,
|
|
mapping = "parameters",
|
|
type = "enum",
|
|
desc = "The model to use for chat completions.",
|
|
default = "route-llm",
|
|
choices = {
|
|
-- Routing Model
|
|
["route-llm"] = { opts = { desc = "Intelligent routing to best model" } },
|
|
|
|
-- OpenAI Models
|
|
["gpt-5.2"] = { opts = { has_vision = true } },
|
|
["gpt-5.1"] = { opts = { has_vision = true } },
|
|
["gpt-5.1-chat-latest"] = { opts = { has_vision = true } },
|
|
["gpt-5"] = { opts = { has_vision = true } },
|
|
["gpt-5-mini"] = { opts = { has_vision = true } },
|
|
["gpt-5-nano"] = { opts = { has_vision = true } },
|
|
["gpt-4o"] = { opts = { has_vision = true } },
|
|
["gpt-4o-mini"] = { opts = { has_vision = true } },
|
|
["o4-mini"] = { opts = { can_reason = true } },
|
|
["o3"] = { opts = { can_reason = true } },
|
|
["o3-pro"] = { opts = { can_reason = true } },
|
|
|
|
-- Anthropic Models
|
|
["claude-4-5-sonnet"] = { opts = { has_vision = true } },
|
|
["claude-4-5-haiku"] = { opts = { has_vision = true } },
|
|
["claude-4-5-opus"] = { opts = { has_vision = true } },
|
|
["claude-3-opus"] = { opts = { has_vision = true } },
|
|
|
|
-- Google Models
|
|
["gemini-3-pro"] = { opts = { has_vision = true } },
|
|
["gemini-3-flash"] = { opts = { has_vision = true } },
|
|
["gemini-2.5-pro"] = { opts = { has_vision = true } },
|
|
["gemini-2.5-flash"] = { opts = { has_vision = true } },
|
|
|
|
-- xAI Models
|
|
["grok-4-1-fast"] = {},
|
|
["grok-4"] = {},
|
|
["grok-code-fast-1"] = {},
|
|
|
|
-- Meta Models
|
|
["llama-4-Maverick-17B"] = {},
|
|
["llama-3.1-405B"] = {},
|
|
["llama-3.1-70B"] = {},
|
|
|
|
-- DeepSeek Models
|
|
["deepseek-v3.2"] = {},
|
|
["deepseek-v3.1-Terminus"] = {},
|
|
["deepseek-R1"] = { opts = { can_reason = true } },
|
|
|
|
-- Qwen Models
|
|
["qwen-3-Max"] = {},
|
|
["qwen3-coder-480b-a35b-instruct"] = {},
|
|
["qwen-3-32B"] = {},
|
|
["qwq-32B"] = { opts = { can_reason = true } },
|
|
},
|
|
},
|
|
temperature = {
|
|
order = 2,
|
|
mapping = "parameters",
|
|
type = "number",
|
|
optional = true,
|
|
default = 1.0,
|
|
desc = "Controls randomness of output (0-2).",
|
|
validate = function(n)
|
|
return n >= 0 and n <= 2, "Must be between 0 and 2"
|
|
end,
|
|
},
|
|
max_tokens = {
|
|
order = 3,
|
|
mapping = "parameters",
|
|
type = "integer",
|
|
optional = true,
|
|
default = nil,
|
|
desc = "Maximum tokens to generate.",
|
|
validate = function(n)
|
|
return n > 0, "Must be greater than 0"
|
|
end,
|
|
},
|
|
top_p = {
|
|
order = 4,
|
|
mapping = "parameters",
|
|
type = "number",
|
|
optional = true,
|
|
default = 1.0,
|
|
desc = "Nucleus sampling parameter (0-1).",
|
|
validate = function(n)
|
|
return n >= 0 and n <= 1, "Must be between 0 and 1"
|
|
end,
|
|
},
|
|
},
|
|
})
|
|
end,
|
|
ollama = function()
|
|
return require("codecompanion.adapters").extend("ollama", {
|
|
env = {
|
|
url = "http://129.100.33.66:11434",
|
|
},
|
|
schema = {
|
|
model = {
|
|
default = "qwen3-coder-next", -- change to whatever you pulled
|
|
},
|
|
},
|
|
})
|
|
end,
|
|
copilot = function()
|
|
return require("codecompanion.adapters").extend("copilot", {
|
|
schema = {
|
|
model = {
|
|
default = "gpt-5-mini", -- Consistent model choice
|
|
},
|
|
max_tokens = {
|
|
default = 16284,
|
|
}
|
|
}
|
|
})
|
|
end,
|
|
},
|
|
acp = {
|
|
opts = {
|
|
show_presets = true,
|
|
},
|
|
copilot_cli = function()
|
|
return require("codecompanion.adapters").extend("copilot_cli", {})
|
|
end,
|
|
codex = function()
|
|
return require("codecompanion.adapters").extend("codex", {
|
|
commands = {
|
|
default = { "codex-acp" },
|
|
},
|
|
schema = {
|
|
model = {
|
|
default = "github-copilot/gpt-5.2-codex",
|
|
},
|
|
},
|
|
defaults = {
|
|
timeout = 20000,
|
|
auth_method = "chatgpt", -- "openai-api-key"|"codex-api-key"|"chatgpt"
|
|
},
|
|
})
|
|
end,
|
|
opencode = function()
|
|
return require("codecompanion.adapters").extend("codex", {
|
|
commands = {
|
|
default = { "opencode", "acp" },
|
|
},
|
|
schema = {
|
|
model = {
|
|
default = "github-copilot/gpt-5.2-codex",
|
|
},
|
|
},
|
|
defaults = {
|
|
timeout = 20000,
|
|
auth_method = "chatgpt", -- "openai-api-key"|"codex-api-key"|"chatgpt"
|
|
},
|
|
})
|
|
end,
|
|
},
|
|
},
|
|
rules = {
|
|
opts = {
|
|
chat = {
|
|
enabled = true,
|
|
autoload = { "default" }
|
|
},
|
|
},
|
|
},
|
|
opts = {
|
|
send_code = true,
|
|
log_level = "WARN", -- Change to DEBUG for troubleshooting
|
|
language = "English",
|
|
-- NEW: Performance improvements
|
|
job_start_delay = 500, -- Reduced from default 1500ms
|
|
submit_delay = 1000, -- Reduced from default 2000ms
|
|
},
|
|
extensions = {
|
|
spinner = {},
|
|
-- ddgr_search = {
|
|
-- opts = {
|
|
-- require_approval_before = false,
|
|
-- },
|
|
-- },
|
|
agentskills = {
|
|
opts = {
|
|
{ "~/Documents/ai-skills", recursive = true },
|
|
},
|
|
},
|
|
-- vectorcode = { lazy = true },
|
|
history = {
|
|
lazy = true,
|
|
enabled = true,
|
|
opts = {
|
|
keymap = "ghf",
|
|
save_chat_keymap = "ghs",
|
|
picker = "snacks",
|
|
dir_to_save = vim.env.HOME .. "/Documents/ai-history",
|
|
title_generation_opts = {
|
|
adapter = "copilot",
|
|
model = "gpt-5-mini",
|
|
},
|
|
summary = {
|
|
create_summary_keymap = "ghc",
|
|
browse_summaries_keymap = "ghb",
|
|
},
|
|
},
|
|
},
|
|
-- mcphub = {
|
|
-- callback = "mcphub.extensions.codecompanion",
|
|
-- opts = {
|
|
-- make_vars = true,
|
|
-- make_slash_commands = true,
|
|
-- show_result_in_chat = true,
|
|
-- },
|
|
-- },
|
|
},
|
|
interactions = {
|
|
chat = {
|
|
variables = {
|
|
project = {
|
|
callback = function()
|
|
-- Get project files structure
|
|
local files = vim.fn.systemlist("fd . -type f")
|
|
return table.concat(files, "\n")
|
|
end,
|
|
description = "Share project structure"
|
|
}
|
|
},
|
|
tools = {
|
|
opts = {
|
|
auto_submit_errors = true, -- Send any errors to the LLM automatically?
|
|
auto_submit_success = true, -- Send any successful output to the LLM automatically?
|
|
system_prompt = {
|
|
enabled = true,
|
|
replace_main_system_prompt = false,
|
|
},
|
|
default_tools = {
|
|
"file_search",
|
|
"read_file",
|
|
"cmd_runner",
|
|
-- "ddgr_search",
|
|
},
|
|
},
|
|
["fetch_enhanced"] = {
|
|
callback = function(url, options)
|
|
options = options or {}
|
|
local max_length = options.max_length or 200000 -- 200KB default
|
|
local timeout = options.timeout or 60
|
|
|
|
-- Use curl for better control
|
|
local cmd = string.format(
|
|
'curl -L -s --max-time %d --user-agent "CodeCompanion-Neovim" "%s"',
|
|
timeout,
|
|
url
|
|
)
|
|
|
|
local handle = io.popen(cmd)
|
|
if not handle then
|
|
return nil, "Failed to execute curl"
|
|
end
|
|
|
|
local result = handle:read("*a")
|
|
local success = handle:close()
|
|
|
|
if not success then
|
|
return nil, "Curl command failed"
|
|
end
|
|
|
|
-- Truncate if too long
|
|
if #result > max_length then
|
|
result = result:sub(1, max_length) .. "\n[... truncated at " .. max_length .. " characters ...]"
|
|
end
|
|
|
|
return result
|
|
end,
|
|
opts = {
|
|
requires_approval = false,
|
|
}
|
|
},
|
|
["fetch_unlimited"] = {
|
|
description = "Fetch a data from the web",
|
|
callback = function(url, options)
|
|
options = options or {}
|
|
|
|
-- Use a local proxy service or direct system calls
|
|
local temp_file = vim.fn.tempname()
|
|
local cmd = string.format(
|
|
'wget --timeout=60 --tries=3 --output-document="%s" "%s" 2>/dev/null && cat "%s" && rm "%s"',
|
|
temp_file, url, temp_file, temp_file
|
|
)
|
|
|
|
local handle = io.popen(cmd)
|
|
if not handle then
|
|
return nil, "Failed to fetch URL"
|
|
end
|
|
|
|
local result = handle:read("*a")
|
|
handle:close()
|
|
|
|
-- Optional: Process and clean the content
|
|
-- Remove excessive whitespace, clean HTML if needed
|
|
-- result = result:gsub("%s+", " "):gsub("^\s+", ""):gsub("%s+$", "")
|
|
|
|
return result
|
|
end,
|
|
opts = {
|
|
requires_approval = false,
|
|
description = "Fetch web content with unlimited size"
|
|
}
|
|
},
|
|
["fetch"] = {
|
|
description = "Fetch a webpage in a markdown format",
|
|
callback = function(url, options)
|
|
local cmd = string.format(
|
|
'reader -o -i none %s 2>/dev/null',
|
|
url
|
|
)
|
|
local handle = io.popen(cmd)
|
|
if not handle then
|
|
return nil, "Failed to fetch URL"
|
|
end
|
|
|
|
local result = handle:read("*a")
|
|
handle:close()
|
|
|
|
return result
|
|
end,
|
|
},
|
|
-- ["mcp"] = { -- Name this tool whatever you like
|
|
-- -- Callback provides the necessary functions to CodeCompanion
|
|
-- callback = function()
|
|
-- return require("mcphub.extensions.codecompanion")
|
|
-- end,
|
|
-- opts = {
|
|
-- -- If true, CodeCompanion will ask for approval before executing the MCP tool call
|
|
-- requires_approval = true,
|
|
-- -- Optional: Pass parameters like temperature to the underlying LLM if the chat strategy supports it
|
|
-- temperature = 0.7
|
|
-- }
|
|
-- },
|
|
groups = {
|
|
['plan'] = {
|
|
description = "Planning my project and codes with enhanced web access",
|
|
prompt = "Using all the ${tools} at your disposal including enhanced web fetching. Analyze the codes and use it to help me with my query. You have access to unlimited web content fetching.",
|
|
tools = {
|
|
"fetch", -- Backup unlimited fetch
|
|
"file_search",
|
|
"grep_search",
|
|
"list_code_usages",
|
|
"next_edit_suggestion",
|
|
"read_file",
|
|
"cmd_runner",
|
|
},
|
|
opts = {
|
|
collapse_tools = true,
|
|
-- Override default fetch behavior for this group
|
|
tool_config = {
|
|
fetch_enhanced = {
|
|
max_length = 500000, -- 500KB for planning tasks
|
|
chunk_processing = true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
['research'] = {
|
|
description = "Deep research with unlimited web access",
|
|
prompt = "You are a research assistant with unlimited web access. Using the ${tools} fetch and analyze large documents, research papers, and comprehensive web content.",
|
|
tools = {
|
|
"fetch",
|
|
"fetch_enhanced",
|
|
"file_search",
|
|
"read_file",
|
|
},
|
|
opts = {
|
|
collapse_tools = false,
|
|
},
|
|
},
|
|
-- NEW: Add development group for coding tasks
|
|
['dev'] = {
|
|
description = "Full-stack development with all necessary tools",
|
|
prompt = "You are an expert full-stack developer. Use ${tools} to understand, modify, and test code. Always gather context before making changes.",
|
|
tools = {
|
|
"file_search",
|
|
"grep_search",
|
|
"fetch",
|
|
"list_code_usages",
|
|
"read_file",
|
|
"insert_edit_into_file",
|
|
"cmd_runner",
|
|
"next_edit_suggestion",
|
|
},
|
|
opts = {
|
|
collapse_tools = true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
slash_commands = {
|
|
["buffer"] = { opts = { provider = "snacks" } }, -- snacks
|
|
["file"] = { opts = { provider = "snacks" } }, -- snackes
|
|
['git_files'] = {
|
|
description = 'List git files',
|
|
---@param chat CodeCompanion.Chat
|
|
callback = function(chat)
|
|
local handle = io.popen 'git ls-files'
|
|
if handle ~= nil then
|
|
local result = handle:read '*a'
|
|
handle:close()
|
|
chat:add_reference({ content = result }, 'git', '<git_files>')
|
|
return vim.notify('Git files added to the chat.')
|
|
else
|
|
return vim.notify('No git files available', vim.log.levels.INFO, { title = 'CodeCompanion' })
|
|
end
|
|
end,
|
|
opts = {
|
|
contains_code = false,
|
|
},
|
|
},
|
|
-- NEW: Add helpful workspace command
|
|
["workspace"] = {
|
|
description = "Add workspace context",
|
|
callback = function(chat)
|
|
local cwd = vim.fn.getcwd()
|
|
local workspace_info = string.format("Working directory: %s", cwd)
|
|
|
|
-- Get project type
|
|
local files = vim.fn.glob(cwd .. "/*", false, true)
|
|
for _, file in ipairs(files) do
|
|
local basename = vim.fn.fnamemodify(file, ":t")
|
|
if basename == "package.json" then
|
|
workspace_info = workspace_info .. "\nProject type: Node.js/JavaScript"
|
|
break
|
|
elseif basename == "Cargo.toml" then
|
|
workspace_info = workspace_info .. "\nProject type: Rust"
|
|
break
|
|
elseif basename == "go.mod" then
|
|
workspace_info = workspace_info .. "\nProject type: Go"
|
|
break
|
|
end
|
|
end
|
|
|
|
chat:add_reference({ content = workspace_info }, 'workspace', '<workspace>')
|
|
return vim.notify('Workspace context added.')
|
|
end,
|
|
opts = {
|
|
contains_code = false,
|
|
},
|
|
},
|
|
},
|
|
-- adapter = { name = "abacus", model = "route-llm" },
|
|
-- adapter = { name = "opencode", model = "github-copilot/gpt-5.2-codex" },
|
|
adapter = { name = "copilot", model = "gpt-5-mini" },
|
|
},
|
|
inline = {
|
|
-- adapter = { name = "abacus", model = "route-llm" },
|
|
adapter = { name = "copilot", model = "gpt-5.1-codex-mini" },
|
|
},
|
|
cmd = {
|
|
adapter = { name = "copilot", model = "gpt-5-mini" },
|
|
},
|
|
background = {
|
|
adapter = { name = "copilot", model = "gpt-5-mini" },
|
|
},
|
|
},
|
|
prompt_library = {
|
|
markdown = {
|
|
dirs = {
|
|
vim.fn.getcwd() .. "/.prompts",
|
|
"~/.agents/prompts",
|
|
},
|
|
},
|
|
["Code Review"] = {
|
|
interaction = "chat",
|
|
description = "Review the selected code for improvements",
|
|
opts = {
|
|
mapping = "<LocalLeader>rpc",
|
|
modes = { "v" },
|
|
adapter = {
|
|
name = "copilot",
|
|
model = "chatgpt-5.1-codex",
|
|
},
|
|
},
|
|
prompts = {
|
|
{
|
|
role = "system",
|
|
content = "You are an expert code reviewer. Analyze the code for: 1) Logic errors 2) Performance issues 3) Security vulnerabilities 4) Best practices 5) Code clarity and maintainability. Provide specific, actionable feedback.",
|
|
},
|
|
{
|
|
role = "user",
|
|
content = function(context)
|
|
local code = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
|
|
return "Please review this code:\n\n```" .. context.filetype .. "\n" .. code .. "\n```"
|
|
end,
|
|
},
|
|
},
|
|
cc_keywords = { "review", "critique", "smell", "security", "vulnerability", "best practice", "maintainab" },
|
|
cc_threshold = 2,
|
|
},
|
|
["Optimize Performance"] = {
|
|
interaction = "chat",
|
|
description = "Get performance optimization suggestions",
|
|
opts = {
|
|
mapping = "<LocalLeader>rpo",
|
|
modes = { "v" },
|
|
adapter = {
|
|
name = "copilot",
|
|
model = "chatgpt-5.2-codex",
|
|
},
|
|
},
|
|
prompts = {
|
|
{
|
|
role = "system",
|
|
content = "You are a performance optimization expert. Focus on: 1) Time complexity improvements 2) Space efficiency 3) Algorithm optimization 4) Framework-specific optimizations 5) Caching strategies.",
|
|
},
|
|
{
|
|
role = "user",
|
|
content = function(context)
|
|
local code = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
|
|
return "How can I optimize the performance of this code?\n\n```" .. context.filetype .. "\n" .. code .. "\n```"
|
|
end,
|
|
},
|
|
},
|
|
cc_keywords = { "optimize", "performance", "slow", "latency", "throughput", "memory", "alloc" },
|
|
},
|
|
["Debug Analysis"] = {
|
|
interaction = "chat",
|
|
description = "Analyze and debug problematic code",
|
|
opts = {
|
|
mapping = "<LocalLeader>rpd",
|
|
modes = { "v" },
|
|
|
|
adapter = {
|
|
name = "copilot",
|
|
model = "chatgpt-5.2-codex",
|
|
},
|
|
},
|
|
prompts = {
|
|
{
|
|
role = "system",
|
|
content = [[You are a debugging expert. Analyze code for:
|
|
1. Potential bugs and issues
|
|
2. Logic errors
|
|
3. Runtime errors
|
|
4. Common pitfalls
|
|
5. Debugging strategies.
|
|
6. Provide specific solutions.]],
|
|
},
|
|
{
|
|
role = "user",
|
|
content = function(context)
|
|
local code = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
|
|
return fmt(
|
|
[[Help me debug this code from buffer %d and identify potential issues:
|
|
|
|
```%s
|
|
%s
|
|
```]],
|
|
context.bufnr,
|
|
context.filetype,
|
|
code
|
|
)
|
|
end,
|
|
opts = {
|
|
contains_code = true,
|
|
}
|
|
},
|
|
},
|
|
cc_keyword = { "bug", "debug", "error", "exception", "crash", "stacktrace", "broken", "issue" },
|
|
},
|
|
["Architecture Review"] = {
|
|
interaction = "chat",
|
|
description = "Review architectural patterns and design",
|
|
opts = {
|
|
mapping = "<LocalLeader>rpa",
|
|
modes = { "v" },
|
|
|
|
adapter = {
|
|
name = "copilot",
|
|
model = "chatgpt-5.2-codex",
|
|
},
|
|
},
|
|
prompts = {
|
|
{
|
|
role = "system",
|
|
content = "You are a software architect. Review code for: 1) Design patterns usage 2) SOLID principles 3) Separation of concerns 4) Scalability considerations 5) Maintainability. Suggest architectural improvements.",
|
|
},
|
|
{
|
|
role = "user",
|
|
content = function(context)
|
|
local code = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
|
|
return fmt(
|
|
[[Please review the architecture and design of this code from buffer %d:
|
|
|
|
```%s
|
|
%s
|
|
```]],
|
|
context.bufnr,
|
|
context.filetype,
|
|
code
|
|
)
|
|
end,
|
|
opts = {
|
|
contains_code = true,
|
|
}
|
|
},
|
|
},
|
|
cc_keywords = { "architecture", "design", "pattern", "solid", "scalab", "maintainab", "refactor" },
|
|
},
|
|
},
|
|
display = {
|
|
action_palette = {
|
|
provider = "snacks",
|
|
opts = {
|
|
show_default_actions = true,
|
|
show_default_prompt_library = true,
|
|
}
|
|
},
|
|
chat = {
|
|
show_settings = false,
|
|
render_headers = false,
|
|
icons = {
|
|
chat_context = "📎️",
|
|
},
|
|
fold_context = true,
|
|
-- NEW: Better chat window configuration
|
|
window = {
|
|
layout = "vertical",
|
|
width = 0.45,
|
|
height = 0.8,
|
|
border = "rounded", -- Better visual
|
|
},
|
|
auto_scroll = false,
|
|
start_in_insert_mode = false, -- More convenient
|
|
}
|
|
}
|
|
})
|
|
end
|
|
},
|
|
|
|
{
|
|
"zbirenbaum/copilot.lua",
|
|
dependencies = {
|
|
"copilotlsp-nvim/copilot-lsp",
|
|
config = function()
|
|
vim.g.copilot_nes_debounce = 500
|
|
end,
|
|
},
|
|
cmd = "Copilot",
|
|
event = "InsertEnter",
|
|
config = function()
|
|
require('copilot').setup({
|
|
nes = {
|
|
enabled = true,
|
|
keymap = {
|
|
accept_and_goto = "<leader>p",
|
|
accept = false,
|
|
dismiss = "<Esc>",
|
|
},
|
|
},
|
|
panel = {
|
|
enabled = false,
|
|
},
|
|
-- suggestion = {
|
|
-- enabled = false,
|
|
-- },
|
|
-- filetypes = {
|
|
-- -- yaml = false,
|
|
-- -- markdown = false,
|
|
-- help = false,
|
|
-- gitcommit = false,
|
|
-- gitrebase = false,
|
|
-- hgcommit = false,
|
|
-- svn = false,
|
|
-- cvs = false,
|
|
-- ["."] = false,
|
|
-- },
|
|
-- copilot_node_command = 'node', -- Node.js version must be > 18.x
|
|
-- copilot_model = "o4-mini-2025-04-16",
|
|
-- copilot_model = "gpt-5.1-codex-mini",
|
|
-- server_opts_overrides = {
|
|
-- settings = {
|
|
-- advanced = {
|
|
-- listCount = 10,
|
|
-- inlineSuggestCount = 3,
|
|
-- -- model = "claude-3.5-sonnet-20241022",
|
|
-- model = "o3-mini-2025-01-31",
|
|
-- --model = "GPT-4o-copilot"
|
|
-- }
|
|
-- }
|
|
-- },
|
|
})
|
|
end,
|
|
},
|
|
|
|
{
|
|
"PhantomYdn/fabric-ai.nvim",
|
|
cmd = { "Fabric" },
|
|
opts = {
|
|
-- Default configuration (all optional)
|
|
fabric_path = "fabric-ai", -- Path to Fabric CLI
|
|
patterns_path = nil, -- Custom patterns dir (auto-detect if nil)
|
|
timeout = 300000, -- Command timeout in ms (5 minutes)
|
|
window = {
|
|
width = 0.8, -- 80% of editor width
|
|
height = 0.8, -- 80% of editor height
|
|
border = "rounded",
|
|
},
|
|
},
|
|
keys = {
|
|
-- fabric-ai.nvim doesn't have default keymappings
|
|
{ "<leader>fa", ":'<,'>Fabric<CR>", mode = "v", desc = "Fabric AI" },
|
|
{ "<leader>fa", ":Fabric<CR>", mode = "n", desc = "Fabric AI" },
|
|
{ "<leader>fu", ":Fabric url<CR>", mode = "n", desc = "Fabric URL" },
|
|
},
|
|
},
|
|
|
|
{
|
|
'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 = {
|
|
{
|
|
'<leader>bf',
|
|
function()
|
|
require('conform').format { async = true, lsp_format = 'fallback' }
|
|
end,
|
|
mode = { 'n', 'v' },
|
|
desc = 'Format buffer',
|
|
},
|
|
},
|
|
opts = {
|
|
notify_on_error = false,
|
|
-- format_on_save = function(bufnr)
|
|
-- -- Disable "format_on_save lsp_fallback" for languages that don't
|
|
-- -- have a well standardized coding style. You can add additional
|
|
-- -- languages here or re-enable it for the disabled ones.
|
|
-- local disable_filetypes = { c = true, cpp = true }
|
|
-- local lsp_format_opt
|
|
-- if disable_filetypes[vim.bo[bufnr].filetype] then
|
|
-- lsp_format_opt = 'never'
|
|
-- else
|
|
-- lsp_format_opt = 'fallback'
|
|
-- end
|
|
-- return {
|
|
-- timeout_ms = 500,
|
|
-- lsp_format = lsp_format_opt,
|
|
-- }
|
|
-- end,
|
|
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 = {
|
|
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",
|
|
opts = {
|
|
auto_attach = false,
|
|
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', '<leader>vs', function()
|
|
gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
|
|
end, { desc = 'stage git hunk' })
|
|
|
|
map('v', '<leader>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', '<leader>vs', gitsigns.stage_hunk, { desc = 'git stage hunk' })
|
|
map('n', '<leader>vr', gitsigns.reset_hunk, { desc = 'git reset hunk' })
|
|
map('n', '<leader>vS', gitsigns.stage_buffer, { desc = 'git stage buffer' })
|
|
map('n', '<leader>vu', gitsigns.undo_stage_hunk, { desc = 'git undo stage hunk' })
|
|
map('n', '<leader>vR', gitsigns.reset_buffer, { desc = 'git reset buffer' })
|
|
map('n', '<leader>vP', gitsigns.preview_hunk, { desc = 'git preview hunk' })
|
|
map('n', '<leader>vb', gitsigns.blame_line, { desc = 'git blame line' })
|
|
map('n', '<leader>vP', gitsigns.diffthis, { desc = 'git diff against index' })
|
|
map('n', '<leader>vD', function()
|
|
gitsigns.diffthis '@'
|
|
end, { desc = 'git [D]iff against last commit' })
|
|
-- Toggles
|
|
map('n', '<leader>uvb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' })
|
|
map('n', '<leader>uvd', gitsigns.toggle_deleted, { desc = '[T]oggle git show [D]eleted' })
|
|
end,
|
|
}
|
|
},
|
|
|
|
{
|
|
"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", "<leader>va", annotate.file, { desc = "JJ annotate file" })
|
|
vim.keymap.set("n", "<leader>vA", annotate.line, { desc = "JJ annotate line" })
|
|
vim.keymap.set("n", "<leader>vbc", cmd.bookmark_create, { desc = "JJ bookmark create" })
|
|
vim.keymap.set("n", "<leader>vbd", cmd.bookmark_delete, { desc = "JJ bookmark delete" })
|
|
vim.keymap.set("n", "<leader>vbm", cmd.bookmark_move, { desc = "JJ bookmark move" })
|
|
vim.keymap.set("n", "<leader>vd", cmd.describe, { desc = "JJ describe" })
|
|
vim.keymap.set("n", "<leader>vl", cmd.log, { desc = "JJ log" })
|
|
vim.keymap.set("n", "<leader>ve", cmd.edit, { desc = "JJ edit" })
|
|
vim.keymap.set("n", "<leader>vn", cmd.new, { desc = "JJ new" })
|
|
vim.keymap.set("n", "<leader>vs", cmd.status, { desc = "JJ status" })
|
|
vim.keymap.set("n", "<leader>vS", cmd.squash, { desc = "JJ squash" })
|
|
vim.keymap.set("n", "<leader>vju", cmd.undo, { desc = "JJ undo" })
|
|
vim.keymap.set("n", "<leader>vjr", cmd.redo, { desc = "JJ redo" })
|
|
vim.keymap.set("n", "<leader>vr", cmd.rebase, { desc = "JJ rebase" })
|
|
vim.keymap.set("n", "<leader>vf", cmd.fetch, { desc = "JJ fetch" })
|
|
vim.keymap.set("n", "<leader>vx", cmd.abandon, { desc = "JJ abandon" })
|
|
vim.keymap.set("n", "<leader>vp", cmd.push, { desc = "JJ push" })
|
|
vim.keymap.set("n", "<leader>vpr", cmd.open_pr, { desc = "JJ open PR from bookmark in current revision or parent" })
|
|
vim.keymap.set("n", "<leader>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", "<leader>vjd", function() diff.open_vdiff() end, { desc = "JJ diff current buffer" })
|
|
vim.keymap.set("n", "<leader>vjD", function() diff.open_hsplit() end, { desc = "JJ hdiff current buffer" })
|
|
|
|
-- Pickers
|
|
local picker = require("jj.picker")
|
|
vim.keymap.set("n", "<leader>gj", function() picker.status() end, { desc = "JJ Picker status" })
|
|
vim.keymap.set("n", "<leader>vjh", function() picker.file_history() end, { desc = "JJ Picker history" })
|
|
|
|
-- Some functions like `log` can take parameters
|
|
vim.keymap.set("n", "<leader>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", "<leader>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',
|
|
dependencies = {
|
|
{ 'SmiteshP/nvim-navic', lazy = true },
|
|
},
|
|
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)
|
|
if vim.fn.has 'nvim-0.11' == 1 then
|
|
return client:supports_method(method, bufnr)
|
|
else
|
|
return client.supports_method(method, { bufnr = bufnr })
|
|
end
|
|
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" },
|
|
}
|
|
}
|
|
},
|
|
ts_ls= {},
|
|
html= {},
|
|
eslint= {},
|
|
jsonls= {},
|
|
jdtls= {},
|
|
}
|
|
|
|
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.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", "<leader>cct", crates.toggle, { desc = 'toggle' })
|
|
vim.keymap.set("n", "<leader>ccr", crates.reload, { desc = 'reload' })
|
|
vim.keymap.set("n", "<leader>ccv", crates.show_versions_popup, { desc = 'show versions' })
|
|
vim.keymap.set("n", "<leader>ccf", crates.show_features_popup, { desc = 'show features' })
|
|
vim.keymap.set("n", "<leader>ccd", crates.show_dependencies_popup, { desc = 'show dependencies' })
|
|
vim.keymap.set("n", "<leader>ccu", crates.update_crate, { desc = 'update' })
|
|
vim.keymap.set("v", "<leader>ccu", crates.update_crates, { desc = 'update' })
|
|
vim.keymap.set("n", "<leader>cca", crates.update_all_crates, { desc = 'update all' })
|
|
vim.keymap.set("n", "<leader>ccU", crates.upgrade_crate, { desc = 'upgrade' })
|
|
vim.keymap.set("v", "<leader>ccU", crates.upgrade_crates, { desc = 'upgrade' })
|
|
vim.keymap.set("n", "<leader>ccA", crates.upgrade_all_crates, { desc = 'upgrade all' })
|
|
vim.keymap.set("n", "<leader>ccx", crates.expand_plain_crate_to_inline_table, { desc = 'expand' })
|
|
vim.keymap.set("n", "<leader>ccX", crates.extract_crate_into_table, { desc = 'extract' })
|
|
vim.keymap.set("n", "<leader>ccH", crates.open_homepage, { desc = 'open homepage' })
|
|
vim.keymap.set("n", "<leader>ccR", crates.open_repository, { desc = 'open repository' })
|
|
vim.keymap.set("n", "<leader>ccD", crates.open_documentation, { desc = 'open documents' })
|
|
vim.keymap.set("n", "<leader>ccC", crates.open_crates_io, { desc = 'open crates.io' })
|
|
vim.keymap.set("n", "<leader>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", "<leader>lr", function()
|
|
vim.cmd.RustLsp("codeAction")
|
|
end, { desc = "Code Action", buffer = bufnr })
|
|
vim.keymap.set("n", "<leader>ld", function()
|
|
vim.cmd.RustLsp("debuggables")
|
|
end, { desc = "Rust Debuggables", buffer = bufnr })
|
|
vim.keymap.set("n", "<leader>lD", function()
|
|
vim.cmd.RustLsp("openDocs")
|
|
end, { desc = "Open Documents", buffer = bufnr })
|
|
vim.keymap.set("n", "<leader>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',
|
|
dependencies = {
|
|
'nvim-treesitter/nvim-treesitter-textobjects',
|
|
-- 'p00f/nvim-ts-rainbow',
|
|
},
|
|
config = function()
|
|
require('nvim-treesitter.configs').setup({
|
|
-- Add languages to be installed here that you want installed for treesitter
|
|
ensure_installed = {
|
|
'c',
|
|
"lua",
|
|
"markdown",
|
|
"markdown_inline",
|
|
"vim",
|
|
"vimdoc",
|
|
"query",
|
|
"html",
|
|
"go",
|
|
"bash",
|
|
"zig",
|
|
"typescript",
|
|
"javascript",
|
|
"dockerfile",
|
|
"xml",
|
|
"regex",
|
|
"rust"
|
|
},
|
|
ignore_install = { 'org' },
|
|
auto_install = true,
|
|
-- disable = function(lang, buf)
|
|
-- local max_filesize = 100 * 1024
|
|
-- local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buff_get_name(buf))
|
|
-- if ok and stats and stats.size > max_filesize then
|
|
-- return true
|
|
-- end
|
|
-- end,
|
|
highlight = { enable = true, },
|
|
indent = { enable = true },
|
|
})
|
|
end,
|
|
},
|
|
|
|
{
|
|
'JoosepAlviste/nvim-ts-context-commentstring',
|
|
lazy = true,
|
|
opts = {
|
|
enable_autocmd = false,
|
|
}
|
|
},
|
|
|
|
{
|
|
'nvim-treesitter/nvim-treesitter-context',
|
|
enabled = true,
|
|
opts = { mode = "cursor", max_lines = 3 },
|
|
},
|
|
|
|
{
|
|
"folke/todo-comments.nvim",
|
|
lazy = true,
|
|
keys = {
|
|
{ "<leader>st", function() Snacks.picker.todo_comments() end, desc = "Todo" },
|
|
{ "<leader>sT", function() Snacks.picker.todo_comments({ keywords = { "TODO", "FIX", "FIXME" } }) end, desc = "Todo/Fix/Fixme" },
|
|
},
|
|
opts = {},
|
|
},
|
|
|
|
{
|
|
"mbbill/undotree",
|
|
lazy = true,
|
|
keys = {
|
|
{ '<leader>uu', vim.cmd.UndotreeToggle, desc = 'Format buffer' }
|
|
},
|
|
},
|
|
|
|
}
|
|
|