118 lines
2.5 KiB
Lua
118 lines
2.5 KiB
Lua
local toggleterm = require("toggleterm")
|
|
local Terminal = require("toggleterm.terminal").Terminal
|
|
|
|
toggleterm.setup({
|
|
start_in_insert = true,
|
|
insert_mappings = true,
|
|
terminal_mappings = true,
|
|
persist_size = true,
|
|
persist_mode = true,
|
|
close_on_exit = false,
|
|
direction = "horizontal",
|
|
size = 14,
|
|
})
|
|
|
|
local M = {}
|
|
|
|
local runners = {
|
|
build = {
|
|
cmd = "cmake --build --preset debug-with-tidy",
|
|
title = "Build",
|
|
},
|
|
test = {
|
|
cmd = "ctest --test-dir build --output-on-failure",
|
|
title = "Tests",
|
|
},
|
|
}
|
|
|
|
local terminals = {
|
|
shell = Terminal:new({
|
|
hidden = true,
|
|
close_on_exit = false,
|
|
direction = "horizontal",
|
|
}),
|
|
}
|
|
|
|
local last_runner = nil
|
|
|
|
local function run_in_terminal(term, cmd)
|
|
term:open()
|
|
vim.defer_fn(function()
|
|
term:send(cmd .. "\r", false)
|
|
end, 20)
|
|
end
|
|
|
|
local function project_root()
|
|
local current_file = vim.api.nvim_buf_get_name(0)
|
|
local start_path = current_file ~= "" and vim.fs.dirname(current_file) or vim.loop.cwd()
|
|
local markers = { "CMakePresets.json", "CMakeLists.txt", ".git" }
|
|
local found = vim.fs.find(markers, { upward = true, path = start_path })[1]
|
|
|
|
if found then
|
|
return vim.fs.dirname(found)
|
|
end
|
|
|
|
return vim.loop.cwd()
|
|
end
|
|
|
|
local function get_runner_term(name)
|
|
if terminals[name] then
|
|
return terminals[name]
|
|
end
|
|
|
|
terminals[name] = Terminal:new({
|
|
hidden = true,
|
|
close_on_exit = false,
|
|
direction = "horizontal",
|
|
display_name = runners[name].title,
|
|
})
|
|
|
|
return terminals[name]
|
|
end
|
|
|
|
function M.toggle_shell()
|
|
terminals.shell.dir = project_root()
|
|
terminals.shell:toggle()
|
|
end
|
|
|
|
function M.run_build()
|
|
local term = get_runner_term("build")
|
|
term.dir = project_root()
|
|
run_in_terminal(term, runners.build.cmd)
|
|
last_runner = "build"
|
|
end
|
|
|
|
function M.run_tests()
|
|
local term = get_runner_term("test")
|
|
term.dir = project_root()
|
|
run_in_terminal(term, runners.test.cmd)
|
|
last_runner = "test"
|
|
end
|
|
|
|
function M.rerun_last()
|
|
if not last_runner then
|
|
vim.notify("No build/test command has been run yet", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
if last_runner == "build" then
|
|
M.run_build()
|
|
else
|
|
M.run_tests()
|
|
end
|
|
end
|
|
|
|
function M.toggle_build_terminal()
|
|
local term = get_runner_term("build")
|
|
term.dir = project_root()
|
|
term:toggle()
|
|
end
|
|
|
|
function M.toggle_test_terminal()
|
|
local term = get_runner_term("test")
|
|
term.dir = project_root()
|
|
term:toggle()
|
|
end
|
|
|
|
return M
|