Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ColumnWidthManager.cs209 linesDownload Raw Back to common
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5 6namespace Microsoft.PowerShell.Commands.Internal.Format7{8    /// <summary>9    /// Class providing an algorithm for automatic resizing10    /// of table columns.11    /// </summary>12    internal sealed class ColumnWidthManager13    {14        /// <summary>15        /// Class providing an algorithm for automatic resizing.16        /// </summary>17        /// <param name="tableWidth">Overall width of the table in characters.</param>18        /// <param name="minimumColumnWidth">Minimum usable column width.</param>19        /// <param name="separatorWidth">Number of separator characters.</param>20        internal ColumnWidthManager(int tableWidth, int minimumColumnWidth, int separatorWidth)21        {22            _tableWidth = tableWidth;23            _minimumColumnWidth = minimumColumnWidth;24            _separatorWidth = separatorWidth;25        }26 27        /// <summary>28        /// Calculate the widths by applying some heuristics to get them to fit on the29        /// allotted table width. It first assigns widths to the columns that do not have a specified30        /// width, then it checks if the total width exceeds the screen widths. If so, it proceeds31        /// with column elimination, starting from the right most column.32        /// </summary>33        /// <param name="columnWidths">Array of column widths to appropriately size.</param>34        internal void CalculateColumnWidths(Span<int> columnWidths)35        {36            if (AssignColumnWidths(columnWidths))37            {38                // we do not have any trimming to do, we are done39                return;40            }41 42            // total width exceeds screen width, go on with trimming43            TrimToFit(columnWidths);44        }45 46        /// <summary>47        /// Do not remove columns, just assign widths to columns that have a zero width48        /// (meaning unassigned)49        /// </summary>50        /// <param name="columnWidths">Columns to process.</param>51        /// <returns>True if there was a fit, false if there is need for trimming.</returns>52        private bool AssignColumnWidths(Span<int> columnWidths)53        {54            // run a quick check to see if all the columns have a specified width,55            // if so, we are done56            bool allSpecified = true;57            int maxInitialWidthSum = 0;58 59            for (int k = 0; k < columnWidths.Length; k++)60            {61                if (columnWidths[k] <= 0)62                {63                    allSpecified = false;64                    break;65                }66 67                maxInitialWidthSum += columnWidths[k];68            }69 70            if (allSpecified)71            {72                // compute the total table width (columns and separators)73                maxInitialWidthSum += _separatorWidth * (columnWidths.Length - 1);74                if (maxInitialWidthSum <= _tableWidth)75                {76                    // we fit with all the columns specified77                    return true;78                }79                // we do not fit, we will have to trim80                return false;81            }82 83            // we have columns with no width assigned84            // remember the columns we are trying to size85            // assign them the minimum column size86            bool[] fixedColumn = new bool[columnWidths.Length];87            for (int k = 0; k < columnWidths.Length; k++)88            {89                fixedColumn[k] = columnWidths[k] > 0;90                if (columnWidths[k] == 0)91                    columnWidths[k] = _minimumColumnWidth;92            }93 94            // see if we fit95            int currentTableWidth = CurrentTableWidth(columnWidths);96            int availableWidth = _tableWidth - currentTableWidth;97 98            if (availableWidth < 0)99            {100                // if the total width is too much, we will have to remove some columns101                return false;102            }103            else if (availableWidth == 0)104            {105                // we just fit106                return true;107            }108 109            // we still have room and we want to add more width110 111            while (availableWidth > 0)112            {113                for (int k = 0; k < columnWidths.Length; k++)114                {115                    if (fixedColumn[k])116                        continue;117 118                    columnWidths[k]++;119                    availableWidth--;120                    if (availableWidth == 0)121                        break;122                }123            }124 125            return true; // we fit126        }127 128        /// <summary>129        /// Trim columns if the total column width is too much for the screen.130        /// </summary>131        /// <param name="columnWidths">Column widths to trim.</param>132        private void TrimToFit(Span<int> columnWidths)133        {134            while (true)135            {136                int currentTableWidth = CurrentTableWidth(columnWidths);137                int widthInExcess = currentTableWidth - _tableWidth;138                if (widthInExcess <= 0)139                {140                    return; // we are done, because we fit141                }142 143                // we need to remove or shrink the last visible column144                int lastVisibleColumn = GetLastVisibleColumn(columnWidths);145 146                if (lastVisibleColumn < 0)147                    return; // nothing left to hide, because all the columns are hidden148 149                // try to trim the last column to fit150                int newLastVisibleColumnWidth = columnWidths[lastVisibleColumn] - widthInExcess;151 152                if (newLastVisibleColumnWidth < _minimumColumnWidth)153                {154                    // cannot fit it in, just hide155                    columnWidths[lastVisibleColumn] = -1;156                    continue;157                }158                else159                {160                    // shrink the column to fit161                    columnWidths[lastVisibleColumn] = newLastVisibleColumnWidth;162                }163            }164        }165 166        /// <summary>167        /// Computes the total table width from the column width array.168        /// </summary>169        /// <param name="columnWidths">Column widths array.</param>170        /// <returns></returns>171        private int CurrentTableWidth(Span<int> columnWidths)172        {173            int sum = 0;174            int visibleColumns = 0;175 176            for (int k = 0; k < columnWidths.Length; k++)177            {178                if (columnWidths[k] > 0)179                {180                    sum += columnWidths[k];181                    visibleColumns++;182                }183            }184 185            return sum + _separatorWidth * (visibleColumns - 1);186        }187 188        /// <summary>189        /// Get the last visible column (i.e. with a width >= 0)190        /// </summary>191        /// <param name="columnWidths">Column widths array.</param>192        /// <returns>Index of the last visible column, -1 if none.</returns>193        private static int GetLastVisibleColumn(Span<int> columnWidths)194        {195            for (int k = 0; k < columnWidths.Length; k++)196            {197                if (columnWidths[k] < 0)198                    return k - 1;199            }200 201            return columnWidths.Length - 1;202        }203 204        private readonly int _tableWidth;205        private readonly int _minimumColumnWidth;206        private readonly int _separatorWidth;207    }208}209