fix bug: open non-open files in vim
[pygdb.git] / pygdb.vim
1 "shuber, 2008-06-08
2
3 if ! exists("g:pygdb")
4
5 let g:pygdb = 1
6 let s:ScriptLocation = expand("<sfile>")
7
8
9 python << >>
10
11 import gtk
12 import os
13 import string
14 import sys
15 import threading
16 import vim
17
18 import Configuration
19
20
21
22 #Breakpoint positions: List of dictionaries of form
23 #{"signnum" : , "file" : , "lineno":, "cond" : }
24 gdbBps = []
25 signnum = 0
26 clientcmd = ""
27
28 def gdbLaunch():
29 global gdbterm, mainctrlwnd, statuswnd, gdbBps, clientcmd, gdbthread
30
31 clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd).strip()
32
33 if clientcmd.strip()=="":
34 print "No command given!"
35 return
36
37 #Add the breakpoints to the configuration
38 conf = Configuration.Configuration()
39 conf.load(".pygdb.conf")
40 for bp in gdbBps:
41 conf.addBreak(bp["file"], bp["lineno"], bp["cond"])
42 conf.store(".pygdb.conf")
43
44 vim.command("!python %s/pygdb.py %s &\n" % (pygdbdir, clientcmd))
45
46
47 def gdbToggleBreakpoint(lineno=None, file=None):
48 global gdbBps
49
50 #Set lineno and file if not already set
51 if lineno==None:
52 lineno = vim.current.window.cursor[0]
53 if file==None:
54 file = getCurrentFile()
55
56 #Determine index of breakpoint
57 bpidx = gdbGetBreakpoint( file, lineno )
58
59 if bpidx != None:
60 removeBreakpoint(bpidx)
61 else:
62 addBreakpoint(file, lineno)
63
64
65 def addBreakpoint(file, lineno, cond=None):
66 global gdbBps
67
68 #If file is not open, open it
69 if not file in [b.name for b in vim.buffers]:
70 try:
71 os.stat(file)
72 vim.command(":e %s" % file)
73 except OSError:
74 print "Warning: file '%s' does not exist! (Wrong client command?)" % file
75 return
76
77
78 #Determine a sign number
79 signnum = gdbNewSignnum()
80
81 #Create breakpoint and add sign
82 b = {"signnum" : signnum, "lineno" : lineno, "file" : file, "cond" : cond}
83 gdbBps += [b]
84
85 if cond == None:
86 vim.command("sign place %(signnum)d line=%(lineno)d name=BreakPoint file=%(file)s" % b)
87 else:
88 vim.command("sign place %(signnum)d line=%(lineno)d name=CondBreakPoint file=%(file)s" % b)
89
90
91
92 def removeBreakpoint(idx):
93 global gdbBps
94
95 vim.command("sign unplace %(signnum)d" % gdbBps[idx])
96 del gdbBps[idx]
97
98
99 def gdbBreakpointCond(lineno=None, file=None, cond=None):
100 global gdbBps
101
102 #Set lineno and file if not already set
103 if lineno==None:
104 lineno = vim.current.window.cursor[0]
105 if file==None:
106 file = getCurrentFile()
107
108 #Determine index of breakpoint
109 bpidx = gdbGetBreakpoint( file, lineno )
110
111 #Alter condition
112 if bpidx != None:
113 gdbBps[bpidx]["cond"] = vim.eval("input('Breakpoint condition: ', '%s')" % gdbBps[bpidx]["cond"])
114 #Set new breakpoint
115 else:
116 #Get condition
117 cond = vim.eval("input('Breakpoint condition: ', '')")
118 #Add the breakpoint
119 addBreakpoint(file, lineno, cond)
120
121
122 def getCurrentFile():
123 return vim.current.window.buffer.name
124
125
126
127 def gdbNewSignnum():
128 global signnum
129 signnum += 1
130 return signnum
131
132
133 def gdbGetBreakpoint(file, lineno):
134 for i in range(len(gdbBps)):
135 if [gdbBps[i]["file"], gdbBps[i]["lineno"]] == [file,lineno]:
136 return i
137 return None
138
139 def gdbShowBreakpoints():
140 global gdbBps
141
142 if len(gdbBps) == 0:
143 print "No breakpoints set."
144 else:
145 print "%d breakpoints set:" % len(gdbBps)
146
147 for bp in gdbBps:
148 if bp["cond"] != None:
149 print "%(file)s:%(lineno)d if %(cond)s" % bp
150 else:
151 print "%(file)s:%(lineno)d" % bp
152
153
154 def getAbsPath(absfile, relfile):
155 """When an absfile is given and a relfile is given by
156 relative paths relative to absfile, determine the abs
157 path of relfile"""
158
159 #Get directories except for "." parts
160 relsplit = filter(lambda x: x!=".", string.split(relfile, os.sep))
161 #Get the directories of absfile withouth the trailing filename
162 abssplit = string.split(absfile, os.sep)[:-1]
163
164 #Determine number of ".." and remove them
165 up=0
166 while relsplit[0] == "..":
167 up += 1
168 del relsplit[0]
169 del abssplit[-1]
170
171 return string.join(abssplit + relsplit, os.sep)
172
173
174
175 def gdbLoadConfig():
176 global clientcmd, gdbBps
177
178
179 #Load configuration
180 conf = Configuration.Configuration()
181 conf.load(".pygdb.conf")
182
183 #Remove all breakpoints
184 while len(gdbBps)>0:
185 removeBreakpoint(0)
186
187 #Add breakpoints from configuration
188 cmdset = False
189 for bp in conf.breakpoints:
190
191 file = bp["file"]
192
193 #Not a absolute path --> make one
194 if file[0] != os.sep:
195
196 #We need the client command to expand the paths...
197 while clientcmd == "" or not cmdset:
198 clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd).strip()
199 cmdset = True
200
201 #Get the dirs where executeable is in
202 relcmd = string.split(clientcmd)[0]
203 abscmd = getAbsPath(getCurrentFile(), relcmd)
204 bp["file"] = file = getAbsPath(abscmd, file)
205
206 assert(file[0] == "/")
207
208 addBreakpoint(bp["file"], bp["lineno"], bp["cond"])
209
210 >>
211
212
213 highlight BreakPoint term=inverse ctermbg=DarkCyan ctermfg=Black
214
215 sign define BreakPoint text=! texthl=BreakPoint linehl=BreakPoint
216 sign define CondBreakPoint text=? texthl=BreakPoint linehl=BreakPoint
217
218
219
220 command! GDBLaunch :python gdbLaunch()
221 command! GDBToggleBreakpoint :python gdbToggleBreakpoint()
222 command! GDBBreakpointCond :python gdbBreakpointCond()
223 command! GDBShowBreakpoints :python gdbShowBreakpoints()
224 command! GDBLoadConfig :python gdbLoadConfig()
225
226
227
228 function! GDBMapDefaults()
229 nmap <silent> <F5> :GDBLaunch<CR>
230 nmap <silent> <F8> :GDBToggleBreakpoint<CR>
231 nmap <silent> <S-F8> :GDBBreakpointCond<CR>
232 nmap <silent> <F9> :GDBShowBreakpoints<CR>
233 nmap <silent> <S-F9> :GDBLoadConfig<CR>
234 endfunction
235
236
237
238 endif
239
240