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:
@@ -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" })
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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" })
|
||||
|
||||
@@ -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" })
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,7 +14,8 @@ vim.opt.rtp:prepend(lazypath)
|
||||
require("lazy").setup({ { import = "cargdev.plugins" }, { import = "cargdev.plugins.lsp" } }, {
|
||||
checker = {
|
||||
enabled = true,
|
||||
notify = false,
|
||||
notify = true, -- Enable plugin update notifications
|
||||
frequency = 86400, -- Check once per day (in seconds)
|
||||
},
|
||||
change_detection = {
|
||||
notify = false,
|
||||
|
||||
@@ -32,7 +32,22 @@ return {
|
||||
dbml = { "dbml" }, -- DBML formatting
|
||||
sql = { "sqlfluff" }, -- SQL formatting
|
||||
},
|
||||
format_on_save = false, -- Set to true if you want auto-formatting on save
|
||||
format_on_save = function(bufnr)
|
||||
-- Disable autoformat for certain filetypes
|
||||
local ignore_filetypes = { "sql", "markdown" }
|
||||
if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then
|
||||
return
|
||||
end
|
||||
-- Disable for files in certain paths
|
||||
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||||
if bufname:match("/node_modules/") then
|
||||
return
|
||||
end
|
||||
return {
|
||||
timeout_ms = 2000,
|
||||
lsp_fallback = true,
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set({ "n", "v" }, "<leader>mm", function()
|
||||
@@ -41,6 +56,16 @@ return {
|
||||
async = false,
|
||||
timeout_ms = 2000,
|
||||
})
|
||||
end, { desc = "Format file or range (in visual mode)" })
|
||||
end, { desc = "Format: File or range (in visual mode)" })
|
||||
|
||||
-- Toggle auto-format 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("Auto-format on save disabled", vim.log.levels.INFO)
|
||||
else
|
||||
vim.notify("Auto-format on save enabled", vim.log.levels.INFO)
|
||||
end
|
||||
end, { desc = "Toggle auto-format on save" })
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ return {
|
||||
},
|
||||
}
|
||||
|
||||
-- Custom word/character counter function
|
||||
-- Custom word counter function
|
||||
local function word_count()
|
||||
-- Skip for very large files to avoid performance issues
|
||||
local line_count = vim.api.nvim_buf_line_count(0)
|
||||
@@ -58,7 +58,6 @@ return {
|
||||
end
|
||||
|
||||
local words = 0
|
||||
local chars = 0
|
||||
|
||||
-- Get all lines at once for better performance
|
||||
local all_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||
@@ -69,13 +68,11 @@ return {
|
||||
for _ in line:gmatch("%S+") do
|
||||
words = words + 1
|
||||
end
|
||||
-- Count characters (excluding newline)
|
||||
chars = chars + #line
|
||||
end
|
||||
end
|
||||
|
||||
-- Format: show words and characters
|
||||
return string.format("%d words, %d chars", words, chars)
|
||||
-- Format: show only word count
|
||||
return string.format("%d words", words)
|
||||
end
|
||||
|
||||
-- configure lualine with modified theme
|
||||
|
||||
@@ -5,9 +5,38 @@ return {
|
||||
vim.o.timeout = true
|
||||
vim.o.timeoutlen = 200 -- Reduced from 500 for faster response
|
||||
end,
|
||||
opts = {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
},
|
||||
config = function()
|
||||
local wk = require("which-key")
|
||||
|
||||
wk.setup({
|
||||
plugins = {
|
||||
marks = true,
|
||||
registers = true,
|
||||
spelling = { enabled = true, suggestions = 20 },
|
||||
},
|
||||
win = {
|
||||
border = "rounded",
|
||||
padding = { 2, 2, 2, 2 },
|
||||
},
|
||||
})
|
||||
|
||||
-- Register group names for better organization
|
||||
wk.add({
|
||||
{ "<leader>b", group = "Buffer" },
|
||||
{ "<leader>c", group = "Code/Copilot" },
|
||||
{ "<leader>d", group = "Debug/DAP" },
|
||||
{ "<leader>e", group = "Explorer" },
|
||||
{ "<leader>f", group = "Find/Files" },
|
||||
{ "<leader>g", group = "Git" },
|
||||
{ "<leader>l", group = "LSP/LeetCode" },
|
||||
{ "<leader>m", group = "Format" },
|
||||
{ "<leader>n", group = "Notifications" },
|
||||
{ "<leader>p", group = "Project" },
|
||||
{ "<leader>q", group = "Quickfix" },
|
||||
{ "<leader>s", group = "Session/Split/Substitute" },
|
||||
{ "<leader>t", group = "Tab/Terminal/Text" },
|
||||
{ "<leader>x", group = "Trouble/Diagnostics" },
|
||||
{ "<leader>z", group = "Copilot Chat" },
|
||||
})
|
||||
end,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user