Skip to content

Conversation

@BDisp
Copy link
Collaborator

@BDisp BDisp commented Nov 12, 2025

Fixes

Proposed Changes/Todos

  • Use StringInfo with GetTextElementEnumerator to enumerate all graphemes that can be rendered as a single cell which may occupy 1 or 2 columns in the screen.

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

@BDisp BDisp requested a review from tig as a code owner November 12, 2025 18:52
@codecov
Copy link

codecov bot commented Nov 12, 2025

Codecov Report

❌ Patch coverage is 84.23154% with 79 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.64%. Comparing base (726b15d) to head (a8d090c).
⚠️ Report is 1 commits behind head on v2_develop.

Files with missing lines Patch % Lines
Terminal.Gui/Text/TextFormatter.cs 80.79% 12 Missing and 17 partials ⚠️
Terminal.Gui/Views/CharMap/CharMap.cs 45.45% 11 Missing and 1 partial ⚠️
Terminal.Gui/Drivers/OutputBufferImpl.cs 76.19% 5 Missing and 5 partials ⚠️
Terminal.Gui/Views/Slider/Slider.cs 60.00% 8 Missing and 2 partials ⚠️
Terminal.Gui/Views/TextInput/TextModel.cs 90.38% 0 Missing and 5 partials ⚠️
Terminal.Gui/Drawing/Cell.cs 94.64% 1 Missing and 2 partials ⚠️
Terminal.Gui/Views/TreeView/Branch.cs 83.33% 1 Missing and 2 partials ⚠️
.../Views/Autocomplete/AutocompleteFilepathContext.cs 81.81% 1 Missing and 1 partial ⚠️
Terminal.Gui/Views/TextInput/TextView.cs 91.66% 0 Missing and 2 partials ⚠️
Terminal.Gui/ViewBase/View.Drawing.Primitives.cs 83.33% 0 Missing and 1 partial ⚠️
... and 2 more
Additional details and impacted files
@@              Coverage Diff               @@
##           v2_develop    #4388      +/-   ##
==============================================
- Coverage       74.76%   74.64%   -0.13%     
==============================================
  Files             388      389       +1     
  Lines           46690    46697       +7     
  Branches         6641     6645       +4     
==============================================
- Hits            34907    34856      -51     
- Misses           9889     9935      +46     
- Partials         1894     1906      +12     
Files with missing lines Coverage Δ
Terminal.Gui/Drawing/GraphemeHelper.cs 100.00% <100.00%> (ø)
Terminal.Gui/Drawing/LineCanvas/LineCanvas.cs 93.82% <100.00%> (-0.02%) ⬇️
Terminal.Gui/Drivers/DriverImpl.cs 68.51% <100.00%> (-1.13%) ⬇️
Terminal.Gui/Drivers/OutputBase.cs 66.37% <100.00%> (-9.63%) ⬇️
Terminal.Gui/Text/StringExtensions.cs 88.61% <100.00%> (+3.51%) ⬆️
Terminal.Gui/ViewBase/Adornment/ShadowView.cs 93.75% <100.00%> (ø)
Terminal.Gui/ViewBase/View.Drawing.cs 90.09% <100.00%> (ø)
...rminal.Gui/Views/Autocomplete/PopupAutocomplete.cs 61.77% <100.00%> (ø)
Terminal.Gui/Views/TableView/TreeTableSource.cs 79.81% <100.00%> (ø)
Terminal.Gui/ViewBase/View.Drawing.Primitives.cs 65.75% <83.33%> (+1.57%) ⬆️
... and 11 more

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 726b15d...a8d090c. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 12, 2025

Please note that this feature is not compatible with legacy consoles, such as cmd.exe and conhost.exe, due to known limitations, such as true colors.

image

Copy link
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.

Holy moly! this is great stuff @BDisp.

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 12, 2025

@tig I did an update branch from here and it broken my local branch when I pulled. Do you know what's happened?

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 12, 2025

@tig I did an update branch from here and it broken my local branch when I pulled. Do you know what's happened?

I managed to solve it, but I don't understand how it happened.

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 12, 2025

@tig the below message appear sometimes when any test fail in racing conditions. Do you know it exist any static configuration that can be changed while another unit test is running?

Message: 
Assert.Equal() Failure: Values differ
Expected: Border(){X=0,Y=0,Width=20,Height=10}
Actual:   null

@tig
Copy link
Collaborator

tig commented Nov 13, 2025

@tig the below message appear sometimes when any test fail in racing conditions. Do you know it exist any static configuration that can be changed while another unit test is running?


Message: 

Assert.Equal() Failure: Values differ

Expected: Border(){X=0,Y=0,Width=20,Height=10}

Actual:   null

Parallelizable, right? Might have something to do with GlobalTestSetup.

@BDisp BDisp marked this pull request as draft November 14, 2025 11:42
@BDisp
Copy link
Collaborator Author

BDisp commented Nov 14, 2025

Damn, testhost.exe take 80% CPU resources. I'll only running all tests in the Terminal.Gui CI actions.

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 14, 2025

Parallelizable, right? Might have something to do with GlobalTestSetup.

I think I fix this issue in b6072bb.

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 14, 2025

After upgrading Wcwidth to version 4.0.0, I had to disable a few unit tests until I see if there's a solution or better explanation, as commented in #4259 (comment). But there are more advantages to using this version than disadvantages because there are many corrections regarding code points that were previously considered narrow and are now correctly considered zero-length.

@tig
Copy link
Collaborator

tig commented Nov 16, 2025

@BDisp this ready to merge?

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 16, 2025

@BDisp this ready to merge?

Yes @tig, please. There may be more situations where it's necessary to change from Rune to Graphema, but I can't identify them. If that's the case, we'll do it as needed.

Copy link
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.

Good stuff. I think. Hard for me to grok it all.

@tig tig requested a review from Copilot November 20, 2025 02:04
Copilot finished reviewing on behalf of tig November 20, 2025 02:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request refactors the core text handling in Terminal.Gui by replacing the Rune-based Cell representation with a grapheme-based approach using string. The primary goal is to properly support grapheme clusters (complex Unicode sequences like emojis with zero-width joiners) that should render as a single visual unit occupying 1 or 2 columns.

Key Changes:

  • Replaced Cell.Rune property with Cell.Grapheme (type string)
  • Updated text processing throughout the codebase to work with grapheme strings instead of individual runes
  • Enhanced StringExtensions.GetColumns() to properly calculate display width for grapheme clusters
  • Updated test assertions to compare graphemes (strings) instead of runes

Reviewed Changes

Copilot reviewed 53 out of 54 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
Tests/UnitTestsParallelizable/Views/TextViewTests.cs Updated test assertions from Rune to Grapheme property access
Tests/UnitTestsParallelizable/Views/TextFieldTests.cs Changed driver contents access to use Grapheme instead of Rune
Tests/UnitTestsParallelizable/Text/TextFormatterTests.cs Updated test data and renamed test methods for grapheme handling
Tests/UnitTestsParallelizable/Text/StringTests.cs Added comprehensive grapheme-related tests
Tests/UnitTestsParallelizable/Drawing/CellTests.cs Rewrote cell tests to validate grapheme functionality
Terminal.Gui/Views/TreeView/Branch.cs Updated tree rendering to work with grapheme strings
Terminal.Gui/Views/TextInput/TextView.cs Refactored text handling from runes to graphemes
Terminal.Gui/Views/TextInput/TextModel.cs Updated text model operations for grapheme support
Terminal.Gui/Views/TextInput/TextField.cs Changed internal text storage from List<Rune> to List<string>
Terminal.Gui/Text/StringExtensions.cs Enhanced grapheme enumeration and column calculation
Terminal.Gui/Drivers/*.cs Updated driver interfaces and implementations for grapheme support
Comments suppressed due to low confidence (1)

Terminal.Gui/Drawing/LineCanvas/LineCanvas.cs:180

                foreach (var line in _lines)
                {
                    if (line.Intersects (x, y) is { } intersect)
                    {
                        intersectionsBufferList.Add (intersect);
                    }
                }

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 20, 2025

Good stuff. I think. Hard for me to grok it all.

Thanks. You will find that it will be much easier to manipulate virtually all code points and all valid combinations without worrying about the complexity of handling all possible combinations. It also resolves all situations where, using combinations with Rune, the Contents field would be completely filled but after rendering by the console, there would still be unfilled columns, see the image below. Therefore, I recommend never using AddRune unless you are sure you are only adding a simple glyph. Otherwise, we should use AddStr as a rule.

image

@BDisp
Copy link
Collaborator Author

BDisp commented Nov 20, 2025

@tig I think this PR is finalized. Please understand that any changes you make to the Content or Cell will overwhelm me with resolving additional merges. If possible, I would appreciate it if you could perform the merge as soon as possible. Thanks.

@tig tig merged commit cd75a20 into gui-cs:v2_develop Nov 20, 2025
14 checks passed
@BDisp BDisp deleted the v2_4387_cell-refactoring branch November 20, 2025 18:55
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.

Runes should not be used on a cell, but rather should use a single grapheme rendering 1 or 2 columns

2 participants