@@ -13,7 +13,28 @@ local function get_session()
1313 return require (' dap' ).session ()
1414end
1515
16+ local repl
1617local execute -- required for forward reference
18+ local function execute_current (opts )
19+ local current_text = api .nvim_buf_get_lines (repl .buf , - 2 , - 1 , false )[1 ]
20+ local prompt_length = # vim .fn .prompt_getprompt (repl .buf )
21+ execute (string.sub (current_text , prompt_length + 1 ), opts )
22+ end
23+
24+
25+ local REGULAR_PROMPT = 1
26+ local FOLLOWUP_PROMPT = 2
27+ local PROMPT_STATE = ' PROMPT_STATE'
28+
29+ local function get_prompt (buf )
30+ buf = buf or repl .buf
31+ local prompt_state = vim .b [buf ][PROMPT_STATE ]
32+ if prompt_state == REGULAR_PROMPT then
33+ return ' dap> '
34+ else
35+ return ' ...> '
36+ end
37+ end
1738
1839
1940local function new_buf ()
@@ -31,7 +52,12 @@ local function new_buf()
3152 api .nvim_buf_set_keymap (buf , ' n' , ' o' , " <Cmd>lua require('dap.ui').trigger_actions()<CR>" , {})
3253 api .nvim_buf_set_keymap (buf , ' i' , ' <up>' , " <Cmd>lua require('dap.repl').on_up()<CR>" , {})
3354 api .nvim_buf_set_keymap (buf , ' i' , ' <down>' , " <Cmd>lua require('dap.repl').on_down()<CR>" , {})
34- vim .fn .prompt_setprompt (buf , ' dap> ' )
55+
56+ -- CR keybindings may require additional for some terminals see https://stackoverflow.com/a/42461580
57+ vim .keymap .set (' i' , ' <S-CR>' , function () execute_current ({force_followup = true }) end , {buffer = buf })
58+ vim .keymap .set (' i' , ' <C-CR>' , function () execute_current ({force_finish = true }) end , {buffer = buf })
59+ vim .b [buf ][PROMPT_STATE ] = REGULAR_PROMPT
60+ vim .fn .prompt_setprompt (buf , get_prompt (buf ))
3561 vim .fn .prompt_setcallback (buf , execute )
3662 return buf
3763end
@@ -46,7 +72,7 @@ local function new_win(buf, winopts, wincmd)
4672 return win
4773end
4874
49- local repl = ui .new_view (
75+ repl = ui .new_view (
5076 new_buf ,
5177 new_win , {
5278 before_open = function ()
@@ -197,7 +223,48 @@ local function print_threads(threads)
197223end
198224
199225
200- function execute (text )
226+ ---- Handle multiline inputs
227+ --
228+ -- Returns nil if input is not complete, otherwise returns the full user input
229+ local function handle_followup_input (curr_text , force_followup , force_finish )
230+ local session = get_session ()
231+ if not session then
232+ return curr_text
233+ end
234+ local is_multiline = session .adapter .is_multiline
235+ if not force_followup and not is_multiline then
236+ return curr_text
237+ end
238+ local buf_state = vim .b [repl .buf ]
239+ local prompt_state = buf_state [PROMPT_STATE ]
240+ if prompt_state == REGULAR_PROMPT and (force_followup or is_multiline (curr_text )) then
241+ buf_state [PROMPT_STATE ] = FOLLOWUP_PROMPT
242+ buf_state [' curr_text' ] = { curr_text }
243+ vim .fn .prompt_setprompt (repl .buf , get_prompt ())
244+ return nil
245+ elseif prompt_state == FOLLOWUP_PROMPT then
246+ local all_text = buf_state [' curr_text' ]
247+ if curr_text == ' ' or force_finish then
248+ buf_state [PROMPT_STATE ] = REGULAR_PROMPT
249+ vim .fn .prompt_setprompt (repl .buf , get_prompt ())
250+ table.insert (all_text , curr_text )
251+ return table.concat (all_text , ' \n ' )
252+ else
253+ table.insert (all_text , curr_text )
254+ vim .b [repl .buf ][' curr_text' ] = all_text
255+ return nil
256+ end
257+ end
258+ return curr_text
259+ end
260+
261+ function execute (text , opts )
262+ opts = opts or {}
263+ text = handle_followup_input (text , opts .force_followup , opts .force_finish )
264+ if text == nil then
265+ return
266+ end
267+
201268 if text == ' ' then
202269 if history .last then
203270 text = history .last
@@ -315,7 +382,7 @@ local function select_history(delta)
315382 local text = history .entries [history .idx ]
316383 if text then
317384 local lnum = vim .fn .line (' $' ) - 1
318- api .nvim_buf_set_lines (repl .buf , lnum , lnum + 1 , true , {' dap> ' .. text })
385+ api .nvim_buf_set_lines (repl .buf , lnum , lnum + 1 , true , {get_prompt () .. text })
319386 end
320387end
321388
382449 local session = get_session ()
383450 local col = api .nvim_win_get_cursor (0 )[2 ]
384451 local line = api .nvim_get_current_line ()
385- local offset = vim .startswith (line , ' dap> ' ) and 5 or 0
452+ local offset = vim .startswith (line , get_prompt () ) and 5 or 0
386453 local line_to_cursor = line :sub (offset + 1 , col )
387454 local text_match = vim .fn .match (line_to_cursor , ' \\ k*$' )
388455 if vim .startswith (line_to_cursor , ' .' ) or base ~= ' ' then
0 commit comments