From c975d62473327d7ca74666d41c99651c23f09498 Mon Sep 17 00:00:00 2001 From: bennyyip Date: Sun, 14 Sep 2025 04:33:07 -0400 Subject: [PATCH] patch 9.1.1756: termdebug: Need a few more user commands Problem: termdebug: Need a few more user commands Solution: Add the :RunOrContinue and the :ToggleBreak user commands (bennyyip) closes: #18283 Signed-off-by: bennyyip Signed-off-by: Christian Brabandt --- runtime/doc/tags | 2 + runtime/doc/terminal.txt | 6 +- .../dist/opt/termdebug/plugin/termdebug.vim | 32 ++++++- src/testdir/test_plugin_termdebug.vim | 83 +++++++++++++++++++ src/version.c | 2 + 5 files changed, 122 insertions(+), 3 deletions(-) diff --git a/runtime/doc/tags b/runtime/doc/tags index b8acc9e561..31f55bdb0f 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -2212,6 +2212,7 @@ $quote eval.txt /*$quote* :Rexplore pi_netrw.txt /*:Rexplore* :RmVimball pi_vimball.txt /*:RmVimball* :Run terminal.txt /*:Run* +:RunOrContinue terminal.txt /*:RunOrContinue* :RustEmitAsm ft_rust.txt /*:RustEmitAsm* :RustEmitIr ft_rust.txt /*:RustEmitIr* :RustExpand ft_rust.txt /*:RustExpand* @@ -2233,6 +2234,7 @@ $quote eval.txt /*$quote* :Termdebug terminal.txt /*:Termdebug* :TermdebugCommand terminal.txt /*:TermdebugCommand* :Texplore pi_netrw.txt /*:Texplore* +:ToggleBreak terminal.txt /*:ToggleBreak* :Tutor pi_tutor.txt /*:Tutor* :URLOpen eval.txt /*:URLOpen* :Until terminal.txt /*:Until* diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt index eda0b8d489..c25e265970 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -1,4 +1,4 @@ -*terminal.txt* For Vim version 9.1. Last change: 2025 Sep 02 +*terminal.txt* For Vim version 9.1. Last change: 2025 Sep 14 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1427,12 +1427,16 @@ gdb: :Tbreak {position} set a temporary breakpoint at the specified position *:Clear* delete the breakpoint at the cursor position + *:ToggleBreak* set a breakpoint at the cursor position or delete all + breakpoints at the cursor positoin *:Step* execute the gdb "step" command *:Over* execute the gdb "next" command (`:Next` is a Vim command) *:Until* execute the gdb "until" command *:Finish* execute the gdb "finish" command *:Continue* execute the gdb "continue" command + *:RunOrContinue* execute the gdb "continue" command if program is running, + otherwise run the program *:Stop* interrupt the program If 'mouse' is set the plugin adds a window toolbar with these entries: diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 3be4b135fd..d4ee1ca77d 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -4,7 +4,7 @@ vim9script # Author: Bram Moolenaar # Copyright: Vim license applies, see ":help license" -# Last Change: 2025 Sep 02 +# Last Change: 2025 Sep 14 # Converted to Vim9: Ubaldo Tiberi # WORK IN PROGRESS - The basics works stable, more to come @@ -1173,6 +1173,7 @@ def InstallCommands() command -nargs=? Break SetBreakpoint() command -nargs=? Tbreak SetBreakpoint(, true) + command ToggleBreak ToggleBreak() command Clear ClearBreakpoint() command Step SendResumingCommand('-exec-step') command Over SendResumingCommand('-exec-next') @@ -1182,6 +1183,7 @@ def InstallCommands() command -nargs=* Arguments SendResumingCommand('-exec-arguments ' .. ) command Stop StopCommand() command Continue ContinueCommand() + command RunOrContinue RunOrContinue() command -nargs=* Frame Frame() command -count=1 Up Up() @@ -1296,6 +1298,8 @@ def DeleteCommands() delcommand Asm delcommand Var delcommand Winbar + delcommand RunOrContinue + delcommand ToggleBreak if !empty(saved_K_map) && !saved_K_map.buffer @@ -1439,6 +1443,19 @@ def ClearBreakpoint() endif enddef +def ToggleBreak() + var fname = fnameescape(expand('%:p')) + var lnum = line('.') + var bploc = printf('%s:%d', fname, lnum) + if has_key(breakpoint_locations, bploc) + while has_key(breakpoint_locations, bploc) + ClearBreakpoint() + endwhile + else + SetBreakpoint("") + endif +enddef + def Run(args: string) if args != '' SendResumingCommand($'-exec-arguments {args}') @@ -1446,6 +1463,14 @@ def Run(args: string) SendResumingCommand('-exec-run') enddef +def RunOrContinue() + if running + ContinueCommand() + else + Run('') + endif +enddef + # :Frame - go to a specific frame in the stack def Frame(arg: string) # Note: we explicit do not use mi's command @@ -2004,7 +2029,10 @@ def HandleNewBreakpoint(msg: string, modifiedFlag: bool) if !has_key(breakpoint_locations, bploc) breakpoint_locations[bploc] = [] endif - breakpoint_locations[bploc] += [id] + if breakpoint_locations[bploc]->index(id) == -1 + # Make sure all ids are unique + breakpoint_locations[bploc] += [id] + endif var posMsg = '' if bufloaded(fname) diff --git a/src/testdir/test_plugin_termdebug.vim b/src/testdir/test_plugin_termdebug.vim index fa7dd13bdf..9fec8f882f 100644 --- a/src/testdir/test_plugin_termdebug.vim +++ b/src/testdir/test_plugin_termdebug.vim @@ -606,4 +606,87 @@ function Test_termdebug_config_types() unlet g:termdebug_config endfunction +func Test_termdebug_toggle_break() + let g:test_is_flaky = 1 + let bin_name = 'XTD_tbreak' + let src_name = bin_name .. '.c' + + eval s:generate_files(bin_name) + + execute 'edit ' .. src_name + execute 'Termdebug ./' .. bin_name + + call WaitForAssert({-> assert_true(get(g:, "termdebug_is_running", v:false))}) + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + let gdb_buf = winbufnr(1) + wincmd b + + let bp_line = 22 " 'return' statement in main + execute "normal! " .. bp_line .. "G" + execute "ToggleBreak" + + call term_wait(gdb_buf) + redraw! + call assert_equal([ + \ {'lnum': bp_line, 'id': 1014, 'name': 'debugBreakpoint1.0', + \ 'priority': 110, 'group': 'TermDebug'}], + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs) + + RunOrContinue + call term_wait(gdb_buf, 400) + redraw! + call WaitForAssert({-> assert_equal([ + \ {'lnum': bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110, + \ 'group': 'TermDebug'}, + \ {'lnum': bp_line, 'id': 1014, 'name': 'debugBreakpoint1.0', + \ 'priority': 110, 'group': 'TermDebug'}], + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) + + " Add one break point + execute "normal! " .. bp_line .. "G" + execute "ToggleBreak" + call term_wait(gdb_buf) + redraw! + call WaitForAssert({-> assert_equal([ + \ {'lnum': bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110, + \ 'group': 'TermDebug'}], + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) + + " Remove one break point + execute "normal! " .. bp_line .. "G" + execute "ToggleBreak" + call term_wait(gdb_buf) + redraw! + call WaitForAssert({-> assert_equal([ + \ {'lnum': bp_line, 'id': 2014, 'name': 'debugBreakpoint2.0', + \ 'priority': 110, 'group': 'TermDebug'}, + \ {'lnum': bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110, + \ 'group': 'TermDebug'}], + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) + + " Remove multiple break points + execute "Break" + execute "Break" + execute "Break" + execute "Break" + call term_wait(gdb_buf, 400) + execute "ToggleBreak" + call term_wait(gdb_buf) + redraw! + call WaitForAssert({-> assert_equal([ + \ {'lnum': bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110, + \ 'group': 'TermDebug'}], + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) + + + wincmd t + quit! + redraw! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs) + + eval s:cleanup_files(bin_name) + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 01f1f97990..7782b6a13d 100644 --- a/src/version.c +++ b/src/version.c @@ -724,6 +724,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1756, /**/ 1755, /**/