@@ -215,7 +215,9 @@ private void AppendDescription(string description)
215
215
protected virtual void AppendHelpItems ( IReadOnlyCollection < HelpItem > helpItems )
216
216
{
217
217
if ( helpItems is null )
218
+ {
218
219
throw new ArgumentNullException ( nameof ( helpItems ) ) ;
220
+ }
219
221
220
222
var table = CreateTable ( helpItems , item => new [ ]
221
223
{
@@ -228,42 +230,46 @@ protected virtual void AppendHelpItems(IReadOnlyCollection<HelpItem> helpItems)
228
230
}
229
231
230
232
/// <summary>
231
- /// Create a read only table of strings using the projection of a collection.
233
+ /// Create a table of strings using the projection of a collection.
232
234
/// </summary>
233
235
/// <typeparam name="T">The type of the elements of <paramref name="collection"/>.</typeparam>
234
236
/// <param name="collection">The collection of values to create the table from.</param>
235
237
/// <param name="selector">A transformation function to apply to each element of <paramref name="collection"/>.</param>
236
238
/// <returns>
237
- /// A read only table of strings whose elements are the projection of the collection with whitespace formatting removed.
239
+ /// A table of strings whose elements are the projection of the collection with whitespace formatting removed.
238
240
/// </returns>
239
- protected virtual ReadOnlyCollection < ReadOnlyCollection < string > > CreateTable < T > ( IEnumerable < T > collection , Func < T , IEnumerable < string > > selector )
241
+ protected virtual IEnumerable < IReadOnlyList < string > > CreateTable < T > ( IEnumerable < T > collection , Func < T , IEnumerable < string > > selector )
240
242
{
241
243
return collection . Select ( selector )
242
244
. Select ( row => row
243
- . Select ( element => RemoveFormatting ( element ) )
244
- . ToList ( ) . AsReadOnly ( ) )
245
- . ToList ( ) . AsReadOnly ( ) ;
245
+ . Select ( element => ShortenWhitespace ( element ) )
246
+ . ToArray ( ) ) ;
246
247
}
247
248
248
249
/// <summary>
249
250
/// Allocate space for columns favoring minimal rows. Wider columns are allocated more space if it is available.
250
251
/// </summary>
251
252
/// <param name="table">The table of values to determine column widths for.</param>
252
253
/// <returns>A collection of column widths.</returns>
253
- protected virtual ReadOnlyCollection < int > ColumnWidths ( IEnumerable < IList < string > > table )
254
+ private IReadOnlyList < int > ColumnWidths ( IEnumerable < IReadOnlyList < string > > table )
254
255
{
255
256
if ( ! table . Any ( ) )
256
- return Array . AsReadOnly ( Array . Empty < int > ( ) ) ;
257
+ {
258
+ return Array . Empty < int > ( ) ;
259
+ }
257
260
258
261
var columns = table . First ( ) . Count ;
259
- Debug . Assert ( table . All ( e => e . Count == columns ) , $ "Every row in { nameof ( table ) } must have the same number of columns.") ;
260
262
var unsetWidth = - 1 ;
261
263
var widths = new int [ columns ] ;
262
264
for ( int i = 0 ; i < columns ; ++ i )
265
+ {
263
266
widths [ i ] = unsetWidth ;
267
+ }
264
268
var maxWidths = new int [ columns ] ;
265
269
for ( int i = 0 ; i < columns ; ++ i )
270
+ {
266
271
maxWidths [ i ] = table . Max ( row => row [ i ] . Length ) ;
272
+ }
267
273
268
274
var nonEmptyColumns = maxWidths . Count ( width => width > 0 ) ;
269
275
@@ -272,7 +278,9 @@ protected virtual ReadOnlyCollection<int> ColumnWidths(IEnumerable<IList<string>
272
278
// If available space is not sufficent then do not wrap.
273
279
// If all columns are empty then return array of zeros.
274
280
if ( available - nonEmptyColumns < 0 || nonEmptyColumns == 0 )
275
- return Array . AsReadOnly ( maxWidths ) ;
281
+ {
282
+ return maxWidths ;
283
+ }
276
284
277
285
// Loop variables.
278
286
var unset = nonEmptyColumns ;
@@ -293,25 +301,29 @@ protected virtual ReadOnlyCollection<int> ColumnWidths(IEnumerable<IList<string>
293
301
// Attempt to fit column to single line.
294
302
var width = maxWidths [ i ] ;
295
303
if ( allocateRemaining )
304
+ {
296
305
width = Math . Min ( width , equal ) ;
306
+ }
297
307
if ( width <= equal )
308
+ {
298
309
widths [ i ] = width ;
310
+ }
299
311
}
300
312
}
301
313
previousUnset = unset ;
302
314
unset = widths . Count ( width => width < 0 ) ;
303
315
-- loopLimit ;
304
316
}
305
317
306
- return Array . AsReadOnly ( widths ) ;
318
+ return widths ;
307
319
}
308
320
309
321
/// <summary>
310
322
/// Writes a table of strings to the console.
311
323
/// </summary>
312
324
/// <param name="table">The table of values to write.</param>
313
325
/// <param name="columnWidths">The width of each column of the table.</param>
314
- protected virtual void AppendTable ( IEnumerable < IEnumerable < string > > table , IReadOnlyList < int > columnWidths )
326
+ private void AppendTable ( IEnumerable < IEnumerable < string > > table , IReadOnlyList < int > columnWidths )
315
327
{
316
328
foreach ( var row in table )
317
329
AppendRow ( row , columnWidths ) ;
@@ -322,7 +334,7 @@ protected virtual void AppendTable(IEnumerable<IEnumerable<string>> table, IRead
322
334
/// </summary>
323
335
/// <param name="row">The row of elements to write.</param>
324
336
/// <param name="columnWidths">The width of each column of the table.</param>
325
- protected virtual void AppendRow ( IEnumerable < string > row , IReadOnlyList < int > columnWidths )
337
+ private void AppendRow ( IEnumerable < string > row , IReadOnlyList < int > columnWidths )
326
338
{
327
339
var split = row . Select ( ( element , index ) => SplitText ( element , columnWidths [ index ] ) ) . ToArray ( ) ;
328
340
var longest = split . Max ( lines => lines . Count ) ;
@@ -361,21 +373,21 @@ protected virtual void AppendRow(IEnumerable<string> row, IReadOnlyList<int> col
361
373
/// Collection of lines of at most <paramref name="width"/> characters
362
374
/// generated from the supplied <paramref name="text"/>.
363
375
/// </returns>
364
- protected virtual ReadOnlyCollection < string > SplitText ( string text , int width )
376
+ protected virtual IReadOnlyList < string > SplitText ( string text , int width )
365
377
{
366
378
if ( text is null )
367
379
throw new ArgumentNullException ( nameof ( text ) , $ "{ nameof ( text ) } cannot be null.") ;
368
380
if ( width < 0 )
369
381
throw new ArgumentOutOfRangeException ( nameof ( width ) , $ "{ nameof ( width ) } must be non-negative.") ;
370
382
371
383
if ( width == 0 )
372
- return Array . AsReadOnly ( Array . Empty < string > ( ) ) ;
384
+ return Array . Empty < string > ( ) ;
373
385
374
386
var separator = ' ' ;
375
387
376
388
var start = 0 ;
377
389
var lines = new List < string > ( ) ;
378
- text = RemoveFormatting ( text ) ;
390
+ text = ShortenWhitespace ( text ) ;
379
391
380
392
while ( start < text . Length - width )
381
393
{
@@ -398,7 +410,7 @@ protected virtual ReadOnlyCollection<string> SplitText(string text, int width)
398
410
399
411
lines . Add ( text . Substring ( start , text . Length - start ) ) ;
400
412
401
- return lines . AsReadOnly ( ) ;
413
+ return lines ;
402
414
}
403
415
404
416
/// <summary>
@@ -724,20 +736,13 @@ private bool ShouldDisplayArgumentHelp(ICommand? command)
724
736
725
737
private int GetConsoleWindowWidth ( IConsole console )
726
738
{
727
- try
728
- {
729
- if ( console is SystemConsole && System . Console . WindowWidth > 0 )
730
- return System . Console . WindowWidth ;
731
- else
732
- return int . MaxValue ;
733
- }
734
- catch
735
- {
739
+ if ( console is SystemConsole systemConsole )
740
+ return systemConsole . GetConsoleWindowWidth ( ) ;
741
+ else
736
742
return int . MaxValue ;
737
- }
738
743
}
739
744
740
- private string RemoveFormatting ( string input )
745
+ private string ShortenWhitespace ( string input )
741
746
{
742
747
return Regex . Replace ( input , @"\s+" , " " ) ;
743
748
}
0 commit comments