Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Lib/curses/textpad.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import curses
import curses.ascii
import unicodedata

def rectangle(win, uly, ulx, lry, lrx):
"""Draw a rectangle with corners at the provided upper-left
Expand Down Expand Up @@ -98,7 +99,14 @@ def _insert_printable_char(self, ch):
# the cursor out of the window (an error, and it scrolls a
# scrollable window).
if isinstance(ch, int):
self.win.insch(self._decode(ch), ch & curses.A_ATTRIBUTES)
ch, attr = self._decode(ch), ch & curses.A_ATTRIBUTES
else:
attr = curses.A_NORMAL
if isinstance(ch, str) and unicodedata.combining(ch):
cell = self.win.in_wch()
ch = curses.complexchar(str(cell) + ch, cell.attr, cell.pair)
if isinstance(ch, str):
self.win.insch(ch, attr)
else:
self.win.insch(ch)
break
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_curses.py
Original file line number Diff line number Diff line change
Expand Up @@ -2697,6 +2697,18 @@ def test_textbox_combining(self):
box.do_command(ch)
self.assertEqual(box.gather(), text + ' ')

@requires_wide_build
def test_textbox_combining_fill_last_cell(self):
# A combining mark typed into the lower-right cell, which is written
# with insch(), attaches to the character already there instead of
# taking a cell of its own.
text = 'abe\u0301' # 'e' + COMBINING ACUTE ACCENT in the corner
if self._encodable(text):
box, win = self._make_textbox(1, 3, stripspaces=0)
for ch in text:
box.do_command(ch)
self.assertEqual(box.gather(), text)

@requires_wide_build
def test_textbox_double_width(self):
# A double-width (East Asian) character occupies two cells. gather()
Expand Down
Loading