@@ -16,7 +16,31 @@ local function get_session()
1616 return require (' dap' ).session ()
1717end
1818
19+ local repl
1920local execute -- required for forward reference
21+ local function execute_current (opts )
22+ local current_text = api .nvim_buf_get_lines (repl .buf , - 2 , - 1 , false )[1 ]
23+ local prompt_length = # vim .fn .prompt_getprompt (repl .buf )
24+ execute (string.sub (current_text , prompt_length + 1 ), opts )
25+ end
26+
27+
28+ local MULTILINE_INPUT = ' MULTILINE_INPUT'
29+
30+ --- @param buf number
31+ --- @return string[]
32+ local function get_multiline_input (buf )
33+ return vim .b [buf ][MULTILINE_INPUT ] or {}
34+ end
35+
36+ local function get_prompt (buf )
37+ buf = buf or repl .buf
38+ if # get_multiline_input (buf ) == 0 then
39+ return ' dap> '
40+ else
41+ return ' ...> '
42+ end
43+ end
2044
2145
2246local function new_buf ()
@@ -34,7 +58,11 @@ local function new_buf()
3458 api .nvim_buf_set_keymap (buf , ' n' , ' o' , " <Cmd>lua require('dap.ui').trigger_actions()<CR>" , {})
3559 api .nvim_buf_set_keymap (buf , ' i' , ' <up>' , " <Cmd>lua require('dap.repl').on_up()<CR>" , {})
3660 api .nvim_buf_set_keymap (buf , ' i' , ' <down>' , " <Cmd>lua require('dap.repl').on_down()<CR>" , {})
37- vim .fn .prompt_setprompt (buf , ' dap> ' )
61+
62+ -- CR keybindings may require additional configuration for some terminals, see https://stackoverflow.com/a/42461580
63+ vim .keymap .set (' i' , ' <S-CR>' , function () execute_current ({force_multiline = true }) end , {buffer = buf })
64+ vim .keymap .set (' i' , ' <C-CR>' , function () execute_current ({force_finish = true }) end , {buffer = buf })
65+ vim .fn .prompt_setprompt (buf , get_prompt (buf ))
3866 vim .fn .prompt_setcallback (buf , execute )
3967 if vim .fn .has (' nvim-0.7' ) == 1 then
4068 vim .keymap .set (' n' , ' G' , function ()
@@ -67,7 +95,7 @@ local function new_win(buf, winopts, wincmd)
6795 return win
6896end
6997
70- local repl = ui .new_view (
98+ repl = ui .new_view (
7199 new_buf ,
72100 new_win , {
73101 before_open = function ()
@@ -212,7 +240,34 @@ local function print_threads(threads)
212240end
213241
214242
215- function execute (text )
243+ --- @return string | nil full_input nil if input is incomplete
244+ local function handle_multiline_input (last_line , force_multiline , force_finish )
245+ local session = get_session ()
246+ if not session then
247+ return last_line
248+ end
249+ local current_inputs = get_multiline_input (repl .buf )
250+ table.insert (current_inputs , last_line )
251+ local is_multiline = session .adapter .is_multiline
252+ if not force_finish and (force_multiline or (is_multiline and is_multiline (current_inputs ))) then
253+ vim .b [repl .buf ][MULTILINE_INPUT ] = current_inputs
254+ if # current_inputs == 1 then
255+ vim .fn .prompt_setprompt (repl .buf , get_prompt ())
256+ end
257+ return nil
258+ end
259+ vim .b [repl .buf ][MULTILINE_INPUT ] = nil
260+ vim .fn .prompt_setprompt (repl .buf , get_prompt ())
261+ return table.concat (current_inputs , ' \n ' )
262+ end
263+
264+ function execute (text , opts )
265+ opts = opts or {}
266+ text = handle_multiline_input (text , opts .force_multiline , opts .force_finish )
267+ if text == nil then
268+ return
269+ end
270+
216271 if text == ' ' then
217272 if history .last then
218273 text = history .last
@@ -337,9 +392,9 @@ local function select_history(delta)
337392 history .idx = 1
338393 end
339394 local text = history .entries [history .idx ]
340- if text then
395+ if text and string.find ( text , ' \n ' ) == nil then
341396 local lnum = vim .fn .line (' $' )
342- api .nvim_buf_set_lines (repl .buf , lnum - 1 , lnum , true , {' dap> ' .. text })
397+ api .nvim_buf_set_lines (repl .buf , lnum - 1 , lnum , true , {get_prompt () .. text })
343398 vim .fn .setcursorcharpos ({ lnum , vim .fn .col (' $' ) }) -- move cursor to the end of line
344399 end
345400end
439494 local session = get_session ()
440495 local col = api .nvim_win_get_cursor (0 )[2 ]
441496 local line = api .nvim_get_current_line ()
442- local offset = vim .startswith (line , ' dap> ' ) and 5 or 0
497+ local offset = vim .startswith (line , get_prompt () ) and 5 or 0
443498 local line_to_cursor = line :sub (offset + 1 , col )
444499 local text_match = vim .fn .match (line_to_cursor , ' \\ k*$' )
445500 if vim .startswith (line_to_cursor , ' .' ) or base ~= ' ' then
0 commit comments