string_width
gleam add string_width@3
A small package estimating the required number of cells when printing a string on the terminal. It supports all Gleam targets, handles ANSI escape codes, includes useful layout functions, and passes the tests of the NPM string-width package, among others.
It is also one of the fastest options available, even including target-specific ones, while still providing you full flexibility and correctness.
import string_width
pub fn main() {
string_width.dimensions("hello,\n안녕하세요")
// --> string_width.Size(rows: 2, columns: 10)
string_width.line_with(
"👩👩👦👦",
string_width.new() |> string_width.mode_2027,
)
// --> 2
// word wrapping and truncation
string_width.limit(
"Lorem ipsum dolor sit amet\nIs a common placeholder string",
to: Size(rows: 3, columns: 10),
ellipsis: "..."
)
// --> "Lorem ipsum dolor\nsit amet\nIs a common place..."
// position a string inside a box
string_width.position(
"XXX",
in: Size(rows: 3, columns: 10),
align: Center,
place: Middle,
with: "."
)
// --> "..........\n...XXX....\n.........."
}
Limitations
-
Many terminals don’t support grapheme clusters properly, so by default, the values returned by this library try to match the behaviour of libc instead of modern text rendering pipelines.
If you encounter a mismatch that is consistent across multiple environments, feel free to open an issue or ping me on Discord!
-
The behaviour when encountering stray variant selectors does not match other similar libraries.
Sources
The table lookup technique used by this library is heavily based on the musl libc wcwidth
implementation. I built updated tables using the Unicode 16.0 data, and added support for ambiguous characters. It also uses the regex of the ansi-regex npm package, and the test cases of the string-width npm package.
- Grapheme Clusters in Terminals: https://mitchellh.com/writing/grapheme-clusters-in-terminals
- UAX #11 East Asian Width: https://www.unicode.org/reports/tr11/
- Terminal Unicode Core: https://github.com/contour-terminal/terminal-unicode-core
- string-width: https://github.com/sindresorhus/string-width
- musl-libc wcwidth: https://git.musl-libc.org/cgit/musl/tree/src/ctype/wcwidth.c