Commit: patch 9.1.1756: termdebug: Need a few more user commands

3 views
Skip to first unread message

Christian Brabandt

unread,
Sep 14, 2025, 4:45:16 AMSep 14
to vim...@googlegroups.com
patch 9.1.1756: termdebug: Need a few more user commands

Commit: https://github.com/vim/vim/commit/c975d62473327d7ca74666d41c99651c23f09498
Author: bennyyip <yeb...@gmail.com>
Date: Sun Sep 14 04:33:07 2025 -0400

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 <yeb...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/tags b/runtime/doc/tags
index b8acc9e56..31f55bdb0 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 eda0b8d48..c25e26597 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 3be4b135f..d4ee1ca77 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 <ubaldo...@gmail.com>

# WORK IN PROGRESS - The basics works stable, more to come
@@ -1173,6 +1173,7 @@ def InstallCommands()

command -nargs=? Break SetBreakpoint(<q-args>)
command -nargs=? Tbreak SetBreakpoint(<q-args>, 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 ' .. <q-args>)
command Stop StopCommand()
command Continue ContinueCommand()
+ command RunOrContinue RunOrContinue()

command -nargs=* Frame Frame(<q-args>)
command -count=1 Up Up(<count>)
@@ -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 fa7dd13bd..9fec8f882 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 01f1f9799..7782b6a13 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,
/**/
Reply all
Reply to author
Forward
0 new messages