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:
2026-02-10 12:17:36 -05:00
parent 832a664fa0
commit 06dbe4d892
34 changed files with 899 additions and 950 deletions

View File

@@ -1,5 +1,12 @@
-- Highlight .njk files as htmldjango for better templating syntax
vim.api.nvim_create_autocmd({"BufRead", "BufNewFile"}, {
--- Custom filetype detection for unsupported or ambiguous file extensions.
--- Registers autocmds that assign the correct filetype when buffers are
--- opened, enabling proper syntax highlighting and LSP support.
--- @module highlights
--- Set .njk (Nunjucks) files to use the htmldjango filetype,
--- which provides the closest built-in syntax support for
--- Nunjucks/Jinja-style template syntax (blocks, extends, includes).
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*.njk",
callback = function()
vim.cmd("set filetype=htmldjango")

View File

@@ -1,15 +1,33 @@
-- Custom notification manager to handle overlapping and improve UX
--- Custom notification manager to handle overlapping and improve UX.
--- Provides a centralized notification system that prevents overlapping,
--- supports dashboard-aware notifications, and integrates with nvim-notify
--- when available, falling back to cmd echo otherwise.
--- @module notification_manager
local M = {}
local log = vim.log
local api = vim.api
local cmd = vim.cmd
local o = vim.o
local loop = vim.loop
local opt = vim.opt
local deferFn = vim.defer_fn
-- Track active notifications to prevent overlapping
--- List of currently displayed notifications (each entry has win, message, timestamp).
--- @type table[]
local active_notifications = {}
local notification_queue = {}
-- Function to show a notification without overlapping
--- Show a notification without overlapping existing ones.
--- Uses nvim-notify if available; otherwise falls back to echo.
--- Automatically detects the alpha dashboard and delegates to
--- `show_dashboard_notification` when appropriate.
--- @param message string The notification message to display.
--- @param level number|nil Log level from log.levels (default: INFO).
--- @param opts table|nil Optional overrides (timeout, title, render, position, etc.).
--- @return number|nil notification_id The nvim-notify notification id, or nil on fallback.
function M.show_notification(message, level, opts)
level = level or vim.log.levels.INFO
level = level or log.levels.INFO
opts = opts or {}
-- Default options
local default_opts = {
timeout = 3000,
@@ -22,64 +40,64 @@ function M.show_notification(message, level, opts)
background_colour = "#000000",
border_style = "rounded",
}
-- Merge options
for k, v in pairs(default_opts) do
if opts[k] == nil then
opts[k] = v
end
end
-- Check if we're in alpha dashboard
local current_buf = vim.api.nvim_get_current_buf()
local current_ft = vim.api.nvim_buf_get_option(current_buf, "filetype")
local current_buf = api.nvim_get_current_buf()
local current_ft = api.nvim_buf_get_option(current_buf, "filetype")
if current_ft == "alpha" then
-- If in dashboard, use a different approach
M.show_dashboard_notification(message, level, opts)
return
end
-- Use nvim-notify if available
local notify_available = pcall(require, "notify")
if notify_available then
local notify = require("notify")
-- Position notification to avoid overlapping
opts.on_open = function(win)
-- Calculate position to avoid overlapping with other notifications
local row = 2
local col = vim.o.columns - 60
local col = o.columns - 60
-- Adjust position if there are other notifications
for _, notif in ipairs(active_notifications) do
if notif.win and vim.api.nvim_win_is_valid(notif.win) then
if notif.win and api.nvim_win_is_valid(notif.win) then
row = row + 10 -- Stack notifications vertically
end
end
-- Ensure notification doesn't go off-screen
if row > vim.o.lines - 15 then
if row > o.lines - 15 then
row = 2
col = col - 20
end
vim.api.nvim_win_set_config(win, {
api.nvim_win_set_config(win, {
row = row,
col = col,
relative = "editor",
width = opts.max_width,
height = opts.max_height,
})
-- Track this notification
table.insert(active_notifications, {
win = win,
message = message,
timestamp = vim.loop.now(),
timestamp = loop.now(),
})
end
opts.on_close = function(win)
-- Remove from active notifications
for i, notif in ipairs(active_notifications) do
@@ -89,69 +107,78 @@ function M.show_notification(message, level, opts)
end
end
end
-- Show notification
local notification_id = notify(message, level, opts)
return notification_id
else
-- Fallback to echo instead of vim.notify to avoid circular dependency
local icon = "💬"
if level == vim.log.levels.ERROR then
if level == log.levels.ERROR then
icon = ""
elseif level == vim.log.levels.WARN then
elseif level == log.levels.WARN then
icon = "⚠️"
elseif level == vim.log.levels.INFO then
elseif level == log.levels.INFO then
icon = ""
end
-- Use echo for fallback notifications
vim.cmd("echo '" .. icon .. " " .. message .. "'")
cmd("echo '" .. icon .. " " .. message .. "'")
-- Clear message after a delay
vim.defer_fn(function()
vim.cmd("echo ''")
deferFn(function()
cmd("echo ''")
end, opts.timeout or 3000)
end
end
-- Function to show notifications specifically for dashboard
--- Show a minimal notification tailored for the alpha dashboard.
--- Truncates messages longer than 50 characters and uses echo
--- to avoid interfering with the dashboard layout.
--- @param message string The notification message to display.
--- @param level number|nil Log level from log.levels.
--- @param opts table|nil Optional overrides (timeout, etc.).
function M.show_dashboard_notification(message, level, opts)
-- In dashboard, show minimal notifications
local icon = "💬"
if level == vim.log.levels.ERROR then
if level == log.levels.ERROR then
icon = ""
elseif level == vim.log.levels.WARN then
elseif level == log.levels.WARN then
icon = "⚠️"
elseif level == vim.log.levels.INFO then
elseif level == log.levels.INFO then
icon = ""
end
-- Show message in status line or use echo
local short_message = message:sub(1, 50)
if #message > 50 then
short_message = short_message .. "..."
end
-- Use echo for dashboard notifications to avoid overlapping
vim.cmd("echo '" .. icon .. " " .. short_message .. "'")
cmd("echo '" .. icon .. " " .. short_message .. "'")
-- Clear message after a delay
vim.defer_fn(function()
vim.cmd("echo ''")
deferFn(function()
cmd("echo ''")
end, opts.timeout or 3000)
end
-- Function to clear all notifications
--- Close and clear all active notifications.
--- Iterates through `active_notifications`, closes any valid windows,
--- and resets the tracking list.
function M.clear_all_notifications()
for _, notif in ipairs(active_notifications) do
if notif.win and vim.api.nvim_win_is_valid(notif.win) then
vim.api.nvim_win_close(notif.win, true)
if notif.win and api.nvim_win_is_valid(notif.win) then
api.nvim_win_close(notif.win, true)
end
end
active_notifications = {}
end
-- Function to show performance notification
--- Show a performance-related notification with a chart icon prefix.
--- @param message string The performance message to display.
--- @param level number|nil Log level from log.levels.
function M.show_performance_notification(message, level)
M.show_notification("📊 " .. message, level, {
title = "Performance Monitor",
@@ -160,7 +187,9 @@ function M.show_performance_notification(message, level)
})
end
-- Function to show LSP notification
--- Show an LSP status notification with a wrench icon prefix.
--- @param message string The LSP status message to display.
--- @param level number|nil Log level from log.levels.
function M.show_lsp_notification(message, level)
M.show_notification("🔧 " .. message, level, {
title = "LSP Status",
@@ -169,7 +198,9 @@ function M.show_lsp_notification(message, level)
})
end
-- Function to show file operation notification
--- Show a file operation notification with a folder icon prefix.
--- @param message string The file operation message to display.
--- @param level number|nil Log level from log.levels.
function M.show_file_notification(message, level)
M.show_notification("📁 " .. message, level, {
title = "File Operation",
@@ -178,7 +209,9 @@ function M.show_file_notification(message, level)
})
end
-- Function to show plugin notification
--- Show a plugin manager notification with a sloth icon prefix.
--- @param message string The plugin-related message to display.
--- @param level number|nil Log level from log.levels.
function M.show_plugin_notification(message, level)
M.show_notification("🦥 " .. message, level, {
title = "Plugin Manager",
@@ -187,7 +220,9 @@ function M.show_plugin_notification(message, level)
})
end
-- Function to show startup notification
--- Show a startup notification with a rocket icon prefix and a short timeout.
--- @param message string The startup message to display.
--- @param level number|nil Log level from log.levels.
function M.show_startup_notification(message, level)
M.show_notification("🚀 " .. message, level, {
title = "Startup",
@@ -196,116 +231,126 @@ function M.show_startup_notification(message, level)
})
end
-- Function to handle startup messages aggressively
--- Aggressively suppress startup messages and "Press ENTER" prompts.
--- Configures `shortmess` with all relevant flags, sets `cmdheight` to 0,
--- disables `showmode`, and schedules deferred redraws to clear any
--- lingering messages.
function M.handle_startup_messages()
-- Clear any existing messages immediately
vim.cmd("redraw!")
vim.cmd("echo ''")
cmd("redraw!")
cmd("echo ''")
-- Suppress all startup messages
vim.opt.shortmess = vim.opt.shortmess + "I" -- No intro message
vim.opt.shortmess = vim.opt.shortmess + "c" -- No completion messages
vim.opt.shortmess = vim.opt.shortmess + "F" -- No file info message
vim.opt.shortmess = vim.opt.shortmess + "W" -- No "written" message
vim.opt.shortmess = vim.opt.shortmess + "A" -- No attention message
vim.opt.shortmess = vim.opt.shortmess + "o" -- No overwrite messages
vim.opt.shortmess = vim.opt.shortmess + "t" -- No truncation messages
vim.opt.shortmess = vim.opt.shortmess + "T" -- No truncation messages
vim.opt.shortmess = vim.opt.shortmess + "f" -- No file info messages
vim.opt.shortmess = vim.opt.shortmess + "i" -- No intro messages
vim.opt.shortmess = vim.opt.shortmess + "l" -- No line number messages
vim.opt.shortmess = vim.opt.shortmess + "m" -- No modification messages
vim.opt.shortmess = vim.opt.shortmess + "n" -- No line number messages
vim.opt.shortmess = vim.opt.shortmess + "r" -- No read messages
vim.opt.shortmess = vim.opt.shortmess + "s" -- No search messages
vim.opt.shortmess = vim.opt.shortmess + "x" -- No truncation messages
vim.opt.shortmess = vim.opt.shortmess + "O" -- No overwrite messages
opt.shortmess = opt.shortmess + "I" -- No intro message
opt.shortmess = opt.shortmess + "c" -- No completion messages
opt.shortmess = opt.shortmess + "F" -- No file info message
opt.shortmess = opt.shortmess + "W" -- No "written" message
opt.shortmess = opt.shortmess + "A" -- No attention message
opt.shortmess = opt.shortmess + "o" -- No overwrite messages
opt.shortmess = opt.shortmess + "t" -- No truncation messages
opt.shortmess = opt.shortmess + "T" -- No truncation messages
opt.shortmess = opt.shortmess + "f" -- No file info messages
opt.shortmess = opt.shortmess + "i" -- No intro messages
opt.shortmess = opt.shortmess + "l" -- No line number messages
opt.shortmess = opt.shortmess + "m" -- No modification messages
opt.shortmess = opt.shortmess + "n" -- No line number messages
opt.shortmess = opt.shortmess + "r" -- No read messages
opt.shortmess = opt.shortmess + "s" -- No search messages
opt.shortmess = opt.shortmess + "x" -- No truncation messages
opt.shortmess = opt.shortmess + "O" -- No overwrite messages
-- Disable command line messages
vim.opt.cmdheight = 0
vim.opt.showmode = false
opt.cmdheight = 0
opt.showmode = false
-- Clear any existing messages
vim.cmd("echo ''")
cmd("echo ''")
-- Force clear any pending messages
vim.defer_fn(function()
vim.cmd("redraw!")
vim.cmd("echo ''")
deferFn(function()
cmd("redraw!")
cmd("echo ''")
end, 100)
end
-- Function to eliminate "Press ENTER" prompts completely
--- Eliminate "Press ENTER" prompts by overriding `cmd.echo` and
--- installing autocmds that forcibly clear messages on VimEnter and
--- BufReadPost events.
function M.eliminate_enter_prompts()
-- Override the message display to prevent "Press ENTER" prompts
local original_echo = vim.cmd.echo
vim.cmd.echo = function(msg)
local original_echo = cmd.echo
cmd.echo = function(msg)
local msg_str = tostring(msg)
-- Block any messages that might cause "Press ENTER" prompts
if msg_str:match("Press ENTER") or
msg_str:match("lazyredraw") or
msg_str:match("You have enabled") or
msg_str:match("This is only meant") or
msg_str:match("You'll experience issues") then
if
msg_str:match("Press ENTER")
or msg_str:match("lazyredraw")
or msg_str:match("You have enabled")
or msg_str:match("This is only meant")
or msg_str:match("You'll experience issues")
then
return -- Don't show these messages
end
-- Allow other messages
original_echo(msg)
end
-- Create autocmd to handle any remaining prompts
vim.api.nvim_create_autocmd("VimEnter", {
api.nvim_create_autocmd("VimEnter", {
callback = function()
-- Clear any startup messages immediately
vim.cmd("redraw!")
vim.cmd("echo ''")
cmd("redraw!")
cmd("echo ''")
-- Force clear any pending messages multiple times
for i = 1, 5 do
vim.defer_fn(function()
vim.cmd("redraw!")
vim.cmd("echo ''")
deferFn(function()
cmd("redraw!")
cmd("echo ''")
end, i * 50)
end
end,
once = true,
})
-- Create autocmd to handle message events - use valid events
vim.api.nvim_create_autocmd("BufReadPost", {
api.nvim_create_autocmd("BufReadPost", {
callback = function()
-- Clear messages that might cause prompts
vim.cmd("redraw!")
cmd("redraw!")
end,
})
end
-- Function to setup notification system
--- Initialize the notification system.
--- Registers VimEnter and FileType autocmds to handle startup messages
--- and dashboard transitions, and calls `eliminate_enter_prompts`.
--- Called automatically when the module is first required.
function M.setup()
-- Create autocmd to handle startup messages
vim.api.nvim_create_autocmd("VimEnter", {
api.nvim_create_autocmd("VimEnter", {
callback = function()
M.handle_startup_messages()
end,
once = true,
})
-- Create autocmd to handle alpha dashboard
vim.api.nvim_create_autocmd("FileType", {
api.nvim_create_autocmd("FileType", {
pattern = "alpha",
callback = function()
M.handle_startup_messages()
end,
})
-- Eliminate "Press ENTER" prompts
M.eliminate_enter_prompts()
-- Don't override vim.notify here to avoid circular dependency
-- Let the system handle notifications naturally
end
-- Initialize notification manager
--- Initialize notification manager on require.
M.setup()
return M

View File

@@ -1,48 +1,54 @@
--- Terminal toggle utility.
--- Provides a function and keybinding (`<Leader>ter`) to open or close a
--- vertical-split zsh terminal on the right side of the editor. The terminal
--- automatically enters insert mode on focus and exits insert mode on blur.
--- @module openTerminal
vim.g.mapleader = " "
local keymap = vim.keymap
local cmd = vim.cmd
local api = vim.api
-- Function to open terminal
--- Toggle a terminal split on the rightmost side of the editor.
--- If the rightmost buffer is already a terminal, it closes it.
--- Otherwise, opens a new vertical split running zsh with line numbers
--- disabled and auto insert-mode behavior on focus/blur.
local function open_terminal()
-- Move to the rightmost buffer (equivalent to `<C-l>` multiple times)
vim.cmd("wincmd l")
vim.cmd("wincmd l")
vim.cmd("wincmd l")
vim.cmd("wincmd l")
cmd("wincmd l")
cmd("wincmd l")
cmd("wincmd l")
cmd("wincmd l")
-- Get current buffer number and type
local buf_num = vim.api.nvim_get_current_buf()
local buf_type = vim.api.nvim_buf_get_option(buf_num, "buftype")
local buf_num = apinvim_get_current_buf()
local buf_type = apinvim_buf_get_option(buf_num, "buftype")
if buf_type == "terminal" then
-- If already in a terminal, close it
vim.cmd("q")
cmd("q")
else
-- Open terminal in a vertical split
vim.cmd("vsp | term zsh")
cmd("vsp | term zsh")
-- Disable line numbers in terminal
vim.cmd("setlocal nonumber norelativenumber")
cmd("setlocal nonumber norelativenumber")
-- Auto-start insert mode in terminal
vim.api.nvim_create_autocmd({ "BufWinEnter", "WinEnter" }, {
apinvim_create_autocmd({ "BufWinEnter", "WinEnter" }, {
buffer = 0,
command = "startinsert!",
})
vim.api.nvim_create_autocmd("BufLeave", {
apinvim_create_autocmd("BufLeave", {
buffer = 0,
command = "stopinsert!",
})
-- Terminal key mappings
vim.keymap.set("t", "<C-h>", "<C-\\><C-n><C-w>h", { buffer = true })
vim.keymap.set("t", "<C-t>", "<C-\\><C-n>:q<CR>", { buffer = true })
vim.keymap.set("t", "<C-\\><C-\\>", "<C-\\><C-n>", { buffer = true })
-- Start terminal in insert mode
vim.cmd("startinsert!")
cmd("startinsert!")
end
end
-- Keybinding to open terminal
--- Map `<Leader>ter` in normal mode to toggle the terminal split.
keymap.set("n", "<Leader>ter", open_terminal, { noremap = true, silent = true })

View File

@@ -1,11 +1,22 @@
--- Performance and LSP health monitoring utilities.
--- Provides functions to inspect memory usage, startup time, loaded plugins,
--- active LSP clients, and per-buffer diagnostic summaries.
--- @module performance_monitor
local M = {}
-- Check overall Neovim performance
local fn = vim.fn
local notify = vim.notify
local lsp = vim.lsp
--- Collect and display overall Neovim performance statistics.
--- Reports memory usage, open buffer count, active LSP clients, and
--- (when lazy.nvim is available) loaded plugin count and startup time.
--- Results are shown via `vim.notify` at INFO level.
function M.check_performance()
local stats = {}
-- Startup time
stats.startup = vim.fn.reltimefloat(vim.fn.reltime(vim.g.start_time or vim.fn.reltime()))
stats.startup = fn.reltimefloat(fn.reltime(vim.g.start_time or fn.reltime()))
-- Memory usage
local mem = collectgarbage("count")
@@ -13,7 +24,7 @@ function M.check_performance()
stats.memory_mb = string.format("%.2f", mem / 1024)
-- Buffer count
stats.buffers = #vim.fn.getbufinfo({ buflisted = 1 })
stats.buffers = #fn.getbufinfo({ buflisted = 1 })
-- Loaded plugins (lazy.nvim)
local lazy_ok, lazy = pcall(require, "lazy")
@@ -25,7 +36,7 @@ function M.check_performance()
end
-- Active LSP clients
stats.lsp_clients = #vim.lsp.get_clients()
stats.lsp_clients = #lsp.get_clients()
-- Display results
local lines = {
@@ -41,15 +52,19 @@ function M.check_performance()
table.insert(lines, string.format("Startup Time: %s ms", stats.startup_ms))
end
vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO, { title = "Performance" })
notify(table.concat(lines, "\n"), vim.log.levels.INFO, { title = "Performance" })
end
-- Check LSP health for current buffer
--- Check LSP health for the current buffer.
--- Lists all attached LSP clients with their root directory and
--- server capabilities (completion, hover, definition, references,
--- formatting, code_actions), followed by a diagnostic severity summary.
--- Warns if no LSP clients are attached.
function M.check_lsp_health()
local clients = vim.lsp.get_clients({ bufnr = 0 })
local clients = lsp.get_clients({ bufnr = 0 })
if #clients == 0 then
vim.notify("No LSP clients attached to this buffer", vim.log.levels.WARN, { title = "LSP Health" })
notify("No LSP clients attached to this buffer", vim.log.levels.WARN, { title = "LSP Health" })
return
end
@@ -103,10 +118,18 @@ function M.check_lsp_health()
end
table.insert(lines, "")
table.insert(lines, string.format("Diagnostics: %d errors, %d warnings, %d hints, %d info",
counts.errors, counts.warnings, counts.hints, counts.info))
table.insert(
lines,
string.format(
"Diagnostics: %d errors, %d warnings, %d hints, %d info",
counts.errors,
counts.warnings,
counts.hints,
counts.info
)
)
vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO, { title = "LSP Health" })
notify(table.concat(lines, "\n"), vim.log.levels.INFO, { title = "LSP Health" })
end
return M

View File

@@ -1,27 +1,43 @@
vim.api.nvim_create_user_command("RunProject", function()
--- Project-level user commands for running and debugging.
--- Reads a per-project configuration file at `.nvim/project.lua` that should
--- return a table with `run` and/or `debug` keys containing shell commands.
--- Registers the `:RunProject` and `:DebugProject` user commands.
--- @module project_commands
local api = vim.api
local fn = vim.fn
local notify = vim.notify
--- Run the project using the `run` command from `.nvim/project.lua`.
--- Opens a vertical split terminal with the configured run command.
--- Notifies the user if the config file or run command is missing.
api.nvim_create_user_command("RunProject", function()
local config_path = ".nvim/project.lua"
if vim.fn.filereadable(config_path) == 0 then
vim.notify("No project config found. Run `:e` on any file to generate it.", vim.log.levels.WARN)
if fn.filereadable(config_path) == 0 then
notify("No project config found. Run `:e` on any file to generate it.", vim.log.levels.WARN)
return
end
local config = loadfile(config_path)()
if config and config.run then
vim.cmd("vsplit | terminal " .. config.run)
else
vim.notify("Run command not found in project config.", vim.log.levels.ERROR)
notify("Run command not found in project config.", vim.log.levels.ERROR)
end
end, {})
vim.api.nvim_create_user_command("DebugProject", function()
--- Debug the project using the `debug` command from `.nvim/project.lua`.
--- Opens a vertical split terminal with the configured debug command.
--- Notifies the user if the config file or debug command is missing.
api.nvim_create_user_command("DebugProject", function()
local config_path = ".nvim/project.lua"
if vim.fn.filereadable(config_path) == 0 then
vim.notify("No project config found. Run `:e` on any file to generate it.", vim.log.levels.WARN)
if fn.filereadable(config_path) == 0 then
notify("No project config found. Run `:e` on any file to generate it.", vim.log.levels.WARN)
return
end
local config = loadfile(config_path)()
if config and config.debug then
vim.cmd("vsplit | terminal " .. config.debug)
else
vim.notify("Debug command not found in project config.", vim.log.levels.ERROR)
notify("Debug command not found in project config.", vim.log.levels.ERROR)
end
end, {})