172 lines
4.7 KiB
Lua
172 lines
4.7 KiB
Lua
-- Prevent cargo compiler from being loaded
|
||
vim.g.current_compiler = 'custom'
|
||
|
||
-- Load persistent configuration from .workspace.lua
|
||
local ws_file = "./.nvim.workspace.lua"
|
||
local loaded, workspace = pcall(dofile, ws_file)
|
||
if not loaded then
|
||
workspace = { args = {}, build_type = "debug", binary = "blog-server" }
|
||
end
|
||
|
||
local build_folder
|
||
local bin_target
|
||
local bin_name
|
||
|
||
local function updateBuildEnv()
|
||
build_folder = './target/' .. workspace.build_type
|
||
bin_target = workspace.binary
|
||
bin_name = build_folder .. '/' .. bin_target
|
||
|
||
-- The run (F6) arguments
|
||
vim.opt.makeprg = "cargo build"
|
||
vim.g.cargo_makeprg_params = 'build'
|
||
if workspace.build_type == "release" then
|
||
vim.opt.makeprg = vim.opt.makeprg .. " --release"
|
||
vim.g.cargo_makeprg_params = vim.g.cargo_makeprg_params .. " --release"
|
||
end
|
||
|
||
-- Rust compiler error format
|
||
vim.opt.errorformat = {
|
||
-- Main error/warning line with file:line:col format
|
||
'%E%>error%m,' .. -- Start of error block
|
||
'%W%>warning: %m,' .. -- Start of warning block
|
||
'%-G%>help: %m,' .. -- Ignore help lines
|
||
'%-G%>note: %m,' .. -- Ignore note lines
|
||
'%C%> --> %f:%l:%c,' .. -- Continuation: file location
|
||
'%Z%>%p^%m,' .. -- End: column pointer (^^^)
|
||
'%C%>%s%#|%.%#,' .. -- Continuation: context lines with |
|
||
'%C%>%s%#%m,' .. -- Continuation: other context
|
||
'%-G%.%#' -- Ignore everything else
|
||
}
|
||
end
|
||
|
||
updateBuildEnv()
|
||
|
||
-- Prevent Vim's built-in rust ftplugin from loading the cargo compiler
|
||
vim.api.nvim_create_autocmd("FileType", {
|
||
pattern = "rust",
|
||
callback = function()
|
||
vim.b.current_compiler = 'custom'
|
||
end,
|
||
})
|
||
|
||
local function writeWorkspace()
|
||
-- A very minimal serializer for workspace configuration
|
||
local s = { l = "", ls = {}, i = "" }
|
||
local function w(v) s.l = s.l .. v end
|
||
local function nl()
|
||
s.ls[#s.ls + 1] = s.l; s.l = s.i;
|
||
end
|
||
local function wv(v)
|
||
local t = type(v)
|
||
if t == 'table' then
|
||
w('{'); local pi = s.i; s.i = s.i .. " "
|
||
for k1, v1 in pairs(v) do
|
||
nl(); w('['); wv(k1); w('] = '); wv(v1); w(',')
|
||
end
|
||
s.i = pi; nl(); w('}');
|
||
elseif t == 'number' then
|
||
w(tostring(v))
|
||
elseif t == 'string' then
|
||
w('"' .. v .. '"')
|
||
else
|
||
w(tostring(v))
|
||
end
|
||
end
|
||
|
||
-- Write the workspace file
|
||
w("return "); wv(workspace); nl()
|
||
vim.fn.writefile(s.ls, ws_file)
|
||
end
|
||
|
||
-- nvim-dap configuration
|
||
local dap_ok, dap = pcall(require, "dap")
|
||
local dap_def_cfg
|
||
local dap_configs
|
||
|
||
-- Update args for both run and debug configs
|
||
local function updateArgs(args)
|
||
workspace.args = args
|
||
if dap_configs ~= nil then dap_configs[1].args = args end
|
||
writeWorkspace()
|
||
end
|
||
|
||
-- Find terminal tab or create new one, then run command
|
||
local function TermRun(cmd)
|
||
local found = false
|
||
for i = 1, vim.fn.tabpagenr('$') do
|
||
vim.cmd('tabnext ' .. i)
|
||
if vim.bo.buftype == 'terminal' then
|
||
found = true
|
||
break
|
||
end
|
||
end
|
||
if not found then vim.cmd('tabnew | terminal') end
|
||
vim.fn.chansend(vim.b.terminal_job_id, '' .. cmd .. '\n')
|
||
vim.fn.feedkeys("G", "n")
|
||
end
|
||
|
||
-- The Configure command
|
||
vim.api.nvim_create_user_command("Configure", function(a)
|
||
local args = {}
|
||
local bt = "debug"
|
||
if #a.args > 0 then bt = a.args end
|
||
workspace.build_type = bt
|
||
updateBuildEnv()
|
||
writeWorkspace()
|
||
end, { nargs = '?', desc = "Update run/debug arguments" })
|
||
|
||
vim.api.nvim_create_user_command("Args", function(a) updateArgs(a.fargs) end,
|
||
{ nargs = '*', desc = "Update run/debug arguments" })
|
||
|
||
if dap_ok then
|
||
local lldb_init = {}
|
||
dap_configs = {
|
||
{
|
||
name = 'test all',
|
||
type = 'codelldb',
|
||
request = 'launch',
|
||
program = bin_name,
|
||
args = workspace.args,
|
||
cwd = '${workspaceFolder}',
|
||
stopOnEntry = false,
|
||
initCommands = lldb_init
|
||
}
|
||
}
|
||
dap_def_cfg = dap_configs[1]
|
||
dap.providers.configs["project"] = function()
|
||
return dap_configs
|
||
end
|
||
|
||
-- DebugArgs to set debugger arguments and run immediately
|
||
vim.api.nvim_create_user_command("DebugArgs", function(a)
|
||
updateArgs(a.fargs)
|
||
dap.run(dap_configs[1])
|
||
end, { nargs = '*', desc = "Starts debugging with specified arguments" })
|
||
end
|
||
|
||
if MakeAnd then
|
||
local r = function()
|
||
MakeAnd(function()
|
||
TermRun(bin_name .. " " .. table.concat(workspace.args, " "))
|
||
end)
|
||
end
|
||
-- RunArgs sets the run arguments that F6 uses and reruns immediately
|
||
vim.api.nvim_create_user_command("RunArgs", function(a)
|
||
updateArgs(a.fargs)
|
||
r()
|
||
end, { nargs = '*', desc = "Starts debugging with specified arguments" })
|
||
|
||
-- F6 to run the application
|
||
vim.keymap.set('n', '<F6>', r)
|
||
|
||
if dap_ok then
|
||
-- Shift-F5 to launch default config
|
||
vim.keymap.set('n', '<F17>', function()
|
||
MakeAnd(function()
|
||
dap.run(dap_def_cfg)
|
||
end)
|
||
end)
|
||
end
|
||
end
|