If you're a user of the text editor Vim, chances are you are already impressed with the number and power of its inbuilt features. If you've ever tried to add your own functionality to the editor but been turned off by its arcane Vimscript language, then you'll be pleased to know that Vim now supports internal Python scripting.

The following commands only work if your version of Vim has been compiled with the -python flag set, pre-built versions of Vim later than version 7.0 have this flag set by default, older versions may not. You can check if your Vim program has Python support by typing the following command:

:python print "hi"

If the status bar displays hi, then you're in business.

You can use the Python command whenever you need a little Python right away, but as you might have noticed from the previous example, its standard output goes to the status line, not to the document.

To do more complicated Python code, you'll want to start embedding your code into functions. There are a few different ways to do this, either you can embed a Python block in a Vimscript function or use a map or a macro to call a Python function. We'll show you the first.

We'll be writing a function that uses the urllib and BeautifulSoup libraries to download a Web page and insert it into the current window. If you're unfamiliar with using BeautifulSoup, you may want to look back over our guide to Web parsing in Python.

Open up a new text file, and call it pyextend.vim -- we'll be writing our functions in here, and then sourcing this file in our editor to interpret it. Once you're comfortable with your code, you could include the code in your .vimrc (or _vimrc, in Windows) file so that it is always interpreted whenever you start a Vim or gVim session.

In pyextend.vim type the following:

function! GetHTML()
python << EOF
import vim, BeautifulSoup, urllib
handle = urllib.urlopen(vim.current.line)
soup = BeautifulSoup.BeautifulSoup(handle.read())
vim.current.buffer[:] = soup.prettify().split('\n')
EOF
endfunction

There's a lot going on there, so we'll go through it line by line.

function! GetHTML()

This first line defines a function in Vimscript called GetHTML, which takes no arguments. Function names must start with capital letters in Vim. The ! symbol after function tells Vim to overwrite any existing function called GetHTML.

python << EOF

This line says that until Vim sees a line containing just "EOF" we'll be writing Python code, rather than Vimscript.

import vim, BeautifulSoup, urllib

Here we import the three modules we'll be using: the vim module gives us access to the Vim window and its contents, BeautifulSoup is the library we use to parse the HTML and urllib is the library we use to download the Web page.

handle = urllib.urlopen(vim.current.line)

Creates a variable, called handle, and sets it to the file handle of opening a connection to the Web page. The address of the Web page is taken as the contents of the current line in the Vim window.

soup = BeautifulSoup.BeautifulSoup(handle.read())

Reads from the file handle and creates a BeautifulSoup instance with its contents.

vim.current.buffer[:] = soup.prettify().split('\n')

vim.current.buffer is a list containing the lines in the file we are currently working on in Vim. By using the [:] slice we are replacing it's entire contents with the prettified HTML source of the Web page.

EOF

We put "EOF" on a line all by itself to tell Vim that we are finished with Python code;

endfunction

Then end the function.

Save the pyextend.vim file and open a new window (or, type :new in Vim to open a new split). Then source the new function by typing :source pyextend.vim -- if there are errors check your indentation, Python code is still sensitive to indentation when embedded.

You can test this new function by typing in the address of any Web site (don't forget the http:// prefix) -- then in command mode, with your cursor on the line of the address, type :call GetHTML(). Your buffer should be replaced with the source of the page.

If your address was http://www.builderau.com.au/ then it should look something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>
   By developers, for developers - Builder AU
  </title>

There is a lot more you can do by extending Vim with Python scripting. If you want to explore, have a browse through the Vim module documentation.

Do you need help with Python? Gain advice from Builder AU forums

Comments

1

rig - 16/08/08

Thanks for sharing this! It opens up endless possibilities for a Python and VIM fan like me! :)

» Report offensive content

2

Andre - 13/06/09

Brilliant!! I didn't know you could write python in vim scripts! You just made my day. Time to start playing!

» Report offensive content

Leave a comment

You must read and type the 6 chars within 0..9 and A..F

* indicates mandatory fields.

2

Andre - 13/06/09

Brilliant!! I didn't know you could write python in vim scripts! You just made my day. Time to start playing! ... more

1

rig - 16/08/08

Thanks for sharing this! It opens up endless possibilities for a Python and VIM fan like me! :) ... more

Log in


Sign up | Forgot your password?

  • Staff Aussies to pay more for Win 7

    If you are looking to make some money in these troubled times, perhaps importing copies of Windows 7 could be for you. Read more »

    -- posted by Staff

  • Staff Firefox: Greens want it, 3.5rc2 not up to par

    This week's roundup looks at the situation surrounding a campaign to change Outlook HTML renderer, a Greens MP wants to install Firefox but is restricted and all the photos from the iPhone 3GS launch. Read more »

    -- posted by Staff

  • Chris Duckett Microsoft misses the Outlook point

    Ask designers which mail program is the bane of their existence, and you'll find that Outlook tops the list. The reason why the most popular email reader is also the most painful is simple: it uses Word to render HTML emails. Read more »

    -- posted by Chris Duckett

What's on?