### Install go-runewidth Package Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Add the runewidth module to your Go project using go get. ```bash go get github.com/mattn/go-runewidth ``` -------------------------------- ### Go RuneWidth Example Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Compares rune width calculation in non-CJK and CJK modes using RuneWidth. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Non-CJK mode cond := runewidth.NewCondition() cond.EastAsianWidth = false fmt.Println(cond.RuneWidth('あ')) // Output: 1 // CJK mode cond.EastAsianWidth = true fmt.Println(cond.RuneWidth('あ')) // Output: 2 } ``` -------------------------------- ### Go StringWidth Example Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Demonstrates calculating the width of a mixed ASCII and CJK string using StringWidth with EastAsianWidth enabled. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true width := cond.StringWidth("Hello世界") fmt.Println(width) // Output: 9 (5 for "Hello" + 4 for "世界") } ``` -------------------------------- ### Go Truncate Example Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Shows how to truncate a string to a specific display width, including the tail suffix, with EastAsianWidth enabled. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true s := cond.Truncate("つのだ☆HIRO", 8, "...") fmt.Println(s) // Truncated to fit 8 cells with "..." } ``` -------------------------------- ### Go NewCondition Example Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Demonstrates creating a custom Condition for CJK locale and using it for string width calculation. ```go package main import ( "github.com/mattn/go-runewidth" ) func main() { // Create a custom condition for CJK locale cond := runewidth.NewCondition() cond.EastAsianWidth = true // Now use it for calculations width := cond.StringWidth("これはテストです") } ``` -------------------------------- ### Create Custom Width Configurations Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Instantiate a new Condition to define custom width calculation rules, allowing different configurations for different parts of an application. This example shows creating separate configurations for CJK and Western locales, each with its own lookup table. ```go // Different rules for different parts of your app cjk := runewidth.NewCondition() cjk.EastAsianWidth = true cjk.CreateLUT() western := runewidth.NewCondition() western.EastAsianWidth = false western.CreateLUT() ``` -------------------------------- ### Example Locale Strings Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Illustrates how different locale strings are interpreted for East Asian width detection. Note the effect of the '@cjk_narrow' modifier. ```text ja_JP.UTF-8 → East Asian (Japanese) zh_CN.GB2312 → East Asian (Chinese) ko_KR.EUC-KR → East Asian (Korean) en_US.UTF-8 → Not East Asian (English) ja_JP.UTF-8@cjk_narrow → Not East Asian (CJK narrow modifier) ``` -------------------------------- ### Calculate String Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Use StringWidth to calculate the total display width of a string, considering multi-cell characters. This example shows a string of 5 ASCII characters. ```go width := runewidth.StringWidth("Hello") // 5 ``` -------------------------------- ### Truncate String from Left to Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Truncates the beginning of a string to fit within a specified display width, prepending a prefix string. Removes characters from the start and respects grapheme cluster boundaries. The final result fits within the specified width. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Truncate from left with ellipsis s := runewidth.TruncateLeft("Hello World", 8, "...") fmt.Println(s) // Output: "...orld" or "... orld" (space-padded) // CJK characters s = runewidth.TruncateLeft("つのだ☆HIRO", 6, "") fmt.Println(s) // Output: "☆HIRO" } ``` -------------------------------- ### Get Width of Very Long Strings Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md The `StringWidth` function handles very long strings efficiently. ```go // Function works with any string length longText := strings.Repeat("A", 1000000) width := runewidth.StringWidth(longText) // Works fine, returns 1000000 ``` -------------------------------- ### Get Width of Empty String Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md The `StringWidth` function returns 0 for an empty string. ```go width := runewidth.StringWidth("") // 0 ``` -------------------------------- ### Import go-runewidth Package Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Import the runewidth package into your Go source files. ```go import "github.com/mattn/go-runewidth" ``` -------------------------------- ### Get Width of Control Characters Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Control characters like tab and newline have a width of 0. ```go // Tab, newline, etc. have width 0 width := runewidth.RuneWidth('\t') // 0 width = runewidth.RuneWidth('\n') // 0 ``` -------------------------------- ### Create and Use Custom Conditions Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/types.md Demonstrates how to create a custom runewidth condition, set its properties for specific East Asian width rules, and use it to calculate string width. Optionally, a Look-Up Table (LUT) can be created for performance optimization. ```go cond := runewidth.NewCondition() cond.EastAsianWidth = true cond.StrictEmojiNeutral = false width := cond.StringWidth("Some CJK text: 日本語") cond.CreateLUT() ``` -------------------------------- ### Using Separate Condition Instances for Different Locales Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Shows how to manage different locale configurations simultaneously by using separate Condition instances. Using global functions can lead to overwriting configurations, causing incorrect measurements for subsequent calculations. ```go // Wrong: Can't use global functions for different locales simultaneously runewidth.EastAsianWidth = true w1 := runewidth.StringWidth("日本") // 4 runewidth.EastAsianWidth = false w2 := runewidth.StringWidth("日本") // 2, overwrites the first // Right: Use separate Condition instances cjk := runewidth.NewCondition() cjk.EastAsianWidth = true w1 := cjk.StringWidth("日本") // 4 west := runewidth.NewCondition() west.EastAsianWidth = false w2 := west.StringWidth("日本") // 2, independent ``` -------------------------------- ### Get Width of Invalid Runes Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Runes outside the valid Unicode range (e.g., negative or too large) are assigned a width of 0. ```go // Out of valid Unicode range returns width 0 width := runewidth.RuneWidth(-1) // 0 width = runewidth.RuneWidth(0x110000) // 0 ``` -------------------------------- ### Display a Menu with Unicode Support Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Calculate the maximum string width using `runewidth.StringWidth` and pad strings with `runewidth.FillRight` to align menu items, supporting Unicode characters. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func displayMenu(items []string) { // Find max width maxWidth := 0 for _, item := range items { if w := runewidth.StringWidth(item); w > maxWidth { maxWidth = w } } // Display menu fmt.Println("┌─" + fmt.Sprintf("%-*s", maxWidth, "") + "─┐") for i, item := range items { padded := runewidth.FillRight(item, maxWidth) fmt.Printf("│ %s │\n", padded) } fmt.Println("└─" + fmt.Sprintf("%-*s", maxWidth, "") + "─┘") } func main() { menu := []string{ "New File", "Open ファイル", // Japanese "Save", "Exit", } displayMenu(menu) } ``` -------------------------------- ### Display a Progress Bar Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Use `runewidth.FillRight` to format labels and create progress bars for terminal output. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func printProgressBar(label string, percentage int) { // Create bar barWidth := 20 filled := barWidth * percentage / 100 bar := fmt.Sprintf("[%-*s]", barWidth, fmt.Sprintf("%s", "█")) // Format output with label label = runewidth.FillRight(label, 15) fmt.Printf("%s %s %d%%\n", label, bar, percentage) } func main() { printProgressBar("Downloading", 50) printProgressBar("Processing", 100) } ``` -------------------------------- ### Get Width of Combining Sequences Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md The width of a string with combining sequences is determined by the base character. Precomposed and decomposed forms of the same character yield the same width. ```go // Width is determined by base character s := "é" // precomposed: width 1 width := runewidth.StringWidth(s) // 1 s = "é" // decomposed: e + combining acute width = runewidth.StringWidth(s) // 1 (uses first non-zero-width) ``` -------------------------------- ### Build Fixed-Width Output with Truncation and Padding Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Create fixed-width formatted strings by truncating and padding both the name and value fields to specified widths. ```go func formatRecord(name string, value string) string { name = runewidth.Truncate(name, 20, "") name = runewidth.FillRight(name, 20) value = runewidth.Truncate(value, 30, "") value = runewidth.FillRight(value, 30) return fmt.Sprintf("%s | %s", name, value) } func main() { fmt.Println(formatRecord("Product Name", "Description")) fmt.Println(formatRecord("VeryLongProductName", "VeryLongDescription")) } ``` -------------------------------- ### Calculate Single Character Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Use RuneWidth to get the display width of a single character. ASCII characters typically occupy 1 cell. ```go width := runewidth.RuneWidth('A') // 1 ``` -------------------------------- ### Create Lookup Table for Width Calculation Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Builds an in-memory lookup table to accelerate width calculations for Unicode runes. This is optional but provides significant performance improvements. ```go package main import ( "github.com/mattn/go-runewidth" time "time" ) func main() { // Optionally build LUT for performance runewidth.CreateLUT() // Now width operations will be faster start := time.Now() for i := 0; i < 1000000; i++ { runewidth.RuneWidth('A') } println("Time with LUT:", time.Since(start)) } ``` -------------------------------- ### Manage Multiple Locales in One Application Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Configure and use multiple Condition instances with different settings (e.g., CJK and Western) within the same application. Build LUTs for each condition to optimize performance. ```go package main import ( "github.com/mattn/go-runewidth") func main() { // Locale 1: CJK cjk := runewidth.NewCondition() cjk.EastAsianWidth = true // Locale 2: Western west := runewidth.NewCondition() west.EastAsianWidth = false // Build LUTs for performance cjk.CreateLUT() west.CreateLUT() // Use separately println(cjk.StringWidth("テスト")) // 6 println(west.StringWidth("テスト")) // 3 } ``` -------------------------------- ### Rebuilding LUT After Configuration Change Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Illustrates the necessity of rebuilding the Look-Up Table (LUT) after changing configuration, such as setting EastAsianWidth. Failing to do so results in incorrect width calculations based on stale data. ```go // Wrong: LUT has old configuration runewidth.CreateLUT() runewidth.EastAsianWidth = true fmt.Println(runewidth.StringWidth("日本")) // Still calculated as width 1! // Right: Clear and rebuild LUT runewidth.CreateLUT() runewidth.EastAsianWidth = true runewidth.DefaultCondition.combinedLut = nil runewidth.CreateLUT() fmt.Println(runewidth.StringWidth("日本")) // Now correctly 4 ``` -------------------------------- ### Create Custom Condition Instances Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Create and configure custom Condition instances for different application parts, such as CJK or Western content, or for handling broken emoji fonts. ```go // Condition for CJK content cjkCond := runewidth.NewCondition() cjkCond.EastAsianWidth = true cjkCond.StrictEmojiNeutral = true // Condition for Western content westCond := runewidth.NewCondition() westCond.EastAsianWidth = false westCond.StrictEmojiNeutral = true // Condition for broken emoji fonts brokenEmoji := runewidth.NewCondition() brokenEmoji.StrictEmojiNeutral = false // Use as needed width1 := cjkCond.StringWidth("日本語テキスト") width2 := westCond.StringWidth("English text") width3 := brokenEmoji.StringWidth("😀 emoji test") ``` -------------------------------- ### Create Aligned Tables Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Pads strings to specified widths for creating aligned table columns. Use FillRight to right-pad strings. ```go // Pad names to 20 cells, then values to 30 cells fmt.Println( runewidth.FillRight("Name", 20) + runewidth.FillRight("Value", 30), ) ``` -------------------------------- ### Create Lookup Table for Width Calculations Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Builds an in-memory lookup table to accelerate width calculations for all Unicode runes for a given Condition. This is idempotent and must be called again if EastAsianWidth or StrictEmojiNeutral are changed. ```go package main import ( "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true // Build the LUT for faster lookups cond.CreateLUT() // Now all width calculations on this condition are much faster for i := 0; i < 1000000; i++ { cond.RuneWidth('A') } } ``` -------------------------------- ### Enable CJK Mode Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Configure the library to recognize East Asian (CJK) character widths. This can be done automatically, by setting a boolean flag, or via an environment variable. ```go // Auto-detect (default) runewidth.EastAsianWidth // true if CJK locale // Force CJK runewidth.EastAsianWidth = true // Via environment export RUNEWIDTH_EASTASIAN=1 ``` -------------------------------- ### Filling String to Width (Left) Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Pads a string on the left with spaces to reach a target width. Useful for aligning text to the right. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { text := "hello" filled := runewidth.FillLeft(text, 10) fmt.Printf("'%s'\n", filled) // Output: ' hello' } ``` -------------------------------- ### Global Variables and Instance Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/COMPLETION_SUMMARY.txt Information about global variables and the default `Condition` instance. ```APIDOC ## Global Variables ### EastAsianWidth ### Description A global boolean flag to enable East Asian width calculation rules. This is equivalent to setting `DefaultCondition.EastAsianWidth = true`. ### Type `bool` ### Example ```go runewidth.EastAsianWidth = true ``` ### StrictEmojiNeutral ### Description A global boolean flag to enforce stricter rules for emoji neutral width. This is equivalent to setting `DefaultCondition.StrictEmojiNeutral = true`. ### Type `bool` ### Example ```go runewidth.StrictEmojiNeutral = true ``` ## Global Instance ### DefaultCondition ### Description The default `Condition` instance used by global functions when no specific `Condition` is provided. ### Type `*Condition` ### Example ```go width := runewidth.DefaultCondition.StringWidth("example") ``` ``` -------------------------------- ### Creating a Lookup Table (LUT) Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Generates a lookup table for faster character width calculations. Recommended for performance-critical applications. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { runewidth.CreateLUT() fmt.Println("LUT created.") // Now subsequent StringWidth calls might be faster } ``` -------------------------------- ### CreateLUT Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Builds an in-memory lookup table to accelerate width calculations for all Unicode runes. This operation is idempotent and optional, providing a significant speed improvement for width calculations. ```APIDOC ## CreateLUT ### Description Builds an in-memory lookup table to accelerate width calculations for all Unicode runes. The table consumes approximately 557 KB of memory. This operation is idempotent and optional, providing a significant speed improvement for width calculations. ### Function Signature ```go func CreateLUT() ``` ### Parameters This function does not take any parameters. ### Returns Nothing. Creates the LUT on the `DefaultCondition` instance. ### Behavior - Is idempotent; calling it multiple times has no additional effect if already created - Should not be called concurrently with other runewidth operations - Provides significant speed improvement for width calculations - Must be called again if global `EastAsianWidth` or `StrictEmojiNeutral` flags are changed - Is optional; the library works without it (just slower) ### Example ```go package main import ( "github.com/mattn/go-runewidth" time "time" ) func main() { // Optionally build LUT for performance runewidth.CreateLUT() // Now width operations will be faster start := time.Now() for i := 0; i < 1000000; i++ { runewidth.RuneWidth('A') } println("Time with LUT:", time.Since(start)) } ``` ``` -------------------------------- ### Format Strings with Padding Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Pad strings to a specific display width for alignment. Use FillRight for left alignment and FillLeft for right alignment. ```go // Pad right (align left) s := runewidth.FillRight("Name", 20) fmt.Println(s) // "Name " (20 chars total display width) // Pad left (align right) s = runewidth.FillLeft("123", 10) fmt.Println(s) // " 123" (10 chars total display width) ``` -------------------------------- ### Initialize DefaultCondition Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Sets the default condition for runewidth calculations. EastAsianWidth is dynamically set based on environment variables or locale during initialization. StrictEmojiNeutral defaults to true. ```go var DefaultCondition = &Condition{ EastAsianWidth: false, StrictEmojiNeutral: true, } ``` -------------------------------- ### Creating a Custom Condition Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Creates a new Condition instance for custom width calculations. Allows for specific configurations like East Asian width settings. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Create a new condition with East Asian width enabled cond := runewidth.NewCondition(runewidth.WithEastAsianWidth) width := cond.StringWidth("你好") // Chinese characters are wide in East Asian mode fmt.Println(width) // Output: 4 } ``` -------------------------------- ### Go Condition RuneWidth Method Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Defines the RuneWidth method for calculating the display width of a single rune. ```go func (c *Condition) RuneWidth(r rune) int ``` -------------------------------- ### Auto-Detect Locale for Width Calculation Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Use the default configuration to automatically detect the system locale for East Asian width calculations. This is the default behavior when the package is loaded. ```go package main import ( "github.com/mattn/go-runewidth") func main() { // EastAsianWidth is auto-detected from system locale width := runewidth.StringWidth("テスト") println(width) } ``` -------------------------------- ### Build Lookup Table for Performance Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Call CreateLUT to build an internal lookup table. This can significantly improve calculation speed, offering a 5-10x performance boost for frequent operations. ```go // Build lookup table for 5-10x speed improvement runewidth.CreateLUT() ``` -------------------------------- ### Go NewCondition Constructor Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Creates a new Condition instance, copying settings from the global defaults. ```go func NewCondition() *Condition ``` -------------------------------- ### Handle Environment-Specific Widths Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Environments may differ in how they render CJK characters. You can either detect and handle these differences or force a consistent behavior by setting `runewidth.EastAsianWidth`. ```go // Handle both cases if runewidth.EastAsianWidth { // CJK environment } else { // Western environment } // Or force consistent behavior runewidth.EastAsianWidth = true // Always use this setting ``` -------------------------------- ### Basic String Width Calculation Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Calculates the display width of a string using the default condition. Useful for general text rendering. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { width := runewidth.StringWidth("Hello, 世界") fmt.Println(width) // Output: 13 } ``` -------------------------------- ### CreateLUT Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Builds an in-memory lookup table for this Condition to accelerate width calculations for all Unicode runes. This is recommended for performance-critical applications. ```APIDOC ## CreateLUT ### Description Builds an in-memory lookup table for this Condition to accelerate width calculations for all Unicode runes. This is recommended for performance-critical applications. ### Method Signature ```go func (c *Condition) CreateLUT() ``` ### Parameters None. ### Returns Nothing. Populates the internal `combinedLut` field. ### Behavior - Consumes approximately 557 KB of memory - Provides dramatic speed improvement for repeated width calculations - Must not be called concurrently with other operations on this Condition - Is idempotent (calling repeatedly has no additional effect) - Must be called again if `EastAsianWidth` or `StrictEmojiNeutral` are changed ### Example ```go package main import ( "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true // Build the LUT for faster lookups cond.CreateLUT() // Now all width calculations on this condition are much faster for i := 0; i < 1000000; i++ { cond.RuneWidth('A') } } ``` ``` -------------------------------- ### Width Calculation Interface Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/types.md Defines the `WidthCalculation` interface, which outlines methods for calculating rune and string widths, truncating strings, and wrapping text. Both global functions and `Condition` methods implement this interface. ```go type WidthCalculation interface { RuneWidth(r rune) int StringWidth(s string) int Truncate(s string, w int, tail string) string TruncateLeft(s string, w int, prefix string) string Wrap(s string, w int) string FillLeft(s string, w int) string FillRight(s string, w int) string CreateLUT() } ``` -------------------------------- ### Export RUNEWIDTH_EASTASIAN=1 Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Force East Asian mode for width calculations. This setting is evaluated during package initialization. ```bash export RUNEWIDTH_EASTASIAN=1 go run myapp.go ``` -------------------------------- ### Wrap Text to Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Wrap a long string into multiple lines, ensuring each line does not exceed a specified display width. ```go text := "This is a long line of text that needs wrapping" wrapped := runewidth.Wrap(text, 20) fmt.Println(wrapped) // Output: // This is a long line // of text that needs // wrapping ``` -------------------------------- ### Create Default Condition LUT Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Build a lookup table (LUT) on the default condition for performance optimization. This trades memory for speed, making width lookups significantly faster. ```go // Build LUT on the default condition runewidth.CreateLUT() ``` -------------------------------- ### Calculate String Width in Go Source: https://github.com/mattn/go-runewidth/blob/master/README.md Use StringWidth to determine the display width of a string, considering full-width and half-width characters. Ensure the go-runewidth package is imported. ```go import "github.com/mattn/go-runewidth" runewidth.StringWidth("つのだ☆HIRO") == 12 ``` -------------------------------- ### Create LUT for Custom Conditions Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Optionally create a lookup table (LUT) for a custom condition to significantly improve performance for applications with many width calculations. ```go cjkCond.CreateLUT() // LUT only for CJK condition westCond.CreateLUT() // Separate LUT for Western condition ``` -------------------------------- ### Align Table Columns with Padding Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Format data into table columns by calculating and applying appropriate padding to each cell using FillRight. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Format a simple table data := [][]string{ {"Name", "Value"}, {"Item1", "データ"}, {"Item2", "テスト"}, } // Calculate column widths colWidths := []int{15, 15} for _, row := range data { for i, cell := range row { fmt.Print(runewidth.FillRight(cell, colWidths[i])) } fmt.Println() } // Output: // Name Value // Item1 データ // Item2 テスト } ``` -------------------------------- ### Use Separate Conditions for Multiple Locales Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Create independent runewidth.Condition objects to handle text from different locales within the same application. Each condition can have its own LUT. ```go func main() { // Condition for CJK cjk := runewidth.NewCondition() cjk.EastAsianWidth = true cjk.CreateLUT() // Condition for Western western := runewidth.NewCondition() western.EastAsianWidth = false western.CreateLUT() // Use independently cjkText := "日本語テキスト" westText := "English text" fmt.Printf("CJK width: %d\n", cjk.StringWidth(cjkText)) // 12 fmt.Printf("Western width: %d\n", western.StringWidth(westText)) // 12 } ``` -------------------------------- ### NewCondition Constructor Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Creates a new Condition instance initialized with the current global settings. This allows for custom configurations of character width calculations. ```APIDOC ## NewCondition Constructor Creates a new `Condition` instance initialized with the current global settings. ```go func NewCondition() *Condition ``` **Returns:** `*Condition` — A new Condition with `EastAsianWidth` and `StrictEmojiNeutral` copied from the global defaults. **Example:** ```go package main import ( "github.com/mattn/go-runewidth" ) func main() { // Create a custom condition for CJK locale cond := runewidth.NewCondition() cond.EastAsianWidth = true // Now use it for calculations width := cond.StringWidth("これはテストです") } ``` ``` -------------------------------- ### Force CJK Mode via Environment Variable Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Control East Asian width mode using the RUNEWIDTH_EASTASIAN environment variable. Set to '1' to force CJK mode. ```bash # Force CJK mode via environment export RUNEWIDTH_EASTASIAN=1 go run myapp.go ``` -------------------------------- ### Wrap Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Wraps a string by inserting newlines to fit within a specified display width per line. It preserves existing newlines and breaks lines based on rune width. ```APIDOC ## Wrap ### Description Wraps a string by inserting newlines to fit within a specified display width per line. It preserves existing newlines and breaks lines based on rune width. ### Method Signature ```go func (c *Condition) Wrap(s string, w int) string ``` ### Parameters #### Path Parameters - **s** (string) - Required - The string to wrap - **w** (int) - Required - The maximum display width per line in cells ### Returns `string` - The wrapped string with newlines inserted. ### Behavior - Preserves existing newlines in the input - Breaks lines when the next rune would exceed w - Does not respect word boundaries - Uses `\n` as the line separator ### Example ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true s := cond.Wrap("これはテストです", 8) fmt.Print(s) // Output: (wrapped at 8 cells per line) // これは // テスト // です } ``` ``` -------------------------------- ### Rebuild LUT After Configuration Changes Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md If `EastAsianWidth` is changed after `CreateLUT` has been called, the LUT must be rebuilt to reflect the new configuration. ```go runewidth.CreateLUT() runewidth.EastAsianWidth = true runewidth.DefaultCondition.combinedLut = nil runewidth.CreateLUT() // Rebuild with new settings ``` -------------------------------- ### Go Condition StringWidth Method Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Defines the StringWidth method for calculating the display width of a string, accounting for grapheme clusters. ```go func (c *Condition) StringWidth(s string) int ``` -------------------------------- ### Wrap String by Display Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Wraps a string to fit within a specified display width, inserting newlines. Preserves existing newlines but does not respect word boundaries. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { s := runewidth.Wrap("Hello World Example", 8) fmt.Println(s) // Output: // Hello Wo // rld Exam // ple // With existing newlines s = runewidth.Wrap("Hello\nWorld", 5) fmt.Println(s) // Output: // Hello // World } ``` -------------------------------- ### Exported Functions Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md These are the primary functions exported by the go-runewidth library for calculating string and rune widths, and for text manipulation. ```APIDOC ## Exported Functions ### RuneWidth Calculates the display width of a single rune. ### StringWidth Calculates the display width of a string. ### Truncate Truncates a string to a specified width, appending a tail string. ### TruncateLeft Truncates a string from the left to a specified width, prepending a prefix string. ### Wrap Wraps a string to a specified width. ### FillLeft Fills a string from the left to a specified width. ### FillRight Fills a string from the right to a specified width. ### CreateLUT Creates a lookup table for character widths. ### IsAmbiguousWidth Checks if a rune has an ambiguous width. ### IsCombiningWidth Checks if a rune is a combining character. ### IsNeutralWidth Checks if a rune has a neutral width. ``` -------------------------------- ### Detecting and Classifying Ambiguous Width Characters Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Demonstrates checking for ambiguous width characters using IsAmbiguousWidth and how their display width (1 or 2 cells) depends on the EastAsianWidth setting. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Check if ambiguous fmt.Println(runewidth.IsAmbiguousWidth('α')) // Output: true fmt.Println(runewidth.IsAmbiguousWidth('A')) // Output: false // Width depends on locale runewidth.EastAsianWidth = false fmt.Println(runewidth.RuneWidth('α')) // Output: 1 runewidth.EastAsianWidth = true fmt.Println(runewidth.RuneWidth('α')) // Output: 2 } ``` -------------------------------- ### Set EastAsianWidth to true Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Programmatically force CJK mode by setting the global EastAsianWidth variable. Rebuild the LUT if it was previously created. ```go runewidth.EastAsianWidth = true // Rebuild LUT if it was created runewidth.DefaultCondition.combinedLut = nil runewidth.CreateLUT() ``` -------------------------------- ### Pad String Right to Display Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Pads the right side of a string with spaces to reach a target display width. The original string is returned unchanged if it is already wide enough. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { s := runewidth.FillRight("Hello", 10) fmt.Println("[" + s + "]") // Output: "[Hello ]" // String already wide enough s = runewidth.FillRight("Hello", 3) fmt.Println("[" + s + "]") // Output: "[Hello]" } ``` -------------------------------- ### Pad String for Alignment Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Use FillRight to pad a string with spaces on the right to reach a specified width, useful for aligning text in columns. ```go s := runewidth.FillRight("Name", 20) ``` -------------------------------- ### Wrap String by Display Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Wraps a string by inserting newlines to fit within a specified display width per line. Preserves existing newlines and breaks lines without respecting word boundaries. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true s := cond.Wrap("これはテストです", 8) fmt.Print(s) // Output: (wrapped at 8 cells per line) // これは // テスト // です } ``` -------------------------------- ### Calculate String Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/functions.md Calculates the display width of a string, considering grapheme clusters and multi-width characters. Offers a fast path for pure ASCII strings. Ignores zero-width characters in the final count. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Simple ASCII fmt.Println(runewidth.StringWidth("Hello")) // Output: 5 // Mixed ASCII and CJK fmt.Println(runewidth.StringWidth("つのだ☆HIRO")) // Output: 12 // String with combining marks fmt.Println(runewidth.StringWidth("é")) // Output: 1 } ``` -------------------------------- ### Calculate String Display Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Calculate the display width of a string, considering ASCII and mixed content. The width for mixed content depends on the EastAsianWidth setting. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Simple ASCII width := runewidth.StringWidth("Hello") fmt.Println(width) // Output: 5 // Mixed content width = runewidth.StringWidth("Hello 世界") fmt.Println(width) // Depends on EastAsianWidth setting } ``` -------------------------------- ### TruncateLeft String Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Truncates the beginning of a string to fit within a display width, prepending a prefix. Respects grapheme cluster boundaries and can pad with spaces. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true s := cond.TruncateLeft("つのだ☆HIRO", 6, "...") fmt.Println(s) // Output: "...☆HIRO" or similar } ``` -------------------------------- ### Classifying Zero-Width Characters Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Demonstrates how to classify zero-width characters like combining marks, control characters, and joiners using RuneWidth. Returns 0 for these characters. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Combining grave accent fmt.Println(runewidth.RuneWidth('̀')) // Output: 0 // ASCII tab character fmt.Println(runewidth.RuneWidth('\t')) // Output: 0 // Zero-width joiner fmt.Println(runewidth.RuneWidth('‍')) // Output: 0 } ``` -------------------------------- ### Enable CJK Character Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Set `runewidth.EastAsianWidth` to `true` to correctly calculate widths for CJK characters, which are typically 2 units wide. ```go runewidth.EastAsianWidth = true fmt.Println(runewidth.StringWidth("日本")) // Returns 4 ``` -------------------------------- ### Calculate String Width (CJK) Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Calculates the display width of a string, automatically detecting CJK systems or allowing explicit setting of East Asian width. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { // Auto-detected on CJK systems text := "日本語" width := runewidth.StringWidth(text) fmt.Println(width) // 6 on CJK systems, 3 on Western // Or explicitly set runewidth.EastAsianWidth = true width = runewidth.StringWidth(text) fmt.Println(width) // Always 6 } ``` -------------------------------- ### Ambiguous Character Width in Different Locales Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Demonstrates how the width of ambiguous characters like Greek alpha can change based on the `EastAsianWidth` setting. Set `runewidth.EastAsianWidth` to `false` for Western environments and `true` for East Asian environments. ```go // Greek letter alpha r := rune('α') // Western environment runewidth.EastAsianWidth = false fmt.Println(runewidth.RuneWidth(r)) // Typically 1 // East Asian environment runewidth.EastAsianWidth = true fmt.Println(runewidth.RuneWidth(r)) // Typically 2 ``` -------------------------------- ### Condition Type and Methods Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/COMPLETION_SUMMARY.txt Details the `Condition` struct, its constructor, and associated methods for managing character width configurations. ```APIDOC ## Condition Type ### Description The `Condition` struct holds configuration for character width calculations, including East Asian width properties. ### Fields - **EastAsianWidth** (bool) - Enables East Asian width calculation rules. - **StrictEmojiNeutral** (bool) - Enforces stricter rules for emoji neutral width. ## Constructor ### NewCondition ### Description Creates a new `Condition` instance with default settings. ### Signature `NewCondition() *Condition` ### Returns - ** extit{*Condition}** - A pointer to a new `Condition` object. ### Example ```go cond := runewidth.NewCondition() ``` ## Methods on Condition ### RuneWidth ### Description Calculates the display width of a single rune using the condition's settings. ### Signature `RuneWidth(r rune) int` ### Parameters - **r** (rune) - The rune to calculate the width for. ### Returns - **int** - The display width of the rune. ### Example ```go cond := runewidth.NewCondition() width := cond.RuneWidth('a') ``` ### StringWidth ### Description Calculates the display width of a string using the condition's settings. ### Signature `StringWidth(s string) int` ### Parameters - **s** (string) - The string to calculate the width for. ### Returns - **int** - The total display width of the string. ### Example ```go cond := runewidth.NewCondition() width := cond.StringWidth("hello") ``` ### Truncate ### Description Truncates a string to a specified width using the condition's settings, appending a tail string if truncation occurs. ### Signature `Truncate(s string, w int, tail string) string` ### Parameters - **s** (string) - The string to truncate. - **w** (int) - The maximum desired width. - **tail** (string) - The string to append if truncation occurs. ### Returns - **string** - The truncated string. ### Example ```go cond := runewidth.NewCondition() truncated := cond.Truncate("long string", 5, "...") ``` ### TruncateLeft ### Description Truncates a string from the left to a specified width using the condition's settings, prepending a prefix string if truncation occurs. ### Signature `TruncateLeft(s string, w int, prefix string) string` ### Parameters - **s** (string) - The string to truncate. - **w** (int) - The maximum desired width. - **prefix** (string) - The string to prepend if truncation occurs. ### Returns - **string** - The truncated string. ### Example ```go cond := runewidth.NewCondition() truncated := cond.TruncateLeft("long string", 5, "...") ``` ### Wrap ### Description Wraps a string to a specified width using the condition's settings, inserting newlines. ### Signature `Wrap(s string, w int) string` ### Parameters - **s** (string) - The string to wrap. - **w** (int) - The maximum width before wrapping. ### Returns - **string** - The wrapped string. ### Example ```go cond := runewidth.NewCondition() wrapped := cond.Wrap("a very long string that needs wrapping", 10) ``` ### FillLeft ### Description Pads a string on the left with spaces to reach a specified width using the condition's settings. ### Signature `FillLeft(s string, w int) string` ### Parameters - **s** (string) - The string to pad. - **w** (int) - The target width. ### Returns - **string** - The left-filled string. ### Example ```go cond := runewidth.NewCondition() filled := cond.FillLeft("hi", 5) ``` ### FillRight ### Description Pads a string on the right with spaces to reach a specified width using the condition's settings. ### Signature `FillRight(s string, w int) string` ### Parameters - **s** (string) - The string to pad. - **w** (int) - The target width. ### Returns - **string** - The right-filled string. ### Example ```go cond := runewidth.NewCondition() filled := cond.FillRight("hi", 5) ``` ### CreateLUT ### Description Creates a lookup table for character widths based on the condition's settings. ### Signature `CreateLUT()` ### Example ```go cond := runewidth.NewCondition() cond.CreateLUT() ``` ``` -------------------------------- ### Wrapping a String to a Specific Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Wraps a string into multiple lines, ensuring each line does not exceed the specified width. Handles word breaks appropriately. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { longText := "This is a very long string that needs to be wrapped into multiple lines." wrapped := runewidth.Wrap(longText, 20) fmt.Println(wrapped) // Output: // This is a very long // string that needs to // be wrapped into // multiple lines. } ``` -------------------------------- ### Force Non-CJK Mode via Environment Variable Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/configuration.md Control East Asian width mode using the RUNEWIDTH_EASTASIAN environment variable. Set to '0' to force non-CJK mode. ```bash # Force non-CJK mode via environment export RUNEWIDTH_EASTASIAN=0 go run myapp.go ``` -------------------------------- ### Setting EastAsianWidth for Correct CJK Character Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/character-classification.md Demonstrates the correct way to measure CJK text width by setting the EastAsianWidth flag before calculating the string width. Incorrect usage leads to underestimated widths. ```go // Wrong: CJK text still measured as width 1 text := "日本語" fmt.Println(runewidth.StringWidth(text)) // 3, not 6! // Right: Set EastAsianWidth first runewidth.EastAsianWidth = true fmt.Println(runewidth.StringWidth(text)) // 6 ``` -------------------------------- ### StringWidth Method Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/condition.md Returns the display width in cells of a string, using this Condition's settings and accounting for grapheme clusters. It applies the Condition's width calculation rules via RuneWidth(). ```APIDOC ## StringWidth Method Returns the display width in cells of a string, using this Condition's settings and accounting for grapheme clusters. ```go func (c *Condition) StringWidth(s string) int ``` **Parameters:** - **s** (string) - A UTF-8 encoded string **Returns:** `int` — The total display width in cells. **Behavior:** - Uses grapheme clustering for complex scripts - Fast path for ASCII-only strings - Returns the width of the first non-zero-width rune in each grapheme cluster - Applies the Condition's width calculation rules via `RuneWidth()` **Example:** ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { cond := runewidth.NewCondition() cond.EastAsianWidth = true width := cond.StringWidth("Hello世界") fmt.Println(width) // Output: 9 (5 for "Hello" + 4 for "世界") } ``` ``` -------------------------------- ### Use Environment Variable for CJK Mode Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Control CJK mode using the RUNEWIDTH_EASTASIAN environment variable. Set to 1 for CJK mode, 0 for non-CJK mode. ```bash # Force CJK mode export RUNEWIDTH_EASTASIAN=1 go run myapp.go # Force non-CJK mode export RUNEWIDTH_EASTASIAN=0 go run myapp.go ``` -------------------------------- ### Check Character Types Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/api-reference/quick-start.md Classify characters based on their width properties, such as being a combining mark, ambiguous width, or neutral width. ```go func main() { // Is this a combining mark? if runewidth.IsCombiningWidth('̀') { fmt.Println("Combining mark") } // Is this ambiguous width? if runewidth.IsAmbiguousWidth('α') { fmt.Println("Ambiguous character") } // Is this neutral width? if runewidth.IsNeutralWidth('A') { fmt.Println("Neutral character") } } ``` -------------------------------- ### Wrap Text for Terminal Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/README.md Wraps a given string to a specified line width, inserting newlines as needed. This is useful for fitting text within terminal boundaries. ```go // Wrap text to 80 cells per line wrapped := runewidth.Wrap(text, 80) fmt.Println(wrapped) ``` -------------------------------- ### Calculating Rune Width Source: https://github.com/mattn/go-runewidth/blob/master/_autodocs/INDEX.md Calculates the display width of a single rune using the default condition. Useful for character-by-character processing. ```go package main import ( "fmt" "github.com/mattn/go-runewidth" ) func main() { width := runewidth.RuneWidth('A') fmt.Println(width) // Output: 1 width = runewidth.RuneWidth('世') fmt.Println(width) // Output: 2 (in default mode) } ```