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
2 changes: 1 addition & 1 deletion Lib/_pyrepl/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class unix_word_rubout(KillCommand):
def do(self) -> None:
r = self.reader
for i in range(r.get_arg()):
self.kill_range(r.bow(), r.pos)
self.kill_range(r.bow_ws(), r.pos)


class kill_word(KillCommand):
Expand Down
18 changes: 18 additions & 0 deletions Lib/_pyrepl/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,24 @@ def bow(self, p: int | None = None) -> int:
p -= 1
return p + 1

def bow_ws(self, p: int | None = None) -> int:
"""Return the 0-based index of the whitespace-delimited word break
preceding p most immediately.

p defaults to self.pos; only whitespace is considered a word
boundary, matching the behavior of unix-word-rubout in bash/readline.
See https://github.com/python/cpython/issues/146044
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion was to remove the ref to the issue

"""
if p is None:
p = self.pos
b = self.buffer
p -= 1
while p >= 0 and b[p] in " \n\t":
p -= 1
while p >= 0 and b[p] not in " \n\t":
p -= 1
return p + 1

def eow(self, p: int | None = None) -> int:
"""Return the 0-based index of the word break following p most
immediately.
Expand Down
28 changes: 28 additions & 0 deletions Lib/test/test_pyrepl/test_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,34 @@ def test_setpos_from_xy_for_non_printing_char(self):
reader.setpos_from_xy(8, 0)
self.assertEqual(reader.pos, 7)

def test_bow_ws_stops_at_whitespace(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the existing tests for bow()? id there are some, please put those tests next to them

# See https://github.com/python/cpython/issues/146044
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# See https://github.com/python/cpython/issues/146044
# See https://github.com/python/cpython/issues/146044.

reader = prepare_reader(prepare_console([]))
reader.buffer = list("foo.bar baz")
reader.pos = len(reader.buffer)
self.assertEqual(reader.bow_ws(), 8)

def test_bow_ws_includes_punctuation_in_word(self):
reader = prepare_reader(prepare_console([]))
reader.buffer = list("foo.bar(baz) qux")
reader.pos = 12
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the index() method to get the index of )

self.assertEqual(reader.bow_ws(), 0)

def test_bow_vs_bow_ws(self):
reader = prepare_reader(prepare_console([]))
reader.buffer = list("foo.bar")
reader.pos = len(reader.buffer)
# bow() stops at '.' so we return the index of 'b' in "bar"
self.assertEqual(reader.bow(), 4)
# bow_ws() treats entire "foo.bar" as one word
self.assertEqual(reader.bow_ws(), 0)

def test_bow_ws_with_tabs(self):
reader = prepare_reader(prepare_console([]))
reader.buffer = list("foo\tbar")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests with \n and ensure that you also properly jump lines.

reader.pos = len(reader.buffer)
self.assertEqual(reader.bow_ws(), 4)

Comment on lines +387 to +388
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.assertEqual(reader.bow_ws(), 4)
self.assertEqual(reader.bow_ws(), 4)

@force_colorized_test_class
class TestReaderInColor(ScreenEqualMixin, TestCase):
def test_syntax_highlighting_basic(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix ``unix-word-rubout`` (Ctrl-W) in the REPL to use whitespace-only word
boundaries, matching behavior of the basic REPL. Previously it used
syntax-table boundaries which treated punctuation as word separators.
Loading