From 9ab7103d9d6a37916429467c343209d3b53737f9 2015-01-19 23:44:23 From: Min RK Date: 2015-01-19 23:44:23 Subject: [PATCH] handle unicode issues in `ipython console` completions - readline.get_endidx gives byte offset, not character offset - readline talks str, not unicode --- diff --git a/IPython/terminal/console/completer.py b/IPython/terminal/console/completer.py index fbc257b..018e438 100644 --- a/IPython/terminal/console/completer.py +++ b/IPython/terminal/console/completer.py @@ -11,6 +11,7 @@ except ImportError: from IPython.config import Configurable from IPython.core.completer import IPCompleter +from IPython.utils.py3compat import str_to_unicode, cast_bytes, unicode_to_str from IPython.utils.traitlets import Float import IPython.utils.rlineimpl as readline @@ -36,8 +37,17 @@ class ZMQCompleter(IPCompleter): self.readline.set_completer_delims('\r\n') def complete_request(self, text): - line = readline.get_line_buffer() - cursor_pos = readline.get_endidx() + line = str_to_unicode(readline.get_line_buffer()) + byte_cursor_pos = readline.get_endidx() + + # get_endidx is a byte offset + # account for multi-byte characters to get correct cursor_pos + cursor_pos = byte_cursor_pos + i = 0 + while i < cursor_pos: + bytelen = len(cast_bytes(line[i])) + cursor_pos -= (bytelen-1) + i += 1 # send completion request to kernel # Give the kernel up to 5s to respond @@ -54,6 +64,7 @@ class ZMQCompleter(IPCompleter): if content["cursor_end"] < cursor_pos: extra = line[content["cursor_end"]: cursor_pos] matches = [m + extra for m in matches] + matches = [ unicode_to_str(m) for m in matches ] return matches return []