displaywidth

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2025 License: MIT Imports: 2 Imported by: 1

README

displaywidth

A high-performance Go package for measuring the display width of strings in monospace terminals.

go get github.com/clipperhouse/displaywidth

API

// StringWidth calculates the display width of a string
func String(s string) int

// BytesWidth calculates the display width of a []byte
func Bytes(s []byte) int

Usage

package main

import (
    "fmt"
    "github.com/clipperhouse/displaywidth"
)

func main() {
    // Basic usage
    width := displaywidth.String("Hello, 世界!")
    fmt.Println(width) // Output: 13

    // With East Asian width mode
    width = displaywidth.String("café")
    fmt.Println(width) // Output: 4

    // Using BytesWidth
    width = displaywidth.Bytes([]byte("🌍"))
    fmt.Println(width) // Output: 2
}

Details

This package implements the Unicode East Asian Width standard (UAX #11) and is intended to be compatible with go-runewidth and wcwidth. It operates on bytes without decoding runes for better performance.

There is also an Options type, to specify East Asian Width and Strict Emoji Neutral settings. If unspecified, the default is EastAsianWidth: false, StrictEmojiNeutral: true.

Prior Art

mattn/go-runewidth, which is excellent and popular. I've made an effort so that displaywidth returns identical results.

Benchmarks

Part of my motivation is the insight that we can avoid decoding runes for better performance.

go test -bench=. -benchmem
goos: darwin
goarch: arm64
pkg: github.com/clipperhouse/displaywidth
cpu: Apple M2
BenchmarkStringDefault/displaywidth-8         	  112932	     10611 ns/op	 158.98 MB/s	       0 B/op	       0 allocs/op
BenchmarkStringDefault/go-runewidth-8         	   83205	     14570 ns/op	 115.78 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_EAW/displaywidth-8            	  108841	     10915 ns/op	 154.55 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_EAW/go-runewidth-8            	   48816	     25474 ns/op	  66.22 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_StrictEmoji/displaywidth-8    	  113624	     10896 ns/op	 154.82 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_StrictEmoji/go-runewidth-8    	   82554	     14486 ns/op	 116.46 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_ASCII/displaywidth-8          	 1000000	      1081 ns/op	 118.38 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_ASCII/go-runewidth-8          	 1000000	      1168 ns/op	 109.58 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_Unicode/displaywidth-8        	 1344934	       889.3 ns/op	 149.56 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_Unicode/go-runewidth-8        	  792960	      1490 ns/op	  89.27 MB/s	       0 B/op	       0 allocs/op
BenchmarkStringWidth_Emoji/displaywidth-8     	  396948	      3045 ns/op	 237.75 MB/s	       0 B/op	       0 allocs/op
BenchmarkStringWidth_Emoji/go-runewidth-8     	  248937	      4860 ns/op	 148.98 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_Mixed/displaywidth-8          	  301688	      3956 ns/op	 128.15 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_Mixed/go-runewidth-8          	  258480	      4675 ns/op	 108.45 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_ControlChars/displaywidth-8   	 3741540	       320.9 ns/op	 102.85 MB/s	       0 B/op	       0 allocs/op
BenchmarkString_ControlChars/go-runewidth-8   	 3251212	       367.5 ns/op	  89.80 MB/s	       0 B/op	       0 allocs/op

I use a similar technique in this grapheme cluster library.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultOptions = Options{
	EastAsianWidth:     false,
	StrictEmojiNeutral: true,
}

Functions

func Bytes

func Bytes(s []byte) int

func BytesOptions

func BytesOptions(s []byte, options Options) int

BytesOptions calculates the display width of a []byte

func String

func String(s string) int

func StringOptions

func StringOptions(s string, options Options) int

StringOptions calculates the display width of a string

Types

type Options

type Options struct {
	EastAsianWidth     bool
	StrictEmojiNeutral bool
}

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL