Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add string width calculation for TTY-based text layout #3296

Closed
lionel-rowe opened this issue Mar 31, 2023 · 1 comment · Fixed by #3297
Closed

Add string width calculation for TTY-based text layout #3296

lionel-rowe opened this issue Mar 31, 2023 · 1 comment · Fixed by #3297

Comments

@lionel-rowe
Copy link
Contributor

lionel-rowe commented Mar 31, 2023

Split from denoland/deno#18477.

Is your feature request related to a problem? Please describe.

The Deno runtime exposes Deno.consoleSize, which gives the physical width of the console in TTY-like environements in columns and rows. For printable ASCII text and many other characters, 1 column == 1 character; however, across all Unicode characters, there also exist many that are zero columns wide, and many others that are two columns wide.

In order for Deno.consoleSize to be generally reliable for TTY-based text layout, such as calculating where line wrap will occur, some method of getting the width of a string also needs to be exposed.

Describe the solution you'd like

Internally, the Deno repl uses the rustyline crate, a readline implementation for Rust, which in turn relies on the unicode_width crate to measure text width. This is also the crate used by the Rust compiler when determining how to "underline" errors.

unicode_width is based on the character width rules laid out in Unicode Standard Annex #11.

It does not deal with ANSI escape codes (such as "\x1b[36mCYAN\x1b[0m", which is displayed in cyan color in TTYs but remains 4 columns wide).

Adding a port of unicode_width to deno_std would allow userland code to implement TTY-based text layout in a way that's both standards-based and gives results consistent with tooling used in the runtime.
Describe alternatives you've considered

My initial preference was for this to be exposed by the runtime itself, but @dsherret convinced me that's not necessary.

The code for rendering console.table results in the runtime uses its own logic, which is significantly less rigorous than unicode_width. It simply strips ANSI colors and runs a few regexes of known double-width chars, but doesn't handle zero-width chars.

ANSI-stripping functionality is already provided in deno_std by fmt/stripColor.ts.

@jsejcksn
Copy link
Contributor

Link to review discussion thread related to visual columns per line: #3297 (comment)

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 a pull request may close this issue.

2 participants