Skip to content

Commit

Permalink
Add all and hierarchy flags to terminate
Browse files Browse the repository at this point in the history
Relates to #1166
  • Loading branch information
mfussenegger committed Dec 5, 2024
1 parent 6fd05c6 commit 249022f
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 37 deletions.
35 changes: 26 additions & 9 deletions doc/dap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -737,24 +737,41 @@ restart({config}) *dap.restart()*
configuration used to start the current session.


terminate(terminate_opts, disconnect_opts, cb), *dap.terminate()*
terminate(opts), *dap.terminate()*
Terminates the debug session.

If the debug adapter doesn't support the `terminateRequest`
capability, this will instead call |dap.disconnect()| with
`terminateDebugee = true`.

If disconnect is used, the `terminateDebugee` and `suspendDebugee`
options will only take effect if the debug adapter has the
corresponding capabilities.

Parameters: ~
{terminate_opts} Options for the `terminate` request.
Defaults to empty.
Not used if |dap.disconnect| is used.
{opts} Table containing:

- `terminate_args`: table; used if terminate is supported:
- `restart: boolean?

- `disconnect_args`: table; used if terminate is not
supported:
- `restart`: `boolean?`
- `terminateDebugee`: `boolean?`
- `suspendDebugee`: `boolean?`

- `on_done`: function triggered once terminate or
disconnect completes

{disconnect_opts} Opts for |dap.disconnect|
Defaults to `{ terminateDebuggee = true }`
- `all`: `boolean`: flag indicating that all root sessions
should be terminated instead of only the currently
focused session. Defaults to false

{cb} Callback that is invoked once the session
terminated or immediately if no session is
active.
- `hierarchy`: `boolean`: flag indicating that child and
parent sessions should be terminated. This will affect
the current focused session unless combined with `all`,
in that case it terminates all root sessions including
all their children.


set_breakpoint({condition}, {hit_condition}, {log_message})
Expand Down
108 changes: 80 additions & 28 deletions lua/dap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -748,60 +748,109 @@ end


---@param lsession dap.Session?
---@param terminate_opts dap.TerminateArguments?
---@param disconnect_opts dap.DisconnectArguments?
---@param cb fun()?
local function terminate(lsession, terminate_opts, disconnect_opts, cb)
cb = cb or function() end
---@param opts dap.terminate.Opts?
local function terminate(lsession, opts)
opts = opts or {}
local on_done = opts.on_done or function() end
if not lsession then
notify('No active session')
cb()
on_done()
return
end

if lsession.closed then
log().warn('User called terminate on already closed session that is still in use')
sessions[lsession.id] = nil
M.set_session(nil)
cb()
on_done()
return
end
local capabilities = lsession.capabilities or {}
if capabilities.supportsTerminateRequest then
capabilities.supportsTerminateRequest = false
local opts = terminate_opts or vim.empty_dict()
local args = opts.terminate_args or vim.empty_dict()
local timeout_sec = (lsession.adapter.options or {}).disconnect_timeout_sec or 3
local timeout_ms = timeout_sec * 1000
lsession:request_with_timeout('terminate', opts, timeout_ms, function(err)
lsession:request_with_timeout('terminate', args, timeout_ms, function(err)
if err then
log().warn(lazy.utils.fmt_error(err))
end
if not lsession.closed then
lsession:close()
end
notify('Session terminated')
cb()
on_done()
end)
else
local opts = disconnect_opts or { terminateDebuggee = true }
lsession:disconnect(opts, cb)
local args = opts.disconnect_args or { terminateDebuggee = true }
lsession:disconnect(args, on_done)
end
end

---@class dap.terminate.Opts
---@field terminate_args dap.TerminateArguments?
---@field disconnect_args dap.DisconnectArguments?
---@field on_done function?
---@field hierarchy boolean? terminate full hierarchy. Defaults to false
---@field all boolean? terminate all root sessions. Can be combined with hierarchy. Defaults to false

---@param terminate_opts dap.TerminateArguments?
---@param disconnect_opts dap.DisconnectArguments?
---@param cb fun()?
function M.terminate(terminate_opts, disconnect_opts, cb)
local lsession = session
if not lsession then
local _, s = next(sessions)
if s then
log().info("Terminate called without active session, switched to", s.id)

---@param opts dap.terminate.Opts?
function M.terminate(opts, disconnect_opts, cb)
opts = opts or {}
-- old signature was:
--- - terminate_opts dap.TerminateArguments?
--- - disconnect_opts dap.DisconnectArguments?
--- - cb fun()?
---@diagnostic disable-next-line: undefined-field
if opts.restart ~= nil or disconnect_opts ~= nil or cb ~= nil then
opts = {
---@diagnostic disable-next-line: assign-type-mismatch
terminate_args = opts,
disconnect_args = disconnect_opts,
on_done = cb,
hierarchy = false,
all = false,
}
end

local hierarchy = lazy.utils.if_nil(opts.hierarchy, false)
local all = lazy.utils.if_nil(opts.all, false)

---@param s dap.Session
local function rec_terminate(s)
terminate(s, opts)
if hierarchy then
for _, child in pairs(s.children) do
rec_terminate(child)
end
end
lsession = s
end
terminate(lsession, terminate_opts, disconnect_opts, cb)

if all then
for _, s in pairs(sessions) do
rec_terminate(s)
end
else
local lsession = session
if not lsession then
local _, s = next(sessions)
if s then
log().info("Terminate called without active session, switched to", s.id)
end
lsession = s
end
if not lsession then
return
end
if hierarchy then
while lsession.parent ~= nil do
lsession = lsession.parent
assert(lsession)
end
end
rec_terminate(lsession)
end
end


Expand Down Expand Up @@ -861,11 +910,14 @@ function M.restart(config, opts)
end)
end)
else
terminate(lsession, nil, nil, vim.schedule_wrap(function()
local nopts = opts and vim.deepcopy(opts) or {}
nopts.new = true
M.run(config, nopts)
end))
local terminate_opts = {
on_done = vim.schedule_wrap(function()
local nopts = opts and vim.deepcopy(opts) or {}
nopts.new = true
M.run(config, nopts)
end)
}
terminate(lsession, terminate_opts)
end
end

Expand Down

0 comments on commit 249022f

Please sign in to comment.