Mercurial > vim
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 |