Skip to content

Commit 021e9c3

Browse files
committed
Use dicts for completion metadata instead of strs
1 parent dc67fda commit 021e9c3

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

ftplugin/python/ipy.vim

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ def process_matches(matches, metadata, result):
254254
completions = matches
255255
else:
256256
completions = [s.encode(vim_encoding) for s in matches]
257-
metadata = [s.encode(vim_encoding) for s in metadata]
257+
for i, m in enumerate(metadata):
258+
metadata[i] = {k: v.encode(vim_encoding) for k, v in m.items()}
258259
if vim.vars['ipython_dictionary_completion'] and not vim.vars['ipython_greedy_matching']:
259260
for char in '\'"':
260261
if any(c.endswith(char + ']') for c in completions):
@@ -266,16 +267,18 @@ def process_matches(matches, metadata, result):
266267
except ValueError:
267268
pass
268269
for c, m in zip(completions, metadata):
269-
m = m.replace('\0', '^@') # vim can't handle null bytes in Python strings
270+
# vim can't handle null bytes in Python strings
271+
m = {k: v.replace('\0', '^@') for k, v in m.items()}
270272
result.c, result.m = c, m
271-
if 'CALLSIG' in m:
272-
result.split = m.partition('CALLSIG')
273-
vim.command('call add(res, {"word": IPythonPyeval("r.c"), '
274-
'"menu": IPythonPyeval("r.split[0]"), '
275-
'"info": IPythonPyeval("r.split[-1]")})')
273+
if 'info' in m:
274+
r.text, r.info = m['text'], m['info']
275+
vim.command('call add(res, {"word": IPythonPyeval("r.c"), '
276+
'"menu": IPythonPyeval("r.text"), '
277+
'"info": IPythonPyeval("r.info")})')
276278
else:
277-
vim.command('call add(res, {"word": IPythonPyeval("r.c"), '
278-
'"menu": IPythonPyeval("r.m")})')
279+
r.text = m.get('text', '')
280+
vim.command('call add(res, {"word": IPythonPyeval("r.c"), '
281+
'"menu": IPythonPyeval("r.text")})')
279282
endpython
280283

281284
fun! CompleteIPython(findstart, base)

ftplugin/python/vim_ipython.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def __getattribute__(self, key):
1818
vim = NoOp()
1919
print("uh oh, not running inside vim")
2020

21+
import ast
2122
import os
2223
import sys
2324
import time
@@ -345,7 +346,6 @@ def get_doc_msg(msg_id):
345346
elif 'user_expressions' in content:
346347
doc = content['user_expressions']['_doc']
347348
if doc:
348-
import ast
349349
content = ast.literal_eval(doc['data']['text/plain'])
350350

351351
if not content['found']:
@@ -446,20 +446,36 @@ def ipy_complete(base, current_line, pos):
446446
msg_id = complete(code=current_line, cursor_pos=pos)
447447
try:
448448
m = get_child_msg(msg_id, timeout=vim_vars.get('ipython_completion_timeout', 2))
449-
matches = m['content']['matches']
450-
metadata = m['content'].get('metadata', None)
451-
if not metadata:
452-
metadata = ['' for _ in matches]
453-
# we need to be careful with unicode, because we can have unicode
454-
# completions for filenames (for the %run magic, for example). So the next
455-
# line will fail on those:
456-
#completions= [str(u) for u in matches]
457-
# because str() won't work for non-ascii characters
458-
# and we also have problems with unicode in vim, hence the following:
459-
return matches, metadata
449+
try:
450+
return get_completion_metadata()
451+
except KeyError: # completion_metadata function not available
452+
matches = m['content']['matches']
453+
metadata = [{} for _ in matches]
454+
return matches, metadata
455+
except Empty:
456+
echo("no reply from IPython kernel")
457+
raise IOError
458+
459+
def get_completion_metadata():
460+
"""Generate and fetch completion metadata."""
461+
request = '_completions = completion_metadata(get_ipython())'
462+
try:
463+
msg_id = send(request, silent=True, user_variables=['_completions'])
464+
except TypeError: # change in IPython 3.0+
465+
msg_id = send(request, silent=True, user_expressions={'_completions':'_completions'})
466+
try:
467+
m = get_child_msg(msg_id, timeout=vim_vars.get('ipython_completion_timeout', 2))
460468
except Empty:
461469
echo("no reply from IPython kernel")
462470
raise IOError
471+
content = m['content']
472+
if 'user_variables' in content:
473+
metadata = content['user_variables']['_completions']
474+
else:
475+
metadata = content['user_expressions']['_completions']
476+
metadata = ast.literal_eval(metadata['data']['text/plain'])
477+
matches = [c['match'] for c in metadata]
478+
return matches, metadata
463479

464480
def vim_ipython_is_open():
465481
"""

0 commit comments

Comments
 (0)