updated configuration

This commit is contained in:
2026-01-12 23:12:11 -07:00
parent 6d79fde026
commit dc98d50a31
14 changed files with 1219 additions and 224 deletions

182
README.md
View File

@@ -1,4 +1,180 @@
# 💤 LazyVim
# Neovim Configuration with LazyVim
A starter template for [LazyVim](https://github.com/LazyVim/LazyVim).
Refer to the [documentation](https://lazyvim.github.io/installation) to get started.
A comprehensive Neovim setup with LSP support, AI chat, database integration, and debugging.
## Prerequisites
- Neovim >= 0.9.0 (installed via Homebrew)
- Git
- A Nerd Font (for icons)
- Node.js (for some LSP servers and formatters)
- Go (for gopls and delve)
## Installation
1. **Backup existing configuration** (if any):
```bash
mv ~/.config/nvim ~/.config/nvim.bak
mv ~/.local/share/nvim ~/.local/share/nvim.bak
mv ~/.local/state/nvim ~/.local/state/nvim.bak
mv ~/.cache/nvim ~/.cache/nvim.bak
```
2. **Clone this configuration**:
```bash
git clone <your-repo-url> ~/.config/nvim
```
3. **Start Neovim**:
```bash
nvim
```
Lazy.nvim will automatically install all plugins on first launch.
4. **Install LSP servers and tools**:
After plugins load, run:
```
:Mason
```
All required tools should install automatically.
## Features
### Language Support (LSP + Treesitter)
- Go, Lua, TypeScript, JavaScript, HTML, CSS, JSON, YAML, Markdown, SQL, Makefile
### AI Chat Integration
Supports multiple providers via [avante.nvim](https://github.com/yetone/avante.nvim):
- Anthropic Claude
- OpenAI GPT
- Google Gemini
- And more
Set your API keys as environment variables:
```bash
export ANTHROPIC_API_KEY="your-key"
export OPENAI_API_KEY="your-key"
export GEMINI_API_KEY="your-key"
```
Switch providers: `:AvanteProvider claude|openai|gemini`
### Database Integration (vim-dadbod)
- `:DBUIToggle` - Open database UI
- `:DBUIAddConnection` - Add a new connection
Connection string examples:
```
postgresql://user:pass@localhost:5432/dbname
mysql://user:pass@localhost:3306/dbname
sqlite:path/to/db.sqlite
```
### Go Debugging (DAP + Delve)
Full debugging support with breakpoints, stepping, variable inspection.
## Key Bindings
### Terminal
| Key | Action |
|-----|--------|
| `<leader>th` | Open terminal (horizontal split) |
| `<leader>tv` | Open terminal (vertical split) |
| `<C-\>` | Toggle floating terminal |
| `<Esc><Esc>` | Exit terminal mode |
### File Explorer (Snacks explorer)
| Key | Action |
|-----|--------|
| `<C-S-e>` | Toggle explorer |
| `<C-S-v>` or `<C-v>` | Open file in vertical split |
| `<C-S-h>` or `<C-x>` | Open file in horizontal split |
| `<leader>e` | Focus explorer (LazyVim default) |
### AI Chat
| Key | Action |
|-----|--------|
| `<leader>aa` | Ask AI (with selection in visual mode) |
| `<leader>ac` | Open AI chat |
| `<leader>at` | Toggle AI sidebar |
### Database
| Key | Action |
|-----|--------|
| `<leader>db` | Toggle database UI |
| `<leader>da` | Add database connection |
### Debugging
| Key | Action |
|-----|--------|
| `<leader>db` | Toggle breakpoint |
| `<leader>dB` | Breakpoint with condition |
| `<leader>dc` | Continue |
| `<leader>di` | Step into |
| `<leader>do` | Step out |
| `<leader>dO` | Step over |
| `<leader>du` | Toggle DAP UI |
| `<leader>dT` | Debug Go test |
| `<leader>dt` | Terminate debug session |
### Formatting
| Key | Action |
|-----|--------|
| `<leader>cf` | Format buffer |
| `:FormatToggle` | Toggle auto-format on save |
| `:FormatDisable` | Disable auto-format |
| `:FormatEnable` | Enable auto-format |
### General
| Key | Action |
|-----|--------|
| `<C-s>` | Save file |
| `<S-h>` / `<S-l>` | Previous/Next buffer |
| `<C-h/j/k/l>` | Navigate windows |
| `<A-j>` / `<A-k>` | Move line down/up |
## File Structure
```
~/.config/nvim/
├── init.lua # Entry point
├── lua/
│ ├── config/
│ │ ├── lazy.lua # Lazy.nvim bootstrap & LazyVim setup
│ │ ├── options.lua # General Neovim options
│ │ ├── keymaps.lua # Custom key bindings
│ │ └── autocmds.lua # Auto commands
│ └── plugins/
│ ├── lsp.lua # LSP & Treesitter configuration
│ ├── ai.lua # AI chat integration (avante.nvim)
│ ├── dadbod.lua # Database integration
│ ├── dap.lua # Debugging configuration
│ ├── formatting.lua # Auto-formatting (conform.nvim)
│ └── editor.lua # Editor enhancements (snacks explorer, etc.)
```
## Formatters by File Type
| File Type | Formatter |
|-----------|-----------|
| Go | gofumpt, goimports |
| Lua | stylua |
| JS/TS/JSX/TSX | prettier |
| HTML/CSS | prettier |
| JSON/YAML | prettier |
| Markdown | prettier |
| SQL | sql-formatter |
## Troubleshooting
### LSP not working
Run `:LspInfo` to check status. Run `:Mason` to verify tools are installed.
### Formatting not working
Run `:ConformInfo` to check formatter status.
### Icons not displaying
Install a Nerd Font and configure your terminal to use it.
### Ctrl+Shift keybindings not working
Some terminals don't properly send Ctrl+Shift combinations. Use the alternative mappings (`<C-v>` and `<C-x>` in snacks explorer).

View File

@@ -1,2 +1,2 @@
-- bootstrap lazy.nvim, LazyVim and your plugins
-- Bootstrap lazy.nvim and LazyVim
require("config.lazy")

View File

@@ -1,12 +1,11 @@
{
"LazyVim": { "branch": "main", "commit": "28db03f958d58dfff3c647ce28fdc1cb88ac158d" },
"SchemaStore.nvim": { "branch": "main", "commit": "6e4ffd193995176ee5ea5b8adba0f315adc68b9f" },
"SchemaStore.nvim": { "branch": "main", "commit": "20ee0cad0b25e4a028d355c51b06d41eecb90d91" },
"avante.nvim": { "branch": "main", "commit": "e89eb79abf5754645e20aa6074da10ed20bba33c" },
"blink.cmp": { "branch": "main", "commit": "b19413d214068f316c78978b08264ed1c41830ec" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"catppuccin": { "branch": "main", "commit": "beaf41a30c26fd7d6c386d383155cbd65dd554cd" },
"conform.nvim": { "branch": "master", "commit": "8314f4c9e205e7f30b62147069729f9a1227d8bf" },
"copilot.lua": { "branch": "master", "commit": "c13f6f5147b80298301eb409991f28a991736cc3" },
"conform.nvim": { "branch": "master", "commit": "238f542a118984a88124fc915d5b981680418707" },
"dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" },
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
@@ -16,7 +15,8 @@
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
"lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" },
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "e5f73a9e3d271d449685f1059eb1868f4ba276f6" },
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "fe661093f4b05136437b531e7f959af2a2ae66c8" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "9a10e096703966335bd5c46c8c875d5b0690dade" },
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
"mini.ai": { "branch": "main", "commit": "bfb26d9072670c3aaefab0f53024b2f3729c8083" },
@@ -26,26 +26,24 @@
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-dap": { "branch": "master", "commit": "cdfd55a133f63228c55f91378f12908cb2a78ded" },
"nvim-dap-go": { "branch": "main", "commit": "b4421153ead5d726603b02743ea40cf26a51ed5f" },
"nvim-dap-python": { "branch": "master", "commit": "1808458eba2b18f178f990e01376941a42c7f93b" },
"nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },
"nvim-lint": { "branch": "master", "commit": "ca6ea12daf0a4d92dc24c5c9ae22a1f0418ade37" },
"nvim-lspconfig": { "branch": "master", "commit": "92ee7d42320edfbb81f3cad851314ab197fa324a" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-treesitter": { "branch": "main", "commit": "2ba5ec184609a96b513bf4c53a20512d64e27f39" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "28a3494c075ef0f353314f627546537e43c09592" },
"nvim-treesitter": { "branch": "main", "commit": "5a7e5638e7d220575b1c22c8a2e099b52231886e" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "d0d12338230c1ce4ce27373f5b8d50a8c691794b" },
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
"nvim-web-devicons": { "branch": "master", "commit": "6788013bb9cb784e606ada44206b0e755e4323d7" },
"nvim-web-devicons": { "branch": "master", "commit": "803353450c374192393f5387b6a0176d0972b848" },
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"render-markdown.nvim": { "branch": "main", "commit": "73a6ebc842cf81926eb1d424820b800f6f6a1227" },
"render-markdown.nvim": { "branch": "main", "commit": "ae89236e2389836cf1c3787b2b80d5d8685cc13f" },
"snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" },
"telescope.nvim": { "branch": "master", "commit": "3333a52ff548ba0a68af6d8da1e54f9cd96e9179" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" },
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
"trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
"ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" },
"venv-selector.nvim": { "branch": "main", "commit": "58bae72c84b9f7f864c879ec1896e384296f9ffb" },
"vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" },
"vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" },
"vim-dadbod-ui": { "branch": "master", "commit": "48c4f271da13d380592f4907e2d1d5558044e4e5" },

View File

@@ -1,8 +1,108 @@
-- Autocmds are automatically loaded on the VeryLazy event
-- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua
--
-- Add any additional autocmds here
-- with `vim.api.nvim_create_autocmd`
--
-- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults)
-- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell")
-- Autocommands
local augroup = vim.api.nvim_create_augroup
local autocmd = vim.api.nvim_create_autocmd
-- Highlight on yank
augroup("YankHighlight", { clear = true })
autocmd("TextYankPost", {
group = "YankHighlight",
callback = function()
vim.highlight.on_yank({ higroup = "IncSearch", timeout = 200 })
end,
})
-- Resize splits when window is resized
augroup("ResizeSplits", { clear = true })
autocmd("VimResized", {
group = "ResizeSplits",
callback = function()
vim.cmd("tabdo wincmd =")
end,
})
-- Go to last location when opening a buffer
augroup("LastLocation", { clear = true })
autocmd("BufReadPost", {
group = "LastLocation",
callback = function(event)
local exclude = { "gitcommit" }
local buf = event.buf
if vim.tbl_contains(exclude, vim.bo[buf].filetype) or vim.b[buf].lazyvim_last_loc then
return
end
vim.b[buf].lazyvim_last_loc = true
local mark = vim.api.nvim_buf_get_mark(buf, '"')
local lcount = vim.api.nvim_buf_line_count(buf)
if mark[1] > 0 and mark[1] <= lcount then
pcall(vim.api.nvim_win_set_cursor, 0, mark)
end
end,
})
-- Close certain filetypes with q
augroup("CloseWithQ", { clear = true })
autocmd("FileType", {
group = "CloseWithQ",
pattern = {
"help",
"lspinfo",
"man",
"notify",
"qf",
"spectre_panel",
"startuptime",
"checkhealth",
},
callback = function(event)
vim.bo[event.buf].buflisted = false
vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
end,
})
-- Auto create parent directories when saving
augroup("AutoCreateDir", { clear = true })
autocmd("BufWritePre", {
group = "AutoCreateDir",
callback = function(event)
if event.match:match("^%w%w+://") then
return
end
local file = vim.uv.fs_realpath(event.match) or event.match
vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p")
end,
})
-- Set specific options for certain filetypes
augroup("FileTypeSettings", { clear = true })
-- Go files: use tabs
autocmd("FileType", {
group = "FileTypeSettings",
pattern = "go",
callback = function()
vim.opt_local.expandtab = false
vim.opt_local.tabstop = 4
vim.opt_local.shiftwidth = 4
end,
})
-- Makefile: use tabs
autocmd("FileType", {
group = "FileTypeSettings",
pattern = "make",
callback = function()
vim.opt_local.expandtab = false
vim.opt_local.tabstop = 4
vim.opt_local.shiftwidth = 4
end,
})
-- Markdown: enable wrap
autocmd("FileType", {
group = "FileTypeSettings",
pattern = "markdown",
callback = function()
vim.opt_local.wrap = true
vim.opt_local.spell = true
end,
})

View File

@@ -1,13 +1,70 @@
-- Keymaps are automatically loaded on the VeryLazy event
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
-- Add any additional keymaps here
-- Custom keymaps
local map = vim.keymap.set
vim.keymap.set("n", "<leader>th", function()
vim.cmd("lcd %:p:h")
-- Terminal keymaps
-- <leader>th - Open terminal in horizontal split
map("n", "<leader>th", function()
vim.cmd("split | terminal")
end, { desc = "Terminal (horizontal)" })
vim.cmd("startinsert")
end, { desc = "Terminal (horizontal split)" })
vim.keymap.set("n", "<leader>tv", function()
vim.cmd("lcd %:p:h")
-- <leader>tv - Open terminal in vertical split
map("n", "<leader>tv", function()
vim.cmd("vsplit | terminal")
end, { desc = "Terminal (vertical)" })
vim.cmd("startinsert")
end, { desc = "Terminal (vertical split)" })
-- Terminal mode: Escape to normal mode
map("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
-- Explorer keymaps (Snacks explorer)
-- Ctrl+Shift+e - Toggle explorer
map("n", "<C-S-e>", function() Snacks.explorer() end, { desc = "Toggle Explorer" })
map("i", "<C-S-e>", function() Snacks.explorer() end, { desc = "Toggle Explorer" })
-- Note: Ctrl+Shift+v and Ctrl+Shift+h for opening files in splits
-- are configured in the snacks picker config (lua/plugins/editor.lua)
-- as they need to work within the explorer buffer context
-- Additional useful keymaps
-- Better window navigation
map("n", "<C-h>", "<C-w>h", { desc = "Go to left window" })
map("n", "<C-j>", "<C-w>j", { desc = "Go to lower window" })
map("n", "<C-k>", "<C-w>k", { desc = "Go to upper window" })
map("n", "<C-l>", "<C-w>l", { desc = "Go to right window" })
-- Resize windows with arrows
map("n", "<C-Up>", "<cmd>resize +2<cr>", { desc = "Increase window height" })
map("n", "<C-Down>", "<cmd>resize -2<cr>", { desc = "Decrease window height" })
map("n", "<C-Left>", "<cmd>vertical resize -2<cr>", { desc = "Decrease window width" })
map("n", "<C-Right>", "<cmd>vertical resize +2<cr>", { desc = "Increase window width" })
-- Buffer navigation
map("n", "<S-h>", "<cmd>bprevious<cr>", { desc = "Prev buffer" })
map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "Next buffer" })
-- Clear search highlight
map("n", "<Esc>", "<cmd>nohlsearch<cr>", { desc = "Clear search highlight" })
-- Save file
map({ "n", "i", "v", "s" }, "<C-s>", "<cmd>w<cr><esc>", { desc = "Save file" })
-- Better indenting in visual mode
map("v", "<", "<gv")
map("v", ">", ">gv")
-- Move lines up/down
map("n", "<A-j>", "<cmd>m .+1<cr>==", { desc = "Move line down" })
map("n", "<A-k>", "<cmd>m .-2<cr>==", { desc = "Move line up" })
map("v", "<A-j>", ":m '>+1<cr>gv=gv", { desc = "Move selection down" })
map("v", "<A-k>", ":m '<-2<cr>gv=gv", { desc = "Move selection up" })
-- Quick access to AI chat
map("n", "<leader>aa", "<cmd>AvanteAsk<cr>", { desc = "AI Ask" })
map("v", "<leader>aa", "<cmd>AvanteAsk<cr>", { desc = "AI Ask (selection)" })
map("n", "<leader>ac", "<cmd>AvanteChat<cr>", { desc = "AI Chat" })
map("n", "<leader>at", "<cmd>AvanteToggle<cr>", { desc = "AI Toggle" })
-- Database keymaps
map("n", "<leader>db", "<cmd>DBUIToggle<cr>", { desc = "Toggle DB UI" })
map("n", "<leader>da", "<cmd>DBUIAddConnection<cr>", { desc = "Add DB Connection" })

View File

@@ -1,3 +1,4 @@
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
@@ -14,45 +15,46 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then
end
vim.opt.rtp:prepend(lazypath)
-- Set leader keys before loading plugins
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- Setup lazy.nvim with LazyVim
require("lazy").setup({
spec = {
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- Language support (these enable LSP, formatting, linting & DAP)
-- Import LazyVim and its plugins
{
"LazyVim/LazyVim",
import = "lazyvim.plugins",
opts = {
colorscheme = "tokyonight",
},
},
-- Import LazyVim extras for languages
{ import = "lazyvim.plugins.extras.lang.go" },
{ import = "lazyvim.plugins.extras.lang.python" },
{ import = "lazyvim.plugins.extras.lang.json" },
{ import = "lazyvim.plugins.extras.lang.yaml" },
{ import = "lazyvim.plugins.extras.lang.markdown" },
{ import = "lazyvim.plugins.extras.lang.typescript" },
{ import = "lazyvim.plugins.extras.lang.tailwind" },
{ import = "lazyvim.plugins.extras.lang.json" },
-- DAP (Debug Adapter Protocol)
-- DAP for debugging
{ import = "lazyvim.plugins.extras.dap.core" },
-- import/override with your plugins
-- Import custom plugins
{ import = "plugins" },
},
defaults = {
-- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.
-- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.
lazy = false,
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
-- have outdated releases, which may break your Neovim install.
version = false, -- always use the latest git commit
-- version = "*", -- try installing the latest stable version for plugins that support semver
version = false,
},
install = { colorscheme = { "tokyonight", "habamax" } },
checker = {
enabled = true, -- check for plugin updates periodically
notify = false, -- notify on update
}, -- automatically check for plugin updates
enabled = true,
notify = false,
},
performance = {
rtp = {
-- disable some rtp plugins
disabled_plugins = {
"gzip",
-- "matchit",
-- "matchparen",
-- "netrwPlugin",
"tarPlugin",
"tohtml",
"tutor",
@@ -61,3 +63,8 @@ require("lazy").setup({
},
},
})
-- Load custom config
require("config.options")
require("config.keymaps")
require("config.autocmds")

View File

@@ -1,3 +1,47 @@
-- Options are automatically loaded before lazy.nvim startup
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
-- Add any additional options here
local opt = vim.opt
-- General
opt.clipboard = "unnamedplus" -- Sync with system clipboard
opt.confirm = true -- Confirm before closing unsaved buffer
opt.cursorline = true -- Highlight current line
opt.mouse = "a" -- Enable mouse
opt.number = true -- Show line numbers
opt.relativenumber = true -- Relative line numbers
opt.signcolumn = "yes" -- Always show sign column
opt.termguicolors = true -- True color support
opt.wrap = false -- Disable line wrap
-- Indentation
opt.expandtab = true -- Use spaces instead of tabs
opt.shiftwidth = 2 -- Size of indent
opt.tabstop = 2 -- Number of spaces tabs count for
opt.smartindent = true -- Smart indentation
-- Search
opt.ignorecase = true -- Ignore case
opt.smartcase = true -- Don't ignore case with capitals
opt.hlsearch = true -- Highlight search results
opt.incsearch = true -- Show search results as you type
-- Split behavior
opt.splitbelow = true -- Put new windows below current
opt.splitright = true -- Put new windows right of current
-- Undo
opt.undofile = true -- Persistent undo
opt.undolevels = 10000 -- Maximum undo levels
-- Performance
opt.updatetime = 200 -- Faster completion
opt.timeoutlen = 300 -- Faster key sequence completion
-- Completion
opt.completeopt = "menu,menuone,noselect"
-- Folding (using treesitter)
opt.foldmethod = "expr"
opt.foldexpr = "nvim_treesitter#foldexpr()"
opt.foldlevel = 99 -- Start with all folds open

View File

@@ -1,10 +1,14 @@
-- AI Chat Integration using avante.nvim
-- Supports: Anthropic Claude, OpenAI, Google Gemini, Copilot, and more
-- API keys via environment variables:
-- ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY
-- Or scoped: AVANTE_ANTHROPIC_API_KEY, AVANTE_OPENAI_API_KEY, etc.
return {
-- Avante: Cursor-like AI assistant
{
"yetone/avante.nvim",
event = "VeryLazy",
lazy = false,
version = false,
version = false, -- Never set to "*"
build = "make",
dependencies = {
"nvim-treesitter/nvim-treesitter",
@@ -12,49 +16,180 @@ return {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
"nvim-tree/nvim-web-devicons",
"zbirenbaum/copilot.lua", -- Optional for copilot suggestions
{
-- Image support (optional)
"HakonHarnes/img-clip.nvim",
event = "VeryLazy",
opts = {
default = {
embed_image_as_base64 = false,
prompt_for_file_name = false,
drag_and_drop = { insert_mode = true },
drag_and_drop = {
insert_mode = true,
},
},
},
},
{
-- Markdown rendering in Avante
"MeanderingProgrammer/render-markdown.nvim",
opts = { file_types = { "markdown", "Avante" } },
opts = {
file_types = { "markdown", "Avante" },
},
ft = { "markdown", "Avante" },
},
},
---@module 'avante'
---@type avante.Config
opts = {
debug = true,
-- Default provider (switch with :AvanteProvider command)
-- Options: "claude", "openai", "azure", "gemini", "copilot", "cohere"
provider = "claude",
mode = "agentic",
auto_suggestions_provider = "copilot",
-- Provider configurations
providers = {
claude = {
model = "claude-sonnet-4-5",
endpoint = "https://api.anthropic.com",
model = "claude-sonnet-4-5-20250929",
timeout = 30000,
extra_request_body = {
temperature = 0.75,
max_tokens = 20480,
},
},
openai = {
endpoint = "https://api.openai.com/v1",
model = "gpt-4o",
timeout = 30000,
extra_request_body = {
temperature = 0.75,
max_completion_tokens = 16384,
},
},
azure = {
endpoint = "", -- e.g., "https://<resource>.openai.azure.com"
deployment = "", -- Azure deployment name
api_version = "2024-12-01-preview",
timeout = 30000,
extra_request_body = {
temperature = 0.75,
max_completion_tokens = 16384,
},
},
gemini = {
endpoint = "https://generativelanguage.googleapis.com/v1beta/models",
model = "gemini-2.0-flash",
timeout = 30000,
extra_request_body = {
generationConfig = {
temperature = 0.75,
},
},
},
copilot = {
endpoint = "https://api.githubcopilot.com",
model = "gpt-4o-2024-08-06",
timeout = 30000,
extra_request_body = {
temperature = 0.75,
max_tokens = 20480,
},
},
-- Custom provider example for Ollama (local models)
-- Uncomment and configure if using local LLMs
-- ollama = {
-- __inherited_from = "openai",
-- endpoint = "http://localhost:11434/v1",
-- model = "llama3.2",
-- api_key_name = "",
-- },
},
-- Behavior settings
behaviour = {
auto_seggestions = true,
auto_suggestions = false, -- Set true for copilot-like suggestions
auto_set_highlight_group = true,
auto_set_keymaps = true,
auto_apply_diff_after_generation = false,
support_paste_from_clipboard = false,
minimize_diff = true,
enable_token_counting = true,
},
-- Mappings
mappings = {
ask = "<leader>aa",
edit = "<leader>ae",
refresh = "<leader>ar",
toggle = {
default = "<leader>at",
debug = "<leader>ad",
hint = "<leader>ah",
diff = {
ours = "co",
theirs = "ct",
all_theirs = "ca",
both = "cb",
cursor = "cc",
next = "]x",
prev = "[x",
},
suggestion = {
accept = "<M-l>",
next = "<M-]>",
prev = "<M-[>",
dismiss = "<C-]>",
},
jump = {
next = "]]",
prev = "[[",
},
submit = {
normal = "<CR>",
insert = "<C-s>",
},
sidebar = {
apply_all = "A",
apply_cursor = "a",
switch_windows = "<Tab>",
reverse_switch_windows = "<S-Tab>",
},
},
-- Hints shown in the UI
hints = { enabled = true },
-- Window configuration
windows = {
position = "right",
wrap = true,
width = 30,
sidebar_header = {
enabled = true,
align = "center",
rounded = true,
},
input = {
prefix = "> ",
height = 8,
},
edit = {
border = "rounded",
start_insert = true,
},
ask = {
floating = false,
start_insert = true,
border = "rounded",
},
},
-- Highlight groups
highlights = {
diff = {
current = "DiffText",
incoming = "DiffAdd",
},
},
-- Diff settings
diff = {
autojump = true,
list_opener = "copen",
override_timeoutlen = 500,
},
},
},

83
lua/plugins/dadbod.lua Normal file
View File

@@ -0,0 +1,83 @@
-- Database integration with vim-dadbod
-- Supports PostgreSQL, MySQL, SQLite, and more
return {
-- Core dadbod plugin
{
"tpope/vim-dadbod",
cmd = { "DB", "DBUI", "DBUIToggle", "DBUIAddConnection", "DBUIFindBuffer" },
},
-- UI for dadbod
{
"kristijanhusak/vim-dadbod-ui",
cmd = { "DBUI", "DBUIToggle", "DBUIAddConnection", "DBUIFindBuffer" },
dependencies = {
{ "tpope/vim-dadbod", lazy = true },
},
init = function()
-- UI configuration
vim.g.db_ui_use_nerd_fonts = 1
vim.g.db_ui_show_database_icon = 1
vim.g.db_ui_force_echo_notifications = 1
-- Save location for connections
vim.g.db_ui_save_location = vim.fn.stdpath("data") .. "/db_ui"
-- Execute on save
vim.g.db_ui_execute_on_save = 0
-- Icons
vim.g.db_ui_icons = {
expanded = "",
collapsed = "",
saved_query = "*",
new_query = "+",
tables = "~",
buffers = "»",
connection_ok = "",
connection_error = "",
}
end,
},
-- Autocompletion for dadbod
{
"kristijanhusak/vim-dadbod-completion",
dependencies = {
"tpope/vim-dadbod",
"hrsh7th/nvim-cmp",
},
ft = { "sql", "mysql", "plsql" },
init = function()
-- Setup completion for SQL files
vim.api.nvim_create_autocmd("FileType", {
pattern = { "sql", "mysql", "plsql" },
callback = function()
local cmp = require("cmp")
local sources = cmp.get_config().sources or {}
-- Add dadbod completion source
table.insert(sources, { name = "vim-dadbod-completion" })
cmp.setup.buffer({
sources = cmp.config.sources(sources),
})
end,
})
end,
},
-- Add dadbod-completion to nvim-cmp sources
{
"hrsh7th/nvim-cmp",
optional = true,
dependencies = {
"kristijanhusak/vim-dadbod-completion",
},
opts = function(_, opts)
opts.sources = opts.sources or {}
table.insert(opts.sources, { name = "vim-dadbod-completion" })
end,
},
}

View File

@@ -1,65 +1,158 @@
-- Debug Adapter Protocol (DAP) configuration for Go
-- Uses delve for Go debugging
return {
-- Ensure Mason installs debug adapters
{
"mason-org/mason.nvim",
opts = {
ensure_installed = {
"delve", -- Go debugger
"debugpy", -- Python debugger
"js-debug-adapter", -- JS/TS debugger
},
},
},
-- Mason DAP bridge - auto-configures adapters
{
"jay-babu/mason-nvim-dap.nvim",
dependencies = { "mason-org/mason.nvim", "mfussenegger/nvim-dap" },
opts = {
ensure_installed = { "delve", "debugpy", "js" },
automatic_installation = true,
handlers = {},
},
},
-- nvim-dap configuration
{
"mfussenegger/nvim-dap",
dependencies = {
"jay-babu/mason-nvim-dap.nvim",
-- Go-specific DAP configuration
{
"leoluz/nvim-dap-go",
opts = {},
},
{
"mfussenegger/nvim-dap-python",
config = function()
local mason_path = vim.fn.stdpath("data") .. "/mason/packages/debugpy/venv/bin/python"
require("dap-python").setup(mason_path)
end,
opts = {
-- Delve configurations
delve = {
-- Path to delve (uses Mason-installed by default)
path = "dlv",
-- Initialize with default args
initialize_timeout_sec = 20,
-- Whether to use debug adapter mode
port = "${port}",
-- Build flags for delve
build_flags = "",
},
-- DAP configurations for Go
dap_configurations = {
{
type = "go",
name = "Debug",
request = "launch",
program = "${file}",
},
{
type = "go",
name = "Debug Package",
request = "launch",
program = "${fileDirname}",
},
{
type = "go",
name = "Debug test",
request = "launch",
mode = "test",
program = "${file}",
},
{
type = "go",
name = "Debug test (go.mod)",
request = "launch",
mode = "test",
program = "./${relativeFileDirname}",
},
{
type = "go",
name = "Attach",
request = "attach",
mode = "local",
processId = require("dap.utils").pick_process,
},
},
},
},
},
keys = {
-- Debug keymaps
{ "<leader>dB", function() require("dap").set_breakpoint(vim.fn.input("Breakpoint condition: ")) end, desc = "Breakpoint Condition" },
{ "<leader>db", function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint" },
{ "<leader>dc", function() require("dap").continue() end, desc = "Continue" },
{ "<leader>dC", function() require("dap").run_to_cursor() end, desc = "Run to Cursor" },
{ "<leader>dg", function() require("dap").goto_() end, desc = "Go to Line (No Execute)" },
{ "<leader>di", function() require("dap").step_into() end, desc = "Step Into" },
{ "<leader>dj", function() require("dap").down() end, desc = "Down" },
{ "<leader>dk", function() require("dap").up() end, desc = "Up" },
{ "<leader>dl", function() require("dap").run_last() end, desc = "Run Last" },
{ "<leader>do", function() require("dap").step_out() end, desc = "Step Out" },
{ "<leader>dO", function() require("dap").step_over() end, desc = "Step Over" },
{ "<leader>dp", function() require("dap").pause() end, desc = "Pause" },
{ "<leader>dr", function() require("dap").repl.toggle() end, desc = "Toggle REPL" },
{ "<leader>ds", function() require("dap").session() end, desc = "Session" },
{ "<leader>dt", function() require("dap").terminate() end, desc = "Terminate" },
{ "<leader>dw", function() require("dap.ui.widgets").hover() end, desc = "Widgets" },
-- Go-specific
{ "<leader>dT", function() require("dap-go").debug_test() end, desc = "Debug Go Test" },
{ "<leader>dL", function() require("dap-go").debug_last_test() end, desc = "Debug Last Go Test" },
},
},
-- DAP UI for better debugging experience
{
"rcarriga/nvim-dap-ui",
dependencies = { "nvim-neotest/nvim-nio" },
dependencies = {
"mfussenegger/nvim-dap",
"nvim-neotest/nvim-nio",
},
keys = {
{
"<leader>du",
function()
require("dapui").toggle()
end,
desc = "DAP UI",
},
{
"<leader>de",
function()
require("dapui").eval()
end,
desc = "Eval",
mode = { "n", "v" },
{ "<leader>du", function() require("dapui").toggle({}) end, desc = "Dap UI" },
{ "<leader>de", function() require("dapui").eval() end, desc = "Eval", mode = { "n", "v" } },
},
opts = {
layouts = {
{
elements = {
{ id = "scopes", size = 0.25 },
{ id = "breakpoints", size = 0.25 },
{ id = "stacks", size = 0.25 },
{ id = "watches", size = 0.25 },
},
position = "left",
size = 40,
},
{
elements = {
{ id = "repl", size = 0.5 },
{ id = "console", size = 0.5 },
},
position = "bottom",
size = 10,
},
},
},
opts = {},
config = function(_, opts)
local dap = require("dap")
local dapui = require("dapui")
dapui.setup(opts)
-- Auto open/close DAP UI
dap.listeners.after.event_initialized["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,
},
-- Virtual text for debugging
{
"theHamsta/nvim-dap-virtual-text",
opts = {
enabled = true,
enabled_commands = true,
highlight_changed_variables = true,
highlight_new_as_changed = false,
show_stop_reason = true,
commented = false,
only_first_definition = true,
all_references = false,
filter_references_pattern = "<module",
virt_text_pos = "eol",
all_frames = false,
virt_lines = false,
virt_text_win_col = nil,
},
},
}

View File

@@ -1,78 +1,89 @@
-- Editor enhancements - Snacks explorer configuration
-- Custom keybindings for file explorer (snacks.nvim built into LazyVim)
return {
-- Telescope: show gitignored files
{
"nvim-telescope/telescope.nvim",
opts = {
defaults = {
file_ignore_patterns = {}, -- Don't ignore anything by default
},
pickers = {
find_files = {
hidden = true,
no_ignore = true, -- Include .gitignore files
},
live_grep = {
additional_args = function()
return { "--hidden", "--no-ignore" }
end,
},
},
},
keys = {
-- Override default to include hidden/ignored
{ "<leader>ff", "<cmd>Telescope find_files hidden=true no_ignore=true<cr>", desc = "Find Files (all)" },
{ "<leader>fF", "<cmd>Telescope find_files<cr>", desc = "Find Files (respect gitignore)" },
},
},
-- Configure snacks.nvim explorer (already included in LazyVim)
{
"folke/snacks.nvim",
priority = 1000,
lazy = false,
version = false,
---@module 'snacks'
---@type snacks.Config
opts = {
picker = {
hidden = true,
ignored = true,
live = true,
sources = {
files = {
hidden = true,
ignored = true,
},
},
},
explorer = {
ignored = true,
hidden = true,
replace_netrw = true,
},
styles = {
notification = {
wo = {
wrap = true,
picker = {
sources = {
explorer = {
-- Explorer picker configuration
hidden = true,
ignored = true, -- Show files ignored by .gitignore
follow_file = true,
-- Custom keymaps within the explorer
win = {
list = {
keys = {
-- Ctrl+Shift+v - Open in vertical split
["<C-S-v>"] = { "edit_vsplit", mode = { "n", "i" } },
-- Ctrl+Shift+h - Open in horizontal split
["<C-S-h>"] = { "edit_split", mode = { "n", "i" } },
-- Alternative mappings (in case terminal doesn't send Ctrl+Shift properly)
["<C-v>"] = { "edit_vsplit", mode = { "n", "i" } },
["<C-x>"] = { "edit_split", mode = { "n", "i" } },
},
},
},
},
},
},
},
},
{
"folke/todo-comments.nvim",
optional = true,
keys = {
{
"<leader>st",
function()
Snacks.picker.todo_comments()
end,
desc = "Todo",
-- Ctrl+Shift+e - Toggle explorer
{ "<C-S-e>", function() Snacks.explorer() end, desc = "Toggle Explorer" },
-- Alternative binding if terminal doesn't handle Ctrl+Shift
{ "<leader>fe", function() Snacks.explorer() end, desc = "File Explorer" },
},
},
-- Which-key for keybinding hints
{
"folke/which-key.nvim",
opts = {
spec = {
{ "<leader>a", group = "AI" },
{ "<leader>d", group = "Debug/Database" },
{ "<leader>t", group = "Terminal" },
},
{
"<leader>sT",
function()
Snacks.picker.todo_comments({ keywords = { "TODO", "FIX", "FIXME" } })
end,
desc = "Todo/Fix/Fixme",
},
},
-- Better terminal integration
{
"akinsho/toggleterm.nvim",
version = "*",
opts = {
size = function(term)
if term.direction == "horizontal" then
return 15
elseif term.direction == "vertical" then
return vim.o.columns * 0.4
end
end,
open_mapping = [[<c-\>]],
hide_numbers = true,
shade_filetypes = {},
shade_terminals = true,
shading_factor = 2,
start_in_insert = true,
insert_mappings = true,
persist_size = true,
direction = "float",
close_on_exit = true,
shell = vim.o.shell,
float_opts = {
border = "curved",
winblend = 0,
highlights = {
border = "Normal",
background = "Normal",
},
},
},
},

137
lua/plugins/formatting.lua Normal file
View File

@@ -0,0 +1,137 @@
-- Formatting configuration with conform.nvim
-- Autoformat on save with per-filetype formatters
return {
{
"stevearc/conform.nvim",
event = { "BufWritePre" },
cmd = { "ConformInfo" },
keys = {
{
"<leader>cf",
function()
require("conform").format({ async = true, lsp_fallback = true })
end,
mode = { "n", "v" },
desc = "Format buffer",
},
},
opts = {
-- Formatters by filetype
formatters_by_ft = {
-- Go
go = { "gofumpt", "goimports" },
-- Lua
lua = { "stylua" },
-- JavaScript/TypeScript
javascript = { "prettier" },
javascriptreact = { "prettier" },
typescript = { "prettier" },
typescriptreact = { "prettier" },
-- Web
html = { "prettier" },
css = { "prettier" },
scss = { "prettier" },
-- Data formats
json = { "prettier" },
jsonc = { "prettier" },
yaml = { "prettier" },
-- Markdown
markdown = { "prettier" },
["markdown.mdx"] = { "prettier" },
-- SQL
sql = { "sql_formatter" },
mysql = { "sql_formatter" },
plsql = { "sql_formatter" },
-- Makefile (no formatter - they require tabs)
-- make = {},
-- Fallback for all other filetypes
["_"] = { "trim_whitespace" },
},
-- Format on save
format_on_save = function(bufnr)
-- Disable for certain filetypes
local ignore_filetypes = { "sql", "mysql", "plsql" }
if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then
return
end
-- Disable with a global or buffer-local variable
if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
return
end
return {
timeout_ms = 3000,
lsp_fallback = true,
}
end,
-- Formatter options
formatters = {
-- Stylua configuration
stylua = {
prepend_args = { "--indent-type", "Spaces", "--indent-width", "2" },
},
-- Prettier configuration
prettier = {
prepend_args = { "--tab-width", "2", "--single-quote" },
},
-- SQL formatter configuration
sql_formatter = {
prepend_args = { "--language", "postgresql" },
},
-- goimports configuration
goimports = {
prepend_args = { "-local", "github.com" },
},
},
},
init = function()
-- Commands to toggle format on save
vim.api.nvim_create_user_command("FormatDisable", function(args)
if args.bang then
-- FormatDisable! will disable formatting just for this buffer
vim.b.disable_autoformat = true
else
vim.g.disable_autoformat = true
end
vim.notify("Autoformat disabled", vim.log.levels.INFO)
end, {
desc = "Disable autoformat-on-save",
bang = true,
})
vim.api.nvim_create_user_command("FormatEnable", function()
vim.b.disable_autoformat = false
vim.g.disable_autoformat = false
vim.notify("Autoformat enabled", vim.log.levels.INFO)
end, {
desc = "Re-enable autoformat-on-save",
})
vim.api.nvim_create_user_command("FormatToggle", function()
vim.g.disable_autoformat = not vim.g.disable_autoformat
if vim.g.disable_autoformat then
vim.notify("Autoformat disabled", vim.log.levels.INFO)
else
vim.notify("Autoformat enabled", vim.log.levels.INFO)
end
end, {
desc = "Toggle autoformat-on-save",
})
end,
},
}

194
lua/plugins/lsp.lua Normal file
View File

@@ -0,0 +1,194 @@
-- LSP Configuration
-- Extends LazyVim's built-in LSP support
return {
-- Mason: manage LSP servers, linters, formatters
{
"mason-org/mason.nvim",
opts = {
ensure_installed = {
-- LSP servers
"gopls", -- Go
"lua-language-server", -- Lua
"typescript-language-server", -- TypeScript/JavaScript
"html-lsp", -- HTML
"css-lsp", -- CSS
"json-lsp", -- JSON
"yaml-language-server", -- YAML
"marksman", -- Markdown
"sqlls", -- SQL
-- Linters
"golangci-lint",
"eslint_d",
"markdownlint",
-- Formatters
"gofumpt",
"goimports",
"prettier",
"stylua",
"sql-formatter",
-- DAP
"delve", -- Go debugger
},
},
},
-- LSP configuration
{
"neovim/nvim-lspconfig",
opts = {
servers = {
-- Go
gopls = {
settings = {
gopls = {
gofumpt = true,
codelenses = {
gc_details = false,
generate = true,
regenerate_cgo = true,
run_govulncheck = true,
test = true,
tidy = true,
upgrade_dependency = true,
vendor = true,
},
hints = {
assignVariableTypes = true,
compositeLiteralFields = true,
compositeLiteralTypes = true,
constantValues = true,
functionTypeParameters = true,
parameterNames = true,
rangeVariableTypes = true,
},
analyses = {
fieldalignment = true,
nilness = true,
unusedparams = true,
unusedwrite = true,
useany = true,
},
usePlaceholders = true,
completeUnimported = true,
staticcheck = true,
directoryFilters = { "-.git", "-.vscode", "-.idea", "-.vscode-test", "-node_modules" },
semanticTokens = true,
},
},
},
-- Lua
lua_ls = {
settings = {
Lua = {
workspace = {
checkThirdParty = false,
},
completion = {
callSnippet = "Replace",
},
diagnostics = {
globals = { "vim" },
},
},
},
},
-- TypeScript/JavaScript
ts_ls = {
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
},
-- HTML
html = {
filetypes = { "html", "templ" },
},
-- CSS
cssls = {},
-- JSON
jsonls = {},
-- YAML
yamlls = {
settings = {
yaml = {
keyOrdering = false,
schemas = {
["https://json.schemastore.org/github-workflow.json"] = "/.github/workflows/*",
["https://json.schemastore.org/docker-compose.json"] = "docker-compose*.yml",
},
},
},
},
-- Markdown
marksman = {},
-- SQL
sqlls = {},
},
},
},
-- Treesitter for better syntax highlighting
{
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"go",
"gomod",
"gowork",
"gosum",
"lua",
"luadoc",
"typescript",
"javascript",
"tsx",
"html",
"css",
"json",
"jsonc",
"yaml",
"markdown",
"markdown_inline",
"sql",
"make",
"vim",
"vimdoc",
"bash",
"regex",
"diff",
"gitcommit",
"git_rebase",
},
highlight = { enable = true },
indent = { enable = true },
},
},
}

View File

@@ -1,40 +0,0 @@
return {
-- vim-dadbod with project-local connections
{
"kristijanhusak/vim-dadbod-ui",
dependencies = {
{ "tpope/vim-dadbod", lazy = true },
{ "kristijanhusak/vim-dadbod-completion", ft = { "sql", "mysql", "plsql" }, lazy = true },
},
cmd = { "DBUI", "DBUIToggle", "DBUIAddConnection", "DBUIFindBuffer" },
init = function()
vim.g.db_ui_use_nerd_fonts = 1
-- Use project-local connection file
vim.g.db_ui_save_location = vim.fn.getcwd() .. "/.db"
-- Or look for a dadbod.json in project root
vim.g.db_ui_env_variable_url = "DATABASE_URL"
vim.g.db_ui_env_variable_name = "DATABASE_NAME"
-- Auto-load connections from .dadbod.json if it exists
local project_db_config = vim.fn.getcwd() .. "/.dadbod.json"
if vim.fn.filereadable(project_db_config) == 1 then
vim.g.dbs = vim.fn.json_decode(vim.fn.readfile(project_db_config))
end
end,
keys = {
{ "<leader>D", "<cmd>DBUIToggle<CR>", desc = "Toggle DBUI" },
},
},
{
"hrsh7th/nvim-cmp",
optional = true,
dependencies = { "kristijanhusak/vim-dadbod-completion" },
opts = function(_, opts)
opts.sources = opts.sources or {}
table.insert(opts.sources, { name = "vim-dadbod-completion" })
end,
},
}