sequences.py
Module providing ‘sequence awareness’.
- class Sequence(sequence_text: str, term: Terminal)[source]
A “sequence-aware” version of the base
strclass.This unicode-derived class understands the effect of escape sequences of printable length, allowing a properly implemented
rjust(),ljust(),center(), andlength().Note
that other than
Sequence.padd(), this is just a thin layer overwcwidth, kept by name for API compatibility.Class constructor.
- Parameters:
- ljust(width: SupportsIndex, fillchar: str = ' ') str[source]
Return string containing sequences, left-adjusted.
- rjust(width: SupportsIndex, fillchar: str = ' ') str[source]
Return string containing sequences, right-adjusted.
- center(width: SupportsIndex, fillchar: str = ' ') str[source]
Return string containing sequences, centered.
- truncate(width: SupportsIndex) str[source]
Truncate a string in a sequence-aware manner.
Any printable characters beyond
widthare removed, while all sequences remain in place. Horizontal sequences are first expanded bypadd().Wide characters (such as CJK or emoji) that would partially exceed
widthare replaced with space padding to maintain exact width.SGR (terminal styling) sequences are propagated: the result begins with any active style at the start position and ends with a reset sequence if styles were active.
- length() int[source]
Return the printable length of string containing sequences.
Returns the maximum horizontal cursor extent reached while processing the string. Backspace and cursor-left movements do not reduce the length below the maximum position reached.
Some characters may consume more than one cell, mainly CJK (Chinese, Japanese, Korean) and Emojis and some kinds of symbols.
For example:
>>> from blessed import Terminal >>> from blessed.sequences import Sequence >>> term = Terminal() >>> msg = term.clear + term.red('コンニチハ') >>> Sequence(msg, term).length() 10
Note
Although accounted for, strings containing sequences such as
term.clearwill not give accurate returns, it is not considered lengthy (a length of 0).
- strip(chars: str | None = None) str[source]
Return string of sequences, leading and trailing whitespace removed.
- lstrip(chars: str | None = None) str[source]
Return string of all sequences and leading whitespace removed.
- rstrip(chars: str | None = None) str[source]
Return string of all sequences and trailing whitespace removed.
- class SequenceTextWrapper(width: int = 70, *, control_codes: Literal['parse', 'strict', 'ignore'] = 'parse', tabsize: int = 8, ambiguous_width: int = 1, **kwargs: Any)[source]
Sequence-aware text wrapper extending
textwrap.TextWrapper.This wrapper properly handles terminal escape sequences and Unicode grapheme clusters when calculating text width for wrapping.
This implementation is based on the SequenceTextWrapper from the ‘blessed’ library, with contributions from Avram Lubkin and grayjk.
The key difference from the blessed implementation is the addition of grapheme cluster support via
iter_graphemes(), providing width calculation for ZWJ emoji sequences, VS-16 emojis and variations, regional indicator flags, and combining characters.OSC 8 hyperlinks are handled specially: when a hyperlink must span multiple lines, each line receives complete open/close sequences with a shared
idparameter, ensuring terminals treat the fragments as a single hyperlink for hover underlining. If the original hyperlink already has anidparameter, it is preserved; otherwise, one is generated.Initialize the wrapper.
- Parameters:
- _split(text: str) list[str][source]
Sequence-aware variant of
textwrap.TextWrapper._split().This method ensures that terminal escape sequences don’t interfere with the text splitting logic, particularly for hyphen-based word breaking. It builds a position mapping from stripped text to original text, calls the parent’s _split on stripped text, then maps chunks back.
OSC hyperlink sequences are treated as word boundaries:
>>> wrap('foo \x1b]8;;https://example.com\x07link\x1b]8;;\x07 bar', 6) ['foo', '\x1b]8;;https://example.com\x07link\x1b]8;;\x07', 'bar']
Both BEL (
\x07) and ST (\x1b\\) terminators are supported.
- _wrap_chunks(chunks: list[str]) list[str][source]
Wrap chunks into lines using sequence-aware width.
Override TextWrapper._wrap_chunks to use _width instead of len. Follows stdlib’s algorithm: greedily fill lines, handle long words. Also handle OSC hyperlink processing. When hyperlinks span multiple lines, each line gets complete open/close sequences with matching id parameters for hover underlining continuity per OSC 8 spec.
- _track_hyperlink_state(text: str, state: HyperlinkParams | None) HyperlinkParams | None[source]
Track hyperlink state through text.
- _handle_long_word(reversed_chunks: list[str], cur_line: list[str], cur_len: int, width: int) None[source]
Sequence-aware
textwrap.TextWrapper._handle_long_word().This method ensures that word boundaries are not broken mid-sequence, and respects grapheme cluster boundaries when breaking long words.
- _map_stripped_pos_to_original(text: str, stripped_pos: int) int[source]
Map a position in stripped text back to original text position.
- iter_parse(term: Terminal, text: str) Iterator[Tuple[str, Termcap | None]][source]
Generator yields (text, capability) for characters of
text.value for
capabilitymay beNone, wheretextisstrof length 1. Otherwise,textis a full matching sequence of given capability.Note
Previously used by SequenceTextWrapper, sequence-aware text wrapping now exists in wcwidth as
wcwidth.wrap(). This function is kept for API compatibility and used bymeasure_length().