Peter's Blog

Redefining the Impossible

Items filed under php


I still want to set up a system what will automatically record tv programs for playback on my pocketpc. For various reasons this is becoming more important: in a nutshell, I can only take so much ITV.

Been trying to setup mythtv on a new pc I have acquired. I have tried various windows PVR packages in the past but none of them were attractive, being flaky and annoying (including meedio which of now available for free as yahoo go). Mythtv was attractive because of it's flexibility.

I installed a clean kubuntu install in the box which went quite smoothly and after some exploration I established that the kernel already supported my hauppauge nova-t usb. I found an application called kaffeine that was already installed which was able to display tv and this essentially Just Worked out-of-the-box, albeit with lip-sync issues (probably because it needs the proprietary nvidia drivers).

Still desiring mythtv, I found an ubuntu repository that has mythtv packages for version 0.18 and installed that. I looked in the ubuntu package readme which says something to the effect that whoever set it up had no experience with mythtv and didn't know what he was doing. Thanks for the warning. I set it up using the mythtv-setup application, started the mythtv backend and tried to start mythweb. I am mainly interested in this as a way of remotely scheduling recordings, I care not about using the myth frontend. Mythweb wouldn't work, it complained about being a different version to the back end. The php code appears to display this error if there are any problems communicating with the back end but I decided I wouldn't mess around getting an old version to work, I would build the latest 0.19. After a few hours of installing dependant packages it built but when I tried running it I got a segmentation error. At this point I gave up with mythtv, I just don't have the time to nurse it into life. mythtv seems bloated and fragile. there is the option of knoppmyth, a dedicated mythtv distribution, but I'm not sure how cutting edge this is, whether it is any good as a general purpose linux distribution or whether the kernel will support my tv card without having to fiddle with compiling it.

I had a brief look at freevo but sourceforge was down (what an advert for oss) but found that freevo used command line tools to do the recording so I am currently investigating that approach: knocking up simple python scripts to do just what I want. I would rather debug these than mythtv (hell is other peoples source code).

Incidentally, I was browsing through some ruby source yesterday and for a few files there I was wondering whether ruby had a comment character.


3 Comments

Moved Peter's Blog to new oneandone dedicated server. Observations:

The speed may be due to:

  • dedicated server to itself
  • mod_php instead of cgi on site5.

In summary, woo hoo.


Filed under: blogging oneandone php site5

Add a comment

Something is starting to really irritate me. Whenever I make some change on this site through Drupal such as editing a page, I press the submit button and the browser shows me the page as it was before the edit. I have to press refresh to see the changes. This happens all over, if I look at the logs, add a page, look again at the logs, nothing has changed until I refresh the page.

Clues to the cause:

  • I have caching disabled in Drupal and it should not be caching updated pages anyway.
  • My browser is connected directly, no caching proxy.
  • If I run ethereal I can see that the browser is sending a GET for the updated page and receiving the old version
  • If I look at the site apache access logs I do not see this GET reaching the server

Something in between is caching the pages. J'accuse Site5. I've looked all through their site and I see nothing about this but the forums tend to be full of noobs (like most forums). I tried editing the .htaccess file to disable mod_cache if it was loaded but that just caused an internal server error. It is highly likely that they are running some form of cache the other side of apache (squid?), I'd probably do the same to save the load on a shared server for other peoples sites. However, I find it intrusive when I'm the victim.

Hosting contract is coming to an end, I still have time to evaluate a new hosting solution. I'm highly tempted by a cheap dedicated server. It's expensive but:

  • I've plenty of power: I can run X and use a vnc terminal.
  • I can do what I like in python. I have no interest in doing php at all and Site5's python support is weak (python 2.2.3, no generators sad). They now support ruby on rails but I'm more interested in php than ruby (weak python clone).
  • I learn to secure a linux box properly. I think my linode server was hacked through an xmlrpc weakness in drupal which has been fixed now.
  • It's all mine. With VPS's and shared hosting, you are having to share disk and cpu with other people. I would only have to share network bandwidth with them.
  • I can sell CPU time/hosting/web sites should I feel the desire

One thing about dedicated servers: I cannot believe that to get the server rebooted you have to email some guy who has to run to the box and press the reset button. How primitive is that? If I screw things up to the extent that shutdown -r now does not work I will either learn to prototype hacks on a local box or give up and become an estate agent.

UPDATE: er, it wasn't site5's fault, it was Microsofts.


Filed under: drupal linode php python ruby site5

7 Comments

After fixing postfix installation all was looking good until I realised the web server running Drupal was only showing the home page: clicking on other pages kept giving the home page. I looked in /var/log/apache/error.log and found I was getting this error on each click:

/usr/sbin/apache: relocation error: /usr/lib/php4/20020429/mysql.so:
undefined symbol: php_sprintf

A nasty one. Some googling and forum browsing gave me the clue to the solution: I had an unholy mix of Apache 1.3 and Apache 2.0 installed on the box, apache 1.3 was running and finding php compiled for Apache 2.0 (or something like that).

The solution was:

  • run rcconf and disable apache (1.3) and enable apache2
  • stop apache 1.3
  • install mod_php4 for apache2
  • enable php in /etc/apache2/apache2.conf
  • enable mysql.so and gd.so in /etc/php4/apache2/php.ini
  • start apache2

and sanity was restored (if an intranet can be described as that).


Filed under: apache linux mysql php ubuntu

4 Comments

I updated my linode to Ubuntu hoary hedgehog. I followed the upgrade steps here except I didn't install the ubuntu-desktop package as its a GUI-less server (although I may regret that one day).

Notes:

  • it only took a few minutes to upgrade 250 packages.
  • installing one of the packages failed with:
    udev requires a kernel >= 2.6.8, upgrade aborted.
    dpkg: error processing /var/cache/apt/archives/udev_0.050-3ubuntu7_i386.deb (--u
    npack):
     subprocess pre-installation script returned error exit status 1
    Errors were encountered while processing:
     /var/cache/apt/archives/udev_0.050-3ubuntu7_i386.deb
    E: Sub-process /usr/bin/dpkg returned an error code (1)
    
    which appeared to be because I am running a 2.4 kernel. I am not sure how free I am to change kernels on a Linode. I ignored the error and life went on.
  • libphp4 module installation failed because it could not find a php.ini file. I create one for it to fiddle with and this time it was happy.
  • I did shutdown -r now to reboot but this only powered down the linode. I had to go into the Linode control panel to boot it again.
  • It came up and I was happy. If it hadn't I would have to do a clean install. I MUST get around to adding a rescue partition on the virtual hard disk.
  • It had lost the hostname and I had to use the hostname command to reset it.
  • It had decided to upgrade me to apache2 and install the generic index.html which overrode my drupal index.php so I deleted it.
  • I had to enable php in /etc/apache2/apache2.conf by uncommenting:
    AddType application/x-httpd-php .php
    
  • I had to enable mysql and gd in /etc/php4/apache2/php.ini by uncommenting:
    extension=mysql.so
    extension=gd.so
    
  • It has python 2.4 smile
  • It still has subversion 1.06 sad I wanted to try out 1.2 which is why I upgraded Ubuntu.

Filed under: drupal linode mysql php ubuntu

Add a comment

Linode looks interesting. It is a hosting service whereby you get a virtual linux box all of your own. It is on a server and it is shared with 40 other people but you get 64M of ram to yourself, 3G of disk space that you partition yourself as you see fit and a selection of linux distributions to choose from. You install linux, have root access and basically can install whatever software you like on it (even painful gentoo compilation). It is like having your own linux box out there on the web.

It can be used not just for a web server but ftp, mail, proxy, DNS server, backup server, you name it. It sounds more interesting than Site5 which gives plenty of power except there is no root access, cannot use wget to get packages, no compiler, two year old version of Python, no fastcgi or mod_python just slow cgi, etc etc. Linode costs $20 or £10.50 a month which is more expensive and the support would not extend to patching your kernel like Site5 would do. Then again, unlike a shared host, if some other tosser you share with uses up all the mysql connections with a flaky script your account does not suffer (happened for the second time to my knowledge this sunday).

I'd be tempted to go with this rather than renew my site5 deal.


2 Comments

This python code generates syntax highlighted python code in html format. I know about SilverCity but I want this for my Site5 account where I cannot install executable code. The code below was highlighted using the code itself: spooky.

It is a simplistic solution but it should not be confused by multiline strings, comment characters in strings etc. I started off by trying to use the ply python lex as a tokeniser and processing the tokens but that persisted in confusing multiline string characters with normal strings and while thinking about it I realised that I could live without it. I don't know how slow this is: if using it on a website with heavy traffic you will want to cache the output.

#
# Syntax Highlighting
#

import re
import cgi

# Regular expression rules for simple tokens
strStyles = (
    ('PUNC', re.compile( r'<<|>>|<=|>=|!=|==|[-+*|^~/%=<>\[\]{}(),.:]'), None),
    ('NUMBER', re.compile( r'0x[0-9a-fA-F]+|[+-]?\d+(.\d+)?([eE][+-]\d+)?|\d+'),
                            'color: red'),
    ('KEYWORD', re.compile( r'def|class|break|continue|del|exec|finally|pass|' +
                            r'print|raise|return|try|except|global|assert|lambda|' +
                            r'yield|for|while|if|elif|else|and|in|is|not|or|import|' +
                            r'from|True|False'), 'font-weight: bold'),
    ('MULTILINE', re.compile( r'r?u?(\'\'\'|""")'), 'color: darkred'),
    ('STRING', re.compile( r'r?u?\'(.*?)(?<!\\)\'|"(.*?)(?<!\\)"'), 'color: red'),
    ('IDENTIFIER', re.compile( r'[a-zA-Z_][a-zA-Z0-9_]*'), None),
    ('COMMENT', re.compile( r'\#.*\r?\n'), 'color: green; font-style: italic'),
    ('WHITESPACE', re.compile( r'[ \t\r\n]+'), None),

# if all else fails...
    ('UNKNOWN', re.compile( r'.'), None)
)

class Highlight:
    """
    Syntax highlight some python code.
    """
    def __init__( self):
        self.strOutput = []
        self.strSpanStyle = None

    def Highlight( self, strData):
        """
        Syntax highlight some python code.
        Returns html version of code.
        """

        i = 0
        strMultiline = ''

        #
        # While input is not exhausted...
        #
        while i < len(data):
            #
            # Compare current position with all possible display types.
            #
            for strTok, oRE, strStyle in strStyles:
                oMatch = oRE.match( data, i)
                if oMatch:
                    #
                    # Input matches this type.
                    #
                    strValue = cgi.escape( oMatch.group())
                    if strTok == 'MULTILINE':
                        #
                        # Multiline string token
                        #
                        if strMultiline == '':
                            #
                            # If not inside a multiline string then start one now.
                            #
                            self.ChangeStyle( strStyle)
                            self.strOutput.append( strValue)
                            #
                            # Remember you are in a string and remember how it was
                            # started (""" vs ''')
                            #
                            strMultiline = oMatch.group(1)
                        else:
                            #
                            # Multiline Token found within a multiline string
                            #
                            if oMatch.group() == strMultiline:
                                #
                                # Token is end of multiline so stop here.
                                #
                                self.strOutput.append( strMultiline)
                                strMultiline = ''

                            else:
                                #
                                # Not the same multiline token as started so just output it
                                #
                                self.strOutput.append( strValue)
                    else:
                        #
                        # Other token, not multiline
                        #
                        if strMultiline != '':
                            #
                            # In multiline mode so output the raw text of the token
                            #
                            self.strOutput.append( strValue)
                        else:
                            #
                            # Not in multiline mode so change display style as appropriate
                            # and output the text.
                            #
                            self.ChangeStyle( strStyle)
                            self.strOutput.append( strValue)
                    i += len( oMatch.group())
                    break
            else:
                #
                # Token not found so dump out raw text. This doesn't have to be bullet proof.
                #
                self.ChangeStyle( None)
                self.strOutput.append( data[i])
                i += 1

        #
        # Terminate any styles in use.
        #
        self.ChangeStyle( None)

        return "".join( self.strOutput)

    def ChangeStyle( self, strStyle):
        """
        Generate output to change from existing style to another style only.
        """

        #
        # Output minimal formatting code: only output anything is the style has
        # actually  changed.
        #
        if self.strSpanStyle != strStyle:
            if self.strSpanStyle != None:
                self.strOutput.append( '</span>')
            if strStyle != None:
                self.strOutput.append( '<span style="%s">' % strStyle)
            self.strSpanStyle = strStyle

Used like this:

import sys
data = open( sys.argv[0]).read()
strHighlighted = Highlight().Highlight( data)

print """<html>

<head>
<title>It works</title>
</head>
<body>
<pre>
%s
</pre>
</body>

</head>
""" % strHighlighted

Filed under: hosting php python site5

1 Comment

I've been contemplating some python web development. This is mainly for the following reasons:

  • I'd like my blog to have features for threading subjects based on keywords, a kind of related articles list. This would be dynamically updated, old articles could link to newer articles. This is possible in Drupal but the taxonomy system is laborious to configure through the web interface. There is a new keyword feature (folksonomies) but it appears to be a library for other modules to use. There are some modules that promise this kind of thing but they are not what I am looking for. The most important thing is that old articles are displayed with links to new articles, which involves messing around with themeing to add links to a cached page or figuring out how to flush the cache and put articles through a filter that would add the links.
  • I'd rather spend my limited programming time being creative with technologies I am already familiar with. I don't like php enough to want to learn it any more. I know and like python.
  • I don't want to spend my time trying to figure out how the Drupal code base works. Ok, I'm lazy and I have a short attention span and I'm not very interested in how it works.
  • If I do this as a spare time project I want to enjoy it, I don't want it to feel like a maintenance exercise. I can do that at work.
  • I have found that using librarys etc written by third partys can give you 95% of what you want, then you spend weeks trying to hack them to get the extra 5%. The only exception to this rule I can think of is the python standard library which is way cool.

So I looked at a few web application frameworks. This is a little lightweight and short on detail, I did most of it a few weeks ago and I didn't take notes.

cherrypy: Requires python 2.3 and my hosting service will only give me python 2.2 with cgi. I think generator functions are way cool and I'd love to use them. Do I stand any chance of getting my hosting service to upgrade? I'll email them and ask.

quixote: got the demo going, although I had to fix some of the urls within it as they appeared to be broken. It worked easily enough with cgi, the 1.3 version worked with python 2.2. However, again they have just released version 2 which has a couple of yield statements in it, limiting it python 2.3.

webware: I don't think I could see the advantage of 'servlets' and their web site (presumably powered by webware but it only says 'python powered') is not an impressive display of it's capabilities.

zope/plone: I've toyed with zope in the past (version 2) and found it's learning curve to be almighty. It may be very capable but you have to learn the zope way to do everything. The developers seem to be concentrating on inventing new object-orientated paradigms rather than keeping things simple and I hate huge complex object models. I don't like the web-based source editor (what, no syntax highlighting?: although I could use mozex and edit in vim). Also, non-cgi.

I was most interested in quixote until I came to the python 2.3 stumbling block with the new version 2. I don't want to settle for an old version. This led me on to think about what these frameworks actually give me:

  • map urls to class/method calls
    • big deal
  • session management
    • do I need it for my simple purposes?
  • templating systems
  • interface to cgi/mod_python/fastcgi/whatever
    • I can only have cgi anyway
  • easy form generation
    • classes to build the contents of a form. How many forms will I need? Can't templates do this?
  • already used on the internet and exposed to hackers
    • lets not be too ambitious with what we do. Keep drupal in the background for data entry.
  • learning curves

Which has led me to... straight cgi. Run my own scripts from cgi, using the cgi module in the standard python library to get the url parameters and generate a nice error page when things go wrong. I can get it going easily enough and below, with just a few hours hacking, is something that can display nodes from the drupal database. The output is themed through the Cheetah template engine and gives me the same look as my drupal theme. Given that it is only cgi it is not massively scalable, but I understand every line of it and that means a lot in terms of development time. Given that it generates pages that look like the drupal pages, I can chop and change, leaving some bits to drupal (data entry) and others in python (presentation). It's a lash up but so what?

The main challenge is porting my wilki module to python, particularly the geshi syntax highlighting.

I am not planning to rewrite Drupal and I probably won't release Yet Another Python Web Framework. I may not even finish it. It is something for me to play with.

   1  #!/usr/bin/python
   2  #
   3  import Cheetah.Template
   4  import cgi
   5  import cgitb; cgitb.enable()
   6  import time
   7  import datetime
   8  import os
   9  import pdo
  10  
  11  def ThemeAndOutput( strPageTitle, strContent, oParams={}):
  12      "Theme the site"
  13  
  14      strSideBar = """
  15      <div class="block">
  16      <h2>Reports</h2>
  17      <ul>
  18          <li><a href="Intranet.cgi">Drupal Emulator</a></li>
  19      </ul>
  20      </div>"""
  21  
  22      oDict = {
  23          'Root': '/SMB',
  24          'Url': '/Intranet/Intranet.cgi',
  25          'Title': 'Drupal Emulator',
  26          'Slogan': 'There are no Problems, only Challenges',
  27          'PrimaryLinks': [ '<a href="http://intranet.org">Intranet</a>',
  28                              '<a href="http://www.google.co.uk">Google</a>'],
  29          'PageTitle': strPageTitle,
  30          'SideBar': strSideBar,
  31          'Footer': 'Copyright 2005 Peter Wilkinson'
  32      }
  33  
  34      #
  35      # Read page template and shove in the content.
  36      #
  37      strTemplate = open( 'PageTemplate.html').read() % { 'Content': strContent}
  38  
  39      #
  40      # Run template and content through cheetah in one go.
  41      # Is this faster? Doubt it.
  42      #
  43      oHtml = Cheetah.Template.Template( strTemplate, [oDict, oParams])
  44  
  45      print str(oHtml)
  46  
  47  def MainPage( oForm):
  48      "Main welcome page: tell user what is going on"
  49  
  50      #
  51      # Determine how many links to show.
  52      #
  53      strFrom = oForm.getfirst( 'from')
  54      if strFrom == None:
  55          strLimit = ' LIMIT 10'
  56      else:
  57          try:
  58              nLimit = int(strFrom)
  59              strLimit = ' LIMIT %d, 10' % nLimit
  60          except:
  61              strLimit = ' LIMIT 10'
  62  
  63      c = pdo.connect( 'Module=MySQLdb;user=drupal;passwd=secret;db=drupal')
  64      rs = c.open( 'SELECT * FROM node ORDER BY created DESC %s' % strLimit)
  65  
  66      strTitles = []
  67      while rs.next():
  68          strTitles.append( '<a href="Intranet.cgi?node=%s">%s</a>' %
  69                (rs.fields['nid'].value, rs.fields['title'].value))
  70  
  71      strPage = """
  72  <ul>
  73  #for $strTitle in $titles
  74  <li>$strTitle</li>
  75  #end for
  76  </ul>
  77      """
  78  
  79      ThemeAndOutput( "Welcome", strPage, { 'titles': strTitles})
  80  
  81  def NodePage( oForm):
  82      "Display a node"
  83  
  84      strNode = oForm.getfirst( 'node')
  85      if strNode == None:
  86          ErrorPage()
  87          return
  88      else:
  89          try:
  90              nNode = int(strNode)
  91          except:
  92              ErrorPage()
  93              return
  94  
  95      c = pdo.connect( 'Module=MySQLdb;user=drupal;passwd=secret;db=drupal')
  96      rs = c.open( 'SELECT * FROM node WHERE nid = %d' % nNode)
  97  
  98      if rs.next():
  99          strTitle = rs.fields['title'].value
 100          strBody = rs.fields['body'].value
 101      else:
 102          ErrorPage()
 103          return
 104  
 105      strPage = """
 106  <h2>$strTitle</h2>
 107  
 108  <pre>
 109  $strBody
 110  </pre>
 111      """
 112  
 113      ThemeAndOutput( strTitle, strPage,
 114            { 'strTitle': strTitle, 'strBody': strBody})
 115  
 116  def ErrorPage():
 117      strPage = """<p>There has been some kind of navigation error, the link
 118  you just clicked is broken</p>
 119  <p>Better <a href="mailto:someone@somewhere.com">complain about it</a>.</p>
 120      """
 121  
 122      ThemeAndOutput( "Drupal emulator", strPage)
 123  
 124  oForm=cgi.FieldStorage()
 125  
 126  node = oForm.getfirst( 'node')
 127  if node:
 128      NodePage( oForm)
 129  else:
 130      MainPage( oForm)

The page template is kept in a seperate file. It is based on the phptemplate of my drupal theme and was ported over in less than an hour. Theming engines? A specialisation of templates.

   1  Content-Type: text/html
   2  
   3  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   4   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5  <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
   6  <head>
   7  <title>$Title</title>
   8  <meta http-equiv="Content-Style-Type" content="text/css"/>
   9  <style type="text/css">@import url(style.css);</style>
  10  </head>
  11  <body>
  12      <div id="headerleft">
  13      </div>
  14      <div id="headermain">
  15          <div id="ie6hack">
  16          </div>
  17      </div>
  18      <div id="headertitle">
  19          <h1>
  20              <a href="$Url" title="$Title">
  21              $Title</a>
  22          </h1>
  23      </div>
  24      <div class="slogan">
  25          $Slogan
  26      </div>
  27      <div id="logo">
  28          <a href="$Url" title="$Title">
  29              <img src="ITL.gif"/>
  30          </a>
  31      </div>
  32      <div id="headerright">
  33      </div>
  34  #if len($PrimaryLinks) > 0
  35      <div id="primarylinks">
  36          <ul>
  37  #for $PrimaryLink in $PrimaryLinks
  38              <li>$PrimaryLink</li>
  39  #end for
  40          </ul>
  41      </div>
  42  #end if
  43  
  44      <div id="ie5forcemargininsidehack">
  45          <div id="main">
  46              <div class="tab">
  47                  <div class="tabbackground">
  48                      <div class="tableft">
  49                          <h3>
  50                              $PageTitle
  51                          </h3>
  52                      </div>
  53                  </div>
  54              </div>
  55              <div class="tabbody">
  56                  <div class="ieisbuggy">
  57                  </div>
  58                  <div id="content">
  59                      %(Content)s
  60                  </div>
  61                  <div class="ieisbuggy">
  62                  </div>
  63              </div>
  64          </div>
  65          <div id="footer">
  66              <div class="footerleft">
  67                  <p>
  68                  $Footer
  69                  </p>
  70              </div>
  71          </div>
  72      </div>
  73      <div id="sidebarright">
  74          <div id="sidebar">
  75              <div class="sidebarbox">
  76                  $SideBar
  77              </div>
  78          </div>
  79          <div id="sidebarbottom">
  80          </div>
  81      </div>
  82  </body>

Add a comment

Those nice Site5 people appear to have increased the storage on my hosting account from 1.5G to 3G without telling me or charging me.

This is the same as their latest hosting packages.

How very nice of them.


Filed under: hosting php site5

4 Comments

Following my thoughts yesterday, here are some VIM python scripts to add python breakpoint and debugging features to VIM. With this set up the F7 key will set a breakpoint on a line of code, Shift-F7 will remove all breakpoints and Shift-F12 will execute a script in the python debugger. This only runs on windows as far as I know, because it uses the 'start' command to launch the debugger in a seperate process without VIM waiting for it to finish. This allows you to look through the source code (and fix it) while the debugging is still in progress.

This goes in a python block in _vimrc:

   1  def SetBreakpoint():
   2      import re
   3  
   4      nLine = int( vim.eval( 'line(".")'))
   5  
   6      strLine = vim.current.line
   7      strWhite = re.search( '^(\s*)', strLine).group(1)
   8  
   9      vim.current.buffer.append(
  10         "%(space)spdb.set_trace() %(mark)s Breakpoint %(mark)s" %
  11           {'space':strWhite, 'mark': '#' * 30}, nLine - 1)
  12  
  13      for strLine in vim.current.buffer:
  14          if strLine == "import pdb":
  15              break
  16      else:
  17          vim.current.buffer.append( 'import pdb', 0)
  18          vim.command( 'normal j1')
  19  
  20  vim.command( 'map <f7> :py SetBreakpoint()<cr>')
  21  
  22  def RemoveBreakpoints():
  23      import re
  24  
  25      nCurrentLine = int( vim.eval( 'line(".")'))
  26  
  27      nLines = []
  28      nLine = 1
  29      for strLine in vim.current.buffer:
  30          if strLine == 'import pdb' or strLine.lstrip()[:15] == 'pdb.set_trace()':
  31              nLines.append( nLine)
  32          nLine += 1
  33  
  34      nLines.reverse()
  35  
  36      for nLine in nLines:
  37          vim.command( 'normal %dG' % nLine)
  38          vim.command( 'normal dd')
  39          if nLine < nCurrentLine:
  40              nCurrentLine -= 1
  41  
  42      vim.command( 'normal %dG' % nCurrentLine)
  43  
  44  vim.command( 'map <s-f7> :py RemoveBreakpoints()<cr>')
  45  
  46  def RunDebugger():
  47      vim.command( 'wall')
  48      strFile = vim.eval( "g:mainfile")
  49      vim.command( "!start python -m pdb %s" % strFile)
  50  
  51  vim.command( 'map <s-f12> :py RunDebugger()<cr>')

This relies on using the runscript plugin, and modifying the function 'SetMainScript' as follows:

function s:SetMainScript()
  let s:mainfile = bufname('%')
  let g:mainfile = bufname('%')
  echo s:mainfile . ' set as the starting program.'
endfunction

This allows F11 to be used to select which file is executed to start debugging. F12 can still be used to launch the script outside of the debugger.

Now I don't need WingIDE or a pc upgrade.


Filed under: php python vim windows wingide

5 Comments