Skip to content

flexible handling of GetConsoleWidth method's default value would be useful in scripting #1300

@Nejat

Description

@Nejat

Description of the new feature/enhancement

When listing output winget truncates column width(s) to accommodate for the total width of the console, which is determined by a call to GetConsoleWidth in src\AppInstallerCLICore\TableOutput.h

    namespace details
    {
        // Gets the column width of the console.
        inline size_t GetConsoleWidth()
        {
            CONSOLE_SCREEN_BUFFER_INFO consoleInfo{};
            if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
            {
                return static_cast<size_t>(consoleInfo.dwSize.X);
            }
            else
            {
                return 120;
            }
        }
    }

If the console is not wide enough, output of a column is truncated and a UTF8 Horizontal Ellipsis (…) is append to the end of the column, also in src\AppInstallerCLICore\TableOutput.h; see the first listing in the image below.

        void OutputLineToStream(const line_t& line)
        {
            auto out = m_reporter.Info();

            for (size_t i = 0; i < FieldCount; ++i)
            {
                const auto& col = m_columns[i];

                if (col.MaxLength)
                {
                    size_t valueLength = Utility::UTF8ColumnWidth(line[i]);

                    if (valueLength > col.MaxLength)
                    {
                        size_t actualWidth;
                        out << Utility::UTF8TrimRightToColumnWidth(line[i], col.MaxLength - 1, actualWidth) << "\xE2\x80\xA6"; // UTF8 encoding of ellipsis (…) character

                        // Some characters take 2 unit space, the trimmed string length might be 1 less than the expected length.
                        if (actualWidth != col.MaxLength - 1)
                        {
                            out << ' ';
                        }

                        if (col.SpaceAfter)
                        {
                            out << ' ';
                        }
                    }
                    else
                    {
                        out << line[i];

                        if (col.SpaceAfter)
                        {
                            out << std::string(col.MaxLength - valueLength + 1, ' ');
                        }
                    }
                }
            }

            out << std::endl;
        }

When the console is wide enough, all of the columns are output in their entirety; see the second listing in the image below.

However, if you either pipe the output to a subsequent command, such as winget upgrade | Select-Object -skip 3, or you assign it to a variable, GetConsoleWidth uses a hard coded 120 for the console width, because it can't get console buffer info for std out. Besides being truncated, the output is also garbled because it is not captured as UTF8; ; see the third listing in the image below.

image

Proposed technical implementation details (optional)

Adding native PowerShell support as proposed in #221 would be the ideal solution, however a quick simple patch to bump up the default value to 180+ would be great in the mean time.

    namespace details
    {
        // Gets the column width of the console.
        inline size_t GetConsoleWidth()
        {
            CONSOLE_SCREEN_BUFFER_INFO consoleInfo{};
            if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
            {
                return static_cast<size_t>(consoleInfo.dwSize.X);
            }
            else
            {
                return 180; // or more if your heart desires 😋
            }
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-OutputIssue related to CLI outputIssue-FeatureThis is a feature request for the Windows Package Manager client.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions