@@ -93,11 +93,11 @@ status_blank_lines = int(vim_variable('g:ipy_status_blank_lines', '1'))
9393ip = ' 127.0.0.1'
9494try :
9595 km
96- except NameError:
97- km = None
98- try :
96+ kc
9997 pid
10098except NameError:
99+ km = None
100+ kc = None
101101 pid = None
102102
103103def km_from_string (s = ' ' ):
@@ -110,23 +110,23 @@ def km_from_string(s=''):
110110 from Queue import Empty
111111 try :
112112 from IPython.kernel import (
113- BlockingKernelManager ,
113+ KernelManager ,
114114 find_connection_file,
115115 )
116116 except ImportError:
117- # < 0.14
118- from IPython.zmq.blockingkernelmanager import BlockingKernelManager
117+ # IPython < 1.0
118+ from IPython.zmq.blockingkernelmanager import BlockingKernelManager as KernelManager
119119 from IPython.zmq.kernelapp import kernel_aliases
120120 try :
121121 from IPython.lib.kernel import find_connection_file
122122 except ImportError:
123123 # < 0.12 , no find_connection_file
124124 pass
125125
126- global km ,send,Empty
126+ global km , kc, send, Empty
127127
128128 s = s .replace (' --existing' , ' ' )
129- if ' connection_file' in BlockingKernelManager .class_trait_names ():
129+ if ' connection_file' in KernelManager .class_trait_names ():
130130 # 0.12 uses files instead of a collection of ports
131131 # include default IPython search path
132132 # filefind also allows for absolute paths, in which case the search
@@ -147,7 +147,7 @@ def km_from_string(s=''):
147147 echo (" :IPython " + s + " failed" , " Info" )
148148 echo (" ^-- failed '" + s + " ' not found" , " Error" )
149149 return
150- km = BlockingKernelManager (connection_file = fullpath)
150+ km = KernelManager (connection_file = fullpath)
151151 km .load_connection_file ()
152152 else :
153153 if s == ' ' :
@@ -156,7 +156,7 @@ def km_from_string(s=''):
156156 loader = KeyValueConfigLoader (s .split (), aliases= kernel_aliases)
157157 cfg = loader.load_config ()[' KernelApp' ]
158158 try :
159- km = BlockingKernelManager (
159+ km = KernelManager (
160160 shell_address= (ip, cfg[' shell_port' ]),
161161 sub_address= (ip, cfg[' iopub_port' ]),
162162 stdin_address= (ip, cfg[' stdin_port' ]),
@@ -165,12 +165,18 @@ def km_from_string(s=''):
165165 echo (" :IPython " + s + " failed" , " Info" )
166166 echo (" ^-- failed --" + e .message.replace (' _port' ,' ' )+ " not specified" , " Error" )
167167 return
168- km .start_channels ()
169- send = km .shell_channel.execute
168+
169+ try :
170+ kc = km .client ()
171+ except AttributeError:
172+ # 0.13
173+ kc = km
174+ kc.start_channels ()
175+ send = kc.shell_channel.execute
170176
171177 #XXX : backwards compatability for IPython < 1.0
172- if not hasattr (km , ' iopub_channel' ):
173- km .iopub_channel = km .sub_channel
178+ if not hasattr (kc , ' iopub_channel' ):
179+ kc .iopub_channel = kc .sub_channel
174180
175181 # now that we're connect to an ipython kernel, activate completion
176182 # machinery, but do so only for the local buffer if the user added the
@@ -206,10 +212,10 @@ def disconnect():
206212 # XXX : make a prompt here if this km owns the kernel
207213 pass
208214
209- def get_doc (word):
210- if km is None:
215+ def get_doc (word, level = 0 ):
216+ if kc is None:
211217 return [" Not connected to IPython, cannot query: %s" % word]
212- msg_id = km .shell_channel.object_info (word)
218+ msg_id = kc .shell_channel.object_info (word, level )
213219 doc = get_doc_msg (msg_id)
214220 # get around unicode problems when interfacing with vim
215221 return [d .encode (vim_encoding) for d in doc]
@@ -253,7 +259,7 @@ def get_doc_buffer(level=0):
253259 vim .command (" let &isk = '@,48-57,_,192-255,.'" )
254260 word = vim .eval (' expand("<cword>")' ) or ' '
255261 vim .command (" let &isk = isk_save" ) # restore iskeyword list
256- doc = get_doc (word)
262+ doc = get_doc (word, level )
257263 if len (doc) == 0 :
258264 echo (repr (word)+ " not found" ," Error" )
259265 return
@@ -277,8 +283,12 @@ def get_doc_buffer(level=0):
277283 #vim .command (' pcl' )
278284 #vim .command (' pedit doc' )
279285 #vim .command (' normal ' ) # go to previous window
280- # use the ReST formatting that ships with stock vim
281- vim .command (' setlocal syntax=rst' )
286+ if level == 0 :
287+ # use the ReST formatting that ships with stock vim
288+ vim .command (' setlocal syntax=rst' )
289+ else :
290+ # use Python syntax highlighting
291+ vim .command (' setlocal syntax=python' )
282292
283293def vim_ipython_is_open ():
284294 " ""
@@ -296,9 +306,9 @@ def update_subchannel_msgs(debug=False, force=False):
296306 This function will do nothing if the vim - ipython shell is not visible,
297307 unless force= True argument is passed.
298308 " ""
299- if km is None or (not vim_ipython_is_open () and not force):
309+ if kc is None or (not vim_ipython_is_open () and not force):
300310 return False
301- msgs = km .iopub_channel.get_msgs ()
311+ msgs = kc .iopub_channel.get_msgs ()
302312 if debug :
303313 #try :
304314 # vim .command (" b debug_msgs" )
@@ -369,6 +379,9 @@ def update_subchannel_msgs(debug=False, force=False):
369379 elif m [' header' ][' msg_type' ] == ' status' :
370380 continue
371381 elif m [' header' ][' msg_type' ] == ' stream' :
382+ # TODO : alllow for distinguishing between stdout and stderr (using
383+ # custom syntax markers in the vim - ipython buffer perhaps), or by
384+ # also echoing the message to the status bar
372385 s = strip_color_escapes (m [' content' ][' data' ])
373386 elif m [' header' ][' msg_type' ] == ' pyout' :
374387 s = status_prompt_out % {' line' : m [' content' ][' execution_count' ]}
@@ -405,7 +418,8 @@ def update_subchannel_msgs(debug=False, force=False):
405418 if status_blank_lines:
406419 if b [-1 ] != ' ' :
407420 b .append ([' ' ])
408- vim .command (' normal G' ) # go to the end of the file
421+ if update_occured or force:
422+ vim .command (' normal G' ) # go to the end of the file
409423 if not startedin_vimipython:
410424 vim .command (' normal p' ) # go back to where you were
411425 return update_occured
@@ -414,7 +428,7 @@ def get_child_msg(msg_id):
414428 # XXX : message handling should be split into its own process in the future
415429 while True:
416430 # get_msg will raise with Empty exception if no messages arrive in 1 second
417- m = km .shell_channel.get_msg (timeout = 1 )
431+ m = kc .shell_channel.get_msg (timeout = 1 )
418432 if m [' parent_header' ][' msg_id' ] == msg_id:
419433 break
420434 else :
@@ -443,7 +457,7 @@ def with_subchannel(f,*args):
443457 f (* args )
444458 if monitor_subchannel:
445459 update_subchannel_msgs ()
446- except AttributeError: #if km is None
460+ except AttributeError: #if kc is None
447461 echo (" not connected to IPython" , ' Error' )
448462 return f_with_update
449463
@@ -454,6 +468,24 @@ def run_this_file():
454468
455469@w ith_subchannel
456470def run_this_line ():
471+ if vim .current.line .strip ().endswith (' ?' ):
472+ # intercept question mark queries -- move to the word just before the
473+ # question mark and call the get_doc_buffer on it
474+ w = vim .current.window
475+ original_pos = w .cursor
476+ new_pos = (original_pos[0 ], vim .current.line .index (' ?' )-1 )
477+ w .cursor = new_pos
478+ if vim .current.line .strip ().endswith (' ??' ):
479+ # double question mark should display source
480+ # XXX : it's not clear what level = 2 is for , level = 1 is sufficient
481+ # to get the code -- follow up with IPython team on this
482+ get_doc_buffer (1 )
483+ else :
484+ get_doc_buffer ()
485+ # leave insert mode , so we're in command mode
486+ vim .command (' stopi' )
487+ w .cursor = original_pos
488+ return
457489 msg_id = send (vim .current.line )
458490 print_prompt (vim .current.line , msg_id)
459491
@@ -486,7 +518,7 @@ def set_pid():
486518 " ""
487519 Explicitly ask the ipython kernel for its pid
488520 " ""
489- global km , pid
521+ global pid
490522 lines = ' \n' .join ([' import os' , ' _pid = os.getpid()' ])
491523 msg_id = send (lines , silent = True, user_variables= [' _pid' ])
492524
@@ -501,7 +533,12 @@ def set_pid():
501533 return pid
502534
503535
504- def interrupt_kernel_hack ():
536+ def terminate_kernel_hack ():
537+ " Send SIGTERM to our the IPython kernel"
538+ import signal
539+ interrupt_kernel_hack (signal.SIGTERM)
540+
541+ def interrupt_kernel_hack (signal_to_send= None):
505542 " ""
506543 Sends the interrupt signal to the remote kernel. This side steps the
507544 (non- functional) ipython interrupt mechanisms.
@@ -518,10 +555,13 @@ def interrupt_kernel_hack():
518555 if pid is None:
519556 echo (" cannot get kernel PID, Ctrl-C will not be supported" )
520557 return
558+ if not signal_to_send:
559+ signal_to_send = signal.SIGINT
560+
521561 echo (" KeyboardInterrupt (sent to ipython: pid " +
522- " %i with signal %i )" % (pid, signal.SIGINT ),"Operator")
562+ " %i with signal %s )" % (pid, signal_to_send ),"Operator")
523563 try :
524- os.kill (pid, signal.SIGINT )
564+ os.kill (pid, int (signal_to_send) )
525565 except OSError:
526566 echo (" unable to kill pid %d" % pid)
527567 pid = None
@@ -654,7 +694,8 @@ endif
654694command ! -nargs =* IPython :py km_from_string (" <args>" )
655695command ! -nargs =0 IPythonClipboard :py km_from_string (vim .eval (' @+' ))
656696command ! -nargs =0 IPythonXSelection :py km_from_string (vim .eval (' @*' ))
657- command ! -nargs =0 IPythonInterrupt :py interrupt_kernel_hack ()
697+ command ! -nargs =* IPythonInterrupt :py interrupt_kernel_hack (" <args>" )
698+ command ! -nargs =0 IPythonTerminate :py terminate_kernel_hack ()
658699
659700function ! IPythonBalloonExpr ()
660701python << endpython
@@ -684,7 +725,7 @@ endpython
684725 python << endpython
685726base = vim .eval (" a:base" )
686727findstart = vim .eval (" a:findstart" )
687- msg_id = km .shell_channel.complete (base, current_line, vim .eval (" col('.')" ))
728+ msg_id = kc .shell_channel.complete (base, current_line, vim .eval (" col('.')" ))
688729try :
689730 m = get_child_msg (msg_id)
690731 matches = m [' content' ][' matches' ]
0 commit comments