Skip to content

fix: honor a separator at index 0 in MaskedInput word navigation - #6646

Open
mvanhorn wants to merge 1 commit into
Textualize:mainfrom
mvanhorn:fix-maskedinput-leading-separator-word-nav
Open

fix: honor a separator at index 0 in MaskedInput word navigation#6646
mvanhorn wants to merge 1 commit into
Textualize:mainfrom
mvanhorn:fix-maskedinput-leading-separator-word-nav

Conversation

@mvanhorn

Copy link
Copy Markdown

Summary

On a MaskedInput whose template starts with a separator (e.g. "-NNN-NNN"), ctrl+left (action_cursor_left_word) and ctrl+backspace (action_delete_left_word) land the cursor on the leading separator instead of just after it.

Closes #6641.

Why this matters

Word-wise navigation and deletion are core editing affordances, and they silently misbehave for any mask that opens with a separator (phone numbers, dates written -NNN…, etc.). The cursor stops on a read-only separator cell, so the next keystroke behaves unexpectedly — a small but confusing correctness bug in a widely-used widget.

Root cause

Two compounding issues, both around the index-0 separator:

  1. _Template.prev_separator_position() scanned with range(position - 1, 0, -1). The stop value 0 is exclusive, so index 0 was never checked — a leading separator was never found.
  2. Even once index 0 is found, action_cursor_left_word (if position: / self.cursor_position = position or 0) and action_delete_left_word (if position:) treat a returned index of 0 as falsy, skipping the + 1 that moves the cursor past the separator.

So the reporter's suggested one-line change to (1) alone is not enough; both spots have to stop treating a valid index of 0 as "no separator".

Fix

  • Scan the full prefix in prev_separator_position (range(position - 1, -1, -1)).
  • Update the two left-word actions to use the same is None handling that action_cursor_right_word already uses, so an index-0 separator is honored.

Testing

Added test_left_word_actions_with_leading_separator, which reproduces the issue's scenario and also covers action_delete_left_word. It fails on main and passes with this change; the rest of tests/test_masked_input.py continues to pass (14 → 15). Verified against the issue's exact reproducer (ctrl+left now yields 5 then 1).

AI was used for assistance.

_Template.prev_separator_position() used range(position - 1, 0, -1), whose
exclusive stop of 0 never visited index 0, and action_cursor_left_word /
action_delete_left_word then treated a returned index of 0 as falsy
(if position: / position or 0). Together these broke ctrl+left and
ctrl+backspace on templates that start with a separator (e.g. "-NNN-NNN"):
the cursor landed on the separator instead of just after it.

Scan the full prefix and mirror the is-None handling that
action_cursor_right_word already uses, so an index-0 separator is honored.

Closes Textualize#6641
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant