aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.nvim.lua109
1 files changed, 94 insertions, 15 deletions
diff --git a/.nvim.lua b/.nvim.lua
index 2cd34d6..1cec8af 100644
--- a/.nvim.lua
+++ b/.nvim.lua
@@ -28,51 +28,130 @@ vim.filetype.add({
-- Debugging
local dap = require("dap")
-local qemu_job = nil
+local qemu_job_id = nil
+local qemu_bufnr = nil
-dap.adapters.teachos_qemu_mi = function(callback, config)
- if qemu_job then
- qemu_job:kill(9)
+local function resolve_build_paths(artifact_path)
+ local base_path = string.gsub(artifact_path, "%.[%w]+$", "")
+ local build_type = artifact_path:match("bin/([^/]+)/") or "Debug"
+ return {
+ iso = base_path .. ".iso",
+ elf = base_path .. ".elf",
+ sym = base_path .. ".sym",
+ build_type = build_type,
+ }
+end
+
+local function launch_qemu(artifact_path, is_debug)
+ if qemu_job_id then
+ vim.fn.jobstop(qemu_job_id)
+ qemu_job_id = nil
+ end
+
+ local paths = resolve_build_paths(artifact_path)
+
+ local cmd = {
+ "qemu-system-x86_64",
+ "-m", "32M",
+ "-machine", "q35",
+ "-smp", "4,sockets=1,cores=4,threads=1",
+ "-display", "curses",
+ "-debugcon", string.format("file:%s/qemu-debugcon-%s.log", workspace_folder, paths.build_type),
+ "-cdrom", paths.iso
+ }
+
+ if is_debug then
+ table.insert(cmd, 2, "-s")
+ table.insert(cmd, 3, "-no-reboot")
+ table.insert(cmd, 4, "-d")
+ table.insert(cmd, 5, "int,cpu_reset")
end
+ local shell_cmd = string.format("%s 2>%s/qemu-stderr-%s.log", table.concat(cmd, " "), workspace_folder, paths.build_type)
+
+ vim.cmd("botright vsplit")
+ vim.cmd("enew")
+ qemu_bufnr = vim.api.nvim_get_current_buf()
+
+ vim.api.nvim_buf_set_name(qemu_bufnr, "TeachOS QEMU")
+ vim.opt_local.number = false
+ vim.opt_local.relativenumber = false
+ vim.opt_local.signcolumn = "no"
+
+ qemu_job_id = vim.fn.termopen({ "bash", "-c", shell_cmd }, {
+ on_exit = function()
+ qemu_job_id = nil
+ end
+ })
+
+ vim.cmd("wincmd p")
+end
+
+dap.adapters.teachos_qemu_mi = function(callback, config)
local artifact_path = config.program
if not artifact_path then
vim.notify("Fatal: No artifact path resolved by CMake", vim.log.levels.ERROR)
return
end
- local elf_path = string.gsub(artifact_path, "%.sym$", ".elf")
+ launch_qemu(artifact_path, true)
- qemu_job = vim.system({
- "qemu-system-x86_64",
- "-kernel", elf_path,
- "-s", "-S",
- "-nographic"
- }, { text = true })
+ local paths = resolve_build_paths(artifact_path)
+ config.setupCommands = {
+ { description = "Enable pretty-printing for gdb", text = "-enable-pretty-printing" },
+ { description = "Load code", text = string.format("-file-exec-file %s", paths.elf) },
+ { description = "Load symbols", text = string.format("-file-exec-and-symbols %s", paths.sym) },
+ }
+ config.program = paths.sym
vim.defer_fn(function()
callback({
type = "executable",
command = vim.fn.stdpath("data") .. "/mason/bin/OpenDebugAD7",
+ id = "cppdbg",
})
end, 500)
end
-dap.listeners.after.event_terminated["teachos_qemu_teardown"] = function()
- if qemu_job then
- qemu_job:kill(9)
- qemu_job = nil
+local function teardown_qemu()
+ if qemu_job_id then
+ vim.fn.jobstop(qemu_job_id)
+ qemu_job_id = nil
+ end
+
+ if qemu_bufnr and vim.api.nvim_buf_is_valid(qemu_bufnr) then
+ vim.api.nvim_buf_delete(qemu_bufnr, { force = true })
+ qemu_bufnr = nil
end
end
+dap.listeners.after.event_terminated["teachos_qemu_teardown"] = teardown_qemu
+dap.listeners.after.event_exited["teachos_qemu_teardown"] = teardown_qemu
+dap.listeners.after.disconnect["teachos_qemu_teardown"] = teardown_qemu
+
require("cmake-tools").setup({
cmake_dap_configuration = {
name = "(gdb) QEMU MI Attach",
type = "teachos_qemu_mi",
request = "launch",
+ MIMode = "gdb",
+ cwd = workspace_folder,
miDebuggerServerAddress = "localhost:1234",
miDebuggerPath = "x86_64-pc-elf-gdb",
stopAtEntry = true,
}
})
+vim.api.nvim_create_user_command("TeachOSRun", function()
+ local cmake = safe_require("cmake-tools")
+ if not cmake then return end
+
+ local is_ready, target = pcall(cmake.get_launch_target_path)
+ if is_ready and target then
+ launch_qemu(target, false)
+ else
+ vim.notify("Fatal: Cannot determine CMake target path.", vim.log.levels.ERROR)
+ end
+end, {})
+
+vim.keymap.set('n', '<S-F5>', '<cmd>TeachOSRun<CR>', { noremap = true, desc = "Run TeachOS QEMU (No Debug)" })