##// END OF EJS Templates
Merge pull request #2363 from crbates/jinja2...
Merge pull request #2363 from crbates/jinja2 Refactor notebook templates to use Jinja2

File last commit:

r4872:34c10438
r8868:5669d321 merge
Show More
ipy_vimserver.py
245 lines | 7.8 KiB | text/x-python | PythonLexer
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076 """ Integration with gvim, by Erich Heine
Bernardo B. Marques
remove all trailling spaces
r4872 Provides a %vim magic command, and reuses the same vim session. Uses
unix domain sockets for communication between vim and IPython. ipy.vim is
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076 available in doc/examples of the IPython distribution.
Bernardo B. Marques
remove all trailling spaces
r4872 Slightly touched up email announcement (and description how to use it) by
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076 Erich Heine is here:
Ive recently been playing with ipython, and like it quite a bit. I did
however discover a bit of frustration, namely with editor interaction.
I am a gvim user, and using the command edit on a new file causes
ipython to try and run that file as soon as the text editor opens
up. The -x command of course fixes this, but its still a bit annoying,
switching windows to do a run file, then back to the text
editor. Being a heavy tab user in gvim, another annoyance is not being
able to specify weather a new tab is how I choose to open the file.
Not being one to shirk my open source duties (and seeing this as a
good excuse to poke around ipython internals), Ive created a script
for having gvim and ipython work very nicely together. Ive attached
both to this email (hoping of course that the mailing list allows such
things).
Bernardo B. Marques
remove all trailling spaces
r4872 There are 2 files:
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076
ipy_vimserver.py -- this file contains the ipython stuff
ipy.vim -- this file contains the gvim stuff
In combination they allow for a few functionalities:
#1. the vim magic command. This is a fancy wrapper around the edit
magic, that allows for a new option, -t, which opens the text in a new
gvim tab. Otherwise it works the same as edit -x. (it internally
calls edit -x). This magic command also juggles vim server management,
so when it is called when there is not a gvim running, it creates a
new gvim instance, named after the ipython session name. Once such a
gvim instance is running, it will be used for subsequent uses of the
vim command.
#2. ipython - gvim interaction. Once a file has been opened with the
vim magic (and a session set up, see below), pressing the F5 key in
vim will cause the calling ipython instance to execute run
filename.py. (if you typo like I do, this is very useful)
#3. ipython server - this is a thread wich listens on a unix domain
socket, and runs commands sent to that socket.
Note, this only works on POSIX systems, that allow for AF_UNIX type
sockets. It has only been tested on linux (a fairly recent debian
testing distro).
To install it put, the ipserver.py in your favorite locaion for
sourcing ipython scripts. I put the ipy.vim in
~/.vim/after/ftplugin/python/.
To use (this can be scripted im sure, but i usually have 2 or 3
ipythons and corresponding gvims open):
import ipy_vimserver
ipy_vimserver.setup('sessionname')
(Editors note - you can probably add these to your ipy_user_conf.py)
Then use ipython as you normally would, until you need to edit
something. Instead of edit, use the vim magic. Thats it!
"""
Brian Granger
ipapi.py => core/ipapi.py and imports updated.
r2027 from IPython.core import ipapi
Brian Granger
Continuing a massive refactor of everything.
r2205 from IPython.core.error import TryNext
Brian Granger
ipapi.py => core/ipapi.py and imports updated.
r2027
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076 import socket, select
import os, threading, subprocess
import re
Fernando Perez
Better report errors where select is missing POLLHUP/POLERR (win32)....
r3376 try:
ERRCONDS = select.POLLHUP|select.POLLERR
except AttributeError:
raise ImportError("Vim server not supported on this platform - select "
"missing necessary POLLHUP/POLLERR functionality")
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076 SERVER = None
Brian Granger
ipapi.py => core/ipapi.py and imports updated.
r2027 ip = ipapi.get()
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076
# this listens to a unix domain socket in a separate thread, so that comms
# between a vim instance and ipython can happen in a fun and productive way
class IpyServer(threading.Thread):
def __init__(self, sname):
super(IpyServer, self).__init__()
self.keep_running = True
self.__sname = sname
self.socket = socket.socket(socket.AF_UNIX)
self.poller = select.poll()
self.current_conns = dict()
self.setDaemon(True)
def listen(self):
self.socket.bind(self.__sname)
self.socket.listen(1)
def __handle_error(self, socket):
if socket == self.socket.fileno():
self.keep_running = False
for a in self.current_conns.values():
a.close()
return False
else:
y = self.current_conns[socket]
del self.current_conns[socket]
y.close()
self.poller.unregister(socket)
def serve_me(self):
self.listen()
self.poller.register(self.socket,select.POLLIN|ERRCONDS)
while self.keep_running:
try:
avail = self.poller.poll(1)
except:
continue
if not avail: continue
for sock, conds in avail:
if conds & (ERRCONDS):
if self.__handle_error(sock): continue
else: break
if sock == self.socket.fileno():
y = self.socket.accept()[0]
self.poller.register(y, select.POLLIN|ERRCONDS)
self.current_conns[y.fileno()] = y
else: y = self.current_conns.get(sock)
self.handle_request(y)
os.remove(self.__sname)
run = serve_me
def stop(self):
self.keep_running = False
def handle_request(self,sock):
sock.settimeout(1)
while self.keep_running:
try:
x = sock.recv(4096)
except socket.timeout:
pass
else:
break
self.do_it(x)
def do_it(self, data):
data = data.split('\n')
cmds = list()
for line in data:
cmds.append(line)
ip.runlines(cmds)
# try to help ensure that the unix domain socket is cleaned up proper
def shutdown_server(self):
if SERVER:
SERVER.stop()
SERVER.join(3)
Brian Granger
Continuing a massive refactor of everything.
r2205 raise TryNext
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076
ip.set_hook('shutdown_hook', shutdown_server, 10)
# this fun function exists to make setup easier for all, and makes the
# vimhook function ready for instance specific communication
def setup(sessionname='',socketdir=os.path.expanduser('~/.ipython/')):
global SERVER
if sessionname:
session = sessionname
elif os.environ.get('IPY_SESSION'):
session = os.environ.get('IPY_SESSION')
else:
session = 'IPYS'
vimhook.vimserver=session
vimhook.ipyserver = os.path.join(socketdir, session)
if not SERVER:
SERVER = IpyServer(vimhook.ipyserver)
SERVER.start()
# calls gvim, with all ops happening on the correct gvim instance for this
# ipython instance. it then calls edit -x (since gvim will return right away)
# things of note: it sets up a special environment, so that the ipy.vim script
# can connect back to the ipython instance and do fun things, like run the file
def vimhook(self, fname, line):
env = os.environ.copy()
vserver = vimhook.vimserver.upper()
check = subprocess.Popen('gvim --serverlist', stdout = subprocess.PIPE,
shell=True)
check.wait()
cval = [l for l in check.stdout.readlines() if vserver in l]
if cval:
vimargs = '--remote%s' % (vimhook.extras,)
else:
vimargs = ''
vimhook.extras = ''
env['IPY_SESSION'] = vimhook.vimserver
env['IPY_SERVER'] = vimhook.ipyserver
if line is None: line = ''
else: line = '+' + line
vim_cmd = 'gvim --servername %s %s %s %s' % (vimhook.vimserver, vimargs,
line, fname)
subprocess.call(vim_cmd, env=env, shell=True)
#default values to keep it sane...
vimhook.vimserver = ''
vimhook.ipyserver = ''
ip.set_hook('editor',vimhook)
# this is set up so more vim specific commands can be added, instead of just
# the current -t. all thats required is a compiled regex, a call to do_arg(pat)
# and the logic to deal with the new feature
newtab = re.compile(r'-t(?:\s|$)')
def vim(self, argstr):
def do_arg(pat, rarg):
x = len(pat.findall(argstr))
if x:
a = pat.sub('',argstr)
return rarg, a
else: return '', argstr
t, argstr = do_arg(newtab, '-tab')
vimhook.extras = t
argstr = 'edit -x ' + argstr
ip.magic(argstr)
Brian Granger
Continuing a massive refactor of everything.
r2205 ip.define_magic('vim', vim)
Ville M. Vainio
add ipy_vimserver.py extension, and ipy.vim to doc/examples. Both contributed by Erich Heine
r1076