From 6d2c60eedcd8ae02d152357f2148e6324a0646a0 Mon Sep 17 00:00:00 2001 From: a770 Date: Sun, 15 Jun 2025 23:26:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B0=83=E8=AF=95rust?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lazy-lock.json | 4 +- lua/core/keymap.lua | 1 + lua/lazy/plugins/dap.lua | 202 +++++++++++++++++++++++-------------- lua/lazy/plugins/pairs.lua | 45 ++++++++- 4 files changed, 175 insertions(+), 77 deletions(-) diff --git a/lazy-lock.json b/lazy-lock.json index 6ff610a..3713fef 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -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" }, diff --git a/lua/core/keymap.lua b/lua/core/keymap.lua index 254a34e..5dc030d 100644 --- a/lua/core/keymap.lua +++ b/lua/core/keymap.lua @@ -221,6 +221,7 @@ mapcmd("sc", "set spell!") -- au filetype rust noremap r :wall:set splitbelow:sp:term cargo run -- ]]) + -- === -- === map function external environment -- === diff --git a/lua/lazy/plugins/dap.lua b/lua/lazy/plugins/dap.lua index e111562..e54923e 100644 --- a/lua/lazy/plugins/dap.lua +++ b/lua/lazy/plugins/dap.lua @@ -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", "db", dap.toggle_breakpoint, { desc = "DAP: Toggle Breakpoint" }) @@ -25,76 +40,115 @@ return { vim.keymap.set("n", "do", dap.step_over, { desc = "DAP: Step Over" }) vim.keymap.set("n", "di", dap.step_into, { desc = "DAP: Step Into" }) vim.keymap.set("n", "du", dap.step_out, { desc = "DAP: Step Out" }) - vim.keymap.set("n", "dr", dap.repl.open, { desc = "DAP: Open REPL" }) vim.keymap.set("n", "dt", dap.terminate, { desc = "DAP: Terminate" }) - vim.keymap.set("n", "dl", function() - require("dap").run_last() - end, { desc = "DAP: Run Last" }) + vim.keymap.set("n", "dr", dap.repl.open, { desc = "DAP: Open REPL" }) + vim.keymap.set("n", "dl", dap.run_last, { desc = "DAP: Run Last" }) vim.keymap.set("n", "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", "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//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/ + -- 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, } diff --git a/lua/lazy/plugins/pairs.lua b/lua/lazy/plugins/pairs.lua index c69eb61..b0b4016 100644 --- a/lua/lazy/plugins/pairs.lua +++ b/lua/lazy/plugins/pairs.lua @@ -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 'ddkA' +-- else +-- return '' +-- 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', '', 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