Note: the text below is not for the fainthearted. Setting up Vim to
communicate with IPython is currently not very straightforward. The situation
will improve soon.
When I write Python code I tend to use IPython quite a bit to test and experiment. Currently this means quite a bit of reloading and writing test code in the IPython shell. I’ve always been a little jealous of the Emacs folks for being able to communicate with the Python shell with ease. Vim has a different philosophy. We use the editor to edit stuff and the shell to run it. With that in mind, one can set up Vim to talk to IPython.
There are several steps for this:
- Ensure that Vim is compiled with +python
- Get the code that enables communication with IPython
- Write code to send code from Vim to the server
Note: this assumes that you have Python, IPython and Twisted installed.
1. Ensure that vim is compiled with +python
Open your favorite version of Vim and do
In there look for “+python”. If it is not there, you need to somehow get a
version that has “+python”. It is also important to check which version of
Python your Vim was compiled against. For this, execute the following command in vim:
| :python import sys; print sys.version
|
The output should be the same as your primary version of Python.
For example, I am on OS X 10.5.8. By default it ships with Apple Python 2.5. I prefer to use Python 2.6 from MacPorts.
Because of this I had to build a version of Macvim from source that pointed to my installation of Python 2.6. This deserves
its own post.
2. Getting the code for communicating with IPython
Matt Foster has written a plugin for Textmate called ipythontm-bundle. This Textmate bundle
uses the ipy_textmateserver.py to create a Twisted server to which stuff is sent for evaluation from Vim.
This file is can be downloaded from the textmate-server branch
of IPython.
For Vim we only need this file. Why only this file will be explained at the end of this post.
Once the file is downloaded put it in your IPython/Extensions directory. For me this directory is:
| /opt/local/Library/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/IPython/Extensions
|
3. The Vim side of life
At the moment, Vim has no idea that there will be a server running. Therefore, we have to write a plugin. The following (very very simple) code server as said plugin.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | import vim
import socket
def runner(content):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
# make sure to chage the directory here
s.connect("/YOUR/HOME/DIR/.ipython/IPYS")
s.send(content)
s.close()
except:
print "Error: could not connect to iPython server."
# --- Functions for running code in iPython --------------------------------- #
def run_current_line():
runner(vim.current.line)
def run_selection():
runner("\n".join(vim.current.range))
def run_buffer():
runner("\n".join(vim.current.buffer))
# --- Clean up function
def remove_sockets():
import os
import sys
os.remove("/Users/petrov/.ipython/IPYS")
|
Essentially, the server will create a UNIX socket. By default the socket is:
It is possible to rename the socket or use different ones for different Vim windows. For now, I wanted to get the basics going.
The Python code above should go into
4. Using the code
Now that the code is in place we can start using it. Start IPython and execute the following code:
| import ipy_textmateserver
# create the server
s = ipy_textmateserver.TextMateServer()
# start the server
s.start()
# to stop the server do: s.stop()
|
Now the server is running in that instance of the shell. Open a Python file in Vim. Create a map for executing the current line in Vim:
| :map ,el :python run_current_line()<cr>
|
Put the cursor on the line of code you want to eval and do: ,el.
This should send the line to IPython and you should see the results of execution in the shell.
The other two functions in on the plugin side can also be mapped to whatever you want.
Question and Answer
This is very complicated!
Yes, this is not the easiest thing in the world. But it let’s me work the way I want to work. In the future this will be packaged better
as a proper Vim plugin.
Why not use the client that comes with the ipythontm-bundle.
I did try to use that code. However, it seems that Vim and Textmate do things differently. The Vim client that comes with ipythontm-bundle
uses a Twisted reactor to send code to the server. This is great. However, once the reactor is stopped it can’t be restarted. Any attempts to do
so result in a blocked thread. When this happens from inside Vim, it kills the whole session. This sucks. My guess is that Textmate reloads the whole
client file. Vim doesn’t seem to do this. Therefore, I opted to use simple Python sockets.
Why not use ipy_vimserver.py?
I tried this as well. However, it uses socket code that doesn’t work on my machine. If you’re on Linux you should be able to use ipy_vimserver.py without
any problems.