Add LICENSE
[pygdb.git] / pygdb.vim
index b38a173115aca00226ac05589e4039b49f6ac3d9..79a557e074dafc0824832121de074825bd03e619 100644 (file)
--- a/pygdb.vim
+++ b/pygdb.vim
@@ -1,4 +1,11 @@
-"shuber, 2008-06-08
+"pygdb.vim - pygtk interface to gdb in connection with (g)vim
+" Maintainer: Stefan Huber <shuber@cosy.sbg.ac.at>
+
+
+if !has('python')
+       echo "Error: Required vim compiled with +python"
+       finish
+endif
 
 if ! exists("g:pygdb")
 
@@ -9,52 +16,44 @@ let s:ScriptLocation = expand("<sfile>")
 python << >>
 
 import gtk
+import os
 import string
 import sys
 import threading
-
 import vim
 
-#Do not use a ~ for home directory
-sys.path.append("/home/shuber/projekte/pygdb/")
+import Configuration
+import DbgTerminal
 
-import GdbTerminal
-import MainControlWindow
-import StatusWindow
 
 
-#Breakpoint positions: List of dictionaries of form {"signnum" : , "file" : , "lineno":, "cond" : }
+#Breakpoint positions: List of dictionaries of form
+#{"signnum" : , "file" : , "lineno":, "cond" : }
 gdbBps = []
 signnum = 0
 clientcmd = ""
-
-gdbterm = None
-mainctrlwnd = None
-statuswnd = None
-gdbthread = None
-
-
+execsign = None
 
 def gdbLaunch():
-       global gdbterm, mainctrlwnd, statuswnd, gdbBps, clientcmd, gdbthread
+       global gdbBps, clientcmd, pygdbdir
 
-       if gdbterm == None:
+       clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd)
+       
+       #Pressed esq?
+       if clientcmd == None:
+               clientcmd = ""
+               return
 
-               clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd)
-               gdbterm = GdbTerminal.GdbTerminal(clientcmd)
-               mainctrlwnd = MainControlWindow.MainControlWindow(gdbterm, quitonclose=False)
-               statuswnd = StatusWindow.StatusWindow(mainctrlwnd, gdbterm, quitonclose=False)
-               gdbterm.initialize()
+       #Strip away white space
+       clientcmd = clientcmd.strip()
 
+       if clientcmd.strip()=="":
+               print "No command given!"
+               return
 
-               for bp in gdbBps:
-                       statuswnd.breakpointsFrame.addBreakpoint(bp["file"], bp["lineno"], bp["cond"])
-
-               gtk.main()
-               gtk.main()
-               print "hello"
-               #mainctrlwnd.hide()
-               #statuswnd.hide()
+       gdbWriteConfig()
+       
+       vim.command("!python %s/pygdb.py --vim-servername %s %s &\n" % (pygdbdir, vim.eval("v:servername"), clientcmd))
 
 
 def gdbToggleBreakpoint(lineno=None, file=None):
@@ -64,25 +63,84 @@ def gdbToggleBreakpoint(lineno=None, file=None):
        if lineno==None:
                lineno = vim.current.window.cursor[0]
        if file==None:
-               file = vim.current.window.buffer.name
+               file = getCurrentFile()
 
        #Determine index of breakpoint
        bpidx = gdbGetBreakpoint( file, lineno )
 
-       #Remove the breakpoint
        if bpidx != None:
-               vim.command("sign unplace %(signnum)d" % gdbBps[bpidx])
-               del gdbBps[bpidx]
-
-       #Create the breakpoint
+               removeBreakpoint(bpidx)
        else:
-               #Determine a sign number
-               signnum = gdbNewSignnum()
+               addBreakpoint(file, lineno)
+
+
+def setExecutionLine(file, lineno):
+       global execsign
+
+
+       #Open that file!
+       if file != getCurrentFile():
+               try:
+                       os.stat(file)
+                       vim.command(":e %s" % file)
+               except OSError:
+                       print "Warning: file '%s' does not exist! (Wrong client command?)" % file
+                       return
+
+       #Jump to line
+       vim.command(":%d" % lineno)
+
+       #Remove old execsign
+       if execsign != None:
+               delExecutionLine()
+
+       #Set the sign
+       execsign = gdbNewSignnum()
+       vim.command("sign place %d line=%s name=ExecutionLine file=%s"%(execsign, lineno, file))
+
 
-               #Create breakpoint and add sign
-               b = {"signnum" : signnum, "lineno" : lineno, "file" : file, "cond" : None}
+def delExecutionLine():
+       global execsign
+
+       #Remove old execsign
+       if execsign != None:
+               vim.command("sign unplace %d" % execsign)
+               execsign = None
+
+
+def addBreakpoint(file, lineno, cond=None):
+       global gdbBps, cmdset
+
+       #If file is not open, open it
+       if not file in [b.name for b in vim.buffers]:
+               try:
+                       os.stat(file)
+                       vim.command(":e %s" % file)
+               except OSError:
+                       print "Warning: file '%s' does not exist! (Wrong client command?)" % file
+                       cmdset = False
+                       return
+
+
+       #Determine a sign number
+       signnum = gdbNewSignnum()
+
+       #Create breakpoint and add sign
+       b = {"signnum" : signnum, "lineno" : lineno, "file" : file, "cond" : cond}
+       gdbBps += [b]
+
+       if cond == None:
                vim.command("sign place %(signnum)d line=%(lineno)d name=BreakPoint file=%(file)s" % b)
-               gdbBps += [b]
+       else:
+               vim.command("sign place %(signnum)d line=%(lineno)d name=CondBreakPoint file=%(file)s" % b)
+
+               
+
+def removeBreakpoint(idx):
+       global gdbBps
+
+       vim.command("sign unplace %(signnum)d" % gdbBps[idx])
+       del gdbBps[idx]
 
 
 def gdbBreakpointCond(lineno=None, file=None, cond=None):
@@ -92,29 +150,25 @@ def gdbBreakpointCond(lineno=None, file=None, cond=None):
        if lineno==None:
                lineno = vim.current.window.cursor[0]
        if file==None:
-               file = vim.current.window.buffer.name
+               file = getCurrentFile()
 
        #Determine index of breakpoint
        bpidx = gdbGetBreakpoint( file, lineno )
 
-       #Remove the breakpoint
+       #Alter condition
        if bpidx != None:
-               if cond == None:
-                       cond = vim.eval("input('Breakpoint condition: ', '%s')" % gdbBps[bpidx]["cond"])
-               gdbBps[bpidx]["cond"] = cond
-
+               gdbBps[bpidx]["cond"] = vim.eval("input('Breakpoint condition: ', '%s')" % gdbBps[bpidx]["cond"])
+       #Set new breakpoint
        else:
-               #Determine a sign number
-               signnum = gdbNewSignnum()
-
                #Get condition
-               if cond == None:
-                       cond = vim.eval("input('Breakpoint condition: ', '')")
-               
-               #Create breakpoint and add sign
-               b = {"signnum" : signnum, "lineno" : lineno, "file" : file, "cond" : cond}
-               vim.command("sign place %(signnum)d line=%(lineno)d name=CondBreakPoint file=%(file)s" % b)
-               gdbBps += [b]
+               cond = vim.eval("input('Breakpoint condition: ', '')")
+               #Add the breakpoint
+               addBreakpoint(file, lineno, cond)
+
+
+def getCurrentFile():
+       return vim.current.window.buffer.name
+
 
 
 def gdbNewSignnum():
@@ -129,29 +183,112 @@ def gdbGetBreakpoint(file, lineno):
                        return i        
        return None
 
+def gdbShowBreakpoints():
+       global gdbBps
 
->>
+       if len(gdbBps) == 0:
+               print "No breakpoints set."
+       else:
+               print "%d breakpoints set:" % len(gdbBps)
+
+       for bp in gdbBps:
+               if bp["cond"] != None:
+                       print "%(file)s:%(lineno)d if %(cond)s" % bp
+               else:
+                       print "%(file)s:%(lineno)d" % bp
+
+
+
+def toAbsPath(path):
+       global clientcmd, cmdset
+
+       #Not a absolute path --> make one
+       if path[0] != os.sep:
+
+               #We need the client command to expand the paths...
+               while clientcmd == "" or not cmdset:
+                       clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd)
+
+                       if clientcmd == None:
+                               clientcmd = ""
+                       clientcmd = clientcmd.strip()
+
+                       cmdset = True
+
+               #Get the dirs where executeable is in
+               relcmd = string.split(clientcmd)[0]
+               abscmd = DbgTerminal.relToAbsPath(getCurrentFile(), relcmd)
+               path = DbgTerminal.relToAbsPath(abscmd, path)
 
+               assert(path[0] == "/")
 
-highlight ExecutionLine term=bold ctermbg=DarkGreen ctermfg=White
-highlight BreakPoint term=inverse ctermbg=DarkCyan ctermfg=Black
+       return path
+
+
+def gdbLoadConfig():
+       global clientcmd, gdbBps, cmdset
+
+
+       #Load configuration
+       conf = Configuration.Configuration()
+       conf.load(".pygdb.conf")
+
+       #Remove all breakpoints
+       while len(gdbBps)>0:
+               removeBreakpoint(0)
+
+       #Add breakpoints from configuration
+       for bp in conf.breakpoints:
+               bp["file"] = toAbsPath( bp["file"] )
+               addBreakpoint(bp["file"], bp["lineno"], bp["cond"])
+
+       #Set the command from config
+       if conf.getCommand() != None:
+               clientcmd = conf.getCommand()
+       
+       #Set current execution line
+       if conf.isCurrposSet():
+               file = toAbsPath(conf.currfile)
+               setExecutionLine(file, conf.currlineno)
+       else:
+               delExecutionLine()
+
+               
+def gdbWriteConfig():
+
+       #Add the breakpoints to the configuration
+       conf = Configuration.Configuration()
+       conf.load(".pygdb.conf")
+       conf.breakpoints = []
+       for bp in gdbBps:
+               conf.addBreak(bp["file"], bp["lineno"], bp["cond"])
+       conf.store(".pygdb.conf")
+
+
+>>
+
+highlight ExecutionLine term=bold ctermbg=DarkGreen ctermfg=Black guibg=LightGreen guifg=Black
+highlight BreakPoint term=inverse ctermbg=DarkRed ctermfg=Black guibg=LightRed guifg=Black
 
 sign define ExecutionLine text==> texthl=ExecutionLine linehl=ExecutionLine
 sign define BreakPoint text=! texthl=BreakPoint linehl=BreakPoint
 sign define CondBreakPoint text=? texthl=BreakPoint linehl=BreakPoint
 
 
-
 command! GDBLaunch :python gdbLaunch()
 command! GDBToggleBreakpoint :python gdbToggleBreakpoint()
 command! GDBBreakpointCond :python gdbBreakpointCond()
+command! GDBShowBreakpoints :python gdbShowBreakpoints()
+command! GDBLoadConfig :python gdbLoadConfig()
 
 
 
 function! GDBMapDefaults()
        nmap <silent> <F5>              :GDBLaunch<CR>
        nmap <silent> <F8>              :GDBToggleBreakpoint<CR>
-       nmap <silent> <F9>              :GDBBreakpointCond<CR>
+       nmap <silent> <S-F8>            :GDBBreakpointCond<CR>
+       nmap <silent> <F9>              :GDBShowBreakpoints<CR>
+       nmap <silent> <S-F9>            :GDBLoadConfig<CR>
 endfunction