예제 #1
0
        private BufferChar[] ToBufferCharBuffer(CHAR_INFO[] buffer)
        {
            var result = new BufferChar[buffer.Length];

            for (int i = 0; i < buffer.Length; i++)
            {
                result[i] = BufferChar.FromCharInfo(buffer[i]);
            }

            return(result);
        }
예제 #2
0
        public static BufferChar FromCharInfo(CHAR_INFO charInfo)
        {
            BufferChar result = new BufferChar
            {
                UnicodeChar     = (char)charInfo.UnicodeChar,
                ForegroundColor = (ConsoleColor)(charInfo.Attributes & 0xf),
                BackgroundColor = (ConsoleColor)((charInfo.Attributes & 0x00f0) >> 4),
            };

            return(result);
        }
예제 #3
0
        public BufferChar[] ReadBufferLines(int top, int count)
        {
            var result = new BufferChar[BufferWidth * count];

            for (int i = 0; i < BufferWidth * count; ++i)
            {
                result[i].UnicodeChar     = ' ';
                result[i].ForegroundColor = Console.ForegroundColor;
                result[i].BackgroundColor = Console.BackgroundColor;
            }
            return(result);
        }
예제 #4
0
파일: Render.cs 프로젝트: dfinke/powershell
        private void MaybeEmphasize(ref BufferChar 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 palette 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.
#if UNIX // TODO: set Inverse attribute and let render choose what to do.
                ConsoleColor tempColor = (foregroundColor == UnknownColor) ? ConsoleColor.White : foregroundColor;
                foregroundColor = (backgroundColor == UnknownColor) ? ConsoleColor.Black : backgroundColor;
                backgroundColor = tempColor;
#else
                foregroundColor = (ConsoleColor)((int)foregroundColor ^ 7);
                backgroundColor = (ConsoleColor)((int)backgroundColor ^ 7);
#endif
            }

            charInfo.ForegroundColor = foregroundColor;
            charInfo.BackgroundColor = backgroundColor;
        }
예제 #5
0
파일: Render.cs 프로젝트: dfinke/powershell
        private void ReallyRender()
        {
            var text = ParseInput();

            int statusLineCount = GetStatusLineCount();
            int j = _initialX + (_bufferWidth * Options.ExtraPromptLineCount);
            var backgroundColor = _initialBackgroundColor;
            var foregroundColor = _initialForegroundColor;
            bool afterLastToken = false;
            int totalBytes = j;
            int bufferWidth = _console.BufferWidth;

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

            int bufferLineCount;

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

                for (int i = 0; i < text.Length; i++)
                {
                    totalBytes = totalBytes % bufferWidth;
                    if (!afterLastToken)
                    {
                        // 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();
                                if (tokenStack.Count == 0)
                                {
                                    afterLastToken = true;
                                    token = null;
                                    foregroundColor = _initialForegroundColor;
                                    backgroundColor = _initialBackgroundColor;
                                }
                                else
                                {
                                    state = tokenStack.Peek();
                                }
                            }

                            if (!afterLastToken)
                            {
                                foregroundColor = state.ForegroundColor;
                                backgroundColor = state.BackgroundColor;
                                token = state.Tokens[++state.Index];
                            }
                        }

                        if (!afterLastToken && 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 (i == tokens[0].Extent.StartOffset)
                                    {
                                        GetTokenColors(tokens[0], out foregroundColor, out backgroundColor);
                                    }
                                }
                            }
                        }
                    }

                    var charToRender = text[i];
                    if (charToRender == '\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
                    {
                        int size = LengthInBufferCells(charToRender);
                        totalBytes += size;

                        //if there is no enough space for the character at the edge, fill in spaces at the end and 
                        //put the character to next line.
                        int filling = totalBytes > bufferWidth ? (totalBytes - bufferWidth) % size : 0;
                        for (int f = 0; f < filling; f++)
                        {
                            _consoleBuffer[j++] = _space;
                            totalBytes++;
                        }

                        if (char.IsControl(charToRender))
                        {
                            _consoleBuffer[j].UnicodeChar = '^';
                            MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                            _consoleBuffer[j].UnicodeChar = (char)('@' + charToRender);
                            MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);

                        }
#if !UNIX
                        else if (size > 1)
                        {
                            _consoleBuffer[j].UnicodeChar = charToRender;
                            _consoleBuffer[j].IsLeadByte = true;
                            MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                            _consoleBuffer[j].UnicodeChar = charToRender;
                            _consoleBuffer[j].IsTrailByte = true;
                            MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                        }
#endif
                        else
                        {
                            _consoleBuffer[j].UnicodeChar = charToRender;
                            MaybeEmphasize(ref _consoleBuffer[j++], i, foregroundColor, backgroundColor);
                        }
                    }
                }
            }
            finally
            {
                _console.EndRender();
            }

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

            if (_statusLinePrompt != null)
            {
                foregroundColor = _statusIsErrorMessage ? Options.ErrorForegroundColor : _console.ForegroundColor;
                backgroundColor = _statusIsErrorMessage ? Options.ErrorBackgroundColor : _console.BackgroundColor;

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

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

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

                while (promptChar >= 0)
                {
                    var c = _consoleBuffer[promptChar].UnicodeChar;
                    if (char.IsWhiteSpace(c))
                    {
                        promptChar -= 1;
                        continue;
                    }

                    ConsoleColor prevColor = _consoleBuffer[promptChar].ForegroundColor;
                    _consoleBuffer[promptChar].ForegroundColor = ConsoleColor.Red;
                    _console.WriteBufferLines(_consoleBuffer, ref _initialY);
                    rendered = true;
                    _consoleBuffer[promptChar].ForegroundColor = prevColor;
                    break;
                }
            }

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

            PlaceCursor();

            if ((_initialY + bufferLineCount) > (_console.WindowTop + _console.WindowHeight))
            {
#if !UNIX // TODO: verify this isn't necessary for LINUX
                _console.WindowTop = _initialY + bufferLineCount - _console.WindowHeight;
#endif
            }

            _lastRenderTime.Restart();
        }
예제 #6
0
        private BufferChar[] ToBufferCharBuffer(CHAR_INFO[] buffer)
        {
            var result = new BufferChar[buffer.Length];

            for (int i = 0; i < buffer.Length; i++)
            {
                result[i] = BufferChar.FromCharInfo(buffer[i]);
            }

            return result;
        }
예제 #7
0
파일: Render.cs 프로젝트: dfinke/powershell
 private static void WriteBlankLines(int count, int top)
 {
     var console = _singleton._console;
     var blanks = new BufferChar[count * console.BufferWidth];
     for (int i = 0; i < blanks.Length; i++)
     {
         blanks[i].BackgroundColor = console.BackgroundColor;
         blanks[i].ForegroundColor = console.ForegroundColor;
         blanks[i].UnicodeChar = ' ';
     }
     console.WriteBufferLines(blanks, ref top);
 }
예제 #8
0
        public void WriteBufferLines(BufferChar[] buffer, ref int top, bool ensureBottomLineVisible)
        {
            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 handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output);
            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, ToCharInfoBuffer(buffer),
                                             bufferSize, bufferCoord, ref writeRegion);

            // Now make sure the bottom line is visible
            if (ensureBottomLineVisible &&
                (bottom >= (Console.WindowTop + Console.WindowHeight)))
            {
                Console.CursorTop = bottom;
            }
        }
예제 #9
0
        private CHAR_INFO[] ToCharInfoBuffer(BufferChar[] buffer)
        {
            if (cachedBuffer == null || cachedBuffer.Length != buffer.Length)
            {
                cachedBuffer = new CHAR_INFO[buffer.Length];
            }

            for (int i = 0; i < buffer.Length; i++)
            {
                cachedBuffer[i] = buffer[i].ToCharInfo();
            }

            return cachedBuffer;
        }
예제 #10
0
 public void WriteBufferLines(BufferChar[] buffer, ref int top)
 {
     WriteBufferLines(buffer, ref top, true);
 }
예제 #11
0
 public static BufferChar FromCharInfo(CHAR_INFO charInfo)
 {
     BufferChar result = new BufferChar
     {
         UnicodeChar = (char) charInfo.UnicodeChar,
         ForegroundColor = (ConsoleColor)(charInfo.Attributes & 0xf),
         BackgroundColor = (ConsoleColor)((charInfo.Attributes & 0x00f0) >> 4),
     };
     return result;
 }
예제 #12
0
 public BufferChar[] ReadBufferLines(int top, int count)
 {
     var result = new BufferChar[BufferWidth * count];
     for (int i=0; i<BufferWidth*count; ++i)
     {
         result[i].UnicodeChar = ' ';
         result[i].ForegroundColor = Console.ForegroundColor;
         result[i].BackgroundColor = Console.BackgroundColor;
     }
     return result;
 }
예제 #13
0
        public void WriteBufferLines(BufferChar[] buffer, ref int top, bool ensureBottomLineVisible)
        {
            int bufferWidth = Console.BufferWidth;
            int bufferLineCount = buffer.Length / bufferWidth;
            if ((top + bufferLineCount) > Console.BufferHeight)
            {
                var scrollCount = (top + bufferLineCount) - Console.BufferHeight;
                ScrollBuffer(scrollCount);
                top -= scrollCount;
            }

            ConsoleColor foregroundColor = Console.ForegroundColor;
            ConsoleColor backgroundColor = Console.BackgroundColor;

            Console.SetCursorPosition(0, (top>=0) ? top : 0);

            for (int i = 0; i < buffer.Length; ++i)
            {
                // TODO: use escape sequences for better perf
                Console.ForegroundColor =  buffer[i].ForegroundColor;
                Console.BackgroundColor =  buffer[i].BackgroundColor;

                Console.Write(buffer[i].UnicodeChar);
            }

            Console.BackgroundColor = backgroundColor;
            Console.ForegroundColor = foregroundColor;
        }
예제 #14
0
 private static void InvertSelectedCompletion(BufferChar[] buffer, int selectedItem, int menuColumnWidth, int menuRows)
 {
     var selectedX = selectedItem / menuRows;
     var selectedY = selectedItem - (selectedX * menuRows);
     var start = selectedY * _singleton._console.BufferWidth + selectedX * menuColumnWidth;
     for (int i = 0; i < menuColumnWidth; i++)
     {
         buffer[i + start].Inverse = true;
     }
 }