Exemple #1
0
 private static void WriteBlankLines(int count, int top)
 {
     var blanks = new CHAR_INFO[count * Console.BufferWidth];
     for (int i = 0; i < blanks.Length; i++)
     {
         blanks[i].BackgroundColor = Console.BackgroundColor;
         blanks[i].ForegroundColor = Console.ForegroundColor;
         blanks[i].UnicodeChar = ' ';
     }
     WriteBufferLines(blanks, ref top);
 }
Exemple #2
0
 /// <summary>
 /// Turn on demo mode (display events like keys pressed)
 /// </summary>
 public static void EnableDemoMode(ConsoleKeyInfo? key = null, object arg = null)
 {
     const int windowLineCount = 4;  // 1 blank line, 2 border lines, 1 line of info
     _singleton._captureKeys = true;
     _singleton._demoMode = true;
     _singleton._demoWindowLineCount = windowLineCount;
     var newBuffer = new CHAR_INFO[_singleton._consoleBuffer.Length + (windowLineCount * _singleton._bufferWidth)];
     Array.Copy(_singleton._consoleBuffer, newBuffer,
         _singleton._initialX + (_singleton.Options.ExtraPromptLineCount * _singleton._bufferWidth));
     _singleton._consoleBuffer = newBuffer;
     _singleton.Render();
 }
Exemple #3
0
 /// <summary>
 /// Turn on demo mode (display events like keys pressed)
 /// </summary>
 public static void EnableDemoMode(ConsoleKeyInfo? key = null, object arg = null)
 {
     const int windowLineCount = 4;  // 1 blank line, 2 border lines, 1 line of info
     _singleton._captureKeys = true;
     _singleton._demoMode = true;
     _singleton._demoWindowLineCount = windowLineCount;
     var newBuffer = new CHAR_INFO[_singleton._consoleBuffer.Length + (windowLineCount * _singleton._bufferWidth)];
     Array.Copy(_singleton._consoleBuffer, newBuffer,
         _singleton._initialX + (_singleton.Options.ExtraPromptLineCount * _singleton._bufferWidth));
     _singleton._consoleBuffer = newBuffer;
     _singleton.Render();
 }
Exemple #4
0
        private static void ScrollBuffer(int lines)
        {
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            var scrollRectangle = new SMALL_RECT
            {
                Top = (short) lines,
                Left = 0,
                Bottom = (short) (Console.BufferHeight - 1),
                Right = (short)Console.BufferWidth
            };
            var destinationOrigin = new COORD {X = 0, Y = 0};
            var fillChar = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor);
            NativeMethods.ScrollConsoleScreenBuffer(handle, ref scrollRectangle, IntPtr.Zero, destinationOrigin, ref fillChar);
        }
Exemple #5
0
        private void ClearDemoWindow()
        {
            int bufferWidth = Console.BufferWidth;
            var charInfoBuffer = new CHAR_INFO[bufferWidth * 3];

            for (int i = 0; i < charInfoBuffer.Length; i++)
            {
                charInfoBuffer[i].UnicodeChar = ' ';
                charInfoBuffer[i].ForegroundColor = _initialForegroundColor;
                charInfoBuffer[i].BackgroundColor= _initialBackgroundColor;
            }

            int bufferLineCount = ConvertOffsetToCoordinates(_buffer.Length).Y - _initialY + 1;
            int y = _initialY + bufferLineCount + 1;
            WriteBufferLines(charInfoBuffer, ref y);
        }
Exemple #6
0
        private void InteractiveHistorySearch(int direction)
        {
            SaveCurrentLine();

            // Add a status line that will contain the search prompt and string
            _statusLinePrompt = direction > 0 ? _forwardISearchPrompt : _backwardISearchPrompt;
            _statusBuffer.Append("_");

            Render(); // Render prompt
            InteractiveHistorySearchLoop(direction);

            // Remove our status line
            _statusBuffer.Clear();
            _statusLinePrompt = null;
            _emphasisStart    = -1;
            _emphasisLength   = 0;

#if FALSE
            int promptStart = _bufferWidth * Options.ExtraPromptLineCount;
            int promptWidth = _initialX;

            // Copy the prompt (ignoring the possible extra lines which we'll leave alone)
            var savedPrompt = new CHAR_INFO[promptWidth];
            Array.Copy(_consoleBuffer, promptStart, savedPrompt, 0, promptWidth);

            string newPrompt = "(reverse-i-search)`': ";
            _initialX = newPrompt.Length;
            int i, j;
            for (i = promptStart, j = 0; j < newPrompt.Length; i++, j++)
            {
                _consoleBuffer[i].UnicodeChar     = newPrompt[j];
                _consoleBuffer[i].BackgroundColor = Console.BackgroundColor;
                _consoleBuffer[i].ForegroundColor = Console.ForegroundColor;
            }

            InteractiveHistorySearchLoop(direction);

            // Restore the original prompt
            _initialX = promptWidth;
            Array.Copy(savedPrompt, 0, _consoleBuffer, promptStart, savedPrompt.Length);
#endif

            Render();
        }
Exemple #7
0
        private static CHAR_INFO[] ReadBufferLines(int top, int count)
        {
            var result = new CHAR_INFO[Console.BufferWidth * count];
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            var readBufferSize = new COORD {
                X = (short)Console.BufferWidth,
                Y = (short)count};
            var readBufferCoord = new COORD {X = 0, Y = 0};
            var readRegion = new SMALL_RECT
            {
                Top = (short)top,
                Left = 0,
                Bottom = (short)(top + count),
                Right = (short)(Console.BufferWidth - 1)
            };
            NativeMethods.ReadConsoleOutput(handle, result,
                readBufferSize, readBufferCoord, ref readRegion);
            return result;
        }
Exemple #8
0
        private void MaybeEmphasize(ref CHAR_INFO charInfo, int i, ConsoleColor foregroundColor, ConsoleColor backgroundColor)
        {
            if (i >= _emphasisStart && i < (_emphasisStart + _emphasisLength))
            {
                backgroundColor = _options.EmphasisBackgroundColor;
                foregroundColor = _options.EmphasisForegroundColor;
            }
            else if (_visualSelectionCommandCount > 0 && InRegion(i))
            {
                // We can't quite emulate real console selection because it inverts
                // based on actual screen colors, our pallete is limited.  The choice
                // to invert only the lower 3 bits to change the color is somewhat
                // but looks best with the 2 default color schemes - starting PowerShell
                // from it's shortcut or from a cmd shortcut.
                foregroundColor = (ConsoleColor)((int)foregroundColor ^ 7);
                backgroundColor = (ConsoleColor)((int)backgroundColor ^ 7);
            }

            charInfo.ForegroundColor = foregroundColor;
            charInfo.BackgroundColor = backgroundColor;
        }
Exemple #9
0
        private void Initialize()
        {
            _buffer.Clear();
            _edits          = new List <EditItem>();
            _undoEditIndex  = 0;
            _editGroupCount = 0;
            _pushedEditGroupCount.Clear();
            _current                     = 0;
            _mark                        = 0;
            _emphasisStart               = -1;
            _emphasisLength              = 0;
            _tokens                      = null;
            _parseErrors                 = null;
            _inputAccepted               = false;
            _initialX                    = Console.CursorLeft;
            _initialY                    = Console.CursorTop - Options.ExtraPromptLineCount;
            _initialBackgroundColor      = Console.BackgroundColor;
            _initialForegroundColor      = Console.ForegroundColor;
            _space                       = new CHAR_INFO(' ', _initialForegroundColor, _initialBackgroundColor);
            _bufferWidth                 = Console.BufferWidth;
            _killCommandCount            = 0;
            _yankCommandCount            = 0;
            _yankLastArgCommandCount     = 0;
            _tabCommandCount             = 0;
            _visualSelectionCommandCount = 0;

            _consoleBuffer  = ReadBufferLines(_initialY, 1 + Options.ExtraPromptLineCount);
            _lastRenderTime = Stopwatch.StartNew();

            if (_getNextHistoryIndex > 0)
            {
                _currentHistoryIndex = _getNextHistoryIndex;
                UpdateFromHistory(moveCursor: true);
                _getNextHistoryIndex = 0;
            }
        }
Exemple #10
0
 public static extern bool ScrollConsoleScreenBuffer(IntPtr hConsoleOutput,
     ref SMALL_RECT lpScrollRectangle,
     ref SMALL_RECT lpClipRectangle,
     COORD dwDestinationOrigin,
     ref CHAR_INFO lpFill);
Exemple #11
0
 public static extern bool WriteConsoleOutput(IntPtr consoleOutput, CHAR_INFO[] buffer, COORD bufferSize, COORD bufferCoord, ref SMALL_RECT writeRegion);
Exemple #12
0
 private static void InvertSelectedCompletion(CHAR_INFO[] buffer, int selectedItem, int menuColumnWidth, int menuRows)
 {
     var selectedX = selectedItem / menuRows;
     var selectedY = selectedItem - (selectedX * menuRows);
     var start = selectedY * Console.BufferWidth + selectedX * menuColumnWidth;
     for (int i = 0; i < menuColumnWidth; i++)
     {
         int j = i + start;
         buffer[j].ForegroundColor = (ConsoleColor)((int)buffer[j].ForegroundColor ^ 7);
         buffer[j].BackgroundColor = (ConsoleColor)((int)buffer[j].BackgroundColor ^ 7);
     }
 }
Exemple #13
0
        private void ReallyRender()
        {
            _renderForDemoNeeded = false;

            var text = ParseInput();

            int statusLineCount = GetStatusLineCount();
            int bufferLineCount = ConvertOffsetToCoordinates(text.Length).Y - _initialY + 1 + _demoWindowLineCount + statusLineCount;
            int bufferWidth     = Console.BufferWidth;

            if (_consoleBuffer.Length != bufferLineCount * bufferWidth)
            {
                var newBuffer = new CHAR_INFO[bufferLineCount * bufferWidth];
                Array.Copy(_consoleBuffer, newBuffer, _initialX + (Options.ExtraPromptLineCount * _bufferWidth));
                if (_consoleBuffer.Length > bufferLineCount * bufferWidth)
                {
                    // Need to erase the extra lines that we won't draw again
                    for (int i = bufferLineCount * bufferWidth; i < _consoleBuffer.Length; i++)
                    {
                        _consoleBuffer[i] = _space;
                    }
                    WriteBufferLines(_consoleBuffer, ref _initialY);
                }
                _consoleBuffer = newBuffer;
            }

            var tokenStack = new Stack <SavedTokenState>();

            tokenStack.Push(new SavedTokenState
            {
                Tokens          = _tokens,
                Index           = 0,
                BackgroundColor = _initialBackgroundColor,
                ForegroundColor = _initialForegroundColor
            });

            int j = _initialX + (_bufferWidth * Options.ExtraPromptLineCount);
            var backgroundColor = _initialBackgroundColor;
            var foregroundColor = _initialForegroundColor;

            for (int i = 0; i < text.Length; i++)
            {
                // Figure out the color of the character - if it's in a token,
                // use the tokens color otherwise use the initial color.
                var state = tokenStack.Peek();
                var token = state.Tokens[state.Index];
                if (i == token.Extent.EndOffset)
                {
                    if (token == state.Tokens[state.Tokens.Length - 1])
                    {
                        tokenStack.Pop();
                        state = tokenStack.Peek();
                    }
                    foregroundColor = state.ForegroundColor;
                    backgroundColor = state.BackgroundColor;

                    token = state.Tokens[++state.Index];
                }

                if (i == token.Extent.StartOffset)
                {
                    GetTokenColors(token, out foregroundColor, out backgroundColor);

                    var stringToken = token as StringExpandableToken;
                    if (stringToken != null)
                    {
                        // We might have nested tokens.
                        if (stringToken.NestedTokens != null && stringToken.NestedTokens.Any())
                        {
                            var tokens = new Token[stringToken.NestedTokens.Count + 1];
                            stringToken.NestedTokens.CopyTo(tokens, 0);
                            // NestedTokens doesn't have an "EOS" token, so we use
                            // the string literal token for that purpose.
                            tokens[tokens.Length - 1] = stringToken;

                            tokenStack.Push(new SavedTokenState
                            {
                                Tokens          = tokens,
                                Index           = 0,
                                BackgroundColor = backgroundColor,
                                ForegroundColor = foregroundColor
                            });
                        }
                    }
                }

                if (text[i] == '\n')
                {
                    while ((j % bufferWidth) != 0)
                    {
                        _consoleBuffer[j++] = _space;
                    }

                    for (int k = 0; k < Options.ContinuationPrompt.Length; k++, j++)
                    {
                        _consoleBuffer[j].UnicodeChar     = Options.ContinuationPrompt[k];
                        _consoleBuffer[j].ForegroundColor = Options.ContinuationPromptForegroundColor;
                        _consoleBuffer[j].BackgroundColor = Options.ContinuationPromptBackgroundColor;
                    }
                }
                else if (char.IsControl(text[i]))
                {
                    _consoleBuffer[j].UnicodeChar = '^';
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                    _consoleBuffer[j].UnicodeChar = (char)('@' + text[i]);
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                }
                else
                {
                    _consoleBuffer[j].UnicodeChar = text[i];
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                }
            }

            for (; j < (_consoleBuffer.Length - ((statusLineCount + _demoWindowLineCount) * _bufferWidth)); j++)
            {
                _consoleBuffer[j] = _space;
            }

            if (_statusLinePrompt != null)
            {
                for (int i = 0; i < _statusLinePrompt.Length; i++, j++)
                {
                    _consoleBuffer[j].UnicodeChar     = _statusLinePrompt[i];
                    _consoleBuffer[j].ForegroundColor = Console.ForegroundColor;
                    _consoleBuffer[j].BackgroundColor = Console.BackgroundColor;
                }
                for (int i = 0; i < _statusBuffer.Length; i++, j++)
                {
                    _consoleBuffer[j].UnicodeChar     = _statusBuffer[i];
                    _consoleBuffer[j].ForegroundColor = Console.ForegroundColor;
                    _consoleBuffer[j].BackgroundColor = Console.BackgroundColor;
                }

                for (; j < (_consoleBuffer.Length - (_demoWindowLineCount * _bufferWidth)); j++)
                {
                    _consoleBuffer[j] = _space;
                }
            }

            if (_demoMode)
            {
                RenderDemoWindow(j);
            }

            bool rendered = false;

            if (_parseErrors.Length > 0)
            {
                int promptChar = _initialX - 1 + (_bufferWidth * Options.ExtraPromptLineCount);

                while (promptChar >= 0)
                {
                    if (char.IsSymbol((char)_consoleBuffer[promptChar].UnicodeChar))
                    {
                        ConsoleColor prevColor = _consoleBuffer[promptChar].ForegroundColor;
                        _consoleBuffer[promptChar].ForegroundColor = ConsoleColor.Red;
                        WriteBufferLines(_consoleBuffer, ref _initialY);
                        rendered = true;
                        _consoleBuffer[promptChar].ForegroundColor = prevColor;
                        break;
                    }
                    promptChar -= 1;
                }
            }

            if (!rendered)
            {
                WriteBufferLines(_consoleBuffer, ref _initialY);
            }

            PlaceCursor();

            if ((_initialY + bufferLineCount + (_demoMode ? 1 : 0)) > (Console.WindowTop + Console.WindowHeight))
            {
                Console.WindowTop = _initialY + bufferLineCount + (_demoMode ? 1 : 0) - Console.WindowHeight;
            }

            _lastRenderTime.Restart();
        }
Exemple #14
0
 private static void WriteBlankLines(int count, int top)
 {
     var blanks = new CHAR_INFO[count * Console.BufferWidth];
     for (int i = 0; i < blanks.Length; i++)
     {
         blanks[i].BackgroundColor = Console.BackgroundColor;
         blanks[i].ForegroundColor = Console.ForegroundColor;
         blanks[i].UnicodeChar = ' ';
     }
     WriteBufferLines(blanks, ref top);
 }
Exemple #15
0
        private void Initialize(Runspace remoteRunspace)
        {
            _buffer.Clear();
            _edits = new List<EditItem>();
            _undoEditIndex = 0;
            _editGroupCount = 0;
            _pushedEditGroupCount.Clear();
            _current = 0;
            _mark = 0;
            _emphasisStart = -1;
            _emphasisLength = 0;
            _tokens = null;
            _parseErrors = null;
            _inputAccepted = false;
            _initialX = Console.CursorLeft;
            _initialY = Console.CursorTop - Options.ExtraPromptLineCount;
            _initialBackgroundColor = Console.BackgroundColor;
            _initialForegroundColor = Console.ForegroundColor;
            _space = new CHAR_INFO(' ', _initialForegroundColor, _initialBackgroundColor);
            _bufferWidth = Console.BufferWidth;
            _killCommandCount = 0;
            _yankCommandCount = 0;
            _yankLastArgCommandCount = 0;
            _tabCommandCount = 0;
            _visualSelectionCommandCount = 0;
            _remoteRunspace = remoteRunspace;

            _consoleBuffer = ReadBufferLines(_initialY, 1 + Options.ExtraPromptLineCount);
            _lastRenderTime = Stopwatch.StartNew();

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

            if (_getNextHistoryIndex > 0)
            {
                _currentHistoryIndex = _getNextHistoryIndex;
                UpdateFromHistory(moveCursor: true);
                _getNextHistoryIndex = 0;
            }
        }
Exemple #16
0
        private void MaybeEmphasize(ref CHAR_INFO charInfo, int i, ConsoleColor foregroundColor, ConsoleColor backgroundColor)
        {
            if (i >= _emphasisStart && i < (_emphasisStart + _emphasisLength))
            {
                backgroundColor = _options.EmphasisBackgroundColor;
                foregroundColor = _options.EmphasisForegroundColor;
            }
            else if (_visualSelectionCommandCount > 0 && InRegion(i))
            {
                // We can't quite emulate real console selection because it inverts
                // based on actual screen colors, our pallete is limited.  The choice
                // to invert only the lower 3 bits to change the color is somewhat
                // but looks best with the 2 default color schemes - starting PowerShell
                // from it's shortcut or from a cmd shortcut.
                foregroundColor = (ConsoleColor)((int)foregroundColor ^ 7);
                backgroundColor = (ConsoleColor)((int)backgroundColor ^ 7);
            }

            charInfo.ForegroundColor = foregroundColor;
            charInfo.BackgroundColor = backgroundColor;
        }
Exemple #17
0
        private void ReallyRender()
        {
            _renderForDemoNeeded = false;

            var text = ParseInput();

            int statusLineCount = GetStatusLineCount();
            int bufferLineCount = ConvertOffsetToCoordinates(text.Length).Y - _initialY + 1 + _demoWindowLineCount + statusLineCount;
            int bufferWidth = Console.BufferWidth;
            if (_consoleBuffer.Length != bufferLineCount * bufferWidth)
            {
                var newBuffer = new CHAR_INFO[bufferLineCount * bufferWidth];
                Array.Copy(_consoleBuffer, newBuffer, _initialX + (Options.ExtraPromptLineCount * _bufferWidth));
                if (_consoleBuffer.Length > bufferLineCount * bufferWidth)
                {
                    // Need to erase the extra lines that we won't draw again
                    for (int i = bufferLineCount * bufferWidth; i < _consoleBuffer.Length; i++)
                    {
                        _consoleBuffer[i] = _space;
                    }
                    WriteBufferLines(_consoleBuffer, ref _initialY);
                }
                _consoleBuffer = newBuffer;
            }

            var tokenStack = new Stack<SavedTokenState>();
            tokenStack.Push(new SavedTokenState
            {
                Tokens          = _tokens,
                Index           = 0,
                BackgroundColor = _initialBackgroundColor,
                ForegroundColor = _initialForegroundColor
            });

            int j               = _initialX + (_bufferWidth * Options.ExtraPromptLineCount);
            var backgroundColor = _initialBackgroundColor;
            var foregroundColor = _initialForegroundColor;

            for (int i = 0; i < text.Length; i++)
            {
                // Figure out the color of the character - if it's in a token,
                // use the tokens color otherwise use the initial color.
                var state = tokenStack.Peek();
                var token = state.Tokens[state.Index];
                if (i == token.Extent.EndOffset)
                {
                    if (token == state.Tokens[state.Tokens.Length - 1])
                    {
                        tokenStack.Pop();
                        state = tokenStack.Peek();
                    }
                    foregroundColor = state.ForegroundColor;
                    backgroundColor = state.BackgroundColor;

                    token = state.Tokens[++state.Index];
                }

                if (i == token.Extent.StartOffset)
                {
                    GetTokenColors(token, out foregroundColor, out backgroundColor);

                    var stringToken = token as StringExpandableToken;
                    if (stringToken != null)
                    {
                        // We might have nested tokens.
                        if (stringToken.NestedTokens != null && stringToken.NestedTokens.Any())
                        {
                            var tokens = new Token[stringToken.NestedTokens.Count + 1];
                            stringToken.NestedTokens.CopyTo(tokens, 0);
                            // NestedTokens doesn't have an "EOS" token, so we use
                            // the string literal token for that purpose.
                            tokens[tokens.Length - 1] = stringToken;

                            tokenStack.Push(new SavedTokenState
                            {
                                Tokens          = tokens,
                                Index           = 0,
                                BackgroundColor = backgroundColor,
                                ForegroundColor = foregroundColor
                            });
                        }
                    }
                }

                if (text[i] == '\n')
                {
                    while ((j % bufferWidth) != 0)
                    {
                        _consoleBuffer[j++] = _space;
                    }

                    for (int k = 0; k < Options.ContinuationPrompt.Length; k++, j++)
                    {
                        _consoleBuffer[j].UnicodeChar = Options.ContinuationPrompt[k];
                        _consoleBuffer[j].ForegroundColor = Options.ContinuationPromptForegroundColor;
                        _consoleBuffer[j].BackgroundColor = Options.ContinuationPromptBackgroundColor;
                    }
                }
                else if (char.IsControl(text[i]))
                {
                    _consoleBuffer[j].UnicodeChar = '^';
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                    _consoleBuffer[j].UnicodeChar = (char)('@' + text[i]);
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                }
                else
                {
                    _consoleBuffer[j].UnicodeChar = text[i];
                    MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                }
            }

            for (; j < (_consoleBuffer.Length - ((statusLineCount + _demoWindowLineCount) * _bufferWidth)); j++)
            {
                _consoleBuffer[j] = _space;
            }

            if (_statusLinePrompt != null)
            {
                for (int i = 0; i < _statusLinePrompt.Length; i++, j++)
                {
                    _consoleBuffer[j].UnicodeChar = _statusLinePrompt[i];
                    _consoleBuffer[j].ForegroundColor = Console.ForegroundColor;
                    _consoleBuffer[j].BackgroundColor = Console.BackgroundColor;
                }
                for (int i = 0; i < _statusBuffer.Length; i++, j++)
                {
                    _consoleBuffer[j].UnicodeChar = _statusBuffer[i];
                    _consoleBuffer[j].ForegroundColor = Console.ForegroundColor;
                    _consoleBuffer[j].BackgroundColor = Console.BackgroundColor;
                }

                for (; j < (_consoleBuffer.Length - (_demoWindowLineCount * _bufferWidth)); j++)
                {
                    _consoleBuffer[j] = _space;
                }
            }

            if (_demoMode)
            {
                RenderDemoWindow(j);
            }

            bool rendered = false;
            if (_parseErrors.Length > 0)
            {
                int promptChar = _initialX - 1 + (_bufferWidth * Options.ExtraPromptLineCount);

                while (promptChar >= 0)
                {
                    if (char.IsSymbol((char)_consoleBuffer[promptChar].UnicodeChar))
                    {
                        ConsoleColor prevColor = _consoleBuffer[promptChar].ForegroundColor;
                        _consoleBuffer[promptChar].ForegroundColor = ConsoleColor.Red;
                        WriteBufferLines(_consoleBuffer, ref _initialY);
                        rendered = true;
                        _consoleBuffer[promptChar].ForegroundColor = prevColor;
                        break;
                    }
                    promptChar -= 1;
                }
            }

            if (!rendered)
            {
                WriteBufferLines(_consoleBuffer, ref _initialY);
            }

            PlaceCursor();

            if ((_initialY + bufferLineCount + (_demoMode ? 1 : 0)) > (Console.WindowTop + Console.WindowHeight))
            {
                Console.WindowTop = _initialY + bufferLineCount + (_demoMode ? 1 : 0) - Console.WindowHeight;
            }

            _lastRenderTime.Restart();
        }
Exemple #18
0
        private static void WriteBufferLines(CHAR_INFO[] buffer, ref int top)
        {
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            int bufferWidth = Console.BufferWidth;
            int bufferLineCount = buffer.Length / bufferWidth;
            if ((top + bufferLineCount) > Console.BufferHeight)
            {
                var scrollCount = (top + bufferLineCount) - Console.BufferHeight;
                ScrollBuffer(scrollCount);
                top -= scrollCount;
            }
            var bufferSize = new COORD
            {
                X = (short) bufferWidth,
                Y = (short) bufferLineCount
            };
            var bufferCoord = new COORD {X = 0, Y = 0};
            var writeRegion = new SMALL_RECT
            {
                Top = (short) top,
                Left = 0,
                Bottom = (short) (top + bufferLineCount - 1),
                Right = (short) bufferWidth
            };
            NativeMethods.WriteConsoleOutput(handle, buffer,
                                             bufferSize, bufferCoord, ref writeRegion);
        }
Exemple #19
0
 public static extern bool ScrollConsoleScreenBuffer(IntPtr hConsoleOutput,
                                                     ref SMALL_RECT lpScrollRectangle,
                                                     IntPtr lpClipRectangle,
                                                     COORD dwDestinationOrigin,
                                                     ref CHAR_INFO lpFill);
Exemple #20
0
        private static void ScrollBuffer(int lines)
        {
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            var scrollRectangle = new SMALL_RECT
            {
                Top = (short) lines,
                Left = 0,
                Bottom = (short) (lines + Console.BufferHeight - 1),
                Right = (short)Console.BufferWidth
            };
            var destinationOrigin = new COORD {X = 0, Y = 0};
            var fillChar = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor);
            NativeMethods.ScrollConsoleScreenBuffer(handle, ref scrollRectangle, IntPtr.Zero, destinationOrigin, ref fillChar);
        }
Exemple #21
0
        private void Initialize(Runspace remoteRunspace, EngineIntrinsics engineIntrinsics)
        {
            if (!_delayedOneTimeInitCompleted)
            {
                DelayedOneTimeInitialize();
                _delayedOneTimeInitCompleted = true;
            }

            _engineIntrinsics = engineIntrinsics;
            _buffer.Clear();
            _edits                       = new List <EditItem>();
            _undoEditIndex               = 0;
            _editGroupStart              = -1;
            _current                     = 0;
            _mark                        = 0;
            _emphasisStart               = -1;
            _emphasisLength              = 0;
            _tokens                      = null;
            _parseErrors                 = null;
            _inputAccepted               = false;
            _initialX                    = Console.CursorLeft;
            _initialY                    = Console.CursorTop - Options.ExtraPromptLineCount;
            _initialBackgroundColor      = Console.BackgroundColor;
            _initialForegroundColor      = Console.ForegroundColor;
            _space                       = new CHAR_INFO(' ', _initialForegroundColor, _initialBackgroundColor);
            _bufferWidth                 = Console.BufferWidth;
            _killCommandCount            = 0;
            _yankCommandCount            = 0;
            _yankLastArgCommandCount     = 0;
            _tabCommandCount             = 0;
            _visualSelectionCommandCount = 0;
            _remoteRunspace              = remoteRunspace;
            _statusIsErrorMessage        = false;

            _consoleBuffer  = ReadBufferLines(_initialY, 1 + Options.ExtraPromptLineCount);
            _lastRenderTime = Stopwatch.StartNew();

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

            if (_getNextHistoryIndex > 0)
            {
                _currentHistoryIndex = _getNextHistoryIndex;
                UpdateFromHistory(moveCursor: true);
                _getNextHistoryIndex = 0;
                if (_searchHistoryCommandCount > 0)
                {
                    _searchHistoryPrefix = "";
                    if (Options.HistoryNoDuplicates)
                    {
                        _hashedHistory = new Dictionary <string, int>();
                    }
                }
            }
            else
            {
                _searchHistoryCommandCount = 0;
            }
        }
Exemple #22
0
        private static void WriteBufferLines(CHAR_INFO[] buffer, ref int top)
        {
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            int bufferWidth = Console.BufferWidth;
            int bufferLineCount = buffer.Length / bufferWidth;
            if ((top + bufferLineCount) > Console.BufferHeight)
            {
                var scrollCount = (top + bufferLineCount) - Console.BufferHeight;
                ScrollBuffer(scrollCount);
                top -= scrollCount;
            }
            var bufferSize = new COORD
            {
                X = (short) bufferWidth,
                Y = (short) bufferLineCount
            };
            var bufferCoord = new COORD {X = 0, Y = 0};
            var bottom = top + bufferLineCount - 1;
            var writeRegion = new SMALL_RECT
            {
                Top = (short) top,
                Left = 0,
                Bottom = (short) bottom,
                Right = (short) (bufferWidth - 1)
            };
            NativeMethods.WriteConsoleOutput(handle, buffer,
                                             bufferSize, bufferCoord, ref writeRegion);

            // Now make sure the bottom line is visible
            if (bottom >= (Console.WindowTop + Console.WindowHeight))
            {
                Console.CursorTop = bottom;
            }
        }
Exemple #23
0
        static void Box(List<string> list)
        {
            int internalBoxWidth = Math.Min(Console.BufferWidth - 2, list.Max(e => e.Length));
            int boxWidth = internalBoxWidth + 2;
            int internalBoxHeight = list.Count;
            int boxHeight = internalBoxHeight + 2;

            var buffer = new CHAR_INFO[boxWidth * boxHeight];
            buffer[0].UnicodeChar = '+';
            buffer[boxWidth - 1].UnicodeChar = '+';
            for (int i = 1; i < boxWidth - 1; i++)
            {
                buffer[i].UnicodeChar = '-';
            }
            for (int i = 0; i < list.Count; i++)
            {
                int rowStart = (i + 1) * boxWidth;
                buffer[rowStart++].UnicodeChar = '|';
                buffer[rowStart + internalBoxWidth].UnicodeChar = '|';

                string s = list[i];
                int j;
                for (j = 0; j < s.Length; j++)
                {
                    buffer[rowStart + j].UnicodeChar = s[j];
                }
                for (; j < internalBoxWidth; j++)
                {
                    buffer[rowStart + j].UnicodeChar = ' ';
                }
            }
            int lastRowStart = (boxHeight - 1) * boxWidth;
            buffer[lastRowStart].UnicodeChar = '+';
            for (int i = 1; i < boxWidth - 1; i++)
            {
                buffer[i + lastRowStart].UnicodeChar = '-';
            }
            buffer[lastRowStart + boxWidth - 1].UnicodeChar = '+';

            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i].Attributes = (ushort)ConsoleColor.Blue |
                    ((ushort)(ConsoleColor.DarkGreen) << 4);
                if (i % 2 != 0)
                {
                    buffer[i].Attributes |= 0xfff0;
                }
            }

            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);
            var bufferSize = new COORD {X = (short)boxWidth, Y = (short)boxHeight};
            var bufferCoord = new COORD {X = 0, Y = 0};
            var writeRegion = new SMALL_RECT {
                Top = 1,
                Left = 1,
                Bottom = (short)(1 + boxHeight),
                Right = (short)(1 + boxWidth)};

            Console.WriteLine("some random stuff");
            Console.WriteLine("and more some random stuff");
            Console.WriteLine("lorem ipsum blah blah");
            Console.ReadKey();
            var saveBuffer = new CHAR_INFO[buffer.Length];
            NativeMethods.ReadConsoleOutput(handle, saveBuffer,
                bufferSize, bufferCoord, ref writeRegion);
            unsafe
            {
                fixed (CHAR_INFO* p = &buffer[0])
                fixed (CHAR_INFO* sp = &saveBuffer[0])
                {
                    NativeMethods.WriteConsoleOutput(handle, buffer,
                                                                bufferSize, bufferCoord, ref writeRegion);
                    Console.ReadKey();
                    NativeMethods.WriteConsoleOutput(handle, saveBuffer,
                                                                bufferSize, bufferCoord, ref writeRegion);
                }
            }
            Console.ReadKey();
        }
Exemple #24
0
        private void InteractiveHistorySearch(int direction)
        {
            SaveCurrentLine();

            // Add a status line that will contain the search prompt and string
            _statusLinePrompt = direction > 0 ? _forwardISearchPrompt : _backwardISearchPrompt;
            _statusBuffer.Append("_");

            Render(); // Render prompt
            InteractiveHistorySearchLoop(direction);

            _hashedHistory = null;

            // Remove our status line
            _statusBuffer.Clear();
            _statusLinePrompt = null;
            _emphasisStart = -1;
            _emphasisLength = 0;

            #if FALSE
            int promptStart = _bufferWidth * Options.ExtraPromptLineCount;
            int promptWidth = _initialX;

            // Copy the prompt (ignoring the possible extra lines which we'll leave alone)
            var savedPrompt = new CHAR_INFO[promptWidth];
            Array.Copy(_consoleBuffer, promptStart, savedPrompt, 0, promptWidth);

            string newPrompt = "(reverse-i-search)`': ";
            _initialX = newPrompt.Length;
            int i, j;
            for (i = promptStart, j = 0; j < newPrompt.Length; i++, j++)
            {
                _consoleBuffer[i].UnicodeChar = newPrompt[j];
                _consoleBuffer[i].BackgroundColor = Console.BackgroundColor;
                _consoleBuffer[i].ForegroundColor = Console.ForegroundColor;
            }

            InteractiveHistorySearchLoop(direction);

            // Restore the original prompt
            _initialX = promptWidth;
            Array.Copy(savedPrompt, 0, _consoleBuffer, promptStart, savedPrompt.Length);
            #endif

            Render();
        }
Exemple #25
0
        private static CHAR_INFO[] ReadBufferLines(int top, int count)
        {
            var result = new CHAR_INFO[Console.BufferWidth * count];
            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            var readBufferSize = new COORD {
                X = (short)Console.BufferWidth,
                Y = (short)count};
            var readBufferCoord = new COORD {X = 0, Y = 0};
            var readRegion = new SMALL_RECT
            {
                Top = (short)top,
                Left = 0,
                Bottom = (short)(top + count),
                Right = (short)(Console.BufferWidth - 1)
            };
            NativeMethods.ReadConsoleOutput(handle, result,
                readBufferSize, readBufferCoord, ref readRegion);
            return result;
        }
 static void ClearScreen()
 {
     int bufferWidth = Console.BufferWidth;
     const int bufferLineCount = 10;
     var consoleBuffer = new CHAR_INFO[bufferWidth * bufferLineCount];
     for (int i = 0; i < consoleBuffer.Length; i++)
     {
         consoleBuffer[i] = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor);
     }
     int top = 0;
     WriteBufferLines(consoleBuffer, ref top);
 }
Exemple #27
0
        private static void SetPrompt(string prompt)
        {
            if (string.IsNullOrEmpty(prompt))
                return;

            var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);

            var lineCount = 1 + prompt.Count(c => c == '\n');
            if (lineCount > 1)
            {
                var options = new SetPSReadlineOption {ExtraPromptLineCount = lineCount - 1};
                PSConsoleReadLine.SetOptions(options);
            }
            int bufferWidth = Console.BufferWidth;
            var consoleBuffer = new CHAR_INFO[lineCount * bufferWidth];
            int j = 0;
            for (int i = 0; i < prompt.Length; i++, j++)
            {
                if (prompt[i] == '\n')
                {
                    for (; j % Console.BufferWidth != 0; j++)
                    {
                        consoleBuffer[j] = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor);
                    }
                    Console.CursorTop += 1;
                    Console.CursorLeft = 0;
                    j -= 1;  // We don't actually write the newline
                }
                else
                {
                    consoleBuffer[j] = new CHAR_INFO(prompt[i], Console.ForegroundColor, Console.BackgroundColor);
                    Console.CursorLeft += 1;
                }
            }

            var bufferSize = new COORD
                             {
                                 X = (short) bufferWidth,
                                 Y = (short) lineCount
                             };
            var bufferCoord = new COORD {X = 0, Y = 0};
            var writeRegion = new SMALL_RECT
                              {
                                  Top = 0,
                                  Left = 0,
                                  Bottom = (short) (lineCount - 1),
                                  Right = (short) bufferWidth
                              };
            NativeMethods.WriteConsoleOutput(handle, consoleBuffer, bufferSize, bufferCoord, ref writeRegion);
        }
Exemple #28
0
        private void ClearDemoWindow()
        {
            int bufferWidth = Console.BufferWidth;
            var charInfoBuffer = new CHAR_INFO[bufferWidth * 3];

            for (int i = 0; i < charInfoBuffer.Length; i++)
            {
                charInfoBuffer[i].UnicodeChar = ' ';
                charInfoBuffer[i].ForegroundColor = _initialForegroundColor;
                charInfoBuffer[i].BackgroundColor= _initialBackgroundColor;
            }

            int bufferLineCount = ConvertOffsetToCoordinates(_buffer.Length).Y - _initialY + 1;
            int y = _initialY + bufferLineCount + 1;
            WriteBufferLines(charInfoBuffer, ref y);
        }
Exemple #29
0
        private CHAR_INFO[] CreateCharInfoBuffer(int lines, params object[] items)
        {
            var result = new List<CHAR_INFO>();
            var fg = Console.ForegroundColor;
            var bg = Console.BackgroundColor;

            foreach (var i in items)
            {
                var item = i;
                if (item is char)
                {
                    result.Add(new CHAR_INFO((char)item, fg, bg));
                    continue;
                }
                if (item is InvertedToken)
                {
                    fg = (ConsoleColor)((int)fg ^ 7);
                    bg = (ConsoleColor)((int)bg ^ 7);
                    continue;
                }
                if (item is NextLineToken)
                {
                    item = new string(' ', Console.BufferWidth - (result.Count % Console.BufferWidth));
                    fg = Console.ForegroundColor;
                    bg = Console.BackgroundColor;
                    // Fallthrough to string case.
                }
                var str = item as string;
                if (str != null)
                {
                    result.AddRange(str.Select(c => new CHAR_INFO(c, fg, bg)));
                    continue;
                }
                if (item is TokenClassification)
                {
                    fg = ForegroundColors[(int)(TokenClassification)item];
                    bg = BackgroundColors[(int)(TokenClassification)item];
                    continue;
                }
                var tuple = item as Tuple<ConsoleColor, ConsoleColor>;
                if (tuple != null)
                {
                    fg = tuple.Item1;
                    bg = tuple.Item2;
                    continue;
                }
                throw new ArgumentException("Unexpected type");
            }

            var extraSpacesNeeded = (lines * Console.BufferWidth) - result.Count;
            if (extraSpacesNeeded > 0)
            {
                var space = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor);
                result.AddRange(Enumerable.Repeat(space, extraSpacesNeeded));
            }

            return result.ToArray();
        }
Exemple #30
0
        private void PossibleCompletionsImpl(ConsoleKeyInfo? key, object arg, bool menuSelect)
        {
            var completions = GetCompletions();
            if (completions == null || completions.CompletionMatches.Count == 0)
            {
                Ding();
                return;
            }

            if (completions.CompletionMatches.Count >= _options.CompletionQueryItems)
            {
                if (!PromptYesOrNo(string.Format(PSReadLineResources.DisplayAllPossibilities, completions.CompletionMatches.Count)))
                {
                    return;
                }
            }

            // Don't overwrite any of the line - so move to first line after the end of our buffer.
            var coords = ConvertOffsetToCoordinates(_buffer.Length);
            PlaceCursor(0, coords.Y + 1);

            var matches = completions.CompletionMatches;
            var minColWidth = matches.Max(c => c.ListItemText.Length);
            minColWidth += 2;
            var menuColumnWidth = minColWidth;

            CompletionResult[,] matchesMatrix;
            int displayColumns;
            int displayRows;
            var bufferWidth = Console.BufferWidth;
            var sb = new StringBuilder(bufferWidth);
            if (Options.ShowToolTips)
            {
                const string seperator = "- ";
                var maxTooltipWidth = bufferWidth - minColWidth - seperator.Length;

                matchesMatrix = new CompletionResult[1, matches.Count];
                displayRows = matches.Count;
                displayColumns = 1;
                for (int index = 0; index < matches.Count; index++)
                {
                    var match = matches[index];
                    matchesMatrix[0, index] = match;
                    var listItemText = HandleNewlinesForPossibleCompletions(match.ListItemText);
                    sb.Append(listItemText);
                    var spacesNeeded = minColWidth - listItemText.Length;
                    if (spacesNeeded > 0)
                        sb.Append(' ', spacesNeeded);
                    sb.Append(seperator);
                    var toolTip = HandleNewlinesForPossibleCompletions(match.ToolTip);
                    toolTip = toolTip.Length <= maxTooltipWidth
                                  ? toolTip
                                  : toolTip.Substring(0, maxTooltipWidth);
                    sb.Append(toolTip);

                    // Make sure we always write out exactly 1 buffer width
                    spacesNeeded = bufferWidth - sb.Length;
                    if (spacesNeeded > 0)
                    {
                        sb.Append(' ', spacesNeeded);
                    }
                    Console.Write(sb.ToString());
                    sb.Clear();
                }
                menuColumnWidth = bufferWidth;
            }
            else
            {
                var screenColumns = bufferWidth;
                displayColumns = Math.Max(1, screenColumns / minColWidth);
                displayRows = (completions.CompletionMatches.Count + displayColumns - 1) / displayColumns;
                matchesMatrix = new CompletionResult[displayColumns, displayRows];
                for (var row = 0; row < displayRows; row++)
                {
                    for (var col = 0; col < displayColumns; col++)
                    {
                        var index = row + (displayRows * col);
                        if (index >= matches.Count)
                            break;
                        var match = matches[index];
                        matchesMatrix[col, row] = match;
                        var item = HandleNewlinesForPossibleCompletions(match.ListItemText);
                        sb.Append(item);
                        sb.Append(' ', minColWidth - item.Length);
                    }

                    // Make sure we always write out exactly 1 buffer width
                    var spacesNeeded = bufferWidth - sb.Length;
                    if (spacesNeeded > 0)
                    {
                        sb.Append(' ', spacesNeeded);
                    }
                    Console.Write(sb.ToString());
                    sb.Clear();
                }
            }

            if (menuSelect)
            {
                // Move cursor back to the line.
                PlaceCursor();

                StartEditGroup();

                int top = coords.Y + 1;
                int selectedItem = 0;
                bool undo = false;

                InvertSelectedCompletion(top, 0, menuColumnWidth);
                DoReplacementForCompletion(matchesMatrix[0, 0], completions);

                int previousItem = selectedItem;

                bool processingKeys = true;
                while (processingKeys)
                {
                    var nextKey = ReadKey();
                    if (nextKey == Keys.RightArrow)
                    {
                        selectedItem = Math.Min(selectedItem + displayRows, matches.Count - 1);
                    }
                    else if (nextKey == Keys.LeftArrow)
                    {
                        selectedItem = Math.Max(selectedItem - displayRows, 0);
                    }
                    else if (nextKey == Keys.DownArrow)
                    {
                        selectedItem = Math.Min(selectedItem + 1, matches.Count - 1);
                    }
                    else if (nextKey == Keys.UpArrow)
                    {
                        selectedItem = Math.Max(selectedItem - 1, 0);
                    }
                    else if (nextKey == Keys.Tab)
                    {
                        selectedItem = (selectedItem + 1) % matches.Count;
                    }
                    else if (nextKey == Keys.ShiftTab)
                    {
                        selectedItem = (selectedItem - 1) % matches.Count;
                        if (selectedItem < 0)
                        {
                            selectedItem += matches.Count;
                        }
                    }
                    else if (nextKey == Keys.CtrlG || nextKey == Keys.Escape)
                    {
                        undo = true;
                        processingKeys = false;
                    }
                    else
                    {
                        PrependQueuedKeys(nextKey);
                        processingKeys = false;
                    }

                    if (selectedItem != previousItem)
                    {
                        var selectedX = selectedItem / displayRows;
                        var selectedY = selectedItem - (selectedX * displayRows);
                        var completionResult = matchesMatrix[selectedX, selectedY];
                        if (completionResult != null)
                        {
                            var previousX = previousItem / displayRows;
                            var previousY = previousItem - (previousX * displayRows);
                            InvertSelectedCompletion(previousY + top, previousX, menuColumnWidth);
                            InvertSelectedCompletion(selectedY + top, selectedX, menuColumnWidth);
                            DoReplacementForCompletion(completionResult, completions);
                            previousItem = selectedItem;
                        }
                        else
                        {
                            selectedItem = previousItem;
                        }
                    }
                }

                var blanks = new CHAR_INFO[displayRows * bufferWidth];
                for (int i = 0; i < displayRows; i++)
                {
                    blanks[i].BackgroundColor = Console.BackgroundColor;
                    blanks[i].ForegroundColor = Console.ForegroundColor;
                    blanks[i].UnicodeChar = ' ';
                }
                WriteBufferLines(blanks, ref top);

                EndEditGroup();

                if (undo)
                {
                    // Pretend it never happened.
                    Undo();
                }
            }
            else
            {
                _initialY = Console.CursorTop;
                Render();
            }
        }