Module: Clack::Utils
- Defined in:
- lib/clack/utils.rb
Overview
Utility functions for text manipulation and formatting
Class Method Summary collapse
-
.display_width(string) ⇒ Integer
Calculate the terminal display width (columns) of a string.
-
.strip_ansi(text) ⇒ String
Strip ANSI escape sequences from text.
-
.truncate(text, width, ellipsis: "...") ⇒ String
Truncate text to width with ellipsis.
-
.visible_length(text) ⇒ Integer
Get visible length (display width in columns) of text after stripping ANSI.
-
.wrap(text, width) ⇒ String
Wrap text to a specified width, preserving ANSI codes.
-
.wrap_with_prefix(text, prefix, width) ⇒ String
Wrap text with a prefix on each line.
Class Method Details
.display_width(string) ⇒ Integer
Calculate the terminal display width (columns) of a string. ASCII and most chars: width 1. CJK ideographs, fullwidth forms, common emoji: width 2. Zero-width joiners, combining marks, variation selectors: width 0.
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/clack/utils.rb', line 27 def display_width(string) str = string.to_s return 0 if str.empty? width = 0 str.grapheme_clusters.each do |cluster| width += grapheme_width(cluster) end width end |
.strip_ansi(text) ⇒ String
Strip ANSI escape sequences from text
10 11 12 |
# File 'lib/clack/utils.rb', line 10 def strip_ansi(text) text.to_s.gsub(/\e\[[0-9;]*[a-zA-Z]/, "") end |
.truncate(text, width, ellipsis: "...") ⇒ String
Truncate text to width with ellipsis
71 72 73 74 75 76 77 78 79 |
# File 'lib/clack/utils.rb', line 71 def truncate(text, width, ellipsis: "...") return text if visible_length(text) <= width target = width - visible_length(ellipsis) return ellipsis if target <= 0 # Handle ANSI codes: we need to truncate visible chars while preserving codes truncate_visible(text, target) + ellipsis end |
.visible_length(text) ⇒ Integer
Get visible length (display width in columns) of text after stripping ANSI. Uses display_width to correctly measure CJK, emoji, combining chars.
18 19 20 |
# File 'lib/clack/utils.rb', line 18 def visible_length(text) display_width(strip_ansi(text)) end |
.wrap(text, width) ⇒ String
Wrap text to a specified width, preserving ANSI codes
42 43 44 45 46 47 48 49 50 |
# File 'lib/clack/utils.rb', line 42 def wrap(text, width) return text if width <= 0 lines = [] text.to_s.each_line do |line| lines.concat(wrap_line(line.chomp, width)) end lines.join("\n") end |
.wrap_with_prefix(text, prefix, width) ⇒ String
Wrap text with a prefix on each line
57 58 59 60 61 62 63 64 |
# File 'lib/clack/utils.rb', line 57 def wrap_with_prefix(text, prefix, width) prefix_len = visible_length(prefix) content_width = width - prefix_len return text if content_width <= 0 wrapped = wrap(text, content_width) wrapped.lines.map { |line| "#{prefix}#{line.chomp}" }.join("\n") end |