two-way vim-ipython integration #631

Merged
merged 1 commit into from Jul 30, 2011
@@ -1,143 +0,0 @@
-if !exists("$IPY_SESSION")
- finish
-endif
-
-" set up the python interpreter within vim, to have all the right modules
-" imported, as well as certain useful globals set
-python import socket
-python import os
-python import vim
-python from IPython.core.debugger import Pdb
-python IPYSERVER = None
-python reselect = True
-
-python << EOF
-# do we have a connection to the ipython instance?
-def check_server():
- global IPYSERVER
- if IPYSERVER:
- return True
- else:
- return False
-
-# connect to the ipython server, if we need to
-def connect():
- global IPYSERVER
- if check_server():
- return
- try:
- IPYSERVER = socket.socket(socket.AF_UNIX)
- IPYSERVER.connect(os.environ.get('IPY_SERVER'))
- except:
- IPYSERVER = None
-
-def disconnect():
- if IPYSERVER:
- IPYSERVER.close()
-
-def send(cmd):
- x = 0
- while True:
- x += IPYSERVER.send(cmd)
- if x < len(cmd):
- cmd = cmd[x:]
- else:
- break
-
-def run_this_file():
- if check_server():
- send('run %s' % (vim.current.buffer.name,))
- else:
- raise Exception, "Not connected to an IPython server"
- print "\'run %s\' sent to ipython" % vim.current.buffer.name
-
-def run_this_line():
- if check_server():
- send(vim.current.line)
- print "line \'%s\' sent to ipython"% vim.current.line
- else:
- raise Exception, "Not connected to an IPython server"
-
-def run_these_lines():
- r = vim.current.range
- if check_server():
- #send(str((vim.current.range.start,vim.current.range.end)))
- for l in vim.current.buffer[r.start:r.end+1]:
- send(str(l)+'\n')
- #send(str(vim.current.buffer[vim.current.range.start:vim.current.range.end]).join("\n"))
- #print "lines %d-%d sent to ipython"% (r.start,r.end)
- else:
- raise Exception, "Not connected to an IPython server"
-
- #reselect the previously highlighted block
- if reselect:
- vim.command("normal gv")
- #vim lines start with 1
- print "lines %d-%d sent to ipython"% (r.start+1,r.end+1)
-
-def toggle_reselect():
- global reselect
- reselect=not reselect
- print "F9 will%sreselect lines after sending to ipython"% (reselect and " " or " not ")
-
-def set_breakpoint():
- if check_server():
- send("__IP.InteractiveTB.pdb.set_break('%s',%d)" % (vim.current.buffer.name,
- vim.current.window.cursor[0]))
- print "set breakpoint in %s:%d"% (vim.current.buffer.name,
- vim.current.window.cursor[0])
- else:
- raise Exception, "Not connected to an IPython server"
-
-def clear_breakpoint():
- if check_server():
- send("__IP.InteractiveTB.pdb.clear_break('%s',%d)" % (vim.current.buffer.name,
- vim.current.window.cursor[0]))
- print "clearing breakpoint in %s:%d" % (vim.current.buffer.name,
- vim.current.window.cursor[0])
- else:
- raise Exception, "Not connected to an IPython server"
-
-def clear_all_breakpoints():
- if check_server():
- send("__IP.InteractiveTB.pdb.clear_all_breaks()");
- print "clearing all breakpoints"
- else:
- raise Exception, "Not connected to an IPython server"
-
-def run_this_file_pdb():
- if check_server():
- send(' __IP.InteractiveTB.pdb.run(\'execfile("%s")\')' % (vim.current.buffer.name,))
- else:
- raise Exception, "Not connected to an IPython server"
- print "\'run %s\' using pdb sent to ipython" % vim.current.buffer.name
-
- #XXX: have IPYSERVER print the prompt (look at Leo example)
-EOF
-
-fun! <SID>toggle_send_on_save()
- if exists("s:ssos") && s:ssos == 1
- let s:ssos = 0
- au! BufWritePost *.py :py run_this_file()
- echo "Autosend Off"
- else
- let s:ssos = 1
- au BufWritePost *.py :py run_this_file()
- echo "Autowsend On"
- endif
-endfun
-
-map <silent> <F5> :python run_this_file()<CR>
-map <silent> <S-F5> :python run_this_line()<CR>
-map <silent> <F9> :python run_these_lines()<CR>
-map <silent> <S-F9> :python toggle_reselect()<CR>
-map <silent> <C-F6> :python send('%pdb')<CR>
-map <silent> <F6> :python set_breakpoint()<CR>
-map <silent> <s-F6> :python clear_breakpoint()<CR>
-map <silent> <F7> :python run_this_file_pdb()<CR>
-map <silent> <s-F7> :python clear_all_breaks()<CR>
-imap <C-F5> <ESC><F5>a
-imap <S-F5> <ESC><S-F5>a
-imap <silent> <F5> <ESC><F5>a
-map <C-F5> :call <SID>toggle_send_on_save()<CR>
-py connect()
@@ -0,0 +1,107 @@
+###########
+vim-ipython
+###########
+
+A two-way integration between Vim and IPython 0.11+
+
+author: Paul Ivanov (http://pirsquared.org)
+
+github: http://github.com/ivanov/vim-ipython
+
+demo: http://pirsquared.org/vim-ipython/
+
+Using this plugin, you can send lines or whole files for IPython to
+execute, and also get back object introspection and word completions in
+Vim, like what you get with: ``object?<enter>`` and ``object.<tab>`` in
+IPython.
+
+The big change from previous versions of ``ipy.vim`` is that it no longer
+the old requires the brittle ipy_vimserver.py instantiation, and since
+it uses just vim and python, it is platform independent (i.e. should work
+even on windows, unlike the previous \*nix only solution)
+
+
+-----------------
+Quickstart Guide:
+-----------------
+Start ``ipython qtconsole`` and copy the connection string.
+Source ``ipy.vim`` file, which provides new IPython command::
+
+ :source ipy.vim
+ (or copy it to ~/.vim/ftplugin/python to load automatically)
+
+ :IPythonClipboard
+ (or :IPythonXSelection if you're using X11 without having to copy)
+
+The :IPython command allows you to put the full string, e.g.::
+
+ :IPython --existing --shell=41882 --iopub=43286 --stdin=34987 --hb=36697
+
+The ``:IPythonClipboard`` command just uses the ``+`` register to get the
+connection string, whereas ``:IPythonXSelection`` uses the ``*`` register
+
+------------------------
+Sending lines to IPython
+------------------------
+Now type out a line and send it to IPython using ``<Ctrl-S>`` from Command mode::
+
+ import os
+
+You should see a notification message confirming the line was sent, along
+with the input number for the line, like so ``In[1]: import os``.
+
+``<Ctrl-S>`` also works from insert mode, but doesn't show notification
+
+It also works blockwise in Visual Mode. Strip the leading double quotes and
+send these lines using ``<Ctrl-S>``::
+
+ import this,math # secret decoder ring
+ a,b,c,d,e,f,g,h,i = range(1,10)
+ code =(c,a,d,a,e,i,)
+ msg = '...jrer nyy frag sebz Ivz.\nIvz+VClguba=%fyl '+this.s.split()[g]
+ decode=lambda x:"\n"+"".join([this.d.get(c,c) for c in x])+"!"
+ format=lambda x:'These lines:\n '+'\n '.join([l for l in x.splitlines()])
+ secret_decoder = lambda a,b: format(a)+decode(msg)%str(b)[:-1]
+ '%d'*len(code)%code == str(int(math.pi*1e5))
+
+Then, go to the qtconsole and run this line::
+
+ print secret_decoder(_i,_)
+
+You can also send whole files to IPython's ``%run`` magic using ``<F5>``.
+
+-------------------------------
+IPython's object? Functionality
+-------------------------------
+
+If you're using gvim, mouse-over a variable to see IPython's ? equivalent. If
+you're using vim from a terminal, or want to copy something from the
+docstring, type ``<leader>d``. ``<leader>`` is usually ``\`` (the backslash
+key). This will open a quickpreview window, which can be closed by hitting
+``q`` or ``<escape>``.
+
+--------------------------------------
+IPython's tab-completion Functionality
+--------------------------------------
+vim-ipython activates a 'completefunc' that queries IPython.
+A completefunc is activated using ``Ctrl-X Ctrl-U`` in Insert Mode (vim
+default). You can combine this functionality with SuperTab to get tab
+completion
+
+---------------
+Current issues:
+---------------
+For now, vim-ipython only connects to an ipython session in progress.
+
+ipy.vim takes a while to load, I'll eventually move the python code to its
+own file and do a lazy import (only when the IPython command is called)
+
+The ipdb integration is not yet re-implemented.
+
+Need to add more message handling for sub_channel messages from IPython
+(i.e. notification of changes which were not sent from vim).
+
+------
+Thanks
+------
+@MinRK for guiding me through the IPython kernel manager protocol.
Oops, something went wrong.