local vim = vim local cmd = vim.cmd local api = vim.api local M = {} local function register_debug_adapters(cwd) local dap = require 'dap' dap.adapters.python = { type = 'executable', command = "python", args = { "-m", "debugpy.adapter" } } dap.adapters.go = function(callback, _) -- _ config local stdout = vim.loop.new_pipe(false) local stderr = vim.loop.new_pipe(false) local handle local pid_or_err local port = 38697 local opts = { stdio = { nil, stdout }, args = { "run", "-i", "--rm", "--security-opt=seccomp:unconfined", "--volume=/var/run/docker.sock:/var/run/docker.sock", "--env-file=" .. cwd .. "/.env", "-e=GOPROXY=https://proxy.golang.org", "-e=GOOS=linux", "-e=GOARCH=amd64", "-e=GOPATH=" .. cwd .. "/go", "-e=GOCACHE=" .. cwd .. "/.cache/go-build", "-v", cwd .. ":" .. cwd, -- TODO: use os.getenv here "-w", cwd, -- TODO: use find root here "--network", "host", "mvinkio/go", "dlv", "dap", "-l", "127.0.0.1:" .. port, "--only-same-user=false", "--log", }, detached = false } handle, pid_or_err = vim.loop.spawn("docker", opts, function(code) stdout:close() stderr:close() handle:close() if code ~= 0 then print('dlv exited with code', code) end end) assert(handle, 'Error running dlv: ' .. tostring(pid_or_err)) stdout:read_start(function(err, chunk) assert(not err, err) if chunk then P(chunk) vim.schedule(function() require('dap.repl').append(chunk) end) end end) stderr:read_start(function(err, chunk) assert(not err, err) if chunk then P(chunk) end end) -- Wait for delve to start vim.defer_fn( function() callback({ type = "server", host = "127.0.0.1", port = port }) end, 2000) end end local function set_configurations() local dap = require 'dap' dap.configurations.python = { { type = 'python'; request = 'launch'; name = "Launch file"; program = "${file}"; }, } dap.configurations.go = { { type = "go", name = "Debug", request = "launch", program = "${file}" }, { type = "go", name = "Debug test", -- configuration for debugging test files request = "launch", mode = "test", program = vim.fn.fnamemodify(vim.fn.expand('%'), ':p:h') }, { type = "go", name = "Debug test (go.mod)", request = "launch", mode = "test", program = "./${relativeFileDirname}" } } local set_go_keymaps = function() vim.keymap.set( "n", "df", [[lua require'vimrc.dap'.continue(require'dap'.configurations.go[1])]], { noremap = true } ) vim.keymap.set( "n", "df", [[lua require'vimrc.dap'.continue(require'dap'.configurations.go[1])]], { noremap = true } ) end local augroup = api.nvim_create_augroup("vimrc_go_dap_config", { clear = true }) api.nvim_create_autocmd("FileType", { pattern = "go", callback = set_go_keymaps, group = augroup }) end local function set_keymaps() local map = vim.api.nvim_set_keymap -- taken from: https://github.com/Furkanzmc/dotfiles/blob/master/vim/lua/vimrc/dap.lua -- version: 9561e7c700e0ffe74cf9fd61a0e4543ae14938c6 map("n", "dc", ":lua require'vimrc.dap'.continue()", { silent = true, noremap = true }) map("n", "dt", ":lua require'dap'.close()", { silent = true, noremap = true }) map("n", "ds", ":lua require'dap'.step_into()", { silent = true, noremap = true }) map("n", "dk", ":lua require('dapui').eval()", { silent = true, noremap = true }) map("v", "dk", ":lua require('dapui').eval()", { silent = true, noremap = true }) map("n", "do", ":lua require'dap'.step_out()", { silent = true, noremap = true }) map("n", "dn", ":lua require'dap'.step_over()", { silent = true, noremap = true }) map("n", "du", ":lua require'dap'.up()", { silent = true, noremap = true }) map("n", "dd", ":lua require'dap'.down()", { silent = true, noremap = true }) map( "n", "db", ":lua require'dap'.toggle_breakpoint()", { silent = true, noremap = true } ) map( "n", "dbc", ":lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))", { silent = true, noremap = true } ) map( "n", "dbl", ":lua require'dap'.set_breakpoint(nil, nil, vim.fn.input('Log point message: '))", { silent = true, noremap = true } ) map("n", "dui", ":lua require'dapui'.toggle()", { silent = true, noremap = true }) map("n", "dr", ":lua require'dap'.run_to_cursor()", { silent = true, noremap = true }) map( "n", "dl", ":lua require'dap'.list_breakpoints(true)", { silent = true, noremap = true } ) -- map( -- "n", -- "dp", -- ":lua require'dap.ui.variables'.scopes()", -- { silent = true, noremap = true } -- ) end local function set_commands() cmd([[command! DapUIOpen :lua require'dapui'.open()]]) cmd([[command! DapUIClose :lua require'dapui'.close()]]) end function M.continue(config) local dap = require 'dap' register_debug_adapters(vim.fn.getcwd()) set_configurations() if config then dap.run(config) else dap.continue() end end function M.setup_dap() if vim.o.loadplugins == false then return end local vim_startup_dir = vim.fn.getcwd() register_debug_adapters(vim_startup_dir) set_configurations() cmd [[augroup vimrc_dap]] cmd [[au!]] cmd [[au FileType dap-repl lua require('dap.ext.autocompl').attach()]] cmd [[augroup END]] -- Commands and keymaps require('dapui').setup() set_keymaps() set_commands() end return M