chore: remove local/unused plugins and refactor core configs
- Remove locally-developed or rarely-used plugin packages (codetyper, curls, edgy, flash) to reduce maintenance surface, external deps, and startup cost; these were local/optional and caused complexity. - Clean up stale/keymap docs and small duplicate or experimental files (keymaps/README.md, sudoku keymaps). - Apply targeted refactors to core modules for readability, robustness, and to align Java/DAP/Copilot integrations with local environment. - Removed plugin modules: - lua/cargdev/plugins/codetyper.lua (deleted) - lua/cargdev/plugins/curls.lua (deleted) - lua/cargdev/plugins/edgy.lua (deleted) - lua/cargdev/plugins/flash.lua (deleted) - Added .codetyper to .gitignore - Java / JDTLS: - ftplugin/java.lua: pin jdtls java executable to JDK 25, switch to mac_arm config, enable LSP formatter and declare multiple runtimes (JavaSE-17, JavaSE-25). - Notifications & startup UX: - lua/cargdev/core/function/notification_manager.lua: large refactor — use local aliases (api, cmd, loop, opt), improved docs, dashboard-aware handling, nvim-notify fallback, safer tracking and cleanup of notifications. - Utilities & monitors: - lua/cargdev/core/function/performance_monitor.lua: use local references, better notify usage and docs. - lua/cargdev/core/function/project_commands.lua: add docs, use local api/fn/notify, clearer RunProject/DebugProject commands. - Terminal helper: - lua/cargdev/core/function/openTerminal.lua: add module docs and small refactor to use local cmd/api aliases and expose keymap. - Keymaps & docs: - Removed stale keymaps README (lua/cargdev/core/keymaps/README.md). - Reworked many keymap files: docstrings, renamed/moved mappings to avoid conflicts, moved DAP mappings into dap plugin config, removed/disabled experimental mappings (see files under lua/cargdev/core/keymaps/*). - Adjusted quick keybindings and prefixes to reduce overlaps. - Plugins & integrations: - lua/cargdev/plugins/formatting.lua: disabled google-java-format fallback for java (prefer JDTLS). - lua/cargdev/plugins/dap.lua: added additional DAP configs (Bun launch, attach helper), moved/registered dap keymaps here. - lua/cargdev/plugins/copilot.lua: reorganized Copilot/Copilot-cmp/CopilotChat config and added copilot source to nvim-cmp. - lua/cargdev/plugins/nvim-cmp.lua: added copilot source and small formatting tweak.
This commit is contained in:
149
scripts/detect_keymap_conflicts.lua
Normal file
149
scripts/detect_keymap_conflicts.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
--- detect_keymap_conflicts.lua
|
||||
--- Detects duplicate keymap bindings across neovim config files.
|
||||
--- Run from the nvim config root: lua scripts/detect_keymap_conflicts.lua
|
||||
|
||||
local handle = io.popen("find lua -name '*.lua' -print")
|
||||
if not handle then
|
||||
print("Error: could not search for lua files")
|
||||
os.exit(1)
|
||||
end
|
||||
local files = {}
|
||||
for path in handle:lines() do
|
||||
files[#files + 1] = path
|
||||
end
|
||||
handle:close()
|
||||
|
||||
--- Build a lookup table: line_starts[i] = byte position where line i begins.
|
||||
local function build_line_index(content)
|
||||
local starts = { 1 }
|
||||
for i = 1, #content do
|
||||
if content:sub(i, i) == "\n" then
|
||||
starts[#starts + 1] = i + 1
|
||||
end
|
||||
end
|
||||
return starts
|
||||
end
|
||||
|
||||
--- Binary search to find the line number for a byte position.
|
||||
local function line_at(line_starts, pos)
|
||||
local lo, hi = 1, #line_starts
|
||||
while lo < hi do
|
||||
local mid = math.floor((lo + hi + 1) / 2)
|
||||
if line_starts[mid] <= pos then
|
||||
lo = mid
|
||||
else
|
||||
hi = mid - 1
|
||||
end
|
||||
end
|
||||
return lo
|
||||
end
|
||||
|
||||
--- Return true if `pos` sits after a "--" comment marker on the same line.
|
||||
local function is_in_comment(content, line_starts, pos)
|
||||
local ln = line_at(line_starts, pos)
|
||||
local line_start = line_starts[ln]
|
||||
local before = content:sub(line_start, pos - 1)
|
||||
return before:match("%-%-") ~= nil
|
||||
end
|
||||
|
||||
--- Split a mode argument into individual mode strings.
|
||||
--- "n" -> {"n"}, {"n", "v"} -> {"n", "v"}
|
||||
local function extract_modes(mode_arg)
|
||||
local modes = {}
|
||||
for m in mode_arg:gmatch([=["([^"]+)"]=]) do
|
||||
modes[#modes + 1] = m
|
||||
end
|
||||
if #modes == 0 then
|
||||
for m in mode_arg:gmatch("'([^']+)'") do
|
||||
modes[#modes + 1] = m
|
||||
end
|
||||
end
|
||||
if #modes == 0 then
|
||||
local trimmed = mode_arg:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
if #trimmed > 0 then
|
||||
modes[#modes + 1] = trimmed
|
||||
end
|
||||
end
|
||||
return modes
|
||||
end
|
||||
|
||||
-- Patterns to match keymap setter calls.
|
||||
-- Two variants per caller style: single-string mode and table mode.
|
||||
-- Using [=[...]=] to avoid issues with ]] inside patterns.
|
||||
-- () captures the byte position for line-number lookup.
|
||||
local patterns = {
|
||||
-- vim.keymap.set("n", "<key>", ...)
|
||||
[=[()vim%.keymap%.set%(%s*["']([^"']+)["']%s*,%s*["']([^"']+)["']]=],
|
||||
-- vim.keymap.set({"n", "v"}, "<key>", ...)
|
||||
[=[()vim%.keymap%.set%(%s*(%b{})%s*,%s*["']([^"']+)["']]=],
|
||||
-- keymap.set("n", "<key>", ...)
|
||||
[=[()keymap%.set%(%s*["']([^"']+)["']%s*,%s*["']([^"']+)["']]=],
|
||||
-- keymap.set({"n", "v"}, "<key>", ...)
|
||||
[=[()keymap%.set%(%s*(%b{})%s*,%s*["']([^"']+)["']]=],
|
||||
-- keymap("n", "<key>", ...) — when local keymap = vim.keymap.set
|
||||
[=[()keymap%(%s*["']([^"']+)["']%s*,%s*["']([^"']+)["']]=],
|
||||
-- keymap({"n", "v"}, "<key>", ...)
|
||||
[=[()keymap%(%s*(%b{})%s*,%s*["']([^"']+)["']]=],
|
||||
-- map("n", "<key>", ...) — wrapper function
|
||||
[=[()map%(%s*["']([^"']+)["']%s*,%s*["']([^"']+)["']]=],
|
||||
-- map({"n", "v"}, "<key>", ...)
|
||||
[=[()map%(%s*(%b{})%s*,%s*["']([^"']+)["']]=],
|
||||
}
|
||||
|
||||
local keymaps = {} -- "mode|lhs" -> list of "file:line"
|
||||
local seen = {} -- dedup: "file:line:lhs" -> true
|
||||
|
||||
for _, f in ipairs(files) do
|
||||
local fh = io.open(f, "r")
|
||||
if fh then
|
||||
-- Read entire file so patterns can span multiple lines (%s matches \n).
|
||||
local content = fh:read("*a")
|
||||
fh:close()
|
||||
local line_starts = build_line_index(content)
|
||||
|
||||
for _, pat in ipairs(patterns) do
|
||||
for pos, mode_arg, lhs in content:gmatch(pat) do
|
||||
if not is_in_comment(content, line_starts, pos) then
|
||||
local ln = line_at(line_starts, pos)
|
||||
local dedup_key = f .. ":" .. ln .. ":" .. lhs
|
||||
if not seen[dedup_key] then
|
||||
seen[dedup_key] = true
|
||||
local modes = extract_modes(mode_arg)
|
||||
for _, mode in ipairs(modes) do
|
||||
local key = mode .. "|" .. lhs
|
||||
keymaps[key] = keymaps[key] or {}
|
||||
keymaps[key][#keymaps[key] + 1] = string.format("%s:%d", f, ln)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Collect and sort conflicts
|
||||
local conflicts = {}
|
||||
for key, locations in pairs(keymaps) do
|
||||
if #locations > 1 then
|
||||
local mode, lhs = key:match("^(.-)|(.*)")
|
||||
conflicts[#conflicts + 1] = { mode = mode, lhs = lhs, locations = locations }
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(conflicts, function(a, b)
|
||||
if a.mode == b.mode then return a.lhs < b.lhs end
|
||||
return a.mode < b.mode
|
||||
end)
|
||||
|
||||
if #conflicts == 0 then
|
||||
print("No duplicate keymaps found.")
|
||||
else
|
||||
print(string.format("Found %d conflicting keymap(s):\n", #conflicts))
|
||||
for _, c in ipairs(conflicts) do
|
||||
print(string.format(" [%s] %s", c.mode, c.lhs))
|
||||
for _, loc in ipairs(c.locations) do
|
||||
print(" - " .. loc)
|
||||
end
|
||||
print()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user