commit e6d3f87dfd71dde94aebce600fd11cb954af1ba9
parent 5d01d2338943ef535fdb40c9639269208e720d74
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 8 Apr 2023 19:27:58 +0800
fix(termdebug): handle partial lines passed to callback (#22950)
Problem:
Job callbacks in termdebug cannot handle partial lines.
Solution:
Add a wrapper function that handles partial lines and only passes full
lines to the real callback.
Fix #22929.
Diffstat:
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -245,7 +245,7 @@ func s:StartDebug_term(dict)
" Create a hidden terminal window to communicate with gdb
let s:comm_job_id = jobstart('tail -f /dev/null;#gdb communication', {
- \ 'on_stdout': function('s:CommOutput'),
+ \ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:CommOutput')}),
\ 'pty': v:true,
\ })
" hide terminal buffer
@@ -430,7 +430,7 @@ func s:StartDebug_prompt(dict)
" call ch_log('executing "' . join(gdb_cmd) . '"')
let s:gdbjob = jobstart(gdb_cmd, {
\ 'on_exit': function('s:EndPromptDebug'),
- \ 'on_stdout': function('s:GdbOutCallback'),
+ \ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:GdbOutCallback')}),
\ })
if s:gdbjob == 0
echoerr 'invalid argument (or job table is full) while starting gdb job'
@@ -594,6 +594,23 @@ func s:PromptInterrupt()
endif
endfunc
+" Wrapper around job callback that handles partial lines (:h channel-lines).
+" It should be called from a Dictionary with the following keys:
+" - last_line: the last (partial) line received
+" - real_cb: a callback that assumes full lines
+func s:JobOutCallback(jobid, data, event) dict
+ let eof = (a:data == [''])
+ let msgs = a:data
+ let msgs[0] = self.last_line .. msgs[0]
+ if eof
+ let self.last_line = ''
+ else
+ let self.last_line = msgs[-1]
+ unlet msgs[-1]
+ endif
+ call self.real_cb(a:jobid, msgs, a:event)
+endfunc
+
" Function called when gdb outputs text.
func s:GdbOutCallback(job_id, msgs, event)
"call ch_log('received from gdb: ' . a:text)