##// END OF EJS Templates
merge
vivainio2 -
r1077:c10b8067 merge
parent child Browse files
Show More
@@ -0,0 +1,239 b''
1 """ Integration with gvim, by Erich Heine
2
3 Provides a %vim magic command, and reuses the same vim session. Uses
4 unix domain sockets for communication between vim and IPython. ipy.vim is
5 available in doc/examples of the IPython distribution.
6
7 Slightly touched up email announcement (and description how to use it) by
8 Erich Heine is here:
9
10 Ive recently been playing with ipython, and like it quite a bit. I did
11 however discover a bit of frustration, namely with editor interaction.
12 I am a gvim user, and using the command edit on a new file causes
13 ipython to try and run that file as soon as the text editor opens
14 up. The -x command of course fixes this, but its still a bit annoying,
15 switching windows to do a run file, then back to the text
16 editor. Being a heavy tab user in gvim, another annoyance is not being
17 able to specify weather a new tab is how I choose to open the file.
18
19 Not being one to shirk my open source duties (and seeing this as a
20 good excuse to poke around ipython internals), Ive created a script
21 for having gvim and ipython work very nicely together. Ive attached
22 both to this email (hoping of course that the mailing list allows such
23 things).
24
25 There are 2 files:
26
27 ipy_vimserver.py -- this file contains the ipython stuff
28 ipy.vim -- this file contains the gvim stuff
29
30 In combination they allow for a few functionalities:
31
32 #1. the vim magic command. This is a fancy wrapper around the edit
33 magic, that allows for a new option, -t, which opens the text in a new
34 gvim tab. Otherwise it works the same as edit -x. (it internally
35 calls edit -x). This magic command also juggles vim server management,
36 so when it is called when there is not a gvim running, it creates a
37 new gvim instance, named after the ipython session name. Once such a
38 gvim instance is running, it will be used for subsequent uses of the
39 vim command.
40
41 #2. ipython - gvim interaction. Once a file has been opened with the
42 vim magic (and a session set up, see below), pressing the F5 key in
43 vim will cause the calling ipython instance to execute run
44 filename.py. (if you typo like I do, this is very useful)
45
46 #3. ipython server - this is a thread wich listens on a unix domain
47 socket, and runs commands sent to that socket.
48
49 Note, this only works on POSIX systems, that allow for AF_UNIX type
50 sockets. It has only been tested on linux (a fairly recent debian
51 testing distro).
52
53 To install it put, the ipserver.py in your favorite locaion for
54 sourcing ipython scripts. I put the ipy.vim in
55 ~/.vim/after/ftplugin/python/.
56
57 To use (this can be scripted im sure, but i usually have 2 or 3
58 ipythons and corresponding gvims open):
59
60 import ipy_vimserver
61 ipy_vimserver.setup('sessionname')
62
63 (Editors note - you can probably add these to your ipy_user_conf.py)
64
65 Then use ipython as you normally would, until you need to edit
66 something. Instead of edit, use the vim magic. Thats it!
67
68 """
69
70 import IPython.ipapi
71 #import ipythonhooks
72 import socket, select
73 import os, threading, subprocess
74 import re
75
76 ERRCONDS = select.POLLHUP|select.POLLERR
77 SERVER = None
78 ip = IPython.ipapi.get()
79
80 # this listens to a unix domain socket in a separate thread, so that comms
81 # between a vim instance and ipython can happen in a fun and productive way
82 class IpyServer(threading.Thread):
83 def __init__(self, sname):
84 super(IpyServer, self).__init__()
85 self.keep_running = True
86 self.__sname = sname
87 self.socket = socket.socket(socket.AF_UNIX)
88 self.poller = select.poll()
89 self.current_conns = dict()
90 self.setDaemon(True)
91
92 def listen(self):
93 self.socket.bind(self.__sname)
94 self.socket.listen(1)
95
96 def __handle_error(self, socket):
97 if socket == self.socket.fileno():
98 self.keep_running = False
99 for a in self.current_conns.values():
100 a.close()
101 return False
102 else:
103 y = self.current_conns[socket]
104 del self.current_conns[socket]
105 y.close()
106 self.poller.unregister(socket)
107
108 def serve_me(self):
109 self.listen()
110 self.poller.register(self.socket,select.POLLIN|ERRCONDS)
111
112 while self.keep_running:
113 try:
114 avail = self.poller.poll(1)
115 except:
116 continue
117
118 if not avail: continue
119
120 for sock, conds in avail:
121 if conds & (ERRCONDS):
122 if self.__handle_error(sock): continue
123 else: break
124
125 if sock == self.socket.fileno():
126 y = self.socket.accept()[0]
127 self.poller.register(y, select.POLLIN|ERRCONDS)
128 self.current_conns[y.fileno()] = y
129 else: y = self.current_conns.get(sock)
130
131 self.handle_request(y)
132
133 os.remove(self.__sname)
134
135 run = serve_me
136
137 def stop(self):
138 self.keep_running = False
139
140 def handle_request(self,sock):
141 sock.settimeout(1)
142 while self.keep_running:
143 try:
144 x = sock.recv(4096)
145 except socket.timeout:
146 pass
147 else:
148 break
149 self.do_it(x)
150
151 def do_it(self, data):
152 data = data.split('\n')
153 cmds = list()
154 for line in data:
155 cmds.append(line)
156 ip.runlines(cmds)
157
158
159 # try to help ensure that the unix domain socket is cleaned up proper
160 def shutdown_server(self):
161 if SERVER:
162 SERVER.stop()
163 SERVER.join(3)
164 raise IPython.ipapi.TryNext
165
166 ip.set_hook('shutdown_hook', shutdown_server, 10)
167
168 # this fun function exists to make setup easier for all, and makes the
169 # vimhook function ready for instance specific communication
170 def setup(sessionname='',socketdir=os.path.expanduser('~/.ipython/')):
171 global SERVER
172
173 if sessionname:
174 session = sessionname
175 elif os.environ.get('IPY_SESSION'):
176 session = os.environ.get('IPY_SESSION')
177 else:
178 session = 'IPYS'
179 vimhook.vimserver=session
180 vimhook.ipyserver = os.path.join(socketdir, session)
181 if not SERVER:
182 SERVER = IpyServer(vimhook.ipyserver)
183 SERVER.start()
184
185
186
187 # calls gvim, with all ops happening on the correct gvim instance for this
188 # ipython instance. it then calls edit -x (since gvim will return right away)
189 # things of note: it sets up a special environment, so that the ipy.vim script
190 # can connect back to the ipython instance and do fun things, like run the file
191 def vimhook(self, fname, line):
192 env = os.environ.copy()
193 vserver = vimhook.vimserver.upper()
194 check = subprocess.Popen('gvim --serverlist', stdout = subprocess.PIPE,
195 shell=True)
196 check.wait()
197 cval = [l for l in check.stdout.readlines() if vserver in l]
198
199 if cval:
200 vimargs = '--remote%s' % (vimhook.extras,)
201 else:
202 vimargs = ''
203 vimhook.extras = ''
204
205 env['IPY_SESSION'] = vimhook.vimserver
206 env['IPY_SERVER'] = vimhook.ipyserver
207
208 if line is None: line = ''
209 else: line = '+' + line
210 vim_cmd = 'gvim --servername %s %s %s %s' % (vimhook.vimserver, vimargs,
211 line, fname)
212 subprocess.call(vim_cmd, env=env, shell=True)
213
214
215 #default values to keep it sane...
216 vimhook.vimserver = ''
217 vimhook.ipyserver = ''
218
219 ip.set_hook('editor',vimhook)
220
221 # this is set up so more vim specific commands can be added, instead of just
222 # the current -t. all thats required is a compiled regex, a call to do_arg(pat)
223 # and the logic to deal with the new feature
224 newtab = re.compile(r'-t(?:\s|$)')
225 def vim(self, argstr):
226 def do_arg(pat, rarg):
227 x = len(pat.findall(argstr))
228 if x:
229 a = pat.sub('',argstr)
230 return rarg, a
231 else: return '', argstr
232
233 t, argstr = do_arg(newtab, '-tab')
234 vimhook.extras = t
235 argstr = 'edit -x ' + argstr
236 ip.magic(argstr)
237
238 ip.expose_magic('vim', vim)
239
@@ -0,0 +1,67 b''
1 if !exists("$IPY_SESSION")
2 finish
3 endif
4
5 " set up the python interpreter within vim, to have all the right modules
6 " imported, as well as certain useful globals set
7 python import socket
8 python import os
9 python import vim
10 python IPYSERVER = None
11
12 python << EOF
13 # do we have a connection to the ipython instance?
14 def check_server():
15 global IPYSERVER
16 if IPYSERVER:
17 return True
18 else:
19 return False
20
21 # connect to the ipython server, if we need to
22 def connect():
23 global IPYSERVER
24 if check_server():
25 return
26 try:
27 IPYSERVER = socket.socket(socket.AF_UNIX)
28 IPYSERVER.connect(os.environ.get('IPY_SERVER'))
29 except:
30 IPYSERVER = None
31
32 def disconnect():
33 if IPYSERVER:
34 IPYSERVER.close()
35
36 def send(cmd):
37 x = 0
38 while True:
39 x += IPYSERVER.send(cmd)
40 if x < len(cmd):
41 cmd = cmd[x:]
42 else:
43 break
44
45 def run_this_file():
46 if check_server():
47 send('run %s' % (vim.current.buffer.name,))
48 else:
49 raise Exception, "Not connected to an IPython server"
50 EOF
51
52 fun! <SID>toggle_send_on_save()
53 if exists("s:ssos") && s:ssos == 1
54 let s:ssos = 0
55 au! BufWritePost *.py :py run_this_file()
56 echo "Autosend Off"
57 else
58 let s:ssos = 1
59 au BufWritePost *.py :py run_this_file()
60 echo "Autowsend On"
61 endif
62 endfun
63
64 map <silent> <F5> :python run_this_file()<CR>
65 imap <silent> <C-F5> <ESC><F5>a
66 map <F7> :call <SID>toggle_send_on_save()<CR>
67 py connect()
@@ -211,10 +211,15 b' def hg_completer(self,event):'
211 211
212 212
213 213
214 __bzr_commands = None
215
214 216 def bzr_commands():
217 global __bzr_commands
218 if __bzr_commands is not None:
219 return __bzr_commands
215 220 out = os.popen('bzr help commands')
216 return [l.split()[0] for l in out]
217
221 __bzr_commands = [l.split()[0] for l in out]
222 return __bzr_commands
218 223
219 224 def bzr_completer(self,event):
220 225 """ Completer for bazaar commands """
@@ -10,6 +10,7 b' import re'
10 10 import UserDict
11 11 from IPython.ipapi import TryNext
12 12 import IPython.macro
13 import IPython.Shell
13 14
14 15 def init_ipython(ipy):
15 16 """ This will be run by _ip.load('ipy_leo')
@@ -19,6 +20,7 b' def init_ipython(ipy):'
19 20 """
20 21 global ip
21 22 ip = ipy
23 IPython.Shell.hijack_tk()
22 24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
23 25 ip.expose_magic('mb',mb_f)
24 26 ip.expose_magic('lee',lee_f)
@@ -22,9 +22,13 b" name = 'ipython'"
22 22 # because bdist_rpm does not accept dashes (an RPM) convention, and
23 23 # bdist_deb does not accept underscores (a Debian convention).
24 24
25 revision = '46'
25 revision = '57'
26 branch = 'ipython'
26 27
27 version = '0.8.3.bzr.r' + revision
28 if branch == 'ipython':
29 version = '0.8.3.bzr.r' + revision
30 else:
31 version = '0.8.3.bzr.r%s.%s' % (revision,branch)
28 32
29 33 description = "An enhanced interactive Python shell."
30 34
@@ -275,11 +275,12 b' class IPApi:'
275 275 lines = script.splitlines()
276 276 level = 0
277 277 for l in lines:
278 stripped = l.lstrip()
279 if not l.strip():
278 lstripped = l.lstrip()
279 stripped = l.strip()
280 if not stripped:
280 281 continue
281 newlevel = len(l) - len(stripped)
282 if level > 0 and newlevel == 0:
282 newlevel = len(l) - len(lstripped)
283 if level > 0 and newlevel == 0 and not stripped.endswith(':'):
283 284 # add empty line
284 285 res.append('')
285 286 res.append(l)
@@ -3,7 +3,7 b''
3 3 <leo_file>
4 4 <leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/>
5 5 <globals body_outline_ratio="0.307814992026">
6 <global_window_position top="122" left="624" height="627" width="1280"/>
6 <global_window_position top="180" left="223" height="627" width="1280"/>
7 7 <global_log_window_position top="0" left="0" height="0" width="0"/>
8 8 </globals>
9 9 <preferences/>
@@ -25,7 +25,8 b''
25 25 </v>
26 26 </v>
27 27 <v t="vivainio.20080218184525"><vh>@chapters</vh></v>
28 <v t="vivainio.20080223133721"><vh>@settings</vh>
28 <v t="vivainio.20080223133721" a="E"><vh>@settings</vh>
29 <v t="vivainio.20080316092617"><vh>@@string ipython_argv = ipython -pylab</vh></v>
29 30 <v t="vivainio.20080223133721.1"><vh>@enabled-plugins</vh></v>
30 31 </v>
31 32 <v t="vivainio.20080218184540"><vh>@ipy-startup</vh>
@@ -47,11 +48,16 b''
47 48 <v t="vivainio.20080222201226"><vh>NewHeadline</vh></v>
48 49 <v t="vivainio.20080218201219.2"><vh>bar</vh></v>
49 50 </v>
51 <v t="vivainio.20080316144536" a="E"><vh>pylab tests</vh>
52 <v t="vivainio.20080316145539.2" a="TV"><vh>Generate testarr</vh></v>
53 <v t="vivainio.20080316085925"><vh>testarr</vh></v>
54 <v t="vivainio.20080316085950"><vh>Call plotter on testarr</vh></v>
55 </v>
50 56 <v t="vivainio.20080222202211"><vh>test stuff</vh></v>
51 <v t="vivainio.20080223142403" a="E"><vh>@ipy-results</vh>
57 <v t="vivainio.20080223142403"><vh>@ipy-results</vh>
52 58 <v t="vivainio.20080223142403.1"><vh>foo</vh></v>
53 59 </v>
54 <v t="vivainio.20080222202211.1" a="ETV"><vh>spam</vh></v>
60 <v t="vivainio.20080222202211.1" a="E"><vh>spam</vh></v>
55 61 </vnodes>
56 62 <tnodes>
57 63 <t tx="vivainio.20080218184525">?</t>
@@ -129,7 +135,14 b' print "hello"'
129 135 def f(x):
130 136 return x.upper()
131 137
132 f('hello world')</t>
138 f('hello world')
139
140 if 0:
141 print "foo"
142 else:
143 print "bar"
144
145 </t>
133 146 <t tx="vivainio.20080222202211"></t>
134 147 <t tx="vivainio.20080222202211.1" ipython="7d71005506636f6f7264737101284b0c4bde747102732e">@cl rfile
135 148 hello
@@ -495,5 +508,21 b" Create 10 child nodes for baz, where i is headline and 'Hello ' + i is body:"
495 508 </t>
496 509 <t tx="vivainio.20080223142403"></t>
497 510 <t tx="vivainio.20080223142403.1">12</t>
511 <t tx="vivainio.20080316085925">array([[ 0, 1, 2],
512 [ 3, 4, 5],
513 [ 6, 7, 8],
514 [ 9, 10, 11]])</t>
515 <t tx="vivainio.20080316085950"># press alt+i here to plot testarr
516
517 plot(wb.testarr.v)</t>
518 <t tx="vivainio.20080316092617"></t>
519 <t tx="vivainio.20080316144536">Quickstart:
520 easy_install numpy
521 easy_install matplotlib
522
523 Make sure you have '@string ipython-argv = ipython -pylab' in @settings. We currently recommend using TkAgg as the backend (it's also the default)</t>
524 <t tx="vivainio.20080316145539.2">#press alt+i here to generate an array for plotter
525
526 wb.testarr.v = arange(12).reshape(4,3)</t>
498 527 </tnodes>
499 528 </leo_file>
@@ -15,7 +15,7 b' import IPython.ipapi'
15 15 def test_session(shellclass):
16 16 print "*****************\nLaunch shell for",shellclass
17 17 my_ns = dict(a=10)
18 ses = IPython.ipapi.make_session(my_ns)
18 ses = IPython.ipapi.make_session(my_ns, shellclass=shellclass)
19 19
20 20 # Now get the ipapi instance, to be stored somewhere in your program for manipulation of the running
21 21 # IPython session. See http://ipython.scipy.org/moin/IpythonExtensionApi
@@ -38,5 +38,11 b' def test_session(shellclass):'
38 38
39 39 import IPython.Shell
40 40
41 test_session(shellclass = None)
42 test_session(IPython.Shell._select_shell(['ipython', '-q4thread']))
41 def do_test(arg_line):
42 test_session(IPython.Shell._select_shell(arg_line.split()))
43
44 do_test('')
45 do_test('ipython -gthread')
46 do_test('ipython -q4thread')
47 do_test('ipython -pylab')
48 do_test('ipython -pylab -gthread') No newline at end of file
@@ -1,12 +1,7 b''
1 1 import os,sys,shutil
2 2
3 repo = "http://ipython.scipy.org/svn/ipython/ipython/branches/0.7.3"
4 basename = 'ipython'
5 workdir = './mkdist'
6
7 workdir = os.path.abspath(workdir)
3 basever = '0.8.3'
8 4
9 print "working at",workdir
10 5 def oscmd(c):
11 6 print ">",c
12 7 s = os.system(c)
@@ -14,15 +9,24 b' def oscmd(c):'
14 9 print "Error",s
15 10 sys.exit(s)
16 11
12 def verinfo():
13
14 out = os.popen('bzr version-info')
15 pairs = (l.split(':',1) for l in out)
16 d = dict(((k,v.strip()) for (k,v) in pairs))
17 return d
18
19 basename = 'ipython'
20
21 #tarname = '%s.r%s.tgz' % (basename, ver)
22 oscmd('update_revnum.py')
23
24 ver = verinfo()
17 25
18 assert not os.path.isdir(workdir)
19 os.mkdir(workdir)
20 os.chdir(workdir)
26 if ver['branch-nick'] == 'ipython':
27 tarname = 'ipython-%s.bzr.r%s.tgz' % (basever, ver['revno'])
28 else:
29 tarname = 'ipython-%s.bzr.r%s.%s.tgz' % (basever, ver['revno'], ver['branch-nick'])
30
31 oscmd('bzr export ' + tarname)
21 32
22 oscmd('svn export %s %s' % (repo,basename))
23 ver = os.popen('svnversion ../..').read().strip()
24 tarname = '%s.r%s.tgz' % (basename, ver)
25 oscmd('tar czvf ../%s %s' % (tarname, basename))
26 print "Produced: ",os.path.abspath('../' + tarname)
27 os.chdir('/')
28 shutil.rmtree(workdir)
@@ -2,13 +2,22 b''
2 2 """ Change the revision number in Release.py """
3 3
4 4 import os
5 import re
5 import re,pprint
6 6
7 rev = os.popen('bzr revno').read().strip()
7 def verinfo():
8
9 out = os.popen('bzr version-info')
10 pairs = (l.split(':',1) for l in out)
11 d = dict(((k,v.strip()) for (k,v) in pairs))
12 return d
8 13
9 print "current rev is",rev
10 assert ':' not in rev
14 ver = verinfo()
15
16 pprint.pprint(ver)
11 17
12 18 rfile = open('../IPython/Release.py','rb').read()
13 newcont = re.sub(r'revision\s*=.*', "revision = '%s'" % rev, rfile)
19 newcont = re.sub(r'revision\s*=.*', "revision = '%s'" % ver['revno'], rfile)
20
21 newcont = re.sub(r'^branch\s*=[^=].*', "branch = '%s'" % ver['branch-nick'], newcont )
22
14 23 open('../IPython/Release.py','wb').write(newcont)
General Comments 0
You need to be logged in to leave comments. Login now