add debugger support

This commit is contained in:
2026-10-15 11:18:36 -09:00
parent f6115bc048
commit 24392b0e5b
3 changed files with 118 additions and 2 deletions
+14 -1
View File
@@ -126,7 +126,20 @@
(keymap :n "[d" (fn [] (vim.diagnostic.jump {:count -1 :float true})) opts)
(keymap :n "]d" (fn [] (vim.diagnostic.jump {:count 1 :float true})) opts)
(keymap :n "<leader>e" vim.diagnostic.open_float opts)
(keymap :n "<leader>F" vim.lsp.buf.format opts))})
(keymap :n "<leader>F" vim.lsp.buf.format opts)
(let [client (vim.lsp.get_client_by_id ev.data.client_id)]
(when (and client (client.supports_method "textDocument/references"))
(pcall vim.cmd "anoremenu PopUp.Show\\ References <Cmd>lua vim.lsp.buf.references()<CR>"))))})
;; Remove "Show References" from the context menu once no attached client supports it
(autocmd "LspDetach"
{:callback (fn []
(var has-references false)
(each [_ client (ipairs (vim.lsp.get_clients))]
(when (client.supports_method "textDocument/references")
(set has-references true)))
(when (not has-references)
(pcall vim.cmd "aunmenu PopUp.Show\\ References")))})
;; LSP commands (lspconfig-style)
(local usercmd vim.api.nvim_create_user_command)
+101 -1
View File
@@ -114,7 +114,107 @@
{lhs "<leader>h" :group "hunk"}
{lhs "<leader>t" :group "toggle"}
{lhs "<leader>l" :group "log"}
{lhs "<leader>a" :group "AI/Claude"}]))}
{lhs "<leader>a" :group "AI/Claude"}
{lhs "<leader>d" :group "debug"}]))}
;; nvim-dap + nvim-dap-ui - Debugging via the Debug Adapter Protocol
;; Adapters: lldb-dap (LLVM) for Rust, C and compiled rust-mal .clj
;; executables, and gdb (-i dap) for .clj too. rust-mal's executables
;; carry their gdb script (mal_Value variables shown as Clojure prints
;; them); gdb runs it once auto-loading is allowed for their directory.
;; The lldb one is imported when the cwd has debug/rust_mal_lldb.py.
{repo "rcarriga/nvim-dap-ui"
:dependencies ["mfussenegger/nvim-dap" "nvim-neotest/nvim-nio"]
:keys [{lhs "<F5>" rhs #((. (require :dap) :continue)) :desc "Debug: start/continue"}
{lhs "<F6>" rhs #((. (require :dap) :terminate)) :desc "Debug: stop"}
{lhs "<F7>" rhs #((. (require :dapui) :toggle)) :desc "Debug: toggle UI"}
{lhs "<F8>" rhs #((. (require :dap) :run_to_cursor)) :desc "Debug: run to cursor"}
{lhs "<F9>" rhs #((. (require :dap) :toggle_breakpoint)) :desc "Debug: toggle breakpoint"}
{lhs "<F10>" rhs #((. (require :dap) :step_over)) :desc "Debug: step over"}
{lhs "<F11>" rhs #((. (require :dap) :step_into)) :desc "Debug: step into"}
{lhs "<F12>" rhs #((. (require :dap) :step_out)) :desc "Debug: step out"}
{lhs "<leader>db" rhs #((. (require :dap) :set_breakpoint) (vim.fn.input "Condition: "))
:desc "Conditional breakpoint"}
{lhs "<leader>dl" rhs #((. (require :dap) :set_breakpoint) nil nil (vim.fn.input "Log message: "))
:desc "Log point"}
{lhs "<leader>dB" rhs #((. (require :dap) :clear_breakpoints)) :desc "Clear breakpoints"}
{lhs "<leader>dr" rhs #((. (require :dap) :run_last)) :desc "Re-run last session"}
{lhs "<leader>dR" rhs #((. (require :dap) :restart)) :desc "Restart session"}
{lhs "<leader>dk" rhs #((. (require :dap) :up)) :desc "Frame up"}
{lhs "<leader>dj" rhs #((. (require :dap) :down)) :desc "Frame down"}
{lhs "<leader>de" rhs #((. (require :dapui) :eval)) :mode [:n :v] :desc "Eval expression"}
{lhs "<leader>dE" rhs #((. (require :dapui) :eval) (vim.fn.input "Expression: "))
:desc "Eval prompt"}
{lhs "<leader>do" rhs #((. (require :dap) :repl :toggle)) :desc "Toggle debug REPL"}]
:config (fn []
(local dap (require :dap))
(local dapui (require :dapui))
(dapui.setup)
;; Open/close the UI with the session
(set dap.listeners.after.event_initialized.dapui #(dapui.open))
(set dap.listeners.before.event_terminated.dapui #(dapui.close))
(set dap.listeners.before.event_exited.dapui #(dapui.close))
(vim.fn.sign_define "DapBreakpoint" {:text "●" :texthl "DiagnosticError"})
(vim.fn.sign_define "DapBreakpointCondition" {:text "◆" :texthl "DiagnosticWarn"})
(vim.fn.sign_define "DapLogPoint" {:text "◉" :texthl "DiagnosticInfo"})
(vim.fn.sign_define "DapStopped" {:text "▶" :texthl "DiagnosticOk"
:linehl "Visual"})
(set dap.adapters.lldb {:type "executable"
:command "lldb-dap"
:name "lldb"})
;; Import rust-mal's lldb formatters when debugging from a rust-mal checkout
(fn init-commands []
(let [script (.. (vim.fn.getcwd) "/debug/rust_mal_lldb.py")]
(if (= 1 (vim.fn.filereadable script))
[(.. "command script import " script)]
[])))
(fn launch [default-program]
{:name "Launch executable"
:type "lldb"
:request "launch"
:program #(vim.fn.input "Executable: " (default-program) "file")
:args #(vim.split (vim.fn.input "Args: ") " " {:trimempty true})
:cwd "${workspaceFolder}"
:stopOnEntry false
:initCommands init-commands})
;; gdb's own DAP server (gdb 14+), allowed to auto-load the scripts of
;; the program's directory (rust-mal's pretty-printers are in the
;; executable). Unlike lldb-dap, in .clj files its watches and
;; breakpoint conditions are Clojure (built with --debug)
(set dap.adapters.gdb
(fn [callback config]
(let [program (or config.program "")
dir (if (= program "")
(vim.fn.getcwd)
(vim.fn.fnamemodify program ":p:h"))]
(callback {:type "executable"
:command "gdb"
:args ["-q" "-i" "dap"
"-iex" (.. "add-auto-load-safe-path " dir)]}))))
(fn gdb-launch [default-program]
{:name "Launch executable (gdb)"
:type "gdb"
:request "launch"
:program #(vim.fn.input "Executable: " (default-program) "file")
:args #(vim.split (vim.fn.input "Args: ") " " {:trimempty true})
:cwd "${workspaceFolder}"
:stopAtBeginningOfMainSubprogram false})
;; rust-mal: `rust-mal -O0 foo.clj` writes ./foo next to foo.clj
(set dap.configurations.clojure
[(gdb-launch #(vim.fn.expand "%:p:r"))
(launch #(vim.fn.expand "%:p:r"))])
(set dap.configurations.rust
[(launch #(.. (vim.fn.getcwd) "/target/debug/"))])
(set dap.configurations.c
[(launch #(.. (vim.fn.getcwd) "/"))]))}
;; claudecode.nvim - Claude Code AI assistant integration
{repo "coder/claudecode.nvim"
+3
View File
@@ -10,6 +10,9 @@
"mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"nfnl": { "branch": "main", "commit": "a4c47a1e7e52aaf234b358f73135acf783054e35" },
"nvim-dap": { "branch": "master", "commit": "cfa2d58f4537aca6ca83e2de1a0d9f1491121264" },
"nvim-dap-ui": { "branch": "master", "commit": "cc9dd33aade7f20bae414d0cba163bc60d4d4b43" },
"nvim-nio": { "branch": "master", "commit": "edcc181a875301dd21840189aa2f2f9ad69fc172" },
"nvim-treesitter": { "branch": "main", "commit": "f603a2f4da48728f80257fb5fbb90145fd1dc173" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"roslyn.nvim": { "branch": "main", "commit": "bf1bd4e70bc7068d1b4aebf4ce03cc19a86615be" },