Improved flow

This commit is contained in:
Morten Olsen
2026-01-26 23:04:14 +01:00
parent d9950b3e4d
commit b3b70bceeb
28 changed files with 4492 additions and 7 deletions

63
lua/plugins/database.lua Normal file
View File

@@ -0,0 +1,63 @@
-- Database client: vim-dadbod with UI for PostgreSQL, SQLite, etc.
return {
-- Dadbod: Database client
{
"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" },
keys = {
{ "<leader>Du", "<cmd>DBUIToggle<cr>", desc = "Toggle DBUI" },
{ "<leader>Da", "<cmd>DBUIAddConnection<cr>", desc = "Add DB Connection" },
{ "<leader>Df", "<cmd>DBUIFindBuffer<cr>", desc = "Find DB Buffer" },
{ "<leader>Dr", "<cmd>DBUIRenameBuffer<cr>", desc = "Rename DB Buffer" },
{ "<leader>Dl", "<cmd>DBUILastQueryInfo<cr>", desc = "Last Query Info" },
},
init = function()
vim.g.db_ui_use_nerd_fonts = 1
vim.g.db_ui_show_database_icon = 1
-- Store connections in a local file (should be gitignored)
vim.g.db_ui_save_location = vim.fn.stdpath("data") .. "/db_ui"
-- Use .dbout extension for query results
vim.g.db_ui_execute_on_save = false
-- Table helpers - useful query templates
vim.g.db_ui_table_helpers = {
postgresql = {
Count = "SELECT COUNT(*) FROM {table}",
First10 = "SELECT * FROM {table} LIMIT 10",
Schema = "\\d+ {table}",
},
sqlite = {
Count = "SELECT COUNT(*) FROM {table}",
First10 = "SELECT * FROM {table} LIMIT 10",
Schema = ".schema {table}",
},
}
end,
},
-- Which-key group labels for database
{
"folke/which-key.nvim",
opts = {
spec = {
{ "<leader>D", group = "database" },
},
},
},
-- Autocomplete for SQL buffers
{
"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

@@ -120,4 +120,45 @@ return {
terminal = {},
},
},
-- REST Client (kulala.nvim) - keymaps for API testing
-- Plugin is installed via lazyvim.plugins.extras.util.rest
{
"mistweaverco/kulala.nvim",
keys = {
{ "<leader>Rs", function() require("kulala").run() end, desc = "Send Request" },
{ "<leader>Ra", function() require("kulala").run_all() end, desc = "Send All Requests" },
{ "<leader>Rr", function() require("kulala").replay() end, desc = "Replay Last Request" },
{ "<leader>Ri", function() require("kulala").inspect() end, desc = "Inspect Request" },
{ "<leader>Rt", function() require("kulala").toggle_view() end, desc = "Toggle Headers/Body" },
{ "<leader>Rc", function() require("kulala").copy() end, desc = "Copy as cURL" },
{ "<leader>Re", function() require("kulala").set_selected_env() end, desc = "Select Environment" },
{ "<leader>Rv", function() require("kulala").show_stats() end, desc = "Show Stats" },
{ "[r", function() require("kulala").jump_prev() end, desc = "Prev Request" },
{ "]r", function() require("kulala").jump_next() end, desc = "Next Request" },
},
ft = { "http", "rest" },
},
-- Session management keymaps (persistence.nvim is installed via LazyVim)
{
"folke/persistence.nvim",
keys = {
{ "<leader>qs", function() require("persistence").load() end, desc = "Restore Session" },
{ "<leader>ql", function() require("persistence").load({ last = true }) end, desc = "Restore Last Session" },
{ "<leader>qd", function() require("persistence").stop() end, desc = "Don't Save Session" },
{ "<leader>qS", function() require("persistence").select() end, desc = "Select Session" },
},
},
-- Additional which-key groups
{
"folke/which-key.nvim",
opts = {
spec = {
{ "<leader>R", group = "REST client" },
{ "<leader>q", group = "session" },
},
},
},
}

89
lua/plugins/git.lua Normal file
View File

@@ -0,0 +1,89 @@
-- Git workflow enhancements: diffview, git-blame, and Octo keymaps
return {
-- Diffview: Side-by-side diffs and file history
{
"sindrets/diffview.nvim",
cmd = { "DiffviewOpen", "DiffviewClose", "DiffviewFileHistory", "DiffviewToggleFiles" },
keys = {
{ "<leader>gd", "<cmd>DiffviewOpen<cr>", desc = "Diffview: Open" },
{ "<leader>gD", "<cmd>DiffviewClose<cr>", desc = "Diffview: Close" },
{ "<leader>gf", "<cmd>DiffviewFileHistory %<cr>", desc = "Diffview: File History" },
{ "<leader>gF", "<cmd>DiffviewFileHistory<cr>", desc = "Diffview: Branch History" },
{ "<leader>gm", "<cmd>DiffviewOpen origin/main...HEAD<cr>", desc = "Diffview: Compare to main" },
{ "<leader>gM", "<cmd>DiffviewOpen origin/master...HEAD<cr>", desc = "Diffview: Compare to master" },
},
opts = {
enhanced_diff_hl = true,
view = {
default = {
layout = "diff2_horizontal",
},
merge_tool = {
layout = "diff3_mixed",
},
file_history = {
layout = "diff2_horizontal",
},
},
file_panel = {
win_config = {
position = "left",
width = 35,
},
},
},
},
-- Git blame: Inline blame annotations
{
"f-person/git-blame.nvim",
event = "BufRead",
opts = {
enabled = false, -- Disabled by default, toggle with <leader>gB
date_format = "%r", -- relative time
message_when_not_committed = "Not committed yet",
virtual_text_column = 80,
},
keys = {
{ "<leader>gB", "<cmd>GitBlameToggle<cr>", desc = "Toggle Git Blame" },
{ "<leader>go", "<cmd>GitBlameOpenCommitURL<cr>", desc = "Open Commit in Browser" },
{ "<leader>gy", "<cmd>GitBlameCopyCommitURL<cr>", desc = "Copy Commit URL" },
},
},
-- Octo.nvim keymaps (plugin already installed via lazyvim.plugins.extras.util.octo)
{
"pwntester/octo.nvim",
keys = {
-- PR operations
{ "<leader>gpl", "<cmd>Octo pr list<cr>", desc = "List PRs" },
{ "<leader>gpc", "<cmd>Octo pr create<cr>", desc = "Create PR" },
{ "<leader>gpo", "<cmd>Octo pr checkout<cr>", desc = "Checkout PR" },
{ "<leader>gpb", "<cmd>Octo pr browser<cr>", desc = "Open PR in Browser" },
{ "<leader>gpr", "<cmd>Octo pr ready<cr>", desc = "Mark PR Ready" },
{ "<leader>gpd", "<cmd>Octo pr diff<cr>", desc = "Show PR Diff" },
{ "<leader>gpm", "<cmd>Octo pr merge<cr>", desc = "Merge PR" },
-- Issue operations
{ "<leader>gil", "<cmd>Octo issue list<cr>", desc = "List Issues" },
{ "<leader>gic", "<cmd>Octo issue create<cr>", desc = "Create Issue" },
{ "<leader>gib", "<cmd>Octo issue browser<cr>", desc = "Open Issue in Browser" },
-- Review operations
{ "<leader>grs", "<cmd>Octo review start<cr>", desc = "Start Review" },
{ "<leader>grr", "<cmd>Octo review resume<cr>", desc = "Resume Review" },
{ "<leader>grc", "<cmd>Octo review submit<cr>", desc = "Submit Review" },
{ "<leader>grd", "<cmd>Octo review discard<cr>", desc = "Discard Review" },
},
},
-- Which-key group labels for git
{
"folke/which-key.nvim",
opts = {
spec = {
{ "<leader>gp", group = "pull requests" },
{ "<leader>gi", group = "issues" },
{ "<leader>gr", group = "review" },
},
},
},
}

39
lua/plugins/snippets.lua Normal file
View File

@@ -0,0 +1,39 @@
-- Custom snippet configuration for LuaSnip
-- Snippets are loaded from ~/.config/nvim/snippets/
return {
{
"L3MON4D3/LuaSnip",
config = function(_, opts)
local luasnip = require("luasnip")
-- Apply any opts from other configs
if opts then
luasnip.setup(opts)
end
-- Load custom snippets from snippets directory
-- Snippets are written in Lua format for maximum flexibility
require("luasnip.loaders.from_lua").lazy_load({
paths = { vim.fn.stdpath("config") .. "/snippets" },
})
-- Also support VS Code style snippets if you have any
require("luasnip.loaders.from_vscode").lazy_load({
paths = { vim.fn.stdpath("config") .. "/snippets/vscode" },
})
end,
keys = {
{
"<leader>cS",
function()
-- Reload all custom snippets
require("luasnip.loaders.from_lua").load({
paths = { vim.fn.stdpath("config") .. "/snippets" },
})
vim.notify("Snippets reloaded!", vim.log.levels.INFO)
end,
desc = "Reload Snippets",
},
},
},
}

View File

@@ -1,11 +1,50 @@
-- Testing configuration with neotest
-- Supports Vitest (TypeScript), pytest (Python), and go test (Go)
return {
"nvim-neotest/neotest",
dependencies = {
"marilari88/neotest-vitest",
{
"nvim-neotest/neotest",
dependencies = {
"marilari88/neotest-vitest",
},
opts = {
adapters = {
["neotest-vitest"] = {},
},
},
keys = {
-- Run tests
{ "<leader>tt", function() require("neotest").run.run() end, desc = "Run Nearest Test" },
{ "<leader>tf", function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "Run File Tests" },
{ "<leader>ta", function() require("neotest").run.run(vim.uv.cwd()) end, desc = "Run All Tests" },
{ "<leader>tl", function() require("neotest").run.run_last() end, desc = "Run Last Test" },
{ "<leader>tS", function() require("neotest").run.stop() end, desc = "Stop Tests" },
-- Debug tests
{ "<leader>td", function() require("neotest").run.run({ strategy = "dap" }) end, desc = "Debug Nearest Test" },
{ "<leader>tD", function() require("neotest").run.run({ vim.fn.expand("%"), strategy = "dap" }) end, desc = "Debug File Tests" },
-- Watch mode
{ "<leader>tw", function() require("neotest").watch.toggle(vim.fn.expand("%")) end, desc = "Toggle Watch (File)" },
{ "<leader>tW", function() require("neotest").watch.toggle() end, desc = "Toggle Watch (Nearest)" },
-- Output and summary
{ "<leader>ts", function() require("neotest").summary.toggle() end, desc = "Toggle Summary" },
{ "<leader>to", function() require("neotest").output.open({ enter = true, auto_close = true }) end, desc = "Show Output" },
{ "<leader>tO", function() require("neotest").output_panel.toggle() end, desc = "Toggle Output Panel" },
-- Navigation
{ "[t", function() require("neotest").jump.prev({ status = "failed" }) end, desc = "Prev Failed Test" },
{ "]t", function() require("neotest").jump.next({ status = "failed" }) end, desc = "Next Failed Test" },
},
},
opts = {
adapters = {
["neotest-vitest"] = {},
-- Which-key group label
{
"folke/which-key.nvim",
opts = {
spec = {
{ "<leader>t", group = "test" },
},
},
},
}