mirror of
https://github.com/macocianradu/setup.git
synced 2026-03-18 21:00:04 +00:00
added dap dotnet config
This commit is contained in:
@@ -3,139 +3,42 @@ local dapui = require("dapui")
|
|||||||
|
|
||||||
dapui.setup()
|
dapui.setup()
|
||||||
|
|
||||||
dap.listeners.after.event_initialized["dapui_config"] = function()
|
dap.listeners.after.event_initialized["dapui_config"] = function() dapui.open() end
|
||||||
dapui.open()
|
dap.listeners.after.event_terminated["dapui_config"] = function() dapui.close() end
|
||||||
|
dap.listeners.after.event_exited["dapui_config"] = function() dapui.close() end
|
||||||
|
|
||||||
|
local dotnet = require("dap.dap-dotnet")
|
||||||
|
local odoo = require("dap.dap-odoo")
|
||||||
|
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<leader>5", function()
|
||||||
|
if odoo.is_odoo_project() then
|
||||||
|
odoo.debug_odoo()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
local ft = vim.bo.filetype
|
||||||
dap.listeners.after.event_terminated["dapui_config"] = function()
|
if ft == "cs" or ft == "fsharp" or ft == "vb" then
|
||||||
dapui.close()
|
dotnet.debug_dotnet_from_sln()
|
||||||
end
|
|
||||||
|
|
||||||
dap.listeners.after.event_exited["dapui_config"] = function()
|
|
||||||
dapui.close()
|
|
||||||
end
|
|
||||||
|
|
||||||
require("dap-python").setup("~/projects/odoo/venv/bin/python3")
|
|
||||||
dap.adapters['pwa-chrome'] = {
|
|
||||||
type = 'server',
|
|
||||||
host = 'localhost',
|
|
||||||
port = '${port}',
|
|
||||||
executable = {
|
|
||||||
command = 'node',
|
|
||||||
args = {
|
|
||||||
vim.fn.stdpath('data') .. '/mason/packages/js-debug-adapter/js-debug/src/dapDebugServer.js',
|
|
||||||
'${port}',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
local function is_odoo_project()
|
|
||||||
local cwd = vim.fn.getcwd()
|
|
||||||
return vim.fn.filereadable(cwd .. "/odoo-bin") == 1 or
|
|
||||||
vim.fn.filereadable(cwd .. "/odoo/odoo-bin") == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local function debug_odoo()
|
|
||||||
local db_name = vim.fn.input('Odoo DB: ', 'master')
|
|
||||||
if db_name == "" then return end
|
|
||||||
|
|
||||||
dap.run({
|
|
||||||
type = "python",
|
|
||||||
request = "launch",
|
|
||||||
name = "Odoo Server",
|
|
||||||
program = "/home/admac/projects/odoo/odoo/odoo-bin",
|
|
||||||
pythonPath = "/home/admac/projects/odoo/venv/bin/python3",
|
|
||||||
args = {
|
|
||||||
"--addons-path", "/home/admac/projects/odoo/enterprise/,/home/admac/projects/odoo/odoo/addons/",
|
|
||||||
"--dev", "all",
|
|
||||||
"-d", db_name
|
|
||||||
},
|
|
||||||
console = "externalTerminal",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function run_odoo_test_at_cursor()
|
|
||||||
-- Safely get the node at cursor
|
|
||||||
local status, node = pcall(vim.treesitter.get_node)
|
|
||||||
if not status or not node then
|
|
||||||
print("Error: Tree-sitter parser not found. Ensure you are in a Python buffer.")
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Safety Limit: Prevent infinite loop if tree is malformed
|
if dotnet.find_sln_upwards and dotnet.find_sln_upwards() then
|
||||||
local attempts = 0
|
dotnet.debug_dotnet_from_sln()
|
||||||
while node do
|
|
||||||
if node:type() == 'function_definition' then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
node = node:parent()
|
|
||||||
attempts = attempts + 1
|
|
||||||
if attempts > 50 then
|
|
||||||
print("Error: Could not find function definition (traversal limit reached).")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not node then
|
|
||||||
print("Cursor is not inside a function definition.")
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Extract function name safely
|
|
||||||
local func_name = nil
|
|
||||||
for child in node:iter_children() do
|
|
||||||
if child:type() == 'identifier' then
|
|
||||||
func_name = vim.treesitter.get_node_text(child, 0)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not func_name then
|
|
||||||
print("Error: Could not extract function name.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local db = vim.fn.input("Database: ")
|
|
||||||
if db == nil or db == "" then
|
|
||||||
print("Canceled (no database provided).")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
print("Launching Debugger for: " .. func_name)
|
|
||||||
|
|
||||||
dap.run({
|
|
||||||
type = "python",
|
|
||||||
request = "launch",
|
|
||||||
name = "Debug Test: " .. func_name,
|
|
||||||
pythonPath = "/home/admac/projects/odoo/venv/bin/python3",
|
|
||||||
program = "/home/admac/projects/odoo/odoo/odoo-bin",
|
|
||||||
args = {
|
|
||||||
"--addons-path", "/home/admac/projects/odoo/enterprise/,/home/admac/projects/odoo/odoo/addons/",
|
|
||||||
"-d", db,
|
|
||||||
"--log-level=warn",
|
|
||||||
"--test-tags", "." .. func_name,
|
|
||||||
"--stop-after-init",
|
|
||||||
},
|
|
||||||
console = "externalTerminal",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>d5", function()
|
|
||||||
if is_odoo_project() then
|
|
||||||
debug_odoo()
|
|
||||||
else
|
|
||||||
dap.continue()
|
dap.continue()
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
vim.keymap.set("n", "<leader>5", function() dap.continue() end)
|
|
||||||
vim.keymap.set("n", "<leader>6", function() dap.step_over() end)
|
vim.keymap.set("n", "<leader><Up>", function() dap.continue() end)
|
||||||
vim.keymap.set("n", "<leader>+", function() dap.step_into() end)
|
vim.keymap.set("n", "<leader><Down>", function() dap.step_over() end)
|
||||||
vim.keymap.set("n", "<leader>-", function() dap.step_out() end)
|
vim.keymap.set("n", "<leader><Right>", function() dap.step_into() end)
|
||||||
|
vim.keymap.set("n", "<leader><Left>", function() dap.step_out() end)
|
||||||
vim.keymap.set("n", "<leader>b", function() dap.toggle_breakpoint() end)
|
vim.keymap.set("n", "<leader>b", function() dap.toggle_breakpoint() end)
|
||||||
vim.keymap.set("n", "<leader>B", function() dap.set_breakpoint(vim.fn.input("Breakpoint condition: ")) end)
|
vim.keymap.set("n", "<leader>B", function() dap.set_breakpoint(vim.fn.input("Breakpoint condition: ")) end)
|
||||||
vim.keymap.set("n", "<leader>qd", function() dap.terminate() end)
|
vim.keymap.set("n", "<leader>qd", function() dap.terminate() end)
|
||||||
vim.keymap.set("n", "<leader>rd", function() dap.restart() end)
|
vim.keymap.set("n", "<leader>rd", function() dap.restart() end)
|
||||||
vim.keymap.set("n", "<leader>dt", run_odoo_test_at_cursor, { desc = "Debug Odoo Test unde Cursor" })
|
vim.keymap.set("n", "<leader>dt", odoo.run_odoo_test_at_cursor, { desc = "Debug Odoo Test unde Cursor" })
|
||||||
|
|
||||||
dap.configurations.python = {
|
dap.configurations.python = {
|
||||||
{
|
{
|
||||||
|
|||||||
211
.config/nvim/lua/dap/dap-dotnet.lua
Normal file
211
.config/nvim/lua/dap/dap-dotnet.lua
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
local dap = require("dap")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- Adapter (netcoredbg)
|
||||||
|
dap.adapters.coreclr = {
|
||||||
|
type = "executable",
|
||||||
|
command = vim.fn.stdpath("data") .. "/mason/packages/netcoredbg/netcoredbg",
|
||||||
|
args = { "--interpreter=vscode" },
|
||||||
|
}
|
||||||
|
|
||||||
|
-- -------- helpers --------
|
||||||
|
|
||||||
|
local function is_windows()
|
||||||
|
return vim.loop.os_uname().sysname:match("Windows") ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function joinpath(...)
|
||||||
|
local sep = is_windows() and "\\" or "/"
|
||||||
|
return table.concat({ ... }, sep)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parent_dir(path)
|
||||||
|
return vim.fn.fnamemodify(path, ":h")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function file_exists(path)
|
||||||
|
return vim.fn.filereadable(path) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_csproj_upwards()
|
||||||
|
local start = vim.api.nvim_buf_get_name(0)
|
||||||
|
if start ~= "" then
|
||||||
|
start = parent_dir(start)
|
||||||
|
else
|
||||||
|
start = vim.fn.getcwd()
|
||||||
|
end
|
||||||
|
|
||||||
|
local projs = vim.fs.find(function(name)
|
||||||
|
return name:match("%.csproj$")
|
||||||
|
end, { upward = true, path = start, type = "file" })
|
||||||
|
|
||||||
|
if #projs == 0 then return nil end
|
||||||
|
if #projs == 1 then return projs[1] end
|
||||||
|
|
||||||
|
-- multiple csproj found upwards: pick one
|
||||||
|
local display = { "Select project:" }
|
||||||
|
for _, p in ipairs(projs) do
|
||||||
|
table.insert(display, vim.fn.fnamemodify(p, ":~"))
|
||||||
|
end
|
||||||
|
local choice = vim.fn.inputlist(display)
|
||||||
|
if choice < 2 then return nil end
|
||||||
|
return projs[choice - 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_sln_upwards()
|
||||||
|
-- Prefer starting from current file's dir (if any), else cwd
|
||||||
|
local start = vim.api.nvim_buf_get_name(0)
|
||||||
|
if start ~= "" then
|
||||||
|
start = parent_dir(start)
|
||||||
|
else
|
||||||
|
start = vim.fn.getcwd()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Requires Neovim 0.9+ (vim.fs.find)
|
||||||
|
local slns = vim.fs.find(function(name)
|
||||||
|
return name:match("%.sln$")
|
||||||
|
end, { upward = true, path = start, type = "file" })
|
||||||
|
|
||||||
|
if #slns == 0 then return nil end
|
||||||
|
if #slns == 1 then return slns[1] end
|
||||||
|
|
||||||
|
-- Multiple solutions found: pick one
|
||||||
|
local choice = vim.fn.inputlist(vim.list_extend({ "Select solution:" }, slns))
|
||||||
|
if choice < 1 then return nil end
|
||||||
|
return slns[choice]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dotnet_sln_list_projects(sln)
|
||||||
|
local out = vim.fn.system({ "dotnet", "sln", sln, "list" })
|
||||||
|
if vim.v.shell_error ~= 0 then
|
||||||
|
vim.notify(out, vim.log.levels.ERROR)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local projects = {}
|
||||||
|
local sln_dir = parent_dir(sln)
|
||||||
|
|
||||||
|
for line in out:gmatch("[^\r\n]+") do
|
||||||
|
-- dotnet sln list outputs relative paths like:
|
||||||
|
-- "src/MyApp/MyApp.csproj"
|
||||||
|
if line:match("%.csproj%s*$") then
|
||||||
|
line = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||||
|
local full = line
|
||||||
|
|
||||||
|
-- Make absolute if needed
|
||||||
|
if not full:match("^/") and not full:match("^[A-Za-z]:\\") then
|
||||||
|
full = joinpath(sln_dir, line)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(projects, full)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #projects == 0 then
|
||||||
|
vim.notify("No .csproj entries found in solution list output.", vim.log.levels.ERROR)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(projects)
|
||||||
|
return projects
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pick_startup_project(projects)
|
||||||
|
if #projects == 1 then return projects[1] end
|
||||||
|
|
||||||
|
local display = { "Select startup project:" }
|
||||||
|
for _, p in ipairs(projects) do
|
||||||
|
table.insert(display, vim.fn.fnamemodify(p, ":~"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local choice = vim.fn.inputlist(display)
|
||||||
|
if choice < 2 then return nil end
|
||||||
|
return projects[choice - 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dotnet_build(csproj)
|
||||||
|
vim.notify("dotnet build: " .. vim.fn.fnamemodify(csproj, ":~"))
|
||||||
|
local out = vim.fn.system({ "dotnet", "build", csproj, "-c", "Debug" })
|
||||||
|
if vim.v.shell_error ~= 0 then
|
||||||
|
vim.notify(out, vim.log.levels.ERROR)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_built_dll(csproj)
|
||||||
|
local proj_dir = parent_dir(csproj)
|
||||||
|
local proj_name = vim.fn.fnamemodify(csproj, ":t:r")
|
||||||
|
|
||||||
|
-- Find all candidate DLLs under bin/Debug/**/<ProjectName>.dll
|
||||||
|
local glob_pat = joinpath(proj_dir, "bin", "Debug", "*", proj_name .. ".dll")
|
||||||
|
local matches = vim.fn.glob(glob_pat, false, true)
|
||||||
|
|
||||||
|
if #matches == 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If multiple TFMs, pick the newest by mtime
|
||||||
|
table.sort(matches, function(a, b)
|
||||||
|
local sa = vim.loop.fs_stat(a)
|
||||||
|
local sb = vim.loop.fs_stat(b)
|
||||||
|
local ta = sa and sa.mtime.sec or 0
|
||||||
|
local tb = sb and sb.mtime.sec or 0
|
||||||
|
return ta < tb
|
||||||
|
end)
|
||||||
|
|
||||||
|
return matches[#matches]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- -------- main --------
|
||||||
|
|
||||||
|
local function debug_dotnet_from_sln()
|
||||||
|
local sln = find_sln_upwards()
|
||||||
|
local csproj = nil
|
||||||
|
if sln then
|
||||||
|
local projects = dotnet_sln_list_projects(sln)
|
||||||
|
if projects then
|
||||||
|
csproj = pick_startup_project(projects)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not csproj then
|
||||||
|
csproj = find_csproj_upwards()
|
||||||
|
if not csproj then
|
||||||
|
vim.notify("No .sln or .csproj found upwards from current file/cwd.", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if not dotnet_build(csproj) then
|
||||||
|
vim.notify("Build failed — not starting debugger.", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local dll = find_built_dll(csproj)
|
||||||
|
if not dll or not file_exists(dll) then
|
||||||
|
vim.notify("Could not locate built DLL for: " .. csproj, vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
dap.run({
|
||||||
|
type = "coreclr",
|
||||||
|
request = "launch",
|
||||||
|
name = "Debug .NET (sln startup)",
|
||||||
|
program = dll,
|
||||||
|
cwd = parent_dir(sln),
|
||||||
|
console = "integratedTerminal",
|
||||||
|
stopAtEntry = false,
|
||||||
|
env = {
|
||||||
|
ASPNETCORE_ENVIRONMENT = "Development",
|
||||||
|
DOTNET_ENVIRONMENT = "Development",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Export if you want to require it elsewhere
|
||||||
|
M.debug_dotnet_from_sln = debug_dotnet_from_sln
|
||||||
|
M.find_sln_upwards = find_sln_upwards
|
||||||
|
|
||||||
|
return M
|
||||||
114
.config/nvim/lua/dap/dap-odoo.lua
Normal file
114
.config/nvim/lua/dap/dap-odoo.lua
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
local dap = require("dap")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
require("dap-python").setup("~/projects/odoo/venv/bin/python3")
|
||||||
|
dap.adapters['pwa-chrome'] = {
|
||||||
|
type = 'server',
|
||||||
|
host = 'localhost',
|
||||||
|
port = '${port}',
|
||||||
|
executable = {
|
||||||
|
command = 'node',
|
||||||
|
args = {
|
||||||
|
vim.fn.stdpath('data') .. '/mason/packages/js-debug-adapter/js-debug/src/dapDebugServer.js',
|
||||||
|
'${port}',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function is_odoo_project()
|
||||||
|
local cwd = vim.fn.getcwd()
|
||||||
|
return vim.fn.filereadable(cwd .. "/odoo-bin") == 1 or
|
||||||
|
vim.fn.filereadable(cwd .. "/odoo/odoo-bin") == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function debug_odoo()
|
||||||
|
local db_name = vim.fn.input('Odoo DB: ', 'master')
|
||||||
|
if db_name == "" then return end
|
||||||
|
|
||||||
|
dap.run({
|
||||||
|
type = "python",
|
||||||
|
request = "launch",
|
||||||
|
name = "Odoo Server",
|
||||||
|
program = "/home/admac/projects/odoo/odoo/odoo-bin",
|
||||||
|
pythonPath = "/home/admac/projects/odoo/venv/bin/python3",
|
||||||
|
args = {
|
||||||
|
"--addons-path", "/home/admac/projects/odoo/enterprise/,/home/admac/projects/odoo/odoo/addons/",
|
||||||
|
"--dev", "all",
|
||||||
|
"-d", db_name
|
||||||
|
},
|
||||||
|
console = "externalTerminal",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run_odoo_test_at_cursor()
|
||||||
|
-- Safely get the node at cursor
|
||||||
|
local status, node = pcall(vim.treesitter.get_node)
|
||||||
|
if not status or not node then
|
||||||
|
print("Error: Tree-sitter parser not found. Ensure you are in a Python buffer.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Safety Limit: Prevent infinite loop if tree is malformed
|
||||||
|
local attempts = 0
|
||||||
|
while node do
|
||||||
|
if node:type() == 'function_definition' then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
node = node:parent()
|
||||||
|
attempts = attempts + 1
|
||||||
|
if attempts > 50 then
|
||||||
|
print("Error: Could not find function definition (traversal limit reached).")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not node then
|
||||||
|
print("Cursor is not inside a function definition.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Extract function name safely
|
||||||
|
local func_name = nil
|
||||||
|
for child in node:iter_children() do
|
||||||
|
if child:type() == 'identifier' then
|
||||||
|
func_name = vim.treesitter.get_node_text(child, 0)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not func_name then
|
||||||
|
print("Error: Could not extract function name.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local db = vim.fn.input("Database: ")
|
||||||
|
if db == nil or db == "" then
|
||||||
|
print("Canceled (no database provided).")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Launching Debugger for: " .. func_name)
|
||||||
|
|
||||||
|
dap.run({
|
||||||
|
type = "python",
|
||||||
|
request = "launch",
|
||||||
|
name = "Debug Test: " .. func_name,
|
||||||
|
pythonPath = "/home/admac/projects/odoo/venv/bin/python3",
|
||||||
|
program = "/home/admac/projects/odoo/odoo/odoo-bin",
|
||||||
|
args = {
|
||||||
|
"--addons-path", "/home/admac/projects/odoo/enterprise/,/home/admac/projects/odoo/odoo/addons/",
|
||||||
|
"-d", db,
|
||||||
|
"--log-level=warn",
|
||||||
|
"--test-tags", "." .. func_name,
|
||||||
|
"--stop-after-init",
|
||||||
|
},
|
||||||
|
console = "externalTerminal",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
M.is_odoo_project = is_odoo_project
|
||||||
|
M.debug_odoo = debug_odoo
|
||||||
|
M.run_odoo_test_at_cursor = run_odoo_test_at_cursor
|
||||||
|
|
||||||
|
return M
|
||||||
Reference in New Issue
Block a user