mirror of
https://github.com/neovim/neovim.git
synced 2025-09-14 15:28:17 +00:00
180
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
180
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
@@ -2,7 +2,7 @@
|
||||
"
|
||||
" Author: Bram Moolenaar
|
||||
" Copyright: Vim license applies, see ":help license"
|
||||
" Last Change: 2021 Nov 14
|
||||
" Last Change: 2021 Nov 21
|
||||
"
|
||||
" WORK IN PROGRESS - Only the basics work
|
||||
" Note: On MS-Windows you need a recent version of gdb. The one included with
|
||||
@@ -289,8 +289,9 @@ func s:StartDebug_term(dict)
|
||||
call chansend(s:gdb_job_id, 'set args ' . join(proc_args) . "\r")
|
||||
endif
|
||||
|
||||
" Connect gdb to the communication pty, using the GDB/MI interface
|
||||
call chansend(s:gdb_job_id, 'new-ui mi ' . commpty . "\r")
|
||||
" Connect gdb to the communication pty, using the GDB/MI interface.
|
||||
" Prefix "server" to avoid adding this to the history.
|
||||
call chansend(s:gdb_job_id, 'server new-ui mi ' . commpty . "\r")
|
||||
|
||||
" Wait for the response to show up, users may not notice the error and wonder
|
||||
" why the debugger doesn't work.
|
||||
@@ -309,7 +310,7 @@ func s:StartDebug_term(dict)
|
||||
let response = line1 . line2
|
||||
if response =~ 'Undefined command'
|
||||
echoerr 'Sorry, your gdb is too old, gdb 7.12 is required'
|
||||
call s:CloseBuffers()
|
||||
call s:CloseBuffers()
|
||||
return
|
||||
endif
|
||||
if response =~ 'New UI allocated'
|
||||
@@ -504,7 +505,7 @@ func TermDebugSendCommand(cmd)
|
||||
" needed once.
|
||||
call jobstop(s:gdbjob)
|
||||
else
|
||||
call s:SendCommand('-exec-interrupt')
|
||||
Stop
|
||||
endif
|
||||
sleep 10m
|
||||
endif
|
||||
@@ -595,14 +596,14 @@ func s:DecodeMessage(quotedText)
|
||||
if a:quotedText[i] == '\'
|
||||
let i += 1
|
||||
if a:quotedText[i] == 'n'
|
||||
" drop \n
|
||||
let i += 1
|
||||
continue
|
||||
" drop \n
|
||||
let i += 1
|
||||
continue
|
||||
elseif a:quotedText[i] == 't'
|
||||
" append \t
|
||||
let i += 1
|
||||
let result .= "\t"
|
||||
continue
|
||||
" append \t
|
||||
let i += 1
|
||||
let result .= "\t"
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
let result .= a:quotedText[i]
|
||||
@@ -657,8 +658,8 @@ func s:EndDebugCommon()
|
||||
if bufexists(bufnr)
|
||||
exe bufnr .. "buf"
|
||||
if exists('b:save_signcolumn')
|
||||
let &signcolumn = b:save_signcolumn
|
||||
unlet b:save_signcolumn
|
||||
let &signcolumn = b:save_signcolumn
|
||||
unlet b:save_signcolumn
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
@@ -769,7 +770,7 @@ func s:CommOutput(job_id, msgs, event)
|
||||
elseif msg != ''
|
||||
if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)'
|
||||
call s:HandleCursor(msg)
|
||||
elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,'
|
||||
elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' || msg =~ '^=breakpoint-modified,'
|
||||
call s:HandleNewBreakpoint(msg)
|
||||
elseif msg =~ '^=breakpoint-deleted,'
|
||||
call s:HandleBreakpointDelete(msg)
|
||||
@@ -809,12 +810,15 @@ func s:InstallCommands()
|
||||
command Finish call s:SendCommand('-exec-finish')
|
||||
command -nargs=* Run call s:Run(<q-args>)
|
||||
command -nargs=* Arguments call s:SendCommand('-exec-arguments ' . <q-args>)
|
||||
command Stop call s:SendCommand('-exec-interrupt')
|
||||
|
||||
" using -exec-continue results in CTRL-C in gdb window not working
|
||||
if s:way == 'prompt'
|
||||
command Stop call s:PromptInterrupt()
|
||||
command Continue call s:SendCommand('continue')
|
||||
else
|
||||
command Stop call s:SendCommand('-exec-interrupt')
|
||||
" using -exec-continue results in CTRL-C in the gdb window not working,
|
||||
" communicating via commbuf (= use of SendCommand) has the same result
|
||||
"command Continue call s:SendCommand('-exec-continue')
|
||||
command Continue call chansend(s:gdb_job_id, "continue\r")
|
||||
endif
|
||||
|
||||
@@ -913,20 +917,16 @@ func s:SetBreakpoint(at)
|
||||
let do_continue = 0
|
||||
if !s:stopped
|
||||
let do_continue = 1
|
||||
if s:way == 'prompt'
|
||||
call s:PromptInterrupt()
|
||||
else
|
||||
call s:SendCommand('-exec-interrupt')
|
||||
endif
|
||||
Stop
|
||||
sleep 10m
|
||||
endif
|
||||
|
||||
" Use the fname:lnum format, older gdb can't handle --source.
|
||||
let at = empty(a:at) ?
|
||||
\ fnameescape(expand('%:p')) . ':' . line('.') : a:at
|
||||
\ fnameescape(expand('%:p')) . ':' . line('.') : a:at
|
||||
call s:SendCommand('-break-insert ' . at)
|
||||
if do_continue
|
||||
call s:SendCommand('-exec-continue')
|
||||
Continue
|
||||
endif
|
||||
endfunc
|
||||
|
||||
@@ -937,23 +937,32 @@ func s:ClearBreakpoint()
|
||||
let bploc = printf('%s:%d', fname, lnum)
|
||||
if has_key(s:breakpoint_locations, bploc)
|
||||
let idx = 0
|
||||
let nr = 0
|
||||
for id in s:breakpoint_locations[bploc]
|
||||
if has_key(s:breakpoints, id)
|
||||
" Assume this always works, the reply is simply "^done".
|
||||
call s:SendCommand('-break-delete ' . id)
|
||||
for subid in keys(s:breakpoints[id])
|
||||
exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
|
||||
endfor
|
||||
unlet s:breakpoints[id]
|
||||
unlet s:breakpoint_locations[bploc][idx]
|
||||
break
|
||||
" Assume this always works, the reply is simply "^done".
|
||||
call s:SendCommand('-break-delete ' . id)
|
||||
for subid in keys(s:breakpoints[id])
|
||||
exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
|
||||
endfor
|
||||
unlet s:breakpoints[id]
|
||||
unlet s:breakpoint_locations[bploc][idx]
|
||||
let nr = id
|
||||
break
|
||||
else
|
||||
let idx += 1
|
||||
let idx += 1
|
||||
endif
|
||||
endfor
|
||||
if empty(s:breakpoint_locations[bploc])
|
||||
unlet s:breakpoint_locations[bploc]
|
||||
if nr != 0
|
||||
if empty(s:breakpoint_locations[bploc])
|
||||
unlet s:breakpoint_locations[bploc]
|
||||
endif
|
||||
echomsg 'Breakpoint ' . id . ' cleared from line ' . lnum . '.'
|
||||
else
|
||||
echoerr 'Internal error trying to remove breakpoint at line ' . lnum . '!'
|
||||
endif
|
||||
else
|
||||
echomsg 'No breakpoint to remove at line ' . lnum . '.'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
@@ -965,44 +974,72 @@ func s:Run(args)
|
||||
endfunc
|
||||
|
||||
func s:SendEval(expr)
|
||||
" clean up expression that may got in because of range
|
||||
" (newlines and surrounding spaces)
|
||||
let expr = a:expr
|
||||
if &filetype ==# 'cobol'
|
||||
" extra cleanup for COBOL: _every: expression ends with a period,
|
||||
" a trailing comma is ignored as it commonly separates multiple expr.
|
||||
let expr = substitute(expr, '\..*', '', '')
|
||||
let expr = substitute(expr, '[;\n]', ' ', 'g')
|
||||
let expr = substitute(expr, ',*$', '', '')
|
||||
" check for "likely" boolean expressions, in which case we take it as lhs
|
||||
if a:expr =~ "[=!<>]="
|
||||
let exprLHS = a:expr
|
||||
else
|
||||
let expr = substitute(expr, '\n', ' ', 'g')
|
||||
" remove text that is likely an assignment
|
||||
let exprLHS = substitute(a:expr, ' *=.*', '', '')
|
||||
endif
|
||||
let expr = substitute(expr, '^ *\(.*\) *', '\1', '')
|
||||
|
||||
" encoding expression to prevent bad errors
|
||||
let expr = a:expr
|
||||
let expr = substitute(expr, '\\', '\\\\', 'g')
|
||||
let expr = substitute(expr, '"', '\\"', 'g')
|
||||
call s:SendCommand('-data-evaluate-expression "' . expr . '"')
|
||||
let s:evalexpr = expr
|
||||
let s:evalexpr = exprLHS
|
||||
endfunc
|
||||
|
||||
" :Evaluate - evaluate what is under the cursor
|
||||
" :Evaluate - evaluate what is specified / under the cursor
|
||||
func s:Evaluate(range, arg)
|
||||
let expr = s:GetEvaluationExpression(a:range, a:arg)
|
||||
let s:ignoreEvalError = 0
|
||||
call s:SendEval(expr)
|
||||
endfunc
|
||||
|
||||
" get what is specified / under the cursor
|
||||
func s:GetEvaluationExpression(range, arg)
|
||||
if a:arg != ''
|
||||
let expr = a:arg
|
||||
let s:evalFromBalloonExpr = 0
|
||||
" user supplied evaluation
|
||||
let expr = s:CleanupExpr(a:arg)
|
||||
" DSW: replace "likely copy + paste" assignment
|
||||
let expr = substitute(expr, '"\([^"]*\)": *', '\1=', 'g')
|
||||
elseif a:range == 2
|
||||
let pos = getcurpos()
|
||||
let reg = getreg('v', 1, 1)
|
||||
let regt = getregtype('v')
|
||||
normal! gv"vy
|
||||
let expr = @v
|
||||
let expr = s:CleanupExpr(@v)
|
||||
call setpos('.', pos)
|
||||
call setreg('v', reg, regt)
|
||||
let s:evalFromBalloonExpr = 1
|
||||
else
|
||||
" no evaluation provided: get from C-expression under cursor
|
||||
" TODO: allow filetype specific lookup #9057
|
||||
let expr = expand('<cexpr>')
|
||||
let s:evalFromBalloonExpr = 1
|
||||
endif
|
||||
let s:ignoreEvalError = 0
|
||||
call s:SendEval(expr)
|
||||
return expr
|
||||
endfunc
|
||||
|
||||
" clean up expression that may got in because of range
|
||||
" (newlines and surrounding whitespace)
|
||||
func s:CleanupExpr(expr)
|
||||
" replace all embedded newlines/tabs/...
|
||||
let expr = substitute( a:expr, '\s', ' ', 'g')
|
||||
|
||||
if &filetype ==# 'cobol'
|
||||
" extra cleanup for COBOL: _every: expression ends with a period,
|
||||
" a semicolon nmay be used instead of a space
|
||||
" a trailing comma is ignored as it commonly separates multiple expr
|
||||
let expr = substitute(expr, '\..*', '', '')
|
||||
let expr = substitute(expr, ';', ' ', 'g')
|
||||
let expr = substitute(expr, ',*$', '', '')
|
||||
endif
|
||||
|
||||
" get rid of surrounding spaces
|
||||
let expr = substitute(expr, '^ *\(.*\) *', '\1', '')
|
||||
return expr
|
||||
endfunc
|
||||
|
||||
let s:ignoreEvalError = 0
|
||||
@@ -1246,15 +1283,15 @@ func s:HandleCursor(msg)
|
||||
let s:asm_addr = asm_addr
|
||||
|
||||
let curwinid = win_getid(winnr())
|
||||
if win_gotoid(s:asmwin)
|
||||
let lnum = search('^' . s:asm_addr)
|
||||
if lnum == 0
|
||||
call s:SendCommand('disassemble $pc')
|
||||
else
|
||||
exe 'sign unplace ' . s:asm_id
|
||||
exe 'sign place ' . s:asm_id . ' line=' . lnum . ' name=debugPC'
|
||||
if win_gotoid(s:asmwin)
|
||||
let lnum = search('^' . s:asm_addr)
|
||||
if lnum == 0
|
||||
call s:SendCommand('disassemble $pc')
|
||||
else
|
||||
exe 'sign unplace ' . s:asm_id
|
||||
exe 'sign place ' . s:asm_id . ' line=' . lnum . ' name=debugPC'
|
||||
endif
|
||||
|
||||
|
||||
call win_gotoid(curwinid)
|
||||
endif
|
||||
endif
|
||||
@@ -1278,8 +1315,8 @@ func s:HandleCursor(msg)
|
||||
normal! zv
|
||||
exe 'sign unplace ' . s:pc_id
|
||||
exe 'sign place ' . s:pc_id . ' line=' . lnum . ' name=debugPC file=' . fname
|
||||
if !exists('b:save_signcolumn')
|
||||
let b:save_signcolumn = &signcolumn
|
||||
if !exists('b:save_signcolumn')
|
||||
let b:save_signcolumn = &signcolumn
|
||||
call add(s:signcolumn_buflist, bufnr())
|
||||
endif
|
||||
setlocal signcolumn=yes
|
||||
@@ -1308,7 +1345,12 @@ endfunction
|
||||
" Handle setting a breakpoint
|
||||
" Will update the sign that shows the breakpoint
|
||||
func s:HandleNewBreakpoint(msg)
|
||||
if a:msg !~ 'fullname='
|
||||
if a:msg !~ 'fullname='
|
||||
" a watch or a pending breakpoint does not have a file name
|
||||
if a:msg =~ 'pending='
|
||||
let nr = substitute(a:msg, '.*number=\"\([0-9.]*\)\".*', '\1', '')
|
||||
let target = substitute(a:msg, '.*pending=\"\([^"]*\)\".*', '\1', '')
|
||||
echomsg 'Breakpoint ' . nr . ' (' . target . ') pending.'
|
||||
endif
|
||||
return
|
||||
endif
|
||||
@@ -1352,6 +1394,7 @@ func s:HandleNewBreakpoint(msg)
|
||||
|
||||
if bufloaded(fname)
|
||||
call s:PlaceSign(id, subid, entry)
|
||||
endif
|
||||
echomsg 'Breakpoint ' . nr . ' created at line ' . lnum . '.'
|
||||
endfor
|
||||
endfunc
|
||||
@@ -1371,11 +1414,12 @@ func s:HandleBreakpointDelete(msg)
|
||||
endif
|
||||
if has_key(s:breakpoints, id)
|
||||
for [subid, entry] in items(s:breakpoints[id])
|
||||
if has_key(entry, 'placed')
|
||||
exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
|
||||
if has_key(entry, 'placed')
|
||||
exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
|
||||
unlet entry['placed']
|
||||
endif
|
||||
endfor
|
||||
unlet s:breakpoints[id]
|
||||
echomsg 'Breakpoint ' . id . ' cleared.'
|
||||
endif
|
||||
endfunc
|
||||
@@ -1396,7 +1440,7 @@ func s:BufRead()
|
||||
let fname = expand('<afile>:p')
|
||||
for [id, entries] in items(s:breakpoints)
|
||||
for [subid, entry] in items(entries)
|
||||
if entry['fname'] == fname
|
||||
if entry['fname'] == fname
|
||||
call s:PlaceSign(id, subid, entry)
|
||||
endif
|
||||
endfor
|
||||
@@ -1408,7 +1452,7 @@ func s:BufUnloaded()
|
||||
let fname = expand('<afile>:p')
|
||||
for [id, entries] in items(s:breakpoints)
|
||||
for [subid, entry] in items(entries)
|
||||
if entry['fname'] == fname
|
||||
if entry['fname'] == fname
|
||||
let entry['placed'] = 0
|
||||
endif
|
||||
endfor
|
||||
|
Reference in New Issue
Block a user