comparison runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @ 12395:39e1087e7094 v8.0.1077

patch 8.0.1077: no debugger making use of the terminal window commit https://github.com/vim/vim/commit/fe386641b0c56c5de2bca8e1f4cd5e2a1f1aea7e Author: Bram Moolenaar <Bram@vim.org> Date: Fri Sep 8 21:10:04 2017 +0200 patch 8.0.1077: no debugger making use of the terminal window Problem: No debugger making use of the terminal window. Solution: Add the term debugger plugin. So far only displays the current line when stopped.
author Christian Brabandt <cb@256bit.org>
date Fri, 08 Sep 2017 21:15:05 +0200
parents 8d76a56861ec
children 5d4d744151c2
comparison
equal deleted inserted replaced
12394:96f54a0f9fd7 12395:39e1087e7094
1 " Debugger commands. 1 " Debugger plugin using gdb.
2 " 2 "
3 " WORK IN PROGRESS - much doesn't work yet 3 " WORK IN PROGRESS - much doesn't work yet
4 " 4 "
5 " Open two terminal windows: 5 " Open two visible terminal windows:
6 " 1. run a pty, as with ":term NONE" 6 " 1. run a pty, as with ":term NONE"
7 " 2. run gdb, passing the pty 7 " 2. run gdb, passing the pty
8 " The current window is used to edit source code and follows gdb. 8 " The current window is used to view source code and follows gdb.
9 "
10 " A third terminal window is hidden, it is used for communication with gdb.
11 "
12 " The communication with gdb uses GDB/MI. See:
13 " https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
9 " 14 "
10 " Author: Bram Moolenaar 15 " Author: Bram Moolenaar
11 " Copyright: Vim license applies 16 " Copyright: Vim license applies, see ":help license"
12 17
18 " The command that starts debugging, e.g. ":Termdebug vim".
19 " To end type "quit" in the gdb window.
13 command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>) 20 command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>)
14 21
22 " Name of the gdb command, defaults to "gdb".
15 if !exists('debugger') 23 if !exists('debugger')
16 let debugger = 'gdb' 24 let debugger = 'gdb'
17 endif 25 endif
18 26
27 " Sign used to highlight the line where the program has stopped.
28 sign define debugPC linehl=debugPC
29 if &background == 'light'
30 hi debugPC term=reverse ctermbg=lightblue guibg=lightblue
31 else
32 hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
33 endif
34 let s:pc_id = 12
35
19 func s:StartDebug(cmd) 36 func s:StartDebug(cmd)
37 let s:startwin = win_getid(winnr())
38 let s:startsigncolumn = &signcolumn
39
20 " Open a terminal window without a job, to run the debugged program 40 " Open a terminal window without a job, to run the debugged program
21 let s:ptybuf = term_start('NONE', {}) 41 let s:ptybuf = term_start('NONE', {
22 let pty = job_info(term_getjob(s:ptybuf))['tty'] 42 \ 'term_name': 'gdb program',
43 \ })
44 if s:ptybuf == 0
45 echoerr 'Failed to open the program terminal window'
46 return
47 endif
48 let pty = job_info(term_getjob(s:ptybuf))['tty_out']
49
50 " Create a hidden terminal window to communicate with gdb
51 let s:commbuf = term_start('NONE', {
52 \ 'term_name': 'gdb communication',
53 \ 'out_cb': function('s:CommOutput'),
54 \ 'hidden': 1,
55 \ })
56 if s:commbuf == 0
57 echoerr 'Failed to open the communication terminal window'
58 exe 'bwipe! ' . s:ptybuf
59 return
60 endif
61 let commpty = job_info(term_getjob(s:commbuf))['tty_out']
23 62
24 " Open a terminal window to run the debugger. 63 " Open a terminal window to run the debugger.
25 let cmd = [g:debugger, '-tty', pty, a:cmd] 64 let cmd = [g:debugger, '-tty', pty, a:cmd]
26 echomsg 'executing "' . join(cmd) . '"' 65 echomsg 'executing "' . join(cmd) . '"'
27 let gdbbuf = term_start(cmd, { 66 let gdbbuf = term_start(cmd, {
28 \ 'exit_cb': function('s:EndDebug'), 67 \ 'exit_cb': function('s:EndDebug'),
29 \ 'term_finish': 'close' 68 \ 'term_finish': 'close',
30 \ }) 69 \ })
70 if gdbbuf == 0
71 echoerr 'Failed to open the gdb terminal window'
72 exe 'bwipe! ' . s:ptybuf
73 exe 'bwipe! ' . s:commbuf
74 return
75 endif
76
77 " Connect gdb to the communication pty, using the GDB/MI interface
78 call term_sendkeys(gdbbuf, 'new-ui mi ' . commpty . "\r")
31 endfunc 79 endfunc
32 80
33 func s:EndDebug(job, status) 81 func s:EndDebug(job, status)
34 exe 'bwipe! ' . s:ptybuf 82 exe 'bwipe! ' . s:ptybuf
83 exe 'bwipe! ' . s:commbuf
84 call setwinvar(s:startwin, '&signcolumn', s:startsigncolumn)
35 endfunc 85 endfunc
86
87 " Handle a message received from gdb on the GDB/MI interface.
88 func s:CommOutput(chan, msg)
89 let msgs = split(a:msg, "\r")
90
91 for msg in msgs
92 " remove prefixed NL
93 if msg[0] == "\n"
94 let msg = msg[1:]
95 endif
96 if msg != ''
97 if msg =~ '^\*\(stopped\|running\)'
98 let wid = win_getid(winnr())
99
100 if win_gotoid(s:startwin)
101 if msg =~ '^\*stopped'
102 " TODO: proper parsing
103 let fname = substitute(msg, '.*fullname="\([^"]*\)".*', '\1', '')
104 let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '')
105 if lnum =~ '^[0-9]*$'
106 if expand('%:h') != fname
107 if &modified
108 " TODO: find existing window
109 exe 'split ' . fnameescape(fname)
110 let s:startwin = win_getid(winnr())
111 else
112 exe 'edit ' . fnameescape(fname)
113 endif
114 endif
115 exe lnum
116 exe 'sign place ' . s:pc_id . ' line=' . lnum . ' name=debugPC file=' . fnameescape(fname)
117 setlocal signcolumn=yes
118 endif
119 else
120 exe 'sign unplace ' . s:pc_id
121 endif
122
123 call win_gotoid(wid)
124 endif
125 endif
126 endif
127 endfor
128 endfunc