Refactor config: fix conflicts, add features, update docs

- Fix keymap conflicts: session (<leader>sS/sR), substitute (<leader>sl)
- Remove duplicate keymaps (window, resize) and options (synmaxcol, foldmethod)
- Add which-key group names for better keymap organization
- Add auto-format on save with smart filtering (conform.nvim)
- Add diagnostic float on hover (CursorHold)
- Add safe buffer close with unsaved changes confirmation
- Add quickfix/location list navigation keymaps
- Add startup config validation (nvim version, executables)
- Enable plugin update notifications in lazy.nvim
- Clean up: remove temporary files (kkk, cleanup script)
- Clean up: remove commented code and fix double function loading
- Update README.md with comprehensive documentation
- Add CHANGELOG.md tracking all changes
This commit is contained in:
Carlos Gutierrez
2026-01-10 22:13:59 -05:00
parent 0066ac1441
commit cd817820ca
15 changed files with 490 additions and 1093 deletions

View File

@@ -34,31 +34,80 @@ local function load_functions()
end
-- 4. Fix: Force filetype detection on BufRead (fix for nvim-tree/plain text issue)
-- Only run if filetype is not already detected to avoid redundant calls
vim.api.nvim_create_autocmd("BufRead", {
pattern = "*",
callback = function()
vim.cmd("silent filetype detect")
if vim.bo.filetype == "" then
vim.cmd("silent filetype detect")
end
end,
})
-- 5. Load functions immediately
load_functions()
-- 6. Fallback: also try to load on VimEnter if LazyDone doesn't fire
-- 5. Load functions on VimEnter to ensure plugins are loaded first
-- Using a flag to prevent double-loading
local functions_loaded = false
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
-- Wait a bit for plugins to load
vim.defer_fn(function()
load_functions()
end, 200)
if not functions_loaded then
vim.defer_fn(function()
load_functions()
functions_loaded = true
end, 200)
end
end,
once = true,
})
--[[ vim.api.nvim_create_autocmd("BufReadPost", {
once = true,
-- 6. Diagnostic float on hover (show diagnostics when cursor holds)
vim.api.nvim_create_autocmd("CursorHold", {
callback = function()
require("cargdev.core.project_config").bootstrap_config()
end
local opts = {
focusable = false,
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
border = "rounded",
source = "always",
prefix = " ",
scope = "cursor",
}
vim.diagnostic.open_float(nil, opts)
end,
})
]]
-- 7. Configuration validation on startup
local function validate_config()
local warnings = {}
-- Check Neovim version (require 0.9+)
if vim.fn.has("nvim-0.9") == 0 then
table.insert(warnings, "Neovim 0.9+ is recommended for this configuration")
end
-- Check for required executables
local required_executables = { "git", "rg", "node" }
for _, exe in ipairs(required_executables) do
if vim.fn.executable(exe) == 0 then
table.insert(warnings, string.format("'%s' not found in PATH", exe))
end
end
-- Display warnings if any
if #warnings > 0 then
vim.defer_fn(function()
for _, warning in ipairs(warnings) do
vim.notify("Config Warning: " .. warning, vim.log.levels.WARN)
end
end, 1000)
end
end
-- Run validation on startup
vim.api.nvim_create_autocmd("VimEnter", {
callback = validate_config,
once = true,
})
-- 8. Custom health check command
vim.api.nvim_create_user_command("CheckConfig", function()
vim.cmd("checkhealth")
end, { desc = "Run Neovim health check" })

View File

@@ -11,14 +11,16 @@ local opts = { noremap = true, silent = true }
-- "jj" is much less likely to appear in normal typing and won't interfere
keymap.set("i", "jj", "<ESC>", opts) -- Exit insert mode with jj
keymap.set("n", "<leader>nh", ":nohl<CR>", opts) -- Clear search highlights
-- Removed: keymap.set("n", "x", '"_x', opts) -- Delete character without copying into register
-- This was causing single character deletions to not be copied to the default register
-- Save and quit (additional)
keymap.set("n", "<leader>Q", ":qa!<CR>", { desc = "Quit all" })
-- Put this in your init.lua
-- Obsidian vault path with validation
local vault_path = vim.env.IDEA_DIR
if not vault_path or vault_path == "" then
-- Silently skip Obsidian link setup if IDEA_DIR is not configured
return
end

View File

@@ -25,17 +25,7 @@ keymap.set("n", "<leader>no", ":noh <CR>", { desc = "Reset search a word" })
keymap.set("n", "<leader>+", "<C-a>", { desc = "Increment number" }) -- increment
keymap.set("n", "<leader>-", "<C-x>", { desc = "Decrement number" }) -- decrement
-- window management
keymap.set("n", "<leader>sv", "<C-w>v", { desc = "Split window vertically" }) -- split window vertically
keymap.set("n", "<leader>sh", "<C-w>s", { desc = "Split window horizontally" }) -- split window horizontally
keymap.set("n", "<leader>se", "<C-w>=", { desc = "Make splits equal size" }) -- make split windows equal width & height
keymap.set("n", "<leader>sx", "<cmd>close<CR>", { desc = "Close current split" }) -- close current split window
keymap.set("n", "<leader>to", "<cmd>tabnew<CR>", { desc = "Open new tab" }) -- open new tab
keymap.set("n", "<leader>tx", "<cmd>tabclose<CR>", { desc = "Close current tab" }) -- close current tab
keymap.set("n", "<leader>tn", "<cmd>tabn<CR>", { desc = "Go to next tab" }) -- go to next tab
keymap.set("n", "<leader>tp", "<cmd>tabp<CR>", { desc = "Go to previous tab" }) -- go to previous tab
keymap.set("n", "<leader>tf", "<cmd>tabnew %<CR>", { desc = "Open current buffer in new tab" }) -- move current buffer to new tab
-- Window management keymaps are centralized in lua/cargdev/core/keymaps/window.lua
-- sintax fixer
keymap.set("n", "<leader>sy", "gg=G<CR>", { desc = "Format current file" })
@@ -43,8 +33,26 @@ keymap.set("n", "<leader>sy", "gg=G<CR>", { desc = "Format current file" })
keymap.set("n", "<C-e>", "10<C-e>", { noremap = true, silent = true })
keymap.set("n", "<C-y>", "10<C-y>", { noremap = true, silent = true })
-- close current file on buffer
keymap.set("n", "<leader>bd", ":bd<CR>", { desc = "Close current file on buffer" })
-- Buffer management with safe close (confirms if unsaved changes)
keymap.set("n", "<leader>bd", function()
if vim.bo.modified then
vim.ui.select({ "Save & Close", "Discard & Close", "Cancel" }, {
prompt = "Buffer has unsaved changes:",
}, function(choice)
if choice == "Save & Close" then
vim.cmd("w")
vim.cmd("bd")
elseif choice == "Discard & Close" then
vim.cmd("bd!")
end
end)
else
vim.cmd("bd")
end
end, { desc = "Buffer: Close (safe)" })
-- Force close buffer without confirmation
keymap.set("n", "<leader>bD", ":bd!<CR>", { desc = "Buffer: Force close" })
-- Set buftabline mappings
keymap.set("n", "<C-p>", ":bnext<CR>", { noremap = true, silent = true })
@@ -62,17 +70,7 @@ keymap.set("n", "<leader>;", "$a;<ESC>", { desc = "Adding ';' at the end of the
keymap.set("n", "<leader>con", "oconsole.log()<ESC>0w$h", { desc = "Adding console.log() on the line below" })
keymap.set("n", "<leader>x", ":!node %<CR>", { desc = "Running current project using node" })
-- Move between Tmux and Neovim splits using Alt + Arrow keys
-- keymap.set("n", "<A-h>", ":TmuxNavigateLeft<CR>", { noremap = true, silent = true })
-- keymap.set("n", "<A-j>", ":TmuxNavigateDown<CR>", { noremap = true, silent = true })
-- keymap.set("n", "<A-k>", ":TmuxNavigateUp<CR>", { noremap = true, silent = true })
-- keymap.set("n", "<A-l>", ":TmuxNavigateRight<CR>", { noremap = true, silent = true })
-- Resize splits using Ctrl + Arrow keys
keymap.set("n", "<C-l>", ":vertical resize -5<CR>", { noremap = true, silent = true })
keymap.set("n", "<C-h>", ":vertical resize +5<CR>", { noremap = true, silent = true })
keymap.set("n", "<C-k>", ":resize +5<CR>", { noremap = true, silent = true })
keymap.set("n", "<C-j>", ":resize -5<CR>", { noremap = true, silent = true })
-- Resize splits keymaps are centralized in lua/cargdev/core/keymaps/window.lua
-- Run and Debug Project
keymap.set("n", "<leader>pr", ":RunProject<CR>", { desc = "Run Project" })
@@ -91,3 +89,20 @@ keymap.set("v", "<leader>zd", ":CopilotChatDocs<CR>", { desc = "Generate docs (C
keymap.set("n", "<leader>p", function()
vim.cmd("read !pbpaste -Prefer html | pandoc -f html -t gfm")
end, { desc = "Paste HTML clipboard as Markdown" })
-- =============================================================================
-- QUICKFIX NAVIGATION
-- =============================================================================
keymap.set("n", "<leader>qn", ":cnext<CR>zz", { desc = "Quickfix: Next item" })
keymap.set("n", "<leader>qp", ":cprev<CR>zz", { desc = "Quickfix: Previous item" })
keymap.set("n", "<leader>qo", ":copen<CR>", { desc = "Quickfix: Open list" })
keymap.set("n", "<leader>qq", ":cclose<CR>", { desc = "Quickfix: Close list" })
keymap.set("n", "<leader>qf", ":cfirst<CR>zz", { desc = "Quickfix: First item" })
keymap.set("n", "<leader>ql", ":clast<CR>zz", { desc = "Quickfix: Last item" })
-- Location list navigation
keymap.set("n", "<leader>ln", ":lnext<CR>zz", { desc = "Location: Next item" })
keymap.set("n", "<leader>lp", ":lprev<CR>zz", { desc = "Location: Previous item" })
keymap.set("n", "<leader>lo", ":lopen<CR>", { desc = "Location: Open list" })
keymap.set("n", "<leader>lq", ":lclose<CR>", { desc = "Location: Close list" })

View File

@@ -42,17 +42,17 @@ keymap.set("n", "<leader>tf", "<cmd>ToggleTerm direction=float<cr>", { desc = "T
keymap.set("n", "<leader>th", "<cmd>ToggleTerm size=10 direction=horizontal<cr>", { desc = "ToggleTerm horizontal split" })
keymap.set("n", "<leader>tv", "<cmd>ToggleTerm size=80 direction=vertical<cr>", { desc = "ToggleTerm vertical split" })
-- Session management
keymap.set("n", "<leader>ss", "<cmd>SessionSave<cr>", { desc = "Save session" })
keymap.set("n", "<leader>sr", "<cmd>SessionRestore<cr>", { desc = "Restore session" })
-- Session management (using <leader>sS and <leader>sR to avoid conflicts with substitute)
keymap.set("n", "<leader>sS", "<cmd>SessionSave<cr>", { desc = "Session: Save" })
keymap.set("n", "<leader>sR", "<cmd>SessionRestore<cr>", { desc = "Session: Restore" })
-- Formatting
keymap.set("n", "<leader>f", "<cmd>lua vim.lsp.buf.format()<cr>", { desc = "Format buffer" })
-- Substitute (changed from <leader>s to <leader>sub to avoid conflicts)
keymap.set("n", "<leader>sub", "<cmd>lua require('substitute').operator()<cr>", { desc = "Substitute with motion" })
keymap.set("n", "<leader>ss", "<cmd>lua require('substitute').line()<cr>", { desc = "Substitute line" })
keymap.set("n", "<leader>S", "<cmd>lua require('substitute').eol()<cr>", { desc = "Substitute to end of line" })
-- Substitute
keymap.set("n", "<leader>sub", "<cmd>lua require('substitute').operator()<cr>", { desc = "Substitute: With motion" })
keymap.set("n", "<leader>sl", "<cmd>lua require('substitute').line()<cr>", { desc = "Substitute: Line" })
keymap.set("n", "<leader>S", "<cmd>lua require('substitute').eol()<cr>", { desc = "Substitute: To end of line" })
-- Surround
keymap.set("n", "<leader>sa", "<cmd>lua require('nvim-surround').surround_add()<cr>", { desc = "Add surrounding" })

View File

@@ -40,7 +40,7 @@ opt.smartindent = true -- Smart indent
opt.updatetime = 100 -- Faster completion (reduced from 250)
opt.timeoutlen = 200 -- Faster key sequence completion (reduced from 300)
opt.redrawtime = 1500 -- Allow more time for loading syntax
opt.synmaxcol = 240 -- Only highlight the first 240 columns
opt.synmaxcol = 200 -- Only highlight the first 200 columns (conservative for performance)
opt.maxmempattern = 1000 -- Reduce memory for pattern matching
opt.hidden = true -- Allow switching buffers without saving
opt.scrolljump = 1 -- Minimal number of screen lines to scroll
@@ -49,9 +49,7 @@ opt.sidescrolloff = 3 -- Keep 3 columns left/right of cursor (reduced from 8)
-- Syntax loading optimizations
opt.syntax = "on" -- Enable syntax highlighting
opt.synmaxcol = 200 -- Reduce syntax highlighting column limit
opt.lazyredraw = false -- Don't use lazy redraw (can cause issues)
opt.foldmethod = "syntax" -- Use syntax-based folding for better performance
opt.foldlevel = 99 -- Don't fold by default
-- Filetype plugin optimizations
@@ -101,9 +99,8 @@ opt.formatoptions:append("j") -- Remove comment leader when joining lines
opt.showmatch = true -- Show matching brackets
opt.matchtime = 2 -- How long to show matching brackets
-- Folding
-- Folding (indent-based is generally faster than syntax-based)
opt.foldmethod = "indent" -- Fold based on indentation
opt.foldlevel = 99 -- Don't fold by default
opt.foldnestmax = 10 -- Maximum nesting level
-- Backup and swap