Skip to content

Commit 539707c

Browse files
mvanhornclaude
andcommitted
gh-145448: Fix REPL tab completion cursor position in pending wrap state
When __write_changed_line writes to the last column of the terminal, the cursor enters "pending wrap" state where it physically stays at width-1. However, posxy was recording width, causing subsequent CUB (Cursor Backward) calculations to overshoot by one cell. Cap posxy x-coordinate at width-1 to match the physical cursor position in pending wrap state. This fixes the cursor moving backward during tab completion in xterm and Ghostty. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 66eafc9 commit 539707c

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

‎Lib/_pyrepl/unix_console.py‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,8 @@ def __write_changed_line(self, y, oldline, newline, px_coord):
675675
self.__move(x_coord, y)
676676
self.__write_code(self.ich1)
677677
self.__write(newline[x_pos])
678-
self.posxy = x_coord + character_width, y
678+
new_x = x_coord + character_width
679+
self.posxy = min(new_x, self.width - 1), y
679680

680681
# if it's a single character change in the middle of the line
681682
elif (
@@ -686,7 +687,8 @@ def __write_changed_line(self, y, oldline, newline, px_coord):
686687
character_width = wlen(newline[x_pos])
687688
self.__move(x_coord, y)
688689
self.__write(newline[x_pos])
689-
self.posxy = x_coord + character_width, y
690+
new_x = x_coord + character_width
691+
self.posxy = min(new_x, self.width - 1), y
690692

691693
# if this is the last character to fit in the line and we edit in the middle of the line
692694
elif (
@@ -713,7 +715,14 @@ def __write_changed_line(self, y, oldline, newline, px_coord):
713715
if wlen(oldline) > wlen(newline):
714716
self.__write_code(self._el)
715717
self.__write(newline[x_pos:])
716-
self.posxy = wlen(newline), y
718+
# When writing reaches the last column, the terminal enters
719+
# "pending wrap" state where the cursor physically stays at
720+
# width-1. Record position accordingly so CUB calculations
721+
# use the correct physical cursor position (gh-145448).
722+
newline_width = wlen(newline)
723+
if newline_width >= self.width:
724+
newline_width = self.width - 1
725+
self.posxy = newline_width, y
717726

718727
if "\x1b" in newline:
719728
# ANSI escape characters are present, so we can't assume
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed REPL tab completion cursor moving backward by one cell in terminals
2+
that correctly handle CUB (Cursor Backward) in pending wrap state, such as
3+
xterm and Ghostty.

0 commit comments

Comments
 (0)