Skip to content

Use grapheme iteration in DrawHotString#4801

Merged
tig merged 3 commits intogui-cs:v2_developfrom
akrantz:fix/drawhotstring-grapheme-iteration
Mar 7, 2026
Merged

Use grapheme iteration in DrawHotString#4801
tig merged 3 commits intogui-cs:v2_developfrom
akrantz:fix/drawhotstring-grapheme-iteration

Conversation

@akrantz
Copy link
Copy Markdown
Contributor

@akrantz akrantz commented Mar 6, 2026

DrawHotString iterated by rune via EnumerateRunes and rendered each rune individually with AddRune. This breaks grapheme clusters: combining marks sent separately via AddRune fail to compose with their base character (e.g. e + combining acute renders as two separate characters instead of 'é').

Replace with GraphemeHelper.GetGraphemes iteration and AddStr, which preserves grapheme cluster integrity. The hotkey specifier check is unchanged — it only matches single-character graphemes.

Added tests:

  • DrawHotString_CombiningMarks: 3 cases verifying combining marks compose correctly (acute accent, tilde, embedded in word)
  • DrawHotString_HotkeyWithCombiningMarks: hotkey + combining marks

Fixes

Proposed Changes/Todos

  • Replace EnumerateRunes() with GraphemeHelper.GetGraphemes() in DrawHotString
  • Replace AddRune(rune) with AddStr(grapheme) to preserve grapheme cluster integrity
  • Add tests for combining marks rendering (acute accent, tilde, embedded in word)
  • Add test for hotkey specifier combined with combining marks

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui - if you use Visual Studio, hit CTRL-K-D to automatically reformat your files before committing.
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working

DrawHotString iterated by rune via EnumerateRunes and rendered each
rune individually with AddRune. This breaks grapheme clusters:
combining marks sent separately via AddRune fail to compose with
their base character (e.g. e + combining acute renders as two
separate characters instead of 'é').

Replace with GraphemeHelper.GetGraphemes iteration and AddStr, which
preserves grapheme cluster integrity. The hotkey specifier check is
unchanged — it only matches single-character graphemes.

Added tests:
- DrawHotString_CombiningMarks: 3 cases verifying combining marks
  compose correctly (acute accent, tilde, embedded in word)
- DrawHotString_HotkeyWithCombiningMarks: hotkey + combining marks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@akrantz akrantz requested a review from tig as a code owner March 6, 2026 14:03
Copy link
Copy Markdown
Collaborator

@tig tig left a comment

Choose a reason for hiding this comment

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

Nice work! See my request.

Comment thread Tests/UnitTests/View/Draw/DrawTests.cs Outdated
Move DrawHotString grapheme tests from UnitTests to
UnitTestsParallelizable per review feedback. Adapt tests to use
CreateTestDriver() pattern instead of [SetupFakeApplication].

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
akrantz added a commit to akrantz/Terminal.Gui that referenced this pull request Mar 6, 2026
@akrantz akrantz requested a review from tig March 6, 2026 17:42
Copy link
Copy Markdown
Collaborator

@tig tig left a comment

Choose a reason for hiding this comment

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

Another huge thank you!

@tig tig merged commit f2d1a51 into gui-cs:v2_develop Mar 7, 2026
11 checks passed
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.

2 participants