- Updated the shipped
pretty-console-expertskill and its references so the packaged guidance reflects the v6 API surface. - Removed the stale packaged
v5-api-map.mdskill reference and added package cleanup for consumers that already received it. - Clarified
LiveConsoleRegionlifecycle docs so examples useDispose()as the normal cleanup path and describeClear()as the reusable mid-scope hide case. - Refreshed README and file-based example guidance to match the current
Color/Markup/AnsiToken-first model and the current package version.
- Added
LiveConsoleRegionfor retained live output on a singleOutputPipe, enabling Cargo-style durable status lines above a pinned transient region. - Added
AnsiTokenas the guarded ANSI abstraction for interpolated output. - Added
Coloras the preferred interpolation-facing color surface with cached tokens such asColor.Green,Color.DefaultForeground,Color.DefaultBackground, andColor.Default. - Added token-based color support across
ProgressBar,Spinner,TypeWrite, andLiveConsoleRegion.RenderProgress. - Added Windows ANSI capability detection so PrettyConsole can avoid emitting styled ANSI output when the terminal cannot safely render it.
ConsoleColorremains supported for compatibility, butColoris now the preferred API for styled output.
Markupnow exposes guardedAnsiTokens instead of rawstringescape sequences.AnsiColors.Foreground(ConsoleColor)andAnsiColors.Background(ConsoleColor)now return cachedAnsiTokens instead of raw ANSI strings and map to theColorcache.
- Improve perf of
ReadOnlySpanbased overloads ofWriteandWriteLine. SKILLimprovements- Highlight some points that correct invalid API assumptions made by agents.
- Add testing section and teach agents to about
ConsoleContext.
- This version now ships with a specialized AI agent skill
PrettyConsoleExpertthat will be copied to consumers on build.- This can be opt-out of - instructions are in the main
README.md
- This can be opt-out of - instructions are in the main
- BREAKING:
IndeterminateProgressBarwas renamed toSpinner- Internal line reset is now triggered at the start of each frame render, this keeps the output after the last render. You can choose whether to override or keep the output by using
Console.ClearNextLinesorConsole.SkipLines. - All overloads of
RunAsyncnow have a default value for theCancellationToken. AnimationSequencewas renamed toPatternto fitSpinner.Patterns.
- Internal line reset is now triggered at the start of each frame render, this keeps the output after the last render. You can choose whether to override or keep the output by using
- Changes in
ProgressBar- BREAKING: the static
WriteProgressBarmethods have been renamed toRender. - Added overloads that accept a
PrettyConsoleInterpolatedStringHandlerFactorylike the overloads inSpinnerto allow more complex outputs at lower costs. - BREAKING:
ReadOnlySpan<char>parameters of header, now usestringinstead due to language limitation that caused incorrect escape analysis with thePrettyConsoleInterpolatedStringHandlerFactory
- BREAKING: the static
PrettyConsoleInterpolatedStringHandler:- Turned more of the methods to be
publicto enhance the usability of it in an advance usage (unrolling its creation). To further aid in this. - Added
AppendInlinewhich can inline the contents of an anotherPrettyConsoleInterpolatedStringHandlerto the source instance and enable nested use cases. - Added another constructor that accepts just
OutputPipeand an optionalIFormatProvider. - Is now passed by
refto accepting methods.
- Turned more of the methods to be
- Added
SkipLineswhich can be used to move the cursornamount of lines forward. This can be used to keep the output of overwritten lines, like progress bars, spinners,OverWriteand so on and forth. Confirm(trueValues, ref handler, bool emptyIsTrue = true)parameters were reordered,emptyIsTrueis now the last parameter.IndeterminateProgressBaroverloads with theFuncnow usePrettyConsoleInterpolatedStringHandlerFactoryinstead, and usage is now(builder, out handler) => handler = builder.Build(OutputPipe.Error, $"..."). This was required to reduce compiler created struct copies and increase safety.- Building custom handlers is now done with
PrettyConsoleInterpolatedStringHandlerBuilderwhich contains a thread-safe singleton;PrettyConsoleInterpolatedStringHandler.Buildwas removed in favor of using the builder.
- Building custom handlers is now done with
AnsiColorswhich provides static utilities to convertConsoleColortoANSIsequences is now public (was previously internal)
PrettyConsoleInterpolatedStringHandlerwas re-written to buffers interpolated content before emitting it (instead of streaming), along with other optimizations.- Added a
WhiteSpacestruct to declare padding regions; the handler recognizes it as a special argument and writes that many spaces directly into the buffer. IndeterminateProgressBargains overloads that take aFunc<PrettyConsoleInterpolatedStringHandler>, letting each frame build status text with captured locals. UsePrettyConsoleInterpolatedStringHandler.Buildto bind the handler to the correctOutputPipeinside the factory.
Console.WriteInterpolatedandConsole.WriteLineInterpolatednow return aintthat contains the number of characters written using the handler. This could be used to help calculate paddings or other things when creating structured output.- It will ignore escape sequences that were added using the handler like
ConsoleColor,Color,Markup, or any guardedAnsiToken, but if you hardcode your own they might be taken into account. As such, if you do this, I recommend first checking the length without using those helpers, then using this result for the calculation.
- It will ignore escape sequences that were added using the handler like
PrettyConsoleExtensionsthat contains theOut,Error,In, etc... was renamed toConsoleContext.- The standard
Out,Error,Instreams now have a public setter, so end users could mock them in their own tests. Console.WriteWhiteSpaces(length, OutputPipe)was added to reduce the complexity of using theTextWriterextension.
This version contains a lot of breaking changes, but they were necessary to trim legacy and sub-optimal things from the library to ensure it remains the best performing library for stylized console outputs.
ColoredOutputis completely gone, all APIs that used it - are gone as well.Colorstruct is gone too, extension members allowed me to rework it's uses to the built-inSystem.ConsoleColor.
- All of the public facing APIs can now be invoked directly from
System.ConsoleWrite<T>andWrite(ReadOnlySpan<char>, OutputPipe)remain by the same names.WriteandWriteLinethat usePrettyConsoleInterpolatedStringHandlerwere renamed toWriteInterpolatedandWriteLineInterpolatedrespectively - This is slightly more verbose but required to bypass overload resolution which prefers the build-inWriteandWriteLinemethods ofSystem.Console.Selection,Menu,Table,ReadLine,TryReadLinewere all added toSystem.Console.
ConsoleColornow has static properties to allow the same semantics asColorused to.ConsoleColor.DefaultForegroundandConsoleColor.DefaultBackgroundbind to the defaults of the shell and can be used to work with the defaults or reset colors.ConsoleColor.Defaultreturns a tuple of(DefaultForeground, DefaultBackground)ConsoleColor / ConsoleColoralso returns a tuple where the first the foreground and second a background.ConsoleColor / (ConsoleColor, ConsoleColor)returns a tuple of the foreground, and the background from second tuple.- Those can be used with the string handler
$"{ConsoleColor.Red}Hello{ConsoleColor.Default}"to write colored zero allocation outputs.
ProgressBarandIndeterminateProgressBarare no longer nested classes ofConsole(since it doesn't exist anymore) - this can affect your using statements.
TextWriterwhich is the object backingConsole.OutandConsole.Errornow has a static extensionWriteWhiteSpaces(int), which can be used to write paddings and whatever else without any allocations. It was previously an internal method but I chose to expose it for all of you.Markupstatic class provides ANSI escape-sequence toggles (underline, bold, italic, strikethrough) that automatically collapse to empty strings when output/error are redirected, so callers can opt into inline decorations without additional checks.PrettyConsoleInterpolatedStringHandlernow exposes adurationformat forTimeSpanvalues (formerlyhr) that emitsXh Ym Zsand abytesformat fordoublevalues that scales throughB/KB/MB/...with culture-aware separators.ProgressBar.WriteProgressBar(and the instance helper viaProgressBar.MaxLineWidth) now accept an optionalmaxLineWidthso the full[=====] 42%line can be constrained for columnar layouts without overflowing the buffer.
ProgressBarnow includes a static methodWriteProgressBarwhich renders a static progress bar with the set parameters, it can be used in conjunction withOverwriteto create multi-progress-bars UI.ProgressBar.Updateoverloads now include an optional parametersameLinewhich configures whether to render the progress bar at the same of the status. It is set totrueby default to keep current behavior.
ProgressBar.ForegroundColordocs were fixed (they previously were the same asProgressColor) which is invalid.ProgressBarin all variations now shows progress as a round number suffixed by %.ProgressBarno longer tracks if the percentage is changed, being that the numbers are round, percentage could progress or status needs to be re-written while it stays the same when rounded.- Methods that overwrite lines, now have a note in the remarks to clear the used lines after the last call, to prevent artifacts.
PrettyConsoleInterpolatedStringHandlerwas added to allow streaming zero allocation formatted and styled outputs to console pipes. With supported overloads for:WriteandWriteLineReadLineandTryReadLineSelectionandMultiSelectionOverwriteis a wrapper around an action of displaying outputs, with or without closures usingTState, it enables you to use a lambda and call thePrettyConsoleInterpolatedStringHandlermethods inside, to create zero allocation reactive and refreshable components.- To customize colors, use
Coloras an interpolation parameter at the correct place, and restore the colors withColor.Default. for example:WriteLine($"This is in {Color.Green}green{Color.Default} and this is in {Color.Red}red{Color.Default}.");, all overloads that accept the interpolation reset the color at the end, so you can omitColor.Defaultif you colored the last section of your string. - The same conventions and syntax of setting
Foreground / Backgroundcolors works here as well.
IndeterminateProgressBarwill now allow customization of the animated sequence via the propertyAnimationSequence, and it also includes an inner classPatternsthat contains some constant sequences that could be used with it.
- Fixed issue that could sometimes cause writing into buffers beyond their bounds - throwing an exception. Possibly effected:
ProgressBarandIndeterminateProgressBarClearNextLines
IndeterminateProgressBar.UpdateRateis 200 ms by default.IndeterminateProgressBarheader is now positioned right of the animation. Similar to common CLIs.ProgressBarhad numeral optimizations and should perform better in all scenarios.OverrideCurrentLinewas renamed toOverwriteCurrentLineto be more semantically correct.
- Dropped
Sharpifyas a dependency -PrettyConsoleis now self-sufficient.
- Updated to support .NET 9.0
- Updated to use
Sharpify 2.5.0 ProgressBarwas redesigned since it randomly produced artifacts such as printing the header multiple times.- Now the buffer area of
ProgressBaris only 1 line, the (now "status") is printed on the same line, after the bar - Only if the header is empty, the percentage is printed instead.
- An internal lock is now also used to prevent race conditions.
- Now the buffer area of
ClearNextLinesshow now work properly, previously it could actually clear 1 line too many.
OutputPipeenum was added to unify APIsClearNextLinesErrorwas removed, useClearNextLineswithOutputPipe.ErrorinsteadNewLineErrorwas removed, useNewLinewithOutputPipe.ErrorinsteadWriteErrorwas removed, useWritewithOutputPipe.ErrorinsteadWriteLineErrorwas removed, useWriteLinewithOutputPipe.ErrorinsteadOverrideCurrentLinenow has an option to choose the output pipe, useOutputPipe.Errorby defaultWrite<T>had the same treatment, now it has an option to choose the output pipe, useOutputPipe.Outby default, so the overload ofWriteError<T>were removedWriteLine<T>andWriteLine(ReadOnlySpan<char>)were introduced thanks to this change
- Removed
WriteandWriteLineoverloads that contains multipleColoredOutputs, when using the overload withReadOnlySpan<ColoredOutput>andCollectionExpression, the compiler generates an inline array to hold the elements, this is very efficient, and the reduced complexity allows usage of multipleColoredOutputs in more places. - All overloads of all functions that previously took only one
ColoredOutputnow take aReadOnlySpan<ColoredOutput>instead, as noted it will use an inline array, and the internal implementation also has fast paths for size 1. - All fast changing outputs (
ProgressBar,IndeterminateProgressBar,OverrideCurrentLine) now uses the error output pipe by default, this means that if the consumer will pipe the output to another cli, it won't be filled with garbage and retain only the valuable stuff. - Added
ReadOnlySpan<ColoredOutput>overloads toWriteErrorandWriteLineError. - Added overloads for all variants of
ReadLineandTryReadLinethat supportT @defaultthat will be returned if parsing fails. Write,WriteLine,WriteErrorandWriteLineErrorno longer haveparams ColoredOutput[]overloads, they instead have aReadOnlySpan<ColoredOutput>overload. This performs even better as it uses an inline array, and the removal of the restrictions on whereparamscan be used, allowedReadOnlySpan<ColoredOutput>to replace virtually allow singleColoredOutputmethods as well. Allowing greater customization in any function.- You can now access the
In,Out, andErrorstreams ofSystem.Consoledirectly fromPrettyConsole.Consoleby using the propertiesOut,Error, andIn. This reduces verbosity since the names of the classes have collisions. - Added
SetColorsto allow setting the colors of the console output. ClearNextLinesnow also has aClearNextLinesErrorbrother which does the same for theErrorstream.NewLineErrorwas also added for this.- To enhance customization in extreme high perf scenarios where you write a
ReadOnlySpan<char>directly to the output stream, theWriteandWriteErrormethods now have overloads that take aReadOnlySpan<char>instead of aReadOnlySpan<ColoredOutput>, along with foreground and background colors. - Added
WriteandWriteErrorvariants forT : ISpanFormattableas well. ProgressBarshould now be even more performant as internal progress tracking allowed cutting the required operations by 20%.Colorwill now containstatic readonly ConsoleColorfields for bothForegroundandBackgroundcolors, they will be initialized during runtime to support all platforms (fixing the instant crashes on Windows).- You can also refer them when you want to use the defaults for any reason.
- The base methods which are used for outputting
ReadOnlySpan<ColoredOutput>have been re-written to reduce assembly instructions, leading to about 15-20% runtime improvements across the board, and reducing by the binary size by a few bytes too lol. ConsoleandColornow have the correct attributes to disallow compilation on unsupported platforms, if anyone tries to use them now (even thought it should've been obvious that they shouldn't be used on unsupported platforms), it should display the right message at build time.- Removed all overloads that have options to change the input colors, it invites non-streamlined usage, and just increases the code complexity to maintain. Without them the code is simpler and more performant.
- A lot of methods that used white-spaces in any shape or form were now optimized using pre-initialized static buffer.
IndeterminateProgressBarnow has overloads that accept astring headerthat can be displayed before the progress char. There also was a change involving a secondary addition of catching theCancellationToken, removing up to 5 internal iterations.- Added
GetCurrentLineandGoToLinemethods to allow efficiently using the same space in the console for continuous output, such as progress outputting, and general control flow.
- Removed redirection of
ReadOnlySpan<char>print overload that degraded performance. - Improved internal handling of array and memory pooling.
- Decreased formatted length limit for
ISpanFormattableto 50 characters, as it was too long and frequent calls could cause the os to lag. Also changed to use rented buffer instead of stack allocation.
- Fixed default colors, previously colors where defaulted to
Color.Grayfor foreground andColor.Blackfor background, however many shells have custom colors that they render by default, which means the default colors seemed to render in a non ordinary fashion. The default colors now areColor.Unknownwhich will actually use the colors of the shell. ProgressBarnow implementsIDisposablesince the implementation has been optimized, make sure to dispose of it, lest you induce a penalty on other such optimization which are now spread across the library.- Introduced an overload to
Writethat accepts anyT : ISpanFormattable. In many cases users might want to print structs or other types that implement this interface such asint,double,DateTimeand more... splitting the output into a few lines and using this overload will enable you completely avoid the string allocation for this object, the overload is very optimized, writes it directly to the stack and prints it using a span. However, this limitation means that if the formatted item is longer than 256 characters, an exception will be thrown indicating that you should use a different overload.
- All previous variants of output types were removed, now the main output type is
ColoredOutput(which includes a string, foreground color and background color). Thanks to implicit and other converters and the added supportingColorclass, usage is even simpler, and much more performant. - Overloads of many functions were changed, many were deleted.
ReadLine<T>and new overloadsTryReadLine<T>now support reflection free parsing for anyIParsable<T>implementing types (which are most of the base types, and you can create any custom implementations if you choose so).ReadLinenow also has anEnumoverload that can parse for enums, with configurable case sensitivity.- Many functions, especially more advance outputs such as selections, menus and progress bar, had undergone tremendous performance optimizations, and show now perform extremely efficiently.
- A new table view implementation was added.
- The progress bar types
ProgressBarandIndeterminateProgressBarare now classes, and also have been substantially optimized.
TextRenderingSchemetype was added for better handling of outputs consisting of mixed colorsTypeWritenow has aTextRenderingSchemeoverload and thedelayin all overloads was increased to 200 (ms) to look more naturalWrite,WriteLine,ReadLineandOverrideCurrentLinenow also have overloads withTextRenderingScheme, and they are the recommended ones for mixed color use, using them instead of theparams arrayoverload may allow further optimization during JIT compilationWriteandWriteLinenow have overloads forReadOnlySpan<char>for even better performance- More
try-finallyblocks have been implemented to further reduce the possibility of render failure upon exceptions - More methods have been re-implemented to call their overloads for better maintainability and consistency
- More methods were marked as
Pureto provide more information to the end users - After testing it became rather clear, the best way to avoid glitches in frequently updated outputs inside event handlers, such as
ProgressBar,OverrideCurrentLineand the likes is to firstly create an early return based on elapsed time after previous render, secondly, Use the[MethodImpl(MethodImplOptions.Synchronized)]On the event, and if the output is a Task, use.Waitinstead of making the event async and awaiting it ProgressBarDisplaywas modified to be arecord structinstead ofref struct, This is aimed to increase usage flexibility which is limited withref structs, Also it may increase performance in edge cases due to higher potential for compiler optimization
- Re-structured
Consoleas astatic partial classinto many files to separate the code into categorized section for better maintainability and improved workflow for adding new features - Removed
synchronized methodcompiler enforcements that could in some case limit usage flexibility when intentionally usingTasks, if that feature is needed, simply create your own wrapper method with the attribute - Update all places where the color of the output is changed to use
try-finallyblock to ensure color reset even if an exception was thrown, which before could cause bugged colors - Added more safeguards in key places
- Improved performance of various methods
- Merged closely related method implementations to reduce possibility of future errors
- [POSSIBLE BREAKING CHANGE]
ProgressBarDisplayhas been restructured to safeguard against improper initialization. Also aProgressCharproperty was added to allow further customization of the progress bar look - Added
TypeWriteandTypeWriteLinemethods that provide a simple type-writer effect for text. - Fixed issue in
RequestAnyInputthat could read a pre-existing character from the input stream and accept it, basically skipping the entire request.
- FROM THIS VERSION ON, THE PACKAGE WILL BE SIGNED
- Updated many string interpolation instances to use
string.Concatinstead to improve performance - Modified calculations in progress bars to use functions which are more hardware optimized
- Modified evaluated strings in progress bars to only be printed when done
- Added direction to synchronize progress bars to reduce buggy outputs
- Updated csproj file for better compatibility with the nuget website
This is a quality of life update, in most use cases the performance benefit, whether time wise or memory allocation will be visible and sometimes very significant.
This update doesn't introduce any breaking changes so updating is highly encouraged.
- Fixed issues with progress bar where the next override could keep artifacts of previous render.
- Added
OverrideCurrentLine()which allows showing of progress with string only. - Added
ClearNextLines(num)which allows to remove nextnumlines, this is useful when something overriding was used, such as progress bar, but after parts of are left because the new output is shorter.
- Optimized code across the board for better performance and less memory allocation
- Improved organization and documentation
- Added more method overloads
- Added options to output errors to error pipeline to improve stds down the line
- Added trimming safe overloads for generic methods
- Added trim warnings for generic and reflection methods
- Added optional header to the progress bar
- Greatly improved performance by taking generics or strings into output methods instead of objects to avoid boxing.
- Most methods, including
WriteandWriteLinewith single parameter should not require any code modification as they will use generics - Outputs methods which use
tupleswill require modification to enjoy the performance upgrade, with that said, existing code will be break because legacyobjectimplementation was not removed but rather just marked as obsolete for now.
- Fixed memory leak in
TreeMenu - Improved performance and reduced complexity
- Removed
Colors.Primary- it reduced uniformity as default was very close in color. Now default will be used in place of both, if you like primary more, consider overriding theColors.DefaulttoConsoleColor.White - Added Labels - outputs with configurable background color.
- Removed
Colorenum, use theColorsproperty instead - Added progress bars, both regular and indeterminate
- Added documentation file so summaries will be visible
- Added indeterminate progress-bar
- Added regular progress-bar
- Changed parameter-less
WriteandWriteLineto use color version with default values to trim unnecessary code.
- Changed secondary color to be called the default color and also act as such, meaning by default
WriteandWriteLinewill use it - Internal outputs such as ReadLine or others will still use primary color
- Moved
Colorenum into Console to reduce using statements - Changed accessibility of extensions, they were meant to be used internally