Exemple #1
0
        /// <summary>
        /// Loads letter iamge from win32 font.
        /// </summary>
        /// <param name="cache">should the iamge be cached in tga, xml files.</param>
        /// <returns>loader letter information.</returns>
        protected internal override LetterInfo Load(bool cache)
        {
            LetterInfo result = null;

#if WINDOWS
            IntPtr bitmapHandle = IntPtr.Zero;
            byte[] textureData  = null;

            try
            {
                if (null == PlatformWindows.SelectFont(this.font.fontRenderingDisplayContext, this.font.fontHandle))
                {
                    throw new Exception();
                }

                TextMetric tm = new TextMetric();

                if (false == PlatformWindows.GetTextMetrics(this.font.fontRenderingDisplayContext, out tm))
                {
                    throw new Exception();
                }

                if (PlatformWindows.GDI_ERROR == PlatformWindows.SetTextAlign(this.font.fontRenderingDisplayContext, PlatformWindows.TA_LEFT | PlatformWindows.TA_TOP | PlatformWindows.TA_UPDATECP))
                {
                    throw new Exception();
                }

                ABC[] abc = new ABC[1];

                if (false == PlatformWindows.GetCharABCWidths(this.font.fontRenderingDisplayContext, (uint)this.character, (uint)this.character, abc))
                {
                    throw new Exception();
                }

                this.offsetX = abc[0].abcA;
                this.width   = (int)(abc[0].abcB + abc[0].abcC);

                BitmapInfo header = new BitmapInfo();
                header.bmiHeader.biSize = Marshal.SizeOf(header);

                GlyphMetrics metrics  = new GlyphMetrics();
                MAT2         identity = new MAT2();
                identity.eM12.value = 0;
                identity.eM21.value = 0;
                identity.eM11.value = 1;
                identity.eM22.value = 1;

                if (PlatformWindows.GDI_ERROR == PlatformWindows.GetGlyphOutline(this.font.fontRenderingDisplayContext, this.character, PlatformWindows.GGO_METRICS, out metrics, 0, IntPtr.Zero, ref identity))
                {
                    throw new Exception();
                }

                header.bmiHeader.biWidth  = metrics.gmBlackBoxX;
                header.bmiHeader.biHeight = -1 * metrics.gmBlackBoxY;

                header.bmiHeader.biPlanes      = 1;
                header.bmiHeader.biBitCount    = 32;
                header.bmiHeader.biCompression = 0;// BI_RGB;
                byte[] bitmapData = null;

                IntPtr bitmapDataPointer = IntPtr.Zero;

                bitmapHandle = PlatformWindows.CreateDIBSection(this.font.fontRenderingDisplayContext, ref header, /*DIB_RGB_COLORS*/ 0, out bitmapDataPointer, IntPtr.Zero, 0);

                if (IntPtr.Zero == bitmapHandle)
                {
                    int err = Marshal.GetLastWin32Error();

                    throw new Exception();
                }

                if (null == PlatformWindows.SelectObject(this.font.fontRenderingDisplayContext, bitmapHandle))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetBkColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0, 0, 0 }).ToInt32()))
                {
                    throw new Exception();
                }

                if (PlatformWindows.CLR_INVALID == PlatformWindows.SetTextColor(this.font.fontRenderingDisplayContext, new RGB(new byte[] { 0xff, 0xff, 0xff }).ToInt32()))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.OPAQUE))
                {
                    throw new Exception();
                }

                if (false == PlatformWindows.MoveToEx(this.font.fontRenderingDisplayContext, 0 - abc[0].abcA, -1 * (tm.tmAscent - metrics.gmptGlyphOrigin.y), IntPtr.Zero))
                {
                    throw new Exception();
                }

                this.offsetY = tm.tmAscent - metrics.gmptGlyphOrigin.y - tm.tmDescent - 1;

                String str  = "" + this.character;
                RECT   rect = new RECT();

                if (false == PlatformWindows.ExtTextOut(this.font.fontRenderingDisplayContext, 0, 0, (uint)0, ref rect, str, 1, null))
                {
                    throw new Exception();
                }

                if (0 == PlatformWindows.SetBkMode(this.font.fontRenderingDisplayContext, PlatformWindows.TRANSPARENT))
                {
                    throw new Exception();
                }

                int bitmapWidth   = header.bmiHeader.biWidth;
                int bitmapHeight  = -header.bmiHeader.biHeight;
                int textureWidth  = RoundToPowerOf2(bitmapWidth);
                int textureHeight = RoundToPowerOf2(bitmapHeight);

                bitmapData = new byte[bitmapWidth * bitmapHeight * 4];

                Marshal.Copy(bitmapDataPointer, bitmapData, 0, bitmapWidth * bitmapHeight * 4);

                textureData = new byte[4 * textureWidth * textureHeight];

                for (int j = 0; j < textureHeight; j++)
                {
                    for (int i = 0; i < textureWidth; i++)
                    {
                        textureData[4 * (i + j * textureWidth) + 0] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 1] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 2] = 0xff;
                        textureData[4 * (i + j * textureWidth) + 3] = (byte)((i >= bitmapWidth || j >= bitmapHeight) ? 0 : bitmapData[(i + bitmapWidth * j) * 4 + 2]);
                    }
                }

                if (true == cache)
                {
                    result               = new LetterInfo();
                    result.width         = bitmapWidth;
                    result.height        = bitmapHeight;
                    result.bytes         = textureData;
                    result.textureWidth  = textureWidth;
                    result.textureHeight = textureHeight;
                }
                else
                {
                    this.image = this.engine.CreateImage("Letter [" + this.character + "]", textureWidth, textureHeight, textureData);
//                    this.internalImage = true;
                }

                this.textureWidth  = textureWidth;
                this.textureHeight = textureHeight;
            }
            catch (Exception)
            {
                this.engine.DeleteImage(ref this.image);
            }

            if (null != bitmapHandle)
            {
                PlatformWindows.DeleteObject(bitmapHandle);
            }

            this.loaded = true;
#endif
            return(result);
        }
Exemple #2
0
        private void Initialize(Runspace runspace, EngineIntrinsics engineIntrinsics)
        {
            _engineIntrinsics = engineIntrinsics;
            _runspace         = runspace;

            if (!_delayedOneTimeInitCompleted)
            {
                DelayedOneTimeInitialize();
                _delayedOneTimeInitCompleted = true;
            }

            _buffer.Clear();
            _edits             = new List <EditItem>();
            _undoEditIndex     = 0;
            _editGroupStart    = -1;
            _current           = 0;
            _mark              = 0;
            _emphasisStart     = -1;
            _emphasisLength    = 0;
            _ast               = null;
            _tokens            = null;
            _parseErrors       = null;
            _inputAccepted     = false;
            _initialX          = _console.CursorLeft;
            _initialY          = _console.CursorTop;
            _initialForeground = _console.ForegroundColor;
            _initialBackground = _console.BackgroundColor;
            _previousRender    = _initialPrevRender;
            _previousRender.UpdateConsoleInfo(_console);
            _previousRender.initialY = _initialY;
            _statusIsErrorMessage    = false;

            _initialOutputEncoding = _console.OutputEncoding;
            _prediction.Reset();

            // Don't change the OutputEncoding if already UTF8, no console, or using raster font on Windows
            _skipOutputEncodingChange = _initialOutputEncoding == Encoding.UTF8 ||
                                        (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
                                         PlatformWindows.IsConsoleInput() &&
                                         PlatformWindows.IsUsingRasterFont());

            if (!_skipOutputEncodingChange)
            {
                _console.OutputEncoding = Encoding.UTF8;
            }

            _lastRenderTime = Stopwatch.StartNew();

            _killCommandCount            = 0;
            _yankCommandCount            = 0;
            _yankLastArgCommandCount     = 0;
            _tabCommandCount             = 0;
            _recallHistoryCommandCount   = 0;
            _anyHistoryCommandCount      = 0;
            _visualSelectionCommandCount = 0;
            _hashedHistory = null;

            if (_getNextHistoryIndex > 0)
            {
                _currentHistoryIndex = _getNextHistoryIndex;
                UpdateFromHistory(HistoryMoveCursor.ToEnd);
                _getNextHistoryIndex = 0;
                if (_searchHistoryCommandCount > 0)
                {
                    _searchHistoryPrefix = "";
                    if (Options.HistoryNoDuplicates)
                    {
                        _hashedHistory = new Dictionary <string, int>();
                    }
                }
            }
            else
            {
                _currentHistoryIndex       = _history.Count;
                _searchHistoryCommandCount = 0;
            }
            if (_previousHistoryItem != null)
            {
                _previousHistoryItem.ApproximateElapsedTime = DateTime.UtcNow - _previousHistoryItem.StartTime;
            }
        }
Exemple #3
0
        /// <summary>
        /// Entry point - called by custom PSHost implementations that require the
        /// ability to cancel ReadLine.
        /// </summary>
        /// <returns>The complete command line.</returns>
        public static string ReadLine(
            Runspace runspace,
            EngineIntrinsics engineIntrinsics,
            CancellationToken cancellationToken,
            bool?lastRunStatus)
        {
            var console = _singleton._console;

            if (Console.IsInputRedirected || Console.IsOutputRedirected)
            {
                // System.Console doesn't handle redirected input. It matches the behavior on Windows
                // by throwing an "InvalidOperationException".
                // Therefore, if either stdin or stdout is redirected, PSReadLine doesn't really work,
                // so throw and let PowerShell call Console.ReadLine or do whatever else it decides to do.
                //
                // Some CI environments redirect stdin/stdout, but that doesn't affect our test runs
                // because the console is mocked, so we can skip the exception.
                if (!IsRunningCI(console))
                {
                    throw new NotSupportedException();
                }
            }

            var oldControlCAsInput = false;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                PlatformWindows.Init(ref _singleton._charMap);
            }
            else
            {
                try
                {
                    oldControlCAsInput           = Console.TreatControlCAsInput;
                    Console.TreatControlCAsInput = true;
                }
                catch {}
            }

            if (lastRunStatus.HasValue)
            {
                _singleton.ReportExecutionStatus(lastRunStatus.Value);
            }

            bool firstTime = true;

            while (true)
            {
                try
                {
                    if (firstTime)
                    {
                        firstTime = false;
                        _singleton.Initialize(runspace, engineIntrinsics);
                    }

                    _singleton._cancelReadCancellationToken = cancellationToken;
                    return(_singleton.InputLoop());
                }
                catch (OperationCanceledException)
                {
                    // Console is either exiting or the cancellation of ReadLine has been requested
                    // by a custom PSHost implementation.
                    return("");
                }
                catch (ExitException)
                {
                    return("exit");
                }
                catch (CustomHandlerException e)
                {
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(
                        string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message));
                    console.ForegroundColor = oldColor;

                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                catch (Exception e)
                {
                    // If we're running tests, just throw.
                    if (_singleton._mockableMethods != _singleton)
                    {
                        throw;
                    }

                    while (e.InnerException != null)
                    {
                        e = e.InnerException;
                    }
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(PSReadLineResources.OopsAnErrorMessage1);
                    console.ForegroundColor = oldColor;
                    var sb = new StringBuilder();
                    for (int i = 0; i < _lastNKeys.Count; i++)
                    {
                        sb.Append(' ');
                        sb.Append(_lastNKeys[i].KeyStr);

                        if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) &&
                            "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase))
                        {
                            // Make it a little easier to see the keys
                            sb.Append('\n');
                        }
                    }

                    var psVersion    = PSObject.AsPSObject(engineIntrinsics.Host.Version).ToString();
                    var ourVersion   = typeof(PSConsoleReadLine).Assembly.GetCustomAttributes <AssemblyInformationalVersionAttribute>().First().InformationalVersion;
                    var osInfo       = RuntimeInformation.OSDescription;
                    var bufferWidth  = console.BufferWidth;
                    var bufferHeight = console.BufferHeight;

                    console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2,
                                                    ourVersion, psVersion, osInfo, bufferWidth, bufferHeight,
                                                    _lastNKeys.Count, sb, e));
                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                finally
                {
                    try
                    {
                        // If we are closing, restoring the old console settings isn't needed,
                        // and some operating systems, it can cause a hang.
                        if (!_singleton._closingWaitHandle.WaitOne(0))
                        {
                            console.OutputEncoding = _singleton._initialOutputEncoding;

                            bool IsValid(ConsoleColor color)
                            {
                                return(color >= ConsoleColor.Black && color <= ConsoleColor.White);
                            }

                            if (IsValid(_singleton._initialForeground))
                            {
                                console.ForegroundColor = _singleton._initialForeground;
                            }
                            if (IsValid(_singleton._initialBackground))
                            {
                                console.BackgroundColor = _singleton._initialBackground;
                            }
                            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                Console.TreatControlCAsInput = oldControlCAsInput;
                            }
                        }
                    }
                    catch { }

                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        PlatformWindows.Complete();
                    }
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Entry point - called from the PowerShell function PSConsoleHostReadLine
        /// after the prompt has been displayed.
        /// </summary>
        /// <returns>The complete command line.</returns>
        public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
        {
            var console = _singleton._console;

            var oldControlCAsInput = false;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                PlatformWindows.Init(ref _singleton._charMap);
            }
            else
            {
                if (Console.IsInputRedirected || Console.IsOutputRedirected)
                {
                    // System.Console doesn't handle redirected input. It matches the behavior on Windows
                    // by throwing an "InvalidOperationException".
                    // Therefore, if either stdin or stdout is redirected, PSReadLine doesn't really work,
                    // so throw and let PowerShell call Console.ReadLine or do whatever else it decides to do.
                    throw new NotSupportedException();
                }

                try
                {
                    oldControlCAsInput           = Console.TreatControlCAsInput;
                    Console.TreatControlCAsInput = true;
                }
                catch {}
            }

            bool firstTime = true;

            while (true)
            {
                try
                {
                    if (firstTime)
                    {
                        firstTime = false;
                        _singleton.Initialize(runspace, engineIntrinsics);
                    }

                    return(_singleton.InputLoop());
                }
                catch (OperationCanceledException)
                {
                    // Console is exiting - return value isn't too critical - null or 'exit' could work equally well.
                    return("");
                }
                catch (ExitException)
                {
                    return("exit");
                }
                catch (CustomHandlerException e)
                {
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(
                        string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message));
                    console.ForegroundColor = oldColor;

                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                catch (Exception e)
                {
                    // If we're running tests, just throw.
                    if (_singleton._mockableMethods != _singleton)
                    {
                        throw;
                    }

                    while (e.InnerException != null)
                    {
                        e = e.InnerException;
                    }
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(PSReadLineResources.OopsAnErrorMessage1);
                    console.ForegroundColor = oldColor;
                    var sb = new StringBuilder();
                    for (int i = 0; i < _lastNKeys.Count; i++)
                    {
                        sb.Append(' ');
                        sb.Append(_lastNKeys[i].ToGestureString());

                        if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) &&
                            "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase))
                        {
                            // Make it a little easier to see the keys
                            sb.Append('\n');
                        }
                    }

                    console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e));
                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                finally
                {
                    try
                    {
                        // If we are closing, restoring the old console settings isn't needed,
                        // and some operating systems, it can cause a hang.
                        if (!_singleton._closingWaitHandle.WaitOne(0))
                        {
                            console.OutputEncoding = _singleton._initialOutputEncoding;
                            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                Console.TreatControlCAsInput = oldControlCAsInput;
                            }
                        }
                    }
                    catch { }

                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        PlatformWindows.Complete();
                    }
                }
            }
        }
Exemple #5
0
        private void DelayedOneTimeInitialize()
        {
            // Delayed initialization is needed so that options can be set
            // after the constuctor but have an affect before the user starts
            // editing their first command line.  For example, if the user
            // specifies a custom history save file, we don't want to try reading
            // from the default one.

            var historyCountVar = _engineIntrinsics?.SessionState.PSVariable.Get("MaximumHistoryCount");

            if (historyCountVar?.Value is int historyCountValue)
            {
                _options.MaximumHistoryCount = historyCountValue;
            }

            if (_options.PromptText == null &&
                _engineIntrinsics?.InvokeCommand.GetCommand("prompt", CommandTypes.Function) is FunctionInfo promptCommand)
            {
                var promptIsPure = null ==
                                   promptCommand.ScriptBlock.Ast.Find(ast => ast is CommandAst ||
                                                                      ast is InvokeMemberExpressionAst,
                                                                      searchNestedScriptBlocks: true);
                if (promptIsPure)
                {
                    var    res             = promptCommand.ScriptBlock.InvokeReturnAsIs(Array.Empty <object>());
                    string evaluatedPrompt = res as string;
                    if (evaluatedPrompt == null && res is PSObject psobject)
                    {
                        evaluatedPrompt = psobject.BaseObject as string;
                    }
                    if (evaluatedPrompt != null)
                    {
                        int i;
                        for (i = evaluatedPrompt.Length - 1; i >= 0; i--)
                        {
                            if (!char.IsWhiteSpace(evaluatedPrompt[i]))
                            {
                                break;
                            }
                        }

                        if (i >= 0)
                        {
                            _options.PromptText = evaluatedPrompt.Substring(i);
                        }
                    }
                }
            }

            _historyFileMutex = new Mutex(false, GetHistorySaveFileMutexName());

            _history             = new HistoryQueue <HistoryItem>(Options.MaximumHistoryCount);
            _currentHistoryIndex = 0;

            bool readHistoryFile = true;

            try
            {
                if (_options.HistorySaveStyle == HistorySaveStyle.SaveNothing && Runspace.DefaultRunspace != null)
                {
                    using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace))
                    {
                        ps.AddCommand("Microsoft.PowerShell.Core\\Get-History");
                        foreach (var historyInfo in ps.Invoke <HistoryInfo>())
                        {
                            AddToHistory(historyInfo.CommandLine);
                        }
                        readHistoryFile = false;
                    }
                }
            }
            catch
            {
            }

            if (readHistoryFile)
            {
                ReadHistoryFile();
            }

            _killIndex = -1; // So first add indexes 0.
            _killRing  = new List <string>(Options.MaximumKillRingCount);

            _singleton._readKeyWaitHandle     = new AutoResetEvent(false);
            _singleton._keyReadWaitHandle     = new AutoResetEvent(false);
            _singleton._closingWaitHandle     = new ManualResetEvent(false);
            _singleton._requestKeyWaitHandles = new WaitHandle[] { _singleton._keyReadWaitHandle, _singleton._closingWaitHandle };
            _singleton._threadProcWaitHandles = new WaitHandle[] { _singleton._readKeyWaitHandle, _singleton._closingWaitHandle };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                PlatformWindows.OneTimeInit(_singleton);
            }

            // This is for a "being hosted in an alternate appdomain scenario" (the
            // DomainUnload event is not raised for the default appdomain). It allows us
            // to exit cleanly when the appdomain is unloaded but the process is not going
            // away.
            if (!AppDomain.CurrentDomain.IsDefaultAppDomain())
            {
                AppDomain.CurrentDomain.DomainUnload += (x, y) =>
                {
                    _singleton._closingWaitHandle.Set();
                    _singleton._readKeyThread.Join(); // may need to wait for history to be written
                };
            }

            _singleton._readKeyThread = new Thread(_singleton.ReadKeyThreadProc)
            {
                IsBackground = true
            };
            _singleton._readKeyThread.Start();
        }
Exemple #6
0
        /// <summary>
        /// Entry point - called from the PowerShell function PSConsoleHostReadline
        /// after the prompt has been displayed.
        /// </summary>
        /// <returns>The complete command line.</returns>
        public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
        {
            var console = _singleton._console;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                PlatformWindows.Init(ref _singleton._charMap);
            }

            bool firstTime = true;

            while (true)
            {
                try
                {
                    if (firstTime)
                    {
                        firstTime = false;
                        _singleton.Initialize(runspace, engineIntrinsics);
                    }

                    return(_singleton.InputLoop());
                }
                catch (OperationCanceledException)
                {
                    // Console is exiting - return value isn't too critical - null or 'exit' could work equally well.
                    return("");
                }
                catch (ExitException)
                {
                    return("exit");
                }
                catch (CustomHandlerException e)
                {
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(
                        string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message));
                    console.ForegroundColor = oldColor;

                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                catch (Exception e)
                {
                    // If we're running tests, just throw.
                    if (_singleton._mockableMethods != _singleton)
                    {
                        throw;
                    }

                    while (e.InnerException != null)
                    {
                        e = e.InnerException;
                    }
                    var oldColor = console.ForegroundColor;
                    console.ForegroundColor = ConsoleColor.Red;
                    console.WriteLine(PSReadLineResources.OopsAnErrorMessage1);
                    console.ForegroundColor = oldColor;
                    var sb = new StringBuilder();
                    for (int i = 0; i < _lastNKeys.Count; i++)
                    {
                        sb.Append(' ');
                        sb.Append(_lastNKeys[i].ToGestureString());

                        if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) &&
                            "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase))
                        {
                            // Make it a little easier to see the keys
                            sb.Append('\n');
                        }
                    }

                    console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e));
                    var lineBeforeCrash = _singleton._buffer.ToString();
                    _singleton.Initialize(runspace, _singleton._engineIntrinsics);
                    InvokePrompt();
                    Insert(lineBeforeCrash);
                }
                finally
                {
                    Console.OutputEncoding = _singleton._initialOutputEncoding;
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        PlatformWindows.Complete();
                    }
                }
            }
        }