添加调试rust代码的功能

This commit is contained in:
a770 2025-06-15 23:26:39 +08:00
parent 2693f00367
commit 6d2c60eedc
4 changed files with 175 additions and 77 deletions

View file

@ -28,7 +28,6 @@
"llm.nvim": { "branch": "main", "commit": "22eb06f362e89a48e5a0053b93398568b7f26001" },
"lualine.nvim": { "branch": "master", "commit": "0c6cca9f2c63dadeb9225c45bc92bb95a151d4af" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "bef29b653ba71d442816bf56286c2a686210be04" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "4c2cdc69d69fe00c15ae8648f7e954d99e5de3ea" },
"mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" },
"mini.nvim": { "branch": "stable", "commit": "94cae4660a8b2d95dbbd56e1fbc6fcfa2716d152" },
"mini.pick": { "branch": "main", "commit": "c272dc61cd0326b344761cd9d031bfcdef1978c7" },
@ -38,8 +37,9 @@
"nvim-autopairs": { "branch": "master", "commit": "4d74e75913832866aa7de35e4202463ddf6efd1b" },
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
"nvim-dap": { "branch": "master", "commit": "ea82027c3447dc1a022be9a9884de276c05cd33a" },
"nvim-dap-view": { "branch": "main", "commit": "995f5c6a80da3f2a55b5efc352754fb34230c87c" },
"nvim-dap-ui": { "branch": "master", "commit": "73a26abf4941aa27da59820fd6b028ebcdbcf932" },
"nvim-lspconfig": { "branch": "master", "commit": "036885e8e5456d3907626b634693234f628afef6" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-notify": { "branch": "master", "commit": "b5825cf9ee881dd8e43309c93374ed5b87b7a896" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-treesitter-context": { "branch": "master", "commit": "464a443b5a6657f39772b20baa95d02ffe97b268" },

View file

@ -221,6 +221,7 @@ mapcmd("<LEADER>sc", "set spell!")
-- au filetype rust noremap r :wall<cr>:set splitbelow<cr>:sp<cr>:term cargo run<cr>
-- ]])
-- ===
-- === map function external environment
-- ===

View file

@ -2,22 +2,37 @@ return {
"mfussenegger/nvim-dap",
dependencies = {
{
"igorlfs/nvim-dap-view",
"rcarriga/nvim-dap-ui",
-- nvim-dap-ui 依赖 nio
dependencies = { "nvim-neotest/nvim-nio" },
config = function()
-- 在调试会话开始和结束时自动打开/关闭 DAP UI
local dap, dapui = require("dap"), require("dapui")
dapui.setup()
dap.listeners.after.event_initialized["dapui_config"] = function()
dapui.open()
end
dap.listeners.before.event_terminated["dapui_config"] = function()
dapui.close()
end
dap.listeners.before.event_exited["dapui_config"] = function()
dapui.close()
end
end,
},
{ "williamboman/mason.nvim" },
{
"jay-babu/mason-nvim-dap.nvim",
opts = {
switchbuf = "useopen,uselast,newtab",
-- 开启控制栏按钮
winbar = {
controls = {
enabled = true,
},
ensure_installed = {
-- 添加 codelldb
"codelldb",
},
},
},
{ "williamboman/mason.nvim" },
{ "jay-babu/mason-nvim-dap.nvim" },
},
config = function()
local dap, dv = require("dap"), require("dap-view")
local dap = require("dap")
-- Keymappings for DAP
vim.keymap.set("n", "<leader>db", dap.toggle_breakpoint, { desc = "DAP: Toggle Breakpoint" })
@ -25,76 +40,115 @@ return {
vim.keymap.set("n", "<leader>do", dap.step_over, { desc = "DAP: Step Over" })
vim.keymap.set("n", "<leader>di", dap.step_into, { desc = "DAP: Step Into" })
vim.keymap.set("n", "<leader>du", dap.step_out, { desc = "DAP: Step Out" })
vim.keymap.set("n", "<leader>dr", dap.repl.open, { desc = "DAP: Open REPL" })
vim.keymap.set("n", "<leader>dt", dap.terminate, { desc = "DAP: Terminate" })
vim.keymap.set("n", "<leader>dl", function()
require("dap").run_last()
end, { desc = "DAP: Run Last" })
vim.keymap.set("n", "<leader>dr", dap.repl.open, { desc = "DAP: Open REPL" })
vim.keymap.set("n", "<leader>dl", dap.run_last, { desc = "DAP: Run Last" })
vim.keymap.set("n", "<Leader>dp", function()
require("dap").set_breakpoint(nil, nil, vim.fn.input("Log point message: "))
dap.set_breakpoint(nil, nil, vim.fn.input("Log point message: "))
end)
-- 自动切换和关闭
dap.listeners.before.attach["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.launch["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.event_terminated["dap-view-config"] = function()
dv.close()
end
dap.listeners.before.event_exited["dap-view-config"] = function()
dv.close()
end
-- 在 nvim-dap-view 文件类型中将 q 映射为 quit
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = { "dap-view", "dap-view-term", "dap-repl" }, -- dap-repl is set by `nvim-dap`
callback = function(evt)
vim.keymap.set("n", "q", "<C-w>q", { buffer = evt.buf })
end,
})
-- 如果没有窗口包含缓冲区,请创建一个新选项卡
dap.defaults.fallback.switchbuf = "usevisible,usetab,newtab"
dap.configurations.rust = {
{
name = "Launch Rust Program (GDB)",
type = "cppdbg", -- Use the cpptools adapter
request = "launch",
program = function()
-- Ask for the executable path when launching
return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/target/debug/", "file")
end,
cwd = "${workspaceFolder}",
stopAtEntry = false,
MIMode = "gdb", -- Specify GDB
miDebuggerPath = "gdb", -- Or full path to gdb if not in PATH
-- setupCommands are executed at the beginning of the GDB session
setupCommands = {
{
text = "-enable-pretty-printing",
description = "Enable GDB pretty printing",
ignoreFailures = false,
},
-- You might need to find the exact path to rust-gdb on your system
-- It's usually in `~/.rustup/toolchains/<your-toolchain>/lib/rustlib/src/rust/etc/rust-gdb`
-- Or system-wide if rustc was installed differently.
-- Example: (ADJUST THIS PATH!)
-- {
-- text = "source ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/etc/rust-gdb",
-- description = "Load Rust GDB extensions",
-- ignoreFailures = true -- Set to true if the path might not always be valid
-- }
},
-- If you want to pass arguments to your program:
-- args = {"arg1", "arg2"},
-- 在这里配置调试器
dap.adapters.codelldb = {
type = "server",
port = "${port}", -- DAP 会自动替换为可用端口
executable = {
-- ‼️ 如果你手动安装,请确保这里的 'codelldb' 在你的 PATH 中 ‼️
-- 如果使用 mason.nvim它会自动处理路径无需修改
command = "codelldb",
args = { "--port", "${port}" },
},
-- You can add more configurations, e.g., for attaching to a running process
}
dap.adapters["rust-gdb"] = {
type = "executable",
command = "rust-gdb",
args = { "--interpreter=dap" },
}
require("mason-nvim-dap").setup({
ensure_installed = { "cpptools" },
handlers = {}, -- sets up dap in the predefined manner
})
dap.configurations.rust = {
{
-- 这个名字可以自定义,方便你区分
name = "Launch (rust-lldb)",
type = "codelldb", -- ‼️ 关键:使用我们上面定义的 'codelldb' 适配器
request = "launch",
program = function()
-- 0. 运行'cargo build'生成二进制目标文件
vim.fn.system("cargo build")
-- 1. 运行 'cargo metadata' 并获取 JSON 输出
local cargo_metadata_json = vim.fn.system("cargo metadata --no-deps --format-version 1")
if vim.v.shell_error ~= 0 then
vim.notify("Error running 'cargo metadata': " .. cargo_metadata_json, vim.log.levels.ERROR)
return nil
end
-- 2. 解析 JSON
local cargo_metadata = vim.fn.json_decode(cargo_metadata_json)
-- 3. 直接从元数据中获取项目根目录
local project_root = cargo_metadata.workspace_root
-- 4. 寻找二进制目标文件的名字
local executable_name = nil
-- 我们只关心工作区的成员包
for _, member_id in ipairs(cargo_metadata.workspace_members) do
for _, package in ipairs(cargo_metadata.packages) do
if package.id == member_id then
for _, target in ipairs(package.targets) do
-- 找到第一个 kind 为 "bin" 的目标
if target.kind[1] == "bin" then
executable_name = target.name
break
end
end
end
if executable_name then
break
end
end
if executable_name then
break
end
end
if not executable_name then
vim.notify("没有找到可执行文件,请手动输入路径", vim.log.levels.ERROR)
return vim.fn.input("Path to executable: ", "../target/debug/", "file")
end
-- 5. 构建并返回最终路径
local exec_path = vim.fs.joinpath(project_root, "target", "debug", executable_name)
vim.notify("DAP launching: " .. exec_path, vim.log.levels.INFO)
return exec_path
end,
cwd = "${workspaceFolder}",
stopOnEntry = false,
-- 如果需要传递命令行参数,可以取消注释
-- args = function()
-- local new_args = vim.split(vim.fn.input("Arguments: "), " ")
-- return new_args
-- end,
},
-- {
-- name = "Launch (rust-gdb)",
-- type = "rust-gdb", -- 使用我们上面定义的适配器
-- request = "launch",
-- -- 动态获取要调试的可执行文件路径
-- -- 它会提示你输入路径,并默认填充为 target/debug/<your_project_name>
-- program = function()
-- return vim.fn.input("Path to executable: ", "../target/debug/", "file")
-- end,
-- cwd = "${workspaceFolder}", -- 设置工作目录为项目根目录
-- stopOnEntry = false, -- 不在程序入口处自动暂停
-- -- 如果你的程序需要命令行参数,可以取消下面这行的注释
-- -- args = function()
-- -- local new_args = vim.split(vim.fn.input("Arguments: "), " ")
-- -- return new_args
-- -- end,
-- },
}
-- ===================================================================
-- ‼️ NEW: 定义自定义的 DAP 图标 ‼️
-- ===================================================================
local sign = vim.fn.sign_define
sign("DapBreakpoint", { text = "", texthl = "DapBreakpoint", linehl = "", numhl = "" })
sign("DapBreakpointCondition", { text = "󰃤", texthl = "DapBreakpoint", linehl = "", numhl = "" })
sign("DapLogPoint", { text = "󰌑", texthl = "DapLogPoint", linehl = "", numhl = "" })
sign("DapRejectedBreakpoint", { text = "󰚦", texthl = "DapRejectedBreakpoint", linehl = "", numhl = "" })
sign("DapStopped", { text = "", texthl = "DapStopped", linehl = "DapStoppedLine", numhl = "" })
-- ===================================================================
end,
}

View file

@ -1,10 +1,53 @@
-- ===
-- === 智能退格,自动删除行首和行尾只有空格的整行
-- ===
-- 创建一个 autocmd 组,防止重复加载
-- local smartBackspaceGroup = vim.api.nvim_create_augroup("SmartBackspace", { clear = true })
-- 定义要应用此功能的文件类型
-- 你可以根据自己的需要随意添加或删除,例如 "python", "html", "css" 等
-- local filetypes = {
-- "lua",
-- "python",
-- "rust",
-- }
-- 核心函数 (这部分不变)
-- local function smart_backspace()
-- local line = vim.api.nvim_get_current_line()
-- -- 行首和行尾只有tab和空格的情况
-- if line:match('^%s+$') then
-- return '<Esc>ddkA'
-- else
-- return '<BS>'
-- end
-- end
-- 创建自动命令 (这里是修改重点)
-- vim.api.nvim_create_autocmd('FileType', {
-- group = smartBackspaceGroup,
-- pattern = filetypes,
-- callback = function()
-- -- 使用 vim.defer_fn 来延迟设置映射
-- vim.defer_fn(function()
-- vim.keymap.set('i', '<BS>', smart_backspace, {
-- expr = true,
-- buffer = true,
-- silent = true,
-- noremap = true,
-- })
-- end, 1000) -- 延迟 1000 毫秒,通常足够了
-- end,
-- })
return {
'windwp/nvim-autopairs',
config = function()
require('nvim-autopairs').setup({
-- 在写markdown时禁用括号补全
disable_filetype = {"markdown"},
-- can use treesitter to check for a pair.
-- can use treesitter to check for a pair.
check_ts = true,
})
end