mirror of
https://github.com/python/cpython
synced 2024-09-05 16:38:56 +00:00
gh-60436: fix curses textbox backspace/del (#103783)
Co-authored-by: Łukasz Langa <lukasz@langa.pl> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Michael Blahay <mblahay@gmail.com>
This commit is contained in:
parent
44010d0f12
commit
a3a5b4bb23
|
@ -102,7 +102,10 @@ def do_command(self, ch):
|
|||
self._insert_printable_char(ch)
|
||||
elif ch == curses.ascii.SOH: # ^a
|
||||
self.win.move(y, 0)
|
||||
elif ch in (curses.ascii.STX,curses.KEY_LEFT, curses.ascii.BS,curses.KEY_BACKSPACE):
|
||||
elif ch in (curses.ascii.STX,curses.KEY_LEFT,
|
||||
curses.ascii.BS,
|
||||
curses.KEY_BACKSPACE,
|
||||
curses.ascii.DEL):
|
||||
if x > 0:
|
||||
self.win.move(y, x-1)
|
||||
elif y == 0:
|
||||
|
@ -111,7 +114,7 @@ def do_command(self, ch):
|
|||
self.win.move(y-1, self._end_of_line(y-1))
|
||||
else:
|
||||
self.win.move(y-1, self.maxx)
|
||||
if ch in (curses.ascii.BS, curses.KEY_BACKSPACE):
|
||||
if ch in (curses.ascii.BS, curses.KEY_BACKSPACE, curses.ascii.DEL):
|
||||
self.win.delch()
|
||||
elif ch == curses.ascii.EOT: # ^d
|
||||
self.win.delch()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from test.support import (requires, verbose, SaveSignals, cpython_only,
|
||||
check_disallow_instantiation)
|
||||
|
@ -1319,5 +1320,75 @@ def lorem_ipsum(win):
|
|||
for y, line in enumerate(text[:maxy]):
|
||||
win.addstr(y, 0, line[:maxx - (y == maxy - 1)])
|
||||
|
||||
|
||||
class TextboxTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mock_win = MagicMock(spec=curses.window)
|
||||
self.mock_win.getyx.return_value = (1, 1)
|
||||
self.mock_win.getmaxyx.return_value = (10, 20)
|
||||
self.textbox = curses.textpad.Textbox(self.mock_win)
|
||||
|
||||
def test_init(self):
|
||||
"""Test textbox initialization."""
|
||||
self.mock_win.reset_mock()
|
||||
tb = curses.textpad.Textbox(self.mock_win)
|
||||
self.mock_win.getmaxyx.assert_called_once_with()
|
||||
self.mock_win.keypad.assert_called_once_with(1)
|
||||
self.assertEqual(tb.insert_mode, False)
|
||||
self.assertEqual(tb.stripspaces, 1)
|
||||
self.assertIsNone(tb.lastcmd)
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_insert(self):
|
||||
"""Test inserting a printable character."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(ord('a'))
|
||||
self.mock_win.addch.assert_called_with(ord('a'))
|
||||
self.textbox.do_command(ord('b'))
|
||||
self.mock_win.addch.assert_called_with(ord('b'))
|
||||
self.textbox.do_command(ord('c'))
|
||||
self.mock_win.addch.assert_called_with(ord('c'))
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_delete(self):
|
||||
"""Test deleting a character."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(curses.ascii.BS)
|
||||
self.textbox.do_command(curses.KEY_BACKSPACE)
|
||||
self.textbox.do_command(curses.ascii.DEL)
|
||||
assert self.mock_win.delch.call_count == 3
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_move_left(self):
|
||||
"""Test moving the cursor left."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(curses.KEY_LEFT)
|
||||
self.mock_win.move.assert_called_with(1, 0)
|
||||
self.textbox.do_command(curses.KEY_RIGHT)
|
||||
self.mock_win.move.assert_called_with(1, 2)
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_move_left(self):
|
||||
"""Test moving the cursor left."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(curses.KEY_RIGHT)
|
||||
self.mock_win.move.assert_called_with(1, 2)
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_move_up(self):
|
||||
"""Test moving the cursor left."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(curses.KEY_UP)
|
||||
self.mock_win.move.assert_called_with(0, 1)
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
def test_move_down(self):
|
||||
"""Test moving the cursor left."""
|
||||
self.mock_win.reset_mock()
|
||||
self.textbox.do_command(curses.KEY_DOWN)
|
||||
self.mock_win.move.assert_called_with(2, 1)
|
||||
self.mock_win.reset_mock()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
update curses textbox to additionally handle backspace using the ``curses.ascii.DEL`` key press.
|
Loading…
Reference in a new issue