summaryrefslogtreecommitdiff
path: root/config/nvim/lua/plugins/dap.lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--config/nvim/lua/plugins/dap.lua254
1 files changed, 155 insertions, 99 deletions
diff --git a/config/nvim/lua/plugins/dap.lua b/config/nvim/lua/plugins/dap.lua
index 6a17265..95cb891 100644
--- a/config/nvim/lua/plugins/dap.lua
+++ b/config/nvim/lua/plugins/dap.lua
@@ -1,125 +1,174 @@
return {
{
"mfussenegger/nvim-dap",
+ event = "VeryLazy",
+ dependencies = {
+ "leoluz/nvim-dap-go",
+ },
config = function()
local dap = require("dap")
- dap.adapters.go = {
- type = "server",
- port = "${port}",
- executable = {
- command = "dlv",
- args = { "dap", "-l", "127.0.0.1:${port}" },
- },
- }
- -- Хранение истории аргументов для каждой точки входа
- local _args_history = {}
-
- -- Функция для запроса аргументов у пользователя с историей (возвращает строку для парсинга)
- local function get_args(entry_point)
- local cache_key = entry_point
- local default = _args_history[cache_key] or ""
- local prompt = "Arguments for " .. entry_point .. ": "
- local input = vim.fn.input(prompt, default)
- if input and #input > 0 then
- _args_history[cache_key] = input
+ -- Find project root (where go.mod is)
+ local function find_project_root()
+ local current = vim.fn.getcwd()
+ local function find_go_mod(dir)
+ if vim.fn.filereadable(dir .. "/go.mod") == 1 then
+ return dir
+ end
+ local parent = vim.fn.fnamemodify(dir, ":h")
+ if parent == dir or parent == "" then
+ return nil
+ end
+ return find_go_mod(parent)
end
- return _args_history[cache_key]
+ return find_go_mod(current)
end
- -- Генерация конфигураций для Go на основе точек входа
- local function generate_go_configs()
- local workspace_folder = vim.fn.getcwd()
+ -- Find all main.go files in project
+ local function find_main_files(root)
+ -- Use vim glob to find main.go files (excludes vendor)
+ local pattern = root .. "/**/main.go"
+ local files = vim.fn.glob(pattern, true, true)
- -- Проверка существования .env файла в корне проекта
- local env_file = nil
- if vim.fn.filereadable(workspace_folder .. "/.env") == 1 then
- env_file = "${workspaceFolder}/.env"
+ -- Filter out vendor
+ local main_files = {}
+ for _, f in ipairs(files) do
+ if not string.match(f, "/vendor/") then
+ table.insert(main_files, f)
+ end
end
+ return main_files
+ end
- local configs = {}
- local entry_points = {}
+ -- Store last args per main file
+ local last_args = {}
- -- Поиск точки входа: main.go в корне или cmd/*/main.go
- if vim.fn.filereadable(workspace_folder .. "/main.go") == 1 then
- table.insert(entry_points, {
- name = "main",
- path = "${workspaceFolder}",
- })
+ -- Custom debug function with Telescope picker
+ local function debug_go_custom()
+ local root = find_project_root()
+ if not root then
+ vim.notify("Could not find project root (go.mod)", vim.log.levels.ERROR)
+ return
end
- -- Поиск cmd/*/main.go
- local cmd_dirs = vim.fn.glob(workspace_folder .. "/cmd/*", 0, 1)
- for _, cmd_dir in ipairs(cmd_dirs) do
- local main_path = cmd_dir .. "/main.go"
- if vim.fn.filereadable(main_path) == 1 then
- local entry_name = vim.fn.fnamemodify(cmd_dir, ":t")
- table.insert(entry_points, {
- name = entry_name,
- path = cmd_dir,
- })
- end
+ local main_files = find_main_files(root)
+ if #main_files == 0 then
+ vim.notify("No main.go files found", vim.log.levels.WARN)
+ return
end
- -- Генерация конфигураций для каждой точки входа
- for _, entry in ipairs(entry_points) do
- -- Базовая конфигурация без аргументов
- table.insert(configs, {
- type = "go",
- name = "Debug " .. entry.name,
- request = "launch",
- program = entry.path,
- cwd = "${workspaceFolder}",
- envFile = env_file,
- buildFlags = "",
- outputMode = "remote",
- })
+ -- Use Telescope to pick
+ local telescope = require("telescope")
+ local actions = require("telescope.actions")
+ local pickers = require("telescope.pickers")
+ local finders = require("telescope.finders")
+ local conf = require("telescope.config").values
- -- Конфигурация с аргументами (функция для запроса при запуске)
- table.insert(configs, {
- type = "go",
- name = "Debug " .. entry.name .. " (args)",
- request = "launch",
- program = entry.path,
- cwd = "${workspaceFolder}",
- envFile = env_file,
- buildFlags = "",
- outputMode = "remote",
- args = function()
- local args_str = get_args(entry.name)
- -- Разбиваем строку аргументов на массив
- local args = {}
- for arg in args_str:gmatch("%S+") do
- table.insert(args, arg)
- end
- return args
- end,
- })
+ -- Format: relative path + last args
+ local entries = {}
+ for _, f in ipairs(main_files) do
+ local rel = vim.fn.fnamemodify(f, ":.")
+ local args = last_args[f] or ""
+ table.insert(entries, { path = f, display = rel .. (args ~= "" and (" [" .. args .. "]") or "") })
end
- -- Remote attach конфигурация для подключения к уже запущенному delve
- table.insert(configs, {
- type = "go",
- name = "Remote attach (127.0.0.1:43000)",
- request = "attach",
- mode = "remote",
- port = "43000",
- host = "127.0.0.1",
- })
+ pickers.new({}, {
+ prompt_title = "Select main.go",
+ finder = finders.new_table({
+ results = entries,
+ entry_maker = function(entry)
+ return {
+ value = entry.path,
+ display = entry.display,
+ ordinal = entry.display,
+ }
+ end,
+ }),
+ sorter = conf.generic_sorter({}),
+ attach_mappings = function(prompt_bufnr)
+ actions.select_default:replace(function()
+ local selection = require("telescope.actions.state").get_selected_entry(prompt_bufnr)
+ local main_path = selection.value
+
+ -- Get last args or empty
+ local default_args = last_args[main_path] or ""
+
+ vim.api.nvim_buf_delete(prompt_bufnr, { force = true })
+
+ -- Ask for args
+ vim.ui.input({
+ prompt = "Args: ",
+ default = default_args,
+ }, function(input)
+ if input ~= nil then
+ -- Save args
+ last_args[main_path] = input
- return configs
+ -- Parse args into table
+ local args_tbl = {}
+ if input ~= "" then
+ for w in string.gmatch(input, "[^%s]+") do
+ table.insert(args_tbl, w)
+ end
+ end
+
+ -- Build config
+ local config = {
+ type = "go",
+ name = "Debug: " .. vim.fn.fnamemodify(main_path, ":t"),
+ request = "launch",
+ program = main_path,
+ cwd = root,
+ outputMode = "remote",
+ args = args_tbl,
+ }
+
+ -- Check if already running
+ require("dap-go").setup() -- Ensure Go adapter is registered
+ if dap.session() then
+ dap.terminate(nil, nil, function()
+ dap.run(config)
+ end)
+ else
+ dap.run(config)
+ end
+ end
+ end)
+ end)
+ return true
+ end,
+ }):find()
end
- -- Установка конфигураций Go
- dap.configurations.go = generate_go_configs()
+ -- Go adapter configuration
+ dap.configurations.go = {
+ {
+ type = "go",
+ name = "Debug",
+ request = "launch",
+ program = "${file}",
+ outputMode = "remote",
+ },
+ {
+ type = "go",
+ name = "Debug test",
+ request = "launch",
+ mode = "test",
+ program = "${file}",
+ outputMode = "remote",
+ },
+ {
+ type = "go",
+ name = "Debug test (package)",
+ request = "launch",
+ mode = "test",
+ program = "${workspaceFolder}",
+ outputMode = "remote",
+ },
+ }
- -- Автообновление конфигураций при открытии Go файла
- vim.api.nvim_create_autocmd("BufReadPost", {
- pattern = "*.go",
- callback = function()
- dap.configurations.go = generate_go_configs()
- end,
- })
+ -- Register custom command
+ vim.api.nvim_create_user_command("DapGoCustom", debug_go_custom, {})
end,
keys = {
{
@@ -165,6 +214,13 @@ return {
desc = "Debug step out",
},
{
+ "<leader>dd",
+ function()
+ vim.cmd("DapGoCustom")
+ end,
+ desc = "Debug Go (custom)",
+ },
+ {
"<A-b>",
function()
require("dap").toggle_breakpoint()
@@ -183,6 +239,7 @@ return {
},
{
"rcarriga/nvim-dap-ui",
+ event = "VeryLazy",
dependencies = {
"mfussenegger/nvim-dap",
"nvim-neotest/nvim-nio",
@@ -264,7 +321,6 @@ return {
"leoluz/nvim-dap-go",
dependencies = { "mfussenegger/nvim-dap" },
ft = "go",
- -- Не используем автоconfig - конфигурации управляются в nvim-dap
keys = {
{
"<leader>dt",