1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
local workspace_folder = vim.fn.getcwd()
-- Formatting
vim.g.autoformat = true
vim.opt.fixeol = false
-- Enable Doxygen
vim.g.load_doxygen_syntax = true
-- C++
vim.filetype.add({
pattern = {
[".*/include/kstd/.*"] = function(path, _)
if not path:match("%.[^/]+$") then
return "cpp"
end
end
}
})
-- Debugging
local dap = require("dap")
local qemu_job_id = nil
local qemu_bufnr = nil
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 debug_flag = is_debug and "1" or "0"
local cmd_args = {
workspace_folder .. "/scripts/qemu-wrapper.sh",
workspace_folder,
paths.build_type,
paths.iso,
debug_flag
}
vim.cmd("botright vsplit | enew")
qemu_bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_buf_set_name(qemu_bufnr, "TeachOS QEMU (" .. paths.build_type .. ")")
vim.opt_local.number = false
vim.opt_local.relativenumber = false
vim.opt_local.signcolumn = "no"
qemu_job_id = vim.fn.jobstart(cmd_args, {
term = true,
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
launch_qemu(artifact_path, 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
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
vim.api.nvim_create_user_command("TeachOSRun", function()
local cmake = require("cmake-tools")
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)" })
|