• 
      

    Improve styling of wrapped text in Console output.

    Review Request #12393 — Created June 20, 2022 and submitted

    Information

    Review Board
    release-5.0.x

    Reviewers

    Console attempts to nicely style and wrap text for display to the
    user. There were a couple problems, though, in the appearance of wrapped
    text, especially when containing styling.

    When using a prefix for wrapped lines (such as "Warning:"), the prefix
    would end up applying to each paragraph. This was noisy and made it hard
    to differentiate one block from another. We now treat the "subsequent
    indent" as the "initial indent" for all but the first paragraph,
    ensuring only that first paragraph has the prefix. All other paragraphs
    will properly align, and look correct.

    The second issue is more tricky. textwrap isn't aware of ANSI
    character codes, so any styling we apply to the prefix ends up reducing
    the available width of that line.

    There are third-party modules available for this, but at this time it's
    not worth introducing another dependency for this. The only things
    textwrap cares about is the ability to call len() on the string, and
    to concatenate strings together.

    We now use a string wrapper, _StyledWrapperIndent, to wrap the string
    and provide these capabilities. __len__ returns the non-styled length,
    and __add__ helps concatenate.

    This is kind of a hack, but textwrap doesn't appear to change all that
    often, and certainly has not between the versions of Python currently
    supported. Unit tests will ensure it doesn't break unexpectedly.

    Unit tests passed.

    Manually ran the upgrade process and triggered errors. Saw the
    correctly-formatted, wrapped text with consistent line widths.

    Summary ID
    Improve styling of wrapped text in Console output.
    `Console` attempts to nicely style and wrap text for display to the user. There were a couple problems, though, in the appearance of wrapped text, especially when containing styling. When using a prefix for wrapped lines (such as "Warning:"), the prefix would end up applying to each paragraph. This was noisy and made it hard to differentiate one block from another. We now treat the "subsequent indent" as the "initial indent" for all but the first paragraph, ensuring only that first paragraph has the prefix. All other paragraphs will properly align, and look correct. The second issue is more tricky. `textwrap` isn't aware of ANSI character codes, so any styling we apply to the prefix ends up reducing the available width of that line. There are third-party modules available for this, but at this time it's not worth introducing another dependency for this. The only things `textwrap` cares about is the ability to call `len()` on the string, and to concatenate strings together. We now use a string wrapper, `_StyledWrapperIndent`, to wrap the string and provide these capabilities. `__len__` returns the non-styled length, and `__add__` helps concatenate. This is kind of a hack, but `textwrap` doesn't appear to change all that often, and certainly has not between the versions of Python currently supported. Unit tests will ensure it doesn't break unexpectedly.
    0cfa9c3c58d9be5c2ffed78ca5630e0df3b599a5

    Description From Last Updated

    local variable 'lines' is assigned to but never used Column: 13 Error code: F841

    reviewbotreviewbot
    Checks run (1 failed, 1 succeeded)
    flake8 failed.
    JSHint passed.

    flake8

    chipx86
    david
    1. Ship It!
    2. 
        
    chipx86
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-5.0.x (41a07fd)