Python Super-calls in Vim with ease

Overriding methods in Python is very verbose when it comes to calling the base implementation of the method. Say our base object looks like this:

class Base(object):  
  def __init__(self, arg):
    self.somevar = arg

  def methodA(self, arg):
    return self.somevar + arg

Now our code wants to inherit from that Base object add spice it up with it's own functionality:

class Derived(Base):  
  def __init__(self, arg, otherArg):
    super(Derived, self).__init__(arg) # argh!
    self.othervar = otherarg

  def methodA(self, arg, *moreArgs):
    c = super(Derived, self).methodA(arg) #argh!
    return c + reduce(lambda x, y: a + b, moreArgs) / self.othervar

Writing all the super... stuff is not that super. Even repeating the method name all the time is not that great. With an unholy Vim macro we can get that sorted out for free.

<Esc>lma?^\s*def<CR>ffllvt("ay?^class<CR>2fsllvt("by`aisuper(<Esc>"bpa, self).<Esc>"apla  

Now let's say we're implementing methodA of Derived what we need to write is:

def methodA(self, arg, *moreArgs):  
  c = |(arg)

| denotes cursor position. Now when we execute the macro, this is the result:

c = super(Derived, self).methodA(arg)  

Plain English translation of the above macro would be:

  • Enter Normal mode
  • Save current position in a
  • Search backwards for a line starting with def
    • Select from after the def until first ( and save in register a
  • Search backwards for a line starting with class
    • Select from after the class until first ( and save in register b
  • Jump back to position stored in a
  • Fill in super(
    • Paste register b (class name)
  • Fill in , self).
    • Paste register a (method name)
  • Enter Insert mode

And yes, I have that macro mapped like:

imap <C-d> <Esc>lma?^\s*def<CR>ffllvt("ay?^class<CR>2fsllvt("by`aisuper(<Esc>"bpa, self).<Esc>"apla

Now working with Python & inheritance in Vim is not painful :)