# HG changeset patch # User Christian Brabandt # Date 1505063704 -7200 # Node ID 29d21591ad6b0e1614f6c01615bba04cabbfc266 # Parent 8dc58ac828aee12bd690c5a56481a41c888bcdfe patch 8.0.1092: terminal debugger can't evaluate expressions commit https://github.com/vim/vim/commit/45d5f26d11d9aac2383453d2c1a8582cad1c8a3d Author: Bram Moolenaar Date: Sun Sep 10 19:14:31 2017 +0200 patch 8.0.1092: terminal debugger can't evaluate expressions Problem: Terminal debugger can't evaluate expressions. Solution: Add :Evaluate and K. Various other improvements. diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -1,4 +1,4 @@ -*terminal.txt* For Vim version 8.0. Last change: 2017 Sep 09 +*terminal.txt* For Vim version 8.0. Last change: 2017 Sep 10 VIM REFERENCE MANUAL by Bram Moolenaar @@ -318,11 +318,12 @@ To start debugging use `:TermDebug` folo :TermDebug vim This opens two windows: -- A terminal window in which "gdb vim" is executed. Here you can directly - interact with gdb. The buffer name is "!gdb". -- A terminal window for the executed program. When "run" is used in gdb the - program I/O will happen in this window, so that it does not interfere with - controlling gdb. The buffer name is "gdb program". +gdb window A terminal window in which "gdb vim" is executed. Here you + can directly interact with gdb. The buffer name is "!gdb". +program window A terminal window for the executed program. When "run" is + used in gdb the program I/O will happen in this window, so + that it does not interfere with controlling gdb. The buffer + name is "gdb program". The current window is used to show the source code. When gdb pauses the source file location will be displayed, if possible. A sign is used to @@ -334,7 +335,8 @@ to display the current gdb position. Focus the terminal of the executed program to interact with it. This works the same as any command running in a terminal window. -When the debugger ends the two opened windows are closed. +When the debugger ends, typically by typing "quit" in the gdb window, the two +opened windows are closed. Stepping through code ~ @@ -349,13 +351,29 @@ Put focus on the gdb window to type comm - frame N go to the Nth stack frame - continue continue execution -In the window showing the source code some commands can passed to gdb: -- Break set a breakpoint at the current line; a sign will be displayed -- Delete delete a breakpoint at the current line -- Step execute the gdb "step" command -- NNext execute the gdb "next" command (:Next is a Vim command) -- Finish execute the gdb "finish" command -- Continue execute the gdb "continue" command +In the window showing the source code some commands can used to control gdb: + :Break set a breakpoint at the current line; a sign will be displayed + :Delete delete a breakpoint at the current line + :Step execute the gdb "step" command + :Over execute the gdb "next" command (:Next is a Vim command) + :Finish execute the gdb "finish" command + :Continue execute the gdb "continue" command + + +Inspecting variables ~ + + :Evaluate evaluate the expression under the cursor + K same + :Evaluate {expr} evaluate {expr} + :'<,'>Evaluate evaluate the Visually selected text + +This is similar to using "print" in the gdb window. + + +Other commands ~ + + :Gdb jump to the gdb window + :Program jump to the window with the running program Communication ~ @@ -386,9 +404,5 @@ When 'background' is "dark": hi debugBreakpoint term=reverse ctermbg=red guibg=red -NOT WORKING YET: ~ - -Values of variables can be inspected, etc. - vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -54,6 +54,7 @@ func s:StartDebug(cmd) return endif let pty = job_info(term_getjob(s:ptybuf))['tty_out'] + let s:ptywin = win_getid(winnr()) " Create a hidden terminal window to communicate with gdb let s:commbuf = term_start('NONE', { @@ -81,12 +82,15 @@ func s:StartDebug(cmd) exe 'bwipe! ' . s:commbuf return endif + let s:gdbwin = win_getid(winnr()) " Connect gdb to the communication pty, using the GDB/MI interface call term_sendkeys(gdbbuf, 'new-ui mi ' . commpty . "\r") - " Install debugger commands. + " Install debugger commands in the text window. + call win_gotoid(s:startwin) call s:InstallCommands() + call win_gotoid(s:gdbwin) let s:breakpoints = {} endfunc @@ -116,10 +120,14 @@ func s:CommOutput(chan, msg) if msg != '' if msg =~ '^\*\(stopped\|running\)' call s:HandleCursor(msg) - elseif msg =~ '^\^done,bkpt=' + elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' call s:HandleNewBreakpoint(msg) elseif msg =~ '^=breakpoint-deleted,' call s:HandleBreakpointDelete(msg) + elseif msg =~ '^\^done,value=' + call s:HandleEvaluate(msg) + elseif msg =~ '^\^error,msg=' + call s:HandleError(msg) endif endif endfor @@ -130,9 +138,15 @@ func s:InstallCommands() command Break call s:SetBreakpoint() command Delete call s:DeleteBreakpoint() command Step call s:SendCommand('-exec-step') - command NNext call s:SendCommand('-exec-next') + command Over call s:SendCommand('-exec-next') command Finish call s:SendCommand('-exec-finish') command Continue call s:SendCommand('-exec-continue') + command -range -nargs=* Evaluate call s:Evaluate(, ) + command Gdb call win_gotoid(s:gdbwin) + command Program call win_gotoid(s:ptywin) + + " TODO: can the K mapping be restored? + nnoremap K :Evaluate endfunc " Delete installed debugger commands in the current window. @@ -140,9 +154,21 @@ func s:DeleteCommands() delcommand Break delcommand Delete delcommand Step - delcommand NNext + delcommand Over delcommand Finish delcommand Continue + delcommand Evaluate + delcommand Gdb + delcommand Program + + nunmap K + sign undefine debugPC + sign undefine debugBreakpoint + exe 'sign unplace ' . s:pc_id + for key in keys(s:breakpoints) + exe 'sign unplace ' . (s:break_id + key) + endfor + unlet s:breakpoints endfunc " :Break - Set a breakpoint at the cursor position. @@ -171,6 +197,35 @@ func s:SendCommand(cmd) call term_sendkeys(s:commbuf, a:cmd . "\r") endfunc +" :Evaluate - evaluate what is under the cursor +func s:Evaluate(range, arg) + if a:arg != '' + let expr = a:arg + elseif a:range == 2 + let pos = getcurpos() + let reg = getreg('v', 1, 1) + let regt = getregtype('v') + normal! gv"vy + let expr = @v + call setpos('.', pos) + call setreg('v', reg, regt) + else + let expr = expand('') + endif + call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . expr . "\"\r") + let s:evalexpr = expr +endfunc + +" Handle the result of data-evaluate-expression +func s:HandleEvaluate(msg) + echomsg '"' . s:evalexpr . '": ' . substitute(a:msg, '.*value="\(.*\)"', '\1', '') +endfunc + +" Handle an error. +func s:HandleError(msg) + echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '') +endfunc + " Handle stopping and running message from gdb. " Will update the sign that shows the current position. func s:HandleCursor(msg) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1092, +/**/ 1091, /**/ 1090,