Files
dotfiles/nvim/lua/runner.lua
T
2026-07-19 19:36:54 +08:00

130 lines
4.0 KiB
Lua

-- =============================================================================
-- runner.lua — 统一构建/运行/调试分发器
-- =============================================================================
-- 【保留】你的完整 runner.lua 模块。
-- 【修改】使用 quickfix 窗口显示输出,与 CMake 保持一致
local M = {}
--- 检测当前项目类型
---@return "rust"|"cmake"|"python"|"go"|"unknown"
function M.detect()
local cwd = vim.fn.getcwd()
if vim.fn.filereadable(cwd .. "/Cargo.toml") == 1 then return "rust" end
if vim.fn.filereadable(cwd .. "/CMakeLists.txt") == 1 then return "cmake" end
if vim.fn.filereadable(cwd .. "/go.mod") == 1 then return "go" end
if vim.fn.filereadable(cwd .. "/pyproject.toml") == 1 then return "python" end
if vim.fn.filereadable(cwd .. "/setup.py") == 1 then return "python" end
return "unknown"
end
-- 存储终端实例
local terminals = {}
--- 在底部终端运行命令(保留颜色,复用已有终端)
---@param cmd string 要运行的命令
---@param title string 窗口标题
local function run_in_terminal(cmd, title)
local Terminal = require("toggleterm.terminal").Terminal
-- 检查是否已有同名终端
if terminals[title] and vim.api.nvim_buf_is_valid(terminals[title].bufnr) then
-- 复用已有终端,先关闭再重新打开(会执行新命令)
terminals[title]:close()
terminals[title] = nil
end
-- 创建新终端
local term = Terminal:new({
cmd = cmd,
direction = "horizontal",
close_on_exit = false,
on_open = function(t)
pcall(vim.api.nvim_buf_set_name, t.bufnr, title)
end,
on_exit = function(t, _, exit_code)
vim.schedule(function()
-- 退出终端模式
vim.api.nvim_buf_call(t.bufnr, function()
vim.cmd("stopinsert")
end)
-- 显示结果
if exit_code == 0 then
vim.notify(title .. " 成功", vim.log.levels.INFO)
else
vim.notify(title .. " 失败 (退出码: " .. exit_code .. ")", vim.log.levels.WARN)
end
end)
end,
})
terminals[title] = term
term:toggle()
end
--- 构建(使用底部终端)
function M.build()
local project = M.detect()
if project == "rust" then
run_in_terminal("cargo build", "Cargo Build")
elseif project == "cmake" then
vim.cmd("CMakeBuild")
elseif project == "go" then
run_in_terminal("go build ./...", "Go Build")
else
vim.notify("未识别的项目类型,无法自动构建", vim.log.levels.WARN)
end
end
--- 运行(使用底部终端)
function M.run()
local project = M.detect()
if project == "rust" then
run_in_terminal("cargo run", "Cargo Run")
elseif project == "cmake" then
vim.cmd("CMakeRun")
elseif project == "go" then
run_in_terminal("go run .", "Go Run")
elseif project == "python" then
run_in_terminal("python " .. vim.fn.expand("%"), "Python Run")
else
vim.notify("未识别的项目类型,无法自动运行", vim.log.levels.WARN)
end
end
--- 调试
function M.debug()
local project = M.detect()
if project == "rust" then
require("dap").continue()
elseif project == "cmake" then
vim.cmd("CMakeDebug")
else
require("dap").continue()
end
end
--- 测试(使用底部终端)
function M.test()
local project = M.detect()
if project == "rust" then
run_in_terminal("cargo test", "Cargo Test")
elseif project == "cmake" then
vim.cmd("CMakeBuild")
run_in_terminal("ctest --test-dir build", "CTest")
elseif project == "go" then
run_in_terminal("go test ./...", "Go Test")
elseif project == "python" then
run_in_terminal("pytest", "Pytest")
else
vim.notify("未识别的项目类型,无法自动测试", vim.log.levels.WARN)
end
end
return M