Reduce string allocation in console output code (#6882)
This commit is contained in:
parent
50efc4192d
commit
2174dd81a4
9 changed files with 294 additions and 123 deletions
|
@ -2542,61 +2542,91 @@ namespace Microsoft.PowerShell
|
|||
/// Wrap Win32 WriteConsole.
|
||||
/// </summary>
|
||||
/// <param name="consoleHandle">
|
||||
/// handle for the console where the string is written
|
||||
/// Handle for the console where the string is written.
|
||||
/// </param>
|
||||
/// <param name="output">
|
||||
/// string that is written
|
||||
/// String that is written.
|
||||
/// </param>
|
||||
/// <param name="newLine">
|
||||
/// New line is written.
|
||||
/// </param>
|
||||
/// <exception cref="HostException">
|
||||
/// if the Win32's WriteConsole fails
|
||||
/// If the Win32's WriteConsole fails.
|
||||
/// </exception>
|
||||
|
||||
internal static void WriteConsole(ConsoleHandle consoleHandle, string output)
|
||||
internal static void WriteConsole(ConsoleHandle consoleHandle, ReadOnlySpan<char> output, bool newLine)
|
||||
{
|
||||
Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid");
|
||||
Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed");
|
||||
|
||||
if (string.IsNullOrEmpty(output))
|
||||
if (output.Length == 0)
|
||||
{
|
||||
if (newLine)
|
||||
{
|
||||
WriteConsole(consoleHandle, ConsoleHostUserInterface.Crlf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Native WriteConsole doesn't support output buffer longer than 64K.
|
||||
// We need to chop the output string if it is too long.
|
||||
|
||||
int cursor = 0; // This records the chopping position in output string
|
||||
const int maxBufferSize = 16383; // this is 64K/4 - 1 to account for possible width of each character.
|
||||
const int MaxBufferSize = 16383; // this is 64K/4 - 1 to account for possible width of each character.
|
||||
|
||||
while (cursor < output.Length)
|
||||
{
|
||||
string outBuffer;
|
||||
ReadOnlySpan<char> outBuffer;
|
||||
|
||||
if (cursor + maxBufferSize < output.Length)
|
||||
if (cursor + MaxBufferSize < output.Length)
|
||||
{
|
||||
outBuffer = output.Substring(cursor, maxBufferSize);
|
||||
cursor += maxBufferSize;
|
||||
outBuffer = output.Slice(cursor, MaxBufferSize);
|
||||
cursor += MaxBufferSize;
|
||||
|
||||
WriteConsole(consoleHandle, outBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
outBuffer = output.Substring(cursor);
|
||||
outBuffer = output.Slice(cursor);
|
||||
cursor = output.Length;
|
||||
|
||||
if (newLine)
|
||||
{
|
||||
var endOfLine = ConsoleHostUserInterface.Crlf.AsSpan();
|
||||
var endOfLineLength = endOfLine.Length;
|
||||
Span<char> outBufferLine = stackalloc char[outBuffer.Length + endOfLineLength];
|
||||
outBuffer.CopyTo(outBufferLine);
|
||||
endOfLine.CopyTo(outBufferLine.Slice(outBufferLine.Length - endOfLineLength));
|
||||
WriteConsole(consoleHandle, outBufferLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteConsole(consoleHandle, outBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD charsWritten;
|
||||
bool result =
|
||||
NativeMethods.WriteConsole(
|
||||
consoleHandle.DangerousGetHandle(),
|
||||
outBuffer,
|
||||
(DWORD)outBuffer.Length,
|
||||
out charsWritten,
|
||||
IntPtr.Zero);
|
||||
private static void WriteConsole(ConsoleHandle consoleHandle, ReadOnlySpan<char> buffer)
|
||||
{
|
||||
DWORD charsWritten;
|
||||
bool result =
|
||||
NativeMethods.WriteConsole(
|
||||
consoleHandle.DangerousGetHandle(),
|
||||
buffer,
|
||||
(DWORD)buffer.Length,
|
||||
out charsWritten,
|
||||
IntPtr.Zero);
|
||||
|
||||
if (result == false)
|
||||
{
|
||||
int err = Marshal.GetLastWin32Error();
|
||||
if (result == false)
|
||||
{
|
||||
int err = Marshal.GetLastWin32Error();
|
||||
|
||||
HostException e = CreateHostException(err, "WriteConsole",
|
||||
ErrorCategory.WriteError, ConsoleControlStrings.WriteConsoleExceptionTemplate);
|
||||
throw e;
|
||||
}
|
||||
HostException e = CreateHostException(
|
||||
err,
|
||||
"WriteConsole",
|
||||
ErrorCategory.WriteError,
|
||||
ConsoleControlStrings.WriteConsoleExceptionTemplate);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3009,15 +3039,30 @@ namespace Microsoft.PowerShell
|
|||
|
||||
[DllImport(PinvokeDllNames.WriteConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool WriteConsole
|
||||
private static extern unsafe bool WriteConsole
|
||||
(
|
||||
NakedWin32Handle consoleOutput,
|
||||
string buffer,
|
||||
char* buffer,
|
||||
DWORD numberOfCharsToWrite,
|
||||
out DWORD numberOfCharsWritten,
|
||||
IntPtr reserved
|
||||
);
|
||||
|
||||
internal static unsafe bool WriteConsole
|
||||
(
|
||||
NakedWin32Handle consoleOutput,
|
||||
ReadOnlySpan<char> buffer,
|
||||
DWORD numberOfCharsToWrite,
|
||||
out DWORD numberOfCharsWritten,
|
||||
IntPtr reserved
|
||||
)
|
||||
{
|
||||
fixed (char* bufferPtr = &MemoryMarshal.GetReference(buffer))
|
||||
{
|
||||
return WriteConsole(consoleOutput, bufferPtr, numberOfCharsToWrite, out numberOfCharsWritten, reserved);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(PinvokeDllNames.GetConsoleTitleDllName, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern DWORD GetConsoleTitle(StringBuilder consoleTitle, DWORD size);
|
||||
|
||||
|
|
|
@ -705,9 +705,7 @@ namespace Microsoft.PowerShell
|
|||
|
||||
if ((options & ReadKeyOptions.NoEcho) == 0)
|
||||
{
|
||||
parent.WriteToConsole(
|
||||
keyInfo.Character.ToString(),
|
||||
true);
|
||||
parent.WriteToConsole(keyInfo.Character, transcribeResult: true);
|
||||
}
|
||||
|
||||
return keyInfo;
|
||||
|
|
|
@ -10,15 +10,9 @@ using Dbg = System.Management.Automation.Diagnostics;
|
|||
|
||||
namespace Microsoft.PowerShell
|
||||
{
|
||||
internal sealed partial
|
||||
class ConsoleHost
|
||||
:
|
||||
PSHost,
|
||||
IDisposable
|
||||
internal sealed partial class ConsoleHost : PSHost, IDisposable
|
||||
{
|
||||
internal
|
||||
bool
|
||||
IsTranscribing
|
||||
internal bool IsTranscribing
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -69,9 +63,7 @@ namespace Microsoft.PowerShell
|
|||
*/
|
||||
private string _transcriptFileName = string.Empty;
|
||||
|
||||
internal
|
||||
string
|
||||
StopTranscribing()
|
||||
internal string StopTranscribing()
|
||||
{
|
||||
lock (_transcriptionStateLock)
|
||||
{
|
||||
|
@ -106,15 +98,30 @@ namespace Microsoft.PowerShell
|
|||
}
|
||||
}
|
||||
|
||||
internal
|
||||
void
|
||||
WriteToTranscript(string text)
|
||||
internal void WriteToTranscript(ReadOnlySpan<char> text)
|
||||
{
|
||||
WriteToTranscript(text, newLine: false);
|
||||
}
|
||||
|
||||
internal void WriteLineToTranscript(ReadOnlySpan<char> text)
|
||||
{
|
||||
WriteToTranscript(text, newLine: true);
|
||||
}
|
||||
|
||||
internal void WriteToTranscript(ReadOnlySpan<char> text, bool newLine)
|
||||
{
|
||||
lock (_transcriptionStateLock)
|
||||
{
|
||||
if (_isTranscribing && _transcriptionWriter != null)
|
||||
{
|
||||
_transcriptionWriter.Write(text);
|
||||
if (newLine)
|
||||
{
|
||||
_transcriptionWriter.WriteLine(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
_transcriptionWriter.Write(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,18 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Text;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Host;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
#if !UNIX
|
||||
using ConsoleHandle = Microsoft.Win32.SafeHandles.SafeFileHandle;
|
||||
|
@ -268,7 +270,7 @@ namespace Microsoft.PowerShell
|
|||
#else
|
||||
// Ensure that we're in the proper line-input mode.
|
||||
|
||||
ConsoleControl.ConsoleModes desiredMode =
|
||||
const ConsoleControl.ConsoleModes DesiredMode =
|
||||
ConsoleControl.ConsoleModes.Extended |
|
||||
ConsoleControl.ConsoleModes.QuickEdit;
|
||||
|
||||
|
@ -278,13 +280,13 @@ namespace Microsoft.PowerShell
|
|||
bool shouldUnsetMouseInput = shouldUnsetMode(ConsoleControl.ConsoleModes.MouseInput, ref m);
|
||||
bool shouldUnsetProcessInput = shouldUnsetMode(ConsoleControl.ConsoleModes.ProcessedInput, ref m);
|
||||
|
||||
if ((m & desiredMode) != desiredMode ||
|
||||
if ((m & DesiredMode) != DesiredMode ||
|
||||
shouldUnsetMouseInput ||
|
||||
shouldUnsetEchoInput ||
|
||||
shouldUnsetLineInput ||
|
||||
shouldUnsetProcessInput)
|
||||
{
|
||||
m |= desiredMode;
|
||||
m |= DesiredMode;
|
||||
ConsoleControl.SetMode(handle, m);
|
||||
}
|
||||
else
|
||||
|
@ -542,23 +544,35 @@ namespace Microsoft.PowerShell
|
|||
|
||||
#region WriteToConsole
|
||||
|
||||
internal void WriteToConsole(string value, bool transcribeResult)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void WriteToConsole(char c, bool transcribeResult)
|
||||
{
|
||||
ReadOnlySpan<char> value = stackalloc char[1] { c };
|
||||
WriteToConsole(value, transcribeResult);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void WriteToConsole(ReadOnlySpan<char> value, bool transcribeResult)
|
||||
{
|
||||
WriteToConsole(value, transcribeResult, newLine: false);
|
||||
}
|
||||
|
||||
private void WriteToConsole(ReadOnlySpan<char> value, bool transcribeResult, bool newLine)
|
||||
{
|
||||
#if !UNIX
|
||||
ConsoleHandle handle = ConsoleControl.GetActiveScreenBufferHandle();
|
||||
|
||||
// Ensure that we're in the proper line-output mode. We don't lock here as it does not matter if we
|
||||
// attempt to set the mode from multiple threads at once.
|
||||
|
||||
ConsoleControl.ConsoleModes m = ConsoleControl.GetMode(handle);
|
||||
|
||||
const ConsoleControl.ConsoleModes desiredMode =
|
||||
ConsoleControl.ConsoleModes.ProcessedOutput
|
||||
const ConsoleControl.ConsoleModes DesiredMode =
|
||||
ConsoleControl.ConsoleModes.ProcessedOutput
|
||||
| ConsoleControl.ConsoleModes.WrapEndOfLine;
|
||||
|
||||
if ((m & desiredMode) != desiredMode)
|
||||
if ((m & DesiredMode) != DesiredMode)
|
||||
{
|
||||
m |= desiredMode;
|
||||
m |= DesiredMode;
|
||||
ConsoleControl.SetMode(handle, m);
|
||||
}
|
||||
#endif
|
||||
|
@ -566,21 +580,20 @@ namespace Microsoft.PowerShell
|
|||
PreWrite();
|
||||
|
||||
// This is atomic, so we don't lock here...
|
||||
|
||||
#if !UNIX
|
||||
ConsoleControl.WriteConsole(handle, value);
|
||||
ConsoleControl.WriteConsole(handle, value, newLine);
|
||||
#else
|
||||
Console.Out.Write(value);
|
||||
ConsoleOutWriteHelper(value, newLine);
|
||||
#endif
|
||||
|
||||
if (_isInteractiveTestToolListening && Console.IsOutputRedirected)
|
||||
{
|
||||
Console.Out.Write(value);
|
||||
ConsoleOutWriteHelper(value, newLine);
|
||||
}
|
||||
|
||||
if (transcribeResult)
|
||||
{
|
||||
PostWrite(value);
|
||||
PostWrite(value, newLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -588,34 +601,64 @@ namespace Microsoft.PowerShell
|
|||
}
|
||||
}
|
||||
|
||||
private void WriteToConsole(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string text)
|
||||
private void WriteToConsole(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string text, bool newLine = false)
|
||||
{
|
||||
ConsoleColor fg = RawUI.ForegroundColor;
|
||||
ConsoleColor bg = RawUI.BackgroundColor;
|
||||
|
||||
RawUI.ForegroundColor = foregroundColor;
|
||||
RawUI.BackgroundColor = backgroundColor;
|
||||
|
||||
try
|
||||
// Sync access so that we don't race on color settings if called from multiple threads.
|
||||
lock (_instanceLock)
|
||||
{
|
||||
WriteToConsole(text, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RawUI.ForegroundColor = fg;
|
||||
RawUI.BackgroundColor = bg;
|
||||
ConsoleColor fg = RawUI.ForegroundColor;
|
||||
ConsoleColor bg = RawUI.BackgroundColor;
|
||||
|
||||
RawUI.ForegroundColor = foregroundColor;
|
||||
RawUI.BackgroundColor = backgroundColor;
|
||||
|
||||
try
|
||||
{
|
||||
WriteToConsole(text, transcribeResult: true, newLine);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RawUI.ForegroundColor = fg;
|
||||
RawUI.BackgroundColor = bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ConsoleOutWriteHelper(ReadOnlySpan<char> value, bool newLine)
|
||||
{
|
||||
if (newLine)
|
||||
{
|
||||
Console.Out.WriteLine(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Out.Write(value);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void WriteLineToConsole(ReadOnlySpan<char> value, bool transcribeResult)
|
||||
{
|
||||
WriteToConsole(value, transcribeResult, newLine: true);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteLineToConsole(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string text)
|
||||
{
|
||||
WriteToConsole(foregroundColor, backgroundColor, text, newLine: true);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteLineToConsole(string text)
|
||||
{
|
||||
WriteToConsole(text, true);
|
||||
WriteToConsole(Crlf, true);
|
||||
WriteLineToConsole(text, transcribeResult: true);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteLineToConsole()
|
||||
{
|
||||
WriteToConsole(Crlf, true);
|
||||
WriteToConsole(Environment.NewLine, transcribeResult: true, newLine: false);
|
||||
}
|
||||
|
||||
#endregion WriteToConsole
|
||||
|
@ -636,15 +679,28 @@ namespace Microsoft.PowerShell
|
|||
|
||||
public override void Write(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
// do nothing
|
||||
WriteImpl(value, newLine: false);
|
||||
}
|
||||
|
||||
private void WriteImpl(string value, bool newLine)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) && !newLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the test hook is set, write to it and continue.
|
||||
if (s_h != null) s_h.Write(value);
|
||||
if (s_h != null)
|
||||
{
|
||||
if (newLine)
|
||||
{
|
||||
s_h.WriteLine(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_h.Write(value);
|
||||
}
|
||||
}
|
||||
|
||||
TextWriter writer = Console.IsOutputRedirected ? Console.Out : _parent.ConsoleTextWriter;
|
||||
|
||||
|
@ -653,10 +709,22 @@ namespace Microsoft.PowerShell
|
|||
Dbg.Assert(writer == _parent.OutputSerializer.textWriter, "writers should be the same");
|
||||
|
||||
_parent.OutputSerializer.Serialize(value);
|
||||
|
||||
if (newLine)
|
||||
{
|
||||
_parent.OutputSerializer.Serialize(Crlf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(value);
|
||||
if (newLine)
|
||||
{
|
||||
writer.WriteLine(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,8 +750,36 @@ namespace Microsoft.PowerShell
|
|||
|
||||
public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
|
||||
{
|
||||
// Sync access so that we don't race on color settings if called from multiple threads.
|
||||
Write(foregroundColor, backgroundColor, value, newLine: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class.
|
||||
/// </summary>
|
||||
/// <param name="foregroundColor"></param>
|
||||
/// <param name="backgroundColor"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="HostException">
|
||||
/// If obtaining information about the buffer failed
|
||||
/// OR
|
||||
/// Win32's SetConsoleTextAttribute
|
||||
/// OR
|
||||
/// Win32's CreateFile fails
|
||||
/// OR
|
||||
/// Win32's GetConsoleMode fails
|
||||
/// OR
|
||||
/// Win32's SetConsoleMode fails
|
||||
/// OR
|
||||
/// Win32's WriteConsole fails
|
||||
/// </exception>
|
||||
public override void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
|
||||
{
|
||||
Write(foregroundColor, backgroundColor, value, newLine: true);
|
||||
}
|
||||
|
||||
private void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value, bool newLine)
|
||||
{
|
||||
// Sync access so that we don't race on color settings if called from multiple threads.
|
||||
lock (_instanceLock)
|
||||
{
|
||||
ConsoleColor fg = RawUI.ForegroundColor;
|
||||
|
@ -694,7 +790,7 @@ namespace Microsoft.PowerShell
|
|||
|
||||
try
|
||||
{
|
||||
this.Write(value);
|
||||
this.WriteImpl(value, newLine);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -717,16 +813,26 @@ namespace Microsoft.PowerShell
|
|||
/// OR
|
||||
/// Win32's WriteConsole fails
|
||||
/// </exception>
|
||||
|
||||
public override void WriteLine(string value)
|
||||
{
|
||||
// lock here so that the newline is written atomically with the value
|
||||
this.WriteImpl(value, newLine: true);
|
||||
}
|
||||
|
||||
lock (_instanceLock)
|
||||
{
|
||||
this.Write(value);
|
||||
this.Write(Crlf);
|
||||
}
|
||||
/// <summary>
|
||||
/// See base class.
|
||||
/// </summary>
|
||||
/// <exception cref="HostException">
|
||||
/// Win32's CreateFile fails
|
||||
/// OR
|
||||
/// Win32's GetConsoleMode fails
|
||||
/// OR
|
||||
/// Win32's SetConsoleMode fails
|
||||
/// OR
|
||||
/// Win32's WriteConsole fails
|
||||
/// </exception>
|
||||
public override void WriteLine()
|
||||
{
|
||||
this.WriteImpl(Environment.NewLine, newLine: false);
|
||||
}
|
||||
|
||||
#region Word Wrapping
|
||||
|
@ -1227,8 +1333,6 @@ namespace Microsoft.PowerShell
|
|||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
// do nothing
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1351,7 @@ namespace Microsoft.PowerShell
|
|||
if (writer == _parent.ConsoleTextWriter)
|
||||
WriteLine(ErrorForegroundColor, ErrorBackgroundColor, value);
|
||||
else
|
||||
Console.Error.Write(value + Crlf);
|
||||
Console.Error.WriteLine(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1419,15 +1523,15 @@ namespace Microsoft.PowerShell
|
|||
ConsoleHandle handle = ConsoleControl.GetConioDeviceHandle();
|
||||
ConsoleControl.ConsoleModes m = ConsoleControl.GetMode(handle);
|
||||
|
||||
const ConsoleControl.ConsoleModes desiredMode =
|
||||
const ConsoleControl.ConsoleModes DesiredMode =
|
||||
ConsoleControl.ConsoleModes.LineInput
|
||||
| ConsoleControl.ConsoleModes.EchoInput
|
||||
| ConsoleControl.ConsoleModes.ProcessedInput;
|
||||
|
||||
if ((m & desiredMode) != desiredMode || (m & ConsoleControl.ConsoleModes.MouseInput) > 0)
|
||||
if ((m & DesiredMode) != DesiredMode || (m & ConsoleControl.ConsoleModes.MouseInput) > 0)
|
||||
{
|
||||
m &= ~ConsoleControl.ConsoleModes.MouseInput;
|
||||
m |= desiredMode;
|
||||
m |= DesiredMode;
|
||||
ConsoleControl.SetMode(handle, m);
|
||||
}
|
||||
#endif
|
||||
|
@ -1941,7 +2045,7 @@ namespace Microsoft.PowerShell
|
|||
{
|
||||
// Reads always terminate with the enter key, so add that.
|
||||
|
||||
_parent.WriteToTranscript(input + Crlf);
|
||||
_parent.WriteLineToTranscript(input);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace Microsoft.PowerShell
|
|||
|
||||
private
|
||||
void
|
||||
PostWrite(string value)
|
||||
PostWrite(ReadOnlySpan<char> value, bool newLine)
|
||||
{
|
||||
PostWrite();
|
||||
|
||||
|
@ -138,7 +138,7 @@ namespace Microsoft.PowerShell
|
|||
{
|
||||
try
|
||||
{
|
||||
_parent.WriteToTranscript(value);
|
||||
_parent.WriteToTranscript(value, newLine);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -178,7 +178,7 @@ namespace Microsoft.PowerShell
|
|||
try
|
||||
{
|
||||
// Reads always terminate with the enter key, so add that.
|
||||
_parent.WriteToTranscript(value + Crlf);
|
||||
_parent.WriteLineToTranscript(value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
|
@ -118,8 +118,7 @@ namespace Microsoft.PowerShell
|
|||
// Should be a skin lookup
|
||||
|
||||
WriteLineToConsole();
|
||||
WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
WriteLineToConsole();
|
||||
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
|
|
|
@ -70,8 +70,7 @@ namespace Microsoft.PowerShell
|
|||
// Should be a skin lookup
|
||||
|
||||
WriteLineToConsole();
|
||||
WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
WriteLineToConsole();
|
||||
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
|
@ -216,8 +215,7 @@ namespace Microsoft.PowerShell
|
|||
{
|
||||
// Should be a skin lookup
|
||||
WriteLineToConsole();
|
||||
WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
WriteLineToConsole();
|
||||
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
}
|
||||
// write message
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
|
|
|
@ -72,8 +72,7 @@ namespace Microsoft.PowerShell
|
|||
// Should be a skin lookup
|
||||
|
||||
WriteLineToConsole();
|
||||
WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
WriteLineToConsole();
|
||||
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
|
|
|
@ -39,38 +39,59 @@ namespace Microsoft.PowerShell
|
|||
void
|
||||
Write(string value)
|
||||
{
|
||||
_ui.WriteToConsole(value, true);
|
||||
_ui.WriteToConsole(value, transcribeResult: true);
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
Write(ReadOnlySpan<char> value)
|
||||
{
|
||||
_ui.WriteToConsole(value, transcribeResult: true);
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
WriteLine(string value)
|
||||
{
|
||||
this.Write(value + ConsoleHostUserInterface.Crlf);
|
||||
_ui.WriteLineToConsole(value, transcribeResult: true);
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
Write(Boolean b)
|
||||
WriteLine(ReadOnlySpan<char> value)
|
||||
{
|
||||
this.Write(b.ToString());
|
||||
_ui.WriteLineToConsole(value, transcribeResult: true);
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
Write(bool b)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
_ui.WriteToConsole(bool.TrueString, transcribeResult: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ui.WriteToConsole(bool.FalseString, transcribeResult: true);
|
||||
}
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
Write(char c)
|
||||
{
|
||||
this.Write(new String(c, 1));
|
||||
ReadOnlySpan<char> c1 = stackalloc char[1] { c };
|
||||
_ui.WriteToConsole(c1, transcribeResult: true);
|
||||
}
|
||||
|
||||
public override
|
||||
void
|
||||
Write(char[] a)
|
||||
{
|
||||
this.Write(new String(a));
|
||||
_ui.WriteToConsole(a, transcribeResult: true);
|
||||
}
|
||||
|
||||
private ConsoleHostUserInterface _ui;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue