Skip to content

Commit 5876b48

Browse files
committed
Merge pull request ivanov#119 from jjhelmus/ipython3
Support for IPython 3.0, thanks to @jjhelmus
2 parents a47d92b + 64a435c commit 5876b48

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ vim-ipython
44

55
A two-way integration between Vim and IPython.
66

7-
IPython versions 0.11.x, 0.12.x, 0.13.x, 1.x and 2.x
7+
IPython versions 0.11.x, 0.12.x, 0.13.x, 1.x, 2.x and 3.x
88

99
* author: Paul Ivanov (http://pirsquared.org)
1010
* github: http://github.com/ivanov/vim-ipython
@@ -293,6 +293,7 @@ pull request with your attribution.
293293
* @memeplex for fixing the identifier grabbing on e.g. non-PEP8 compliant code
294294
* @pydave for IPythonTerminate (sending SIGTERM using our hack)
295295
* @luispedro for IPythonNew
296+
* @jjhelmus for IPython 3.x support.
296297

297298
Similar Projects
298299
----------------

ftplugin/python/vim_ipython.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def flush(self):pass
3939
def vim_variable(name, default=None):
4040
exists = int(vim.eval("exists('%s')" % name))
4141
return vim.eval(name) if exists else default
42-
42+
4343
def vim_regex_escape(x):
4444
for old, new in (("[", "\\["), ("]", "\\]"), (":", "\\:"), (".", "\."), ("*", "\\*")):
4545
x = x.replace(old, new)
@@ -122,7 +122,7 @@ def km_from_string(s=''):
122122
except ImportError:
123123
# < 0.12, no find_connection_file
124124
pass
125-
125+
126126
global km, kc, send
127127

128128
s = s.replace('--existing', '')
@@ -183,7 +183,7 @@ def km_from_string(s=''):
183183
klass = sc.__class__
184184
klass._oinfo_orig = klass.object_info
185185
klass.object_info = lambda s,x,y: s._oinfo_orig(x)
186-
186+
187187
#XXX: backwards compatibility for IPython < 1.0
188188
if not hasattr(kc, 'iopub_channel'):
189189
kc.iopub_channel = kc.sub_channel
@@ -247,6 +247,16 @@ def get_doc_msg(msg_id):
247247
if not content['found']:
248248
return b
249249

250+
# IPython 3.0+ the documentation message is encoding by the kernel
251+
if 'data' in content:
252+
try:
253+
text = content['data']['text/plain']
254+
for line in text.split('\n'):
255+
b.append(strip_color_escapes(line).rstrip())
256+
return b
257+
except KeyError: # no text/plain key
258+
return b
259+
250260
for field in ['type_name','base_class','string_form','namespace',
251261
'file','length','definition','source','docstring']:
252262
c = content.get(field,None)
@@ -300,7 +310,10 @@ def get_doc_buffer(level=0):
300310
vim.command('setlocal syntax=python')
301311

302312
def ipy_complete(base, current_line, pos):
303-
msg_id = kc.shell_channel.complete(base, current_line, pos)
313+
# pos is the location of the start of base, add the length
314+
# to get the completion position
315+
msg_id = kc.shell_channel.complete(base, current_line,
316+
int(pos) + len(base) - 1)
304317
try:
305318
m = get_child_msg(msg_id)
306319
matches = m['content']['matches']
@@ -399,14 +412,17 @@ def update_subchannel_msgs(debug=False, force=False):
399412
# TODO: alllow for distinguishing between stdout and stderr (using
400413
# custom syntax markers in the vim-ipython buffer perhaps), or by
401414
# also echoing the message to the status bar
402-
s = strip_color_escapes(m['content']['data'])
403-
elif header == 'pyout':
415+
try:
416+
s = strip_color_escapes(m['content']['data'])
417+
except KeyError: # changed in IPython 3.0.0
418+
s = strip_color_escapes(m['content']['text'])
419+
elif header == 'pyout' or header == 'execute_result':
404420
s = status_prompt_out % {'line': m['content']['execution_count']}
405421
s += m['content']['data']['text/plain']
406422
elif header == 'display_data':
407423
# TODO: handle other display data types (HMTL? images?)
408424
s += m['content']['data']['text/plain']
409-
elif header == 'pyin':
425+
elif header == 'pyin' or header == 'execute_input':
410426
# TODO: the next line allows us to resend a line to ipython if
411427
# %doctest_mode is on. In the future, IPython will send the
412428
# execution_count on subchannel, so this will need to be updated
@@ -418,13 +434,13 @@ def update_subchannel_msgs(debug=False, force=False):
418434
dots = '.' * len(prompt.rstrip())
419435
dots += prompt[len(prompt.rstrip()):]
420436
s += m['content']['code'].rstrip().replace('\n', '\n' + dots)
421-
elif header == 'pyerr':
437+
elif header == 'pyerr' or header == 'error':
422438
c = m['content']
423439
s = "\n".join(map(strip_color_escapes,c['traceback']))
424440
s += c['ename'] + ":" + c['evalue']
425441

426442
if s.find('\n') == -1:
427-
# somewhat ugly unicode workaround from
443+
# somewhat ugly unicode workaround from
428444
# http://vim.1045645.n5.nabble.com/Limitations-of-vim-python-interface-with-respect-to-character-encodings-td1223881.html
429445
if isinstance(s,unicode):
430446
s=s.encode(vim_encoding)
@@ -444,7 +460,7 @@ def update_subchannel_msgs(debug=False, force=False):
444460
if not startedin_vimipython:
445461
vim.command('normal! p') # go back to where you were
446462
return update_occured
447-
463+
448464
def get_child_msg(msg_id):
449465
# XXX: message handling should be split into its own process in the future
450466
while True:
@@ -456,7 +472,7 @@ def get_child_msg(msg_id):
456472
#got a message, but not the one we were looking for
457473
echo('skipping a message on shell_channel','WarningMsg')
458474
return m
459-
475+
460476
def print_prompt(prompt,msg_id=None):
461477
"""Print In[] or In[42] style messages"""
462478
global show_execution_count
@@ -554,7 +570,6 @@ def set_pid():
554570
global pid
555571
lines = '\n'.join(['import os', '_pid = os.getpid()'])
556572
msg_id = send(lines, silent=True, user_variables=['_pid'])
557-
558573
# wait to get message back from kernel
559574
try:
560575
child = get_child_msg(msg_id)
@@ -565,6 +580,9 @@ def set_pid():
565580
pid = int(child['content']['user_variables']['_pid'])
566581
except TypeError: # change in IPython 1.0.dev moved this out
567582
pid = int(child['content']['user_variables']['_pid']['data']['text/plain'])
583+
except KeyError: # change in IPython 3.0+
584+
pid = int(
585+
child['content']['user_expressions']['_pid']['data']['text/plain'])
568586
except KeyError: # change in IPython 1.0.dev moved this out
569587
echo("Could not get PID information, kernel not running Python?")
570588
return pid
@@ -608,7 +626,7 @@ def dedent_run_this_line():
608626

609627
def dedent_run_these_lines():
610628
run_these_lines(True)
611-
629+
612630
#def set_this_line():
613631
# # not sure if there's a way to do this, since we have multiple clients
614632
# send("get_ipython().shell.set_next_input(\'%s\')" % vim.current.line.replace("\'","\\\'"))
@@ -625,9 +643,9 @@ def toggle_reselect():
625643
#def set_breakpoint():
626644
# send("__IP.InteractiveTB.pdb.set_break('%s',%d)" % (vim.current.buffer.name,
627645
# vim.current.window.cursor[0]))
628-
# print("set breakpoint in %s:%d"% (vim.current.buffer.name,
646+
# print("set breakpoint in %s:%d"% (vim.current.buffer.name,
629647
# vim.current.window.cursor[0]))
630-
#
648+
#
631649
#def clear_breakpoint():
632650
# send("__IP.InteractiveTB.pdb.clear_break('%s',%d)" % (vim.current.buffer.name,
633651
# vim.current.window.cursor[0]))

0 commit comments

Comments
 (0)