Skip to content

Conversation

@jquast
Copy link
Contributor

@jquast jquast commented Jan 27, 2026

Problem

Copy and paste this test sequence to call prompt_toolkit.prompt('Give me some input: '):

 πŸ‘¨β€πŸ‘©β€πŸ‘§ πŸ‘©β€β€β€πŸ‘¨ πŸ‘©β€πŸ’»πŸ‘‹πŸΏ ❀️⭐ πŸ‡―πŸ‡΅πŸ‡©πŸ‡ͺ café ninΜƒo ÅoΜ‚Μ£ δΈ­ζ–‡!.

Moving the cursor over and around emojis get strange. insertions become chaotic. Cursor position becomes indeterminate (even negative!), input result becomes more corrupted with user confusion as draws become corrupted. This is briefly described in #274 by @jonathanslenders:

Notice that it still requires multiple cursor movements (left/right arrow) to move across these characters.

wcwidth-integration-before-trimmed.mp4

Solution

Close #274 "Handle decomposed unicode characters" (2018) through careful integration of new functions, wcwidth.iter_graphemes and wcwidth.grapheme_boundary_before.

wcwidth-integration-after.mp4

Details

  • Out of respect for the size and popular use of this library, I took the care to rewrite "pty test helper" code I first created for blessed and later in telnetlib3, to provide a real tty to a subprocess for true integration testing. maybe i will publish it as a pytest plugin someday.
  • It covers only the essentials but you might enjoy this new test accessory to provide better coverage elsewhere, I have simulated special keypresses, like HOME, END, etc, hope it helps.

@jquast jquast changed the title Add grapheme clustering support for cursor movement Add grapheme clustering support for cursor movement [WIP] Jan 27, 2026
@jquast jquast force-pushed the jq/grapheme-clustering-support branch 3 times, most recently from a244ba5 to 918a8eb Compare January 27, 2026 21:10
@jquast jquast changed the title Add grapheme clustering support for cursor movement [WIP] Add grapheme clustering support for correct emojis+cursor movement Jan 27, 2026
@jquast jquast changed the title Add grapheme clustering support for correct emojis+cursor movement Improve support for correct emojis+cursor movement with grapheme clustering Jan 27, 2026
@jquast jquast changed the title Improve support for correct emojis+cursor movement with grapheme clustering Improve support for emojis+cursor w/grapheme clustering Jan 27, 2026
@jquast jquast force-pushed the jq/grapheme-clustering-support branch 2 times, most recently from 95e89b0 to 953cfe5 Compare January 27, 2026 22:30

This offers code coverage without mocks, but using real tty features of the natural "live" call to
PromptSession() and session.prompt. prompt_toolkit sees a real terminal through use of shared
pty_accessories module.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might show some improved test coverage for this reason

feel free to extend this test to get those previously unreachable lines

for target in [(40, 120), (10, 40), (3, 10)]:
_setwinsize(fd, *target)
time.sleep(0.05)
assert _get_size(fd) == target
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A more advance version of this test could help verify screen draw reactions and effects of resize on SIGWINCH signal, for example.

time.sleep(0.2)
assert (
extract_output(read_until_marker(fd, ":END", timeout=10.0)) == grapheme * 5
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These tests are simplified but provide pty coverage, the highest level possible exercise, which is nice because it is also necessary to test these changes.

More improvement could be done to also verify screen draw effects of the REPL, these only verify output after sending return key, where repl integration print()'s result.

@jquast jquast marked this pull request as ready for review January 27, 2026 22:30
@jquast jquast force-pushed the jq/grapheme-clustering-support branch 2 times, most recently from 4d6d2ac to 8aeef93 Compare January 27, 2026 23:14
**Problem** Test sequence (copy and paste into any REPL/edit area)::

     πŸ‘¨β€πŸ‘©β€πŸ‘§ πŸ‘©β€β€β€πŸ‘¨ πŸ‘©β€πŸ’»πŸ‘‹πŸΏ ❀️⭐ πŸ‡―πŸ‡΅πŸ‡©πŸ‡ͺ café ninΜƒo ÅoΜ‚Μ£ δΈ­ζ–‡!.

Moving the cursor over and around emojis get strange. insertions become
chaotic. Cursor position becomes indeterminate (even negative!), input
result becomes more corrupted with user confusion as draws become
corrupted. This is briefly described in prompt-toolkit#274 by @jonathanslenders:

> Notice that it still requires multiple cursor movements (left/right
arrow) to move across these characters.

**Solution**: Close prompt-toolkit#274 "Handle decomposed unicode characters" (2018)
through careful integration of new functions,
[wcwidth.iter_graphemes](https://wcwidth.readthedocs.io/en/latest/intro.html#iter-graphemes)
and
[wcwidth.grapheme_boundary_before](https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.grapheme_boundary_before).

getting there, working on a PTY test suite

I don't feel comfortable changing so much code for a large library
without also including more detailed tests -- i keep fixing all errors
with TDD/automatic tests, but when using it interactively, the cursor
position is out of control
@jquast jquast force-pushed the jq/grapheme-clustering-support branch from 8aeef93 to aed10aa Compare January 27, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle decomposed unicode characters.

1 participant