module CLI::UI::Truncater
Truncater
truncates a string to a provided printable width.
Constants
- EMOJI_RANGE
EMOJI_RANGE
in particular is super inaccurate. This is best-effort. If you need this to be more accurate, we'll almost certainly accept a PR improving it.- ESC
- LC_ALPHA_RANGE
- LEFT_SQUARE_BRACKET
- NUMERIC_RANGE
- PARSE_ANSI
- PARSE_ESC
- PARSE_ROOT
- PARSE_ZWJ
- SEMICOLON
- TRUNCATED
- UC_ALPHA_RANGE
- ZWJ
Public Class Methods
call(text, printing_width)
click to toggle source
# File lib/cli/ui/truncater.rb, line 30 def call(text, printing_width) return text if text.size <= printing_width width = 0 mode = PARSE_ROOT truncation_index = nil codepoints = text.codepoints codepoints.each.with_index do |cp, index| case mode when PARSE_ROOT case cp when ESC # non-printable, followed by some more non-printables. mode = PARSE_ESC when ZWJ # non-printable, followed by another non-printable. mode = PARSE_ZWJ else width += width(cp) if width >= printing_width truncation_index ||= index # it looks like we could break here but we still want the # width calculation for the rest of the characters. end end when PARSE_ESC mode = case cp when LEFT_SQUARE_BRACKET PARSE_ANSI else PARSE_ROOT end when PARSE_ANSI # ANSI escape codes preeeetty much have the format of: # \x1b[0-9;]+[A-Za-z] case cp when NUMERIC_RANGE, SEMICOLON when LC_ALPHA_RANGE, UC_ALPHA_RANGE mode = PARSE_ROOT else # unexpected. let's just go back to the root state I guess? mode = PARSE_ROOT end when PARSE_ZWJ # consume any character and consider it as having no width # width(x+ZWJ+y) = width(x). mode = PARSE_ROOT end end # Without the `width <= printing_width` check, we truncate # "foo\x1b[0m" for a width of 3, but it should not be truncated. # It's specifically for the case where we decided "Yes, this is the # point at which we'd have to add a truncation!" but it's actually # the end of the string. return text if !truncation_index || width <= printing_width codepoints[0...truncation_index].pack('U*') + TRUNCATED end
Private Class Methods
width(printable_codepoint)
click to toggle source
# File lib/cli/ui/truncater.rb, line 91 def width(printable_codepoint) case printable_codepoint when EMOJI_RANGE 2 else 1 end end