aboutsummaryrefslogtreecommitdiff
path: root/.nvim.lua
diff options
context:
space:
mode:
Diffstat (limited to '.nvim.lua')
-rw-r--r--.nvim.lua169
1 files changed, 169 insertions, 0 deletions
diff --git a/.nvim.lua b/.nvim.lua
new file mode 100644
index 0000000..0748af9
--- /dev/null
+++ b/.nvim.lua
@@ -0,0 +1,169 @@
+local workspace_folder = vim.fn.getcwd()
+
+-- Formatting
+vim.g.autoformat = true
+vim.opt.fixeol = false
+
+-- Enable Doxygen
+vim.g.load_doxygen_syntax = true
+
+local function safe_require(module)
+ local ok, mod = pcall(require, module)
+ if not ok then return nil end
+ return mod
+end
+
+-- C++
+local default_clangd_config = vim.deepcopy(vim.lsp.config["clangd"]) or {}
+default_clangd_config.cmd = {
+ "clangd",
+ "--background-index",
+ "--clang-tidy",
+ "--header-insertion=iwyu",
+ "--completion-style=detailed",
+ string.format("--compile-commands-dir=%s/build", workspace_folder),
+ "--query-driver=**/x86_64-pc-elf-g++"
+}
+
+vim.lsp.config("clangd", default_clangd_config)
+
+vim.filetype.add({
+ pattern = {
+ [".*/include/kstd/.*"] = function(path, _)
+ if not path:match("%.[^/]+$") then
+ return "cpp"
+ end
+ end
+ }
+})
+
+-- File Browser
+local neo_tree = safe_require("neo-tree")
+if neo_tree then
+ local current_config = neo_tree.config or {}
+ local project_config = vim.tbl_deep_extend("force", current_config, {
+ nesting_rules = {
+ ['*.hpp'] = {
+ pattern = "(.*).hpp",
+ files = { "%1.cpp", "%1.test.cpp", "%1.tests.cpp" }
+ }
+ }
+ })
+ neo_tree.setup(project_config)
+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 shell_cmd = string.format("%s/scripts/qemu-wrapper.sh '%s' '%s' '%s' '%s'",
+ workspace_folder, 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.termopen(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
+
+ 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
+
+local cmake_tools = safe_require("cmake-tools")
+if cmake_tools then
+ require("cmake-tools").setup({
+ cmake_compile_commands_options = {
+ action = "copy",
+ target = string.format("%s/build", workspace_folder),
+ },
+ 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)" })
+end