diff --git a/bpython/curtsiesfrontend/repl.py b/bpython/curtsiesfrontend/repl.py index 9bccca5fe..1e0c89ac0 100644 --- a/bpython/curtsiesfrontend/repl.py +++ b/bpython/curtsiesfrontend/repl.py @@ -19,6 +19,8 @@ from bpython._py3compat import PythonLexer from pygments.formatters import TerminalFormatter +from wcwidth import wcswidth + import blessings import curtsies @@ -1359,7 +1361,11 @@ def display_line_with_prompt(self): @property def current_cursor_line_without_suggestion(self): - """Current line, either output/input or Python prompt + code""" + """ + Current line, either output/input or Python prompt + code + + :returns: FmtStr + """ value = self.current_output_line + ( "" if self.coderunner.running else self.display_line_with_prompt ) @@ -1556,7 +1562,8 @@ def move_screen_up(current_line_start_row): if self.stdin.has_focus: cursor_row, cursor_column = divmod( - len(self.current_stdouterr_line) + self.stdin.cursor_offset, + wcswidth(self.current_stdouterr_line) + + wcswidth(self.stdin.current_line[: self.stdin.cursor_offset]), width, ) assert cursor_column >= 0, cursor_column @@ -1574,12 +1581,12 @@ def move_screen_up(current_line_start_row): len(self.current_line), self.cursor_offset, ) - else: + else: # Common case for determining cursor position cursor_row, cursor_column = divmod( ( - len(self.current_cursor_line_without_suggestion) - - len(self.current_line) - + self.cursor_offset + wcswidth(self.current_cursor_line_without_suggestion.s) + - wcswidth(self.current_line) + + wcswidth(self.current_line[: self.cursor_offset]) ), width, ) diff --git a/setup.py b/setup.py index 24ec50055..92365e442 100755 --- a/setup.py +++ b/setup.py @@ -228,6 +228,7 @@ def initialize_options(self): "curtsies >=0.1.18", "greenlet", "six >=1.5", + "wcwidth" ] extras_require = {