Skip to content

Commit 7abd59c

Browse files
committed
fix: do not clear term on session termination (#83)
1 parent efb540a commit 7abd59c

File tree

7 files changed

+63
-51
lines changed

7 files changed

+63
-51
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ All of that in a unified, unintrusive window.
3434

3535
## Getting Started
3636

37-
Start a regular debugging session. When desired, you can use `:DapViewOpen` to start the plugin. You can switch to another section using the letter outlined in the `'winbar'` (e.g., `B` for "Breakpoints"). Explore what you can do each section by using `g?` to inspect the keymaps.
37+
Start a regular debugging session. When desired, you can use `:DapViewOpen` to start the plugin. You can switch to another section using the letter outlined in the `'winbar'` (e.g., `B` for "Breakpoints"). Explore what you can do in each section by using `g?` to inspect the keymaps.
3838

3939
Once you're done debugging, you can close the plugin with `:DapViewClose` and then terminate your session as usual.
4040

docs/src/routes/known-issues/+page.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,3 @@ title: Known Issues
99
- Can't "toggle" a breakpoint ([#74](https://github.com/igorlfs/nvim-dap-view/issues/74))
1010

1111
These limitations stem from `nvim-dap`'s breakpoints API (or more so, from the lack of a proper one). A new API is [planned](https://github.com/mfussenegger/nvim-dap/issues/1388).
12-
13-
## The terminal buffer is cleared right after a session finishes ([#83](https://github.com/igorlfs/nvim-dap-view/issues/83))
14-
15-
Due to a limitation in the way multisession support is currently implemented, it's necessary to eagerly close buffers. Read [this](https://github.com/mfussenegger/nvim-dap/discussions/1523) discussion for details.

lua/dap-view/events.lua

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,8 @@ dap.listeners.on_session[SUBSCRIPTION_ID] = function(_, new)
2222
state.current_session_id = new.id
2323
state.current_adapter = new.config.type
2424

25-
-- Avoid creating useless buffers for child sessions
26-
if new.parent == nil then
27-
if not state.term_bufnrs[new.id] then
28-
state.term_bufnrs[new.id] = term.setup_term_win_cmd()
29-
30-
if not (term_config.start_hidden or vim.tbl_contains(config.winbar.sections, "console")) then
31-
term.open_term_buf_win()
32-
end
33-
end
34-
else
35-
state.term_bufnrs[new.id] = state.term_bufnrs[new.parent.id]
36-
end
37-
38-
if not vim.tbl_contains(term_config.hide, state.current_adapter) then
25+
-- Handle switching the buf if session is already initialized
26+
if new.term_buf and not vim.tbl_contains(term_config.hide, state.current_adapter) then
3927
term.switch_term_buf()
4028
end
4129

@@ -58,6 +46,25 @@ dap.listeners.after.configurationDone[SUBSCRIPTION_ID] = function()
5846
-- Sync exception breakpoints for the newly initialized session
5947
-- The downside is that not all adapters support `configurationDone` :/
6048
require("dap-view.exceptions").update_exception_breakpoints_filters()
49+
50+
local config = setup.config
51+
local term_config = config.windows.terminal
52+
53+
local has_console = vim.tbl_contains(config.winbar.sections, "console")
54+
local hidden_adapter = vim.tbl_contains(term_config.hide, state.current_adapter)
55+
local open_term = not term_config.start_hidden and not has_console and not hidden_adapter
56+
57+
-- We can't setup inside `on_session` hook because at that stage the session does not have a `term_buf`
58+
term.setup_term_buf()
59+
60+
-- `term_buf` must be setup before calling open
61+
if open_term then
62+
term.open_term_buf_win()
63+
end
64+
65+
if not hidden_adapter then
66+
term.switch_term_buf()
67+
end
6168
end
6269

6370
dap.listeners.after.setBreakpoints[SUBSCRIPTION_ID] = function()
@@ -142,7 +149,7 @@ dap.listeners.after.initialize[SUBSCRIPTION_ID] = function(session)
142149
end
143150
end
144151

145-
dap.listeners.after.event_terminated[SUBSCRIPTION_ID] = function(session)
152+
dap.listeners.after.event_terminated[SUBSCRIPTION_ID] = function()
146153
-- Refresh threads view on exit to avoid showing outdated trace
147154
if state.current_section == "threads" then
148155
threads.show()
@@ -159,17 +166,6 @@ dap.listeners.after.event_terminated[SUBSCRIPTION_ID] = function(session)
159166
end
160167
end
161168

162-
-- TODO find a cleaner way to dispose of these buffers
163-
local term_bufnr = state.term_bufnrs[session.id]
164-
if util.is_buf_valid(term_bufnr) then
165-
vim.api.nvim_buf_delete(term_bufnr, { force = true })
166-
end
167-
for k, v in pairs(state.term_bufnrs) do
168-
if v == term_bufnr then
169-
state.term_bufnrs[k] = nil
170-
end
171-
end
172-
173169
winbar.redraw_controls()
174170
end
175171

lua/dap-view/state.lua

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
---@class dapview.State
2323
---@field bufnr? integer
2424
---@field winnr? integer
25-
---@field term_bufnrs {[number]: number}
2625
---@field term_winnr? integer
2726
---@field last_term_winnr? integer
2827
---@field threads_filter string
@@ -40,7 +39,6 @@
4039
---@field watched_expressions table<string, dapview.ExpressionPack>
4140
---@field cur_pos table<dapview.DefaultSection,integer?>
4241
local M = {
43-
term_bufnrs = {},
4442
threads_filter = "",
4543
threads_filter_invert = false,
4644
exceptions_options = {},

lua/dap-view/term/init.lua

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ M.show = function()
1515
return
1616
end
1717

18-
assert(state.current_session_id, "has active session")
18+
local session = dap.session()
19+
20+
assert(session ~= nil, "has active session")
21+
assert(session.term_buf, "session has term")
1922

2023
api.nvim_win_call(state.winnr, function()
2124
vim.wo[state.winnr][0].winfixbuf = false
22-
api.nvim_set_current_buf(state.term_bufnrs[state.current_session_id])
25+
api.nvim_set_current_buf(session.term_buf)
2326
vim.wo[state.winnr][0].winfixbuf = true
2427
end)
2528

@@ -41,10 +44,18 @@ end
4144
---III. There's no term win or it is invalid
4245
---@return integer?
4346
M.open_term_buf_win = function()
44-
if not state.current_session_id then
47+
local session = require("dap").session()
48+
49+
if session == nil then
50+
return nil
51+
end
52+
53+
local term_bufnr = session.term_buf
54+
55+
if term_bufnr == nil then
56+
vim.notify_once("No terminal for the current session")
4557
return nil
4658
end
47-
local term_bufnr = state.term_bufnrs[state.current_session_id]
4859

4960
local windows_config = setup.config.windows
5061
local term_config = setup.config.windows.terminal
@@ -74,13 +85,17 @@ M.open_term_buf_win = function()
7485
return state.term_winnr
7586
end
7687

77-
---Create a term buf and setup nvim-dap's `terminal_win_cmd` to use it
78-
M.setup_term_win_cmd = function()
79-
-- Can't use an unlisted term buffers
80-
-- See https://github.com/igorlfs/nvim-dap-view/pull/37#issuecomment-2785076872
81-
local term_bufnr = api.nvim_create_buf(true, false)
88+
M.setup_term_buf = function()
89+
local session = dap.session()
90+
91+
assert(session ~= nil, "has active session")
8292

83-
assert(term_bufnr ~= 0, "Failed to create dap-view-term buffer")
93+
local term_bufnr = session.term_buf
94+
95+
if term_bufnr == nil then
96+
vim.notify("No terminal for the current session")
97+
return
98+
end
8499

85100
-- We have to set the filetype for each term buf to avoid issues when calling switch_term_buf
86101
-- See https://github.com/igorlfs/nvim-dap-view/issues/69
@@ -91,25 +106,28 @@ M.setup_term_win_cmd = function()
91106
end
92107

93108
require("dap-view.term.scroll").scroll(term_bufnr)
94-
95-
dap.defaults.fallback.terminal_win_cmd = function()
96-
return term_bufnr
97-
end
98-
99-
return term_bufnr
100109
end
101110

102111
M.switch_term_buf = function()
103112
local has_console = vim.tbl_contains(setup.config.winbar.sections, "console")
104113
local winnr = (has_console and state.winnr) or state.term_winnr
105114
local is_console_active = state.current_section == "console"
106115

116+
local session = dap.session()
117+
118+
assert(session ~= nil, "has active session")
119+
120+
if session.term_buf == nil then
121+
vim.notify_once("No terminal for the current session")
122+
return
123+
end
124+
107125
if util.is_win_valid(winnr) and (is_console_active or not has_console) then
108126
---@cast winnr integer
109127

110128
api.nvim_win_call(winnr, function()
111129
vim.wo[winnr][0].winfixbuf = false
112-
api.nvim_set_current_buf(state.term_bufnrs[state.current_session_id])
130+
api.nvim_set_current_buf(session.term_buf)
113131
vim.wo[winnr][0].winfixbuf = true
114132

115133
if is_console_active then

lua/dap-view/term/options.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ local M = {}
22

33
---@param winnr integer
44
M.set_win_options = function(winnr)
5-
local win = vim.wo[winnr][0]
5+
-- We actually want other buffers (e.g, term_bufs from other sessions) to inherit these options
6+
local win = vim.wo[winnr]
67
win.scrolloff = 0
78
win.wrap = false
89
win.number = false

plugin/dap-view.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
-- Let nvim-dap handle terminal buffers internally without interfering in the layout
2+
require("dap").defaults.fallback.terminal_win_cmd = nil
3+
14
local command = vim.api.nvim_create_user_command
25

36
command("DapViewOpen", function()

0 commit comments

Comments
 (0)