Exemple #1
0
 public static void WriteReverse(string text, bool reverse)
 {
     if (reverse)
     {
         if (Runtime.HasFeature("ansi-terminal"))
         {
             Console.Write("\x1b[7m");
             Console.Write(text);
             Console.Write("\x1b[27m");
         }
         else
         {
             Console.Write("[");
             Console.Write(text);
             Console.Write("]");
         }
     }
     else
     {
         Console.Write(text);
     }
 }
Exemple #2
0
        public static string ReplReadImp(string prompt, bool lispCompletion, bool symbolCompletion, bool crlf)
        {
            //ReplReadTest();

            var top      = Console.CursorTop;
            var left     = Console.CursorLeft;
            var pos      = 0;
            var buffer   = new StringBuilder();
            var col      = 0;
            var row      = 0;
            var scrolled = 0;

            Action <char> writeChar = (char ch) =>
            {
                var r1 = Console.CursorTop;
                var c1 = Console.CursorLeft;
                Console.Write(ch);
                var r2 = Console.CursorTop;
                var c2 = Console.CursorLeft;
                if (r1 == Console.BufferHeight - 1)
                {
                    // on last row
                    if (c2 == 0)
                    {
                        ++scrolled;
                        --top;
                        --row;
                    }
                }
            };

            Action <string> writeStr = (string str) =>
            {
                foreach (var ch in str)
                {
                    writeChar(ch);
                }
            };

            Action cursorReset = () =>
            {
                Console.SetCursorPosition(left, top);
                row = top;
                col = left;
            };

            Action paint = () =>
            {
                //
                // update display
                //

                cursorReset();

                if (prompt != null)
                {
                    writeStr(prompt);
                    row = Console.CursorTop;
                    col = Console.CursorLeft;
                }

                for (var i = 0; i < buffer.Length; ++i)
                {
                    writeChar(buffer[i]);

                    if (i + 1 == pos)
                    {
                        row = Console.CursorTop;
                        col = Console.CursorLeft;
                    }
                }
                writeChar(' ');
            };

            Action erase = () =>
            {
                if (Runtime.HasFeature("ansi-terminal"))
                {
                    Console.Write("\x1b[J");
                }
                else
                {
                    var start = Console.CursorLeft + Console.CursorTop * Console.BufferWidth;
                    var end   = (Console.WindowTop + Console.WindowHeight) * Console.BufferWidth - 1;
                    if (start < end)
                    {
                        var blanks = new String(' ', end - start);
                        Console.Write(blanks);
                    }
                }
            };

            Action setupNewPromptLocation = () =>
            {
                top      = Console.CursorTop;
                left     = Console.CursorLeft;
                col      = 0;
                row      = 0;
                scrolled = 0;
            };

            while (true)
            {
                paint();
                erase();

                //
                // get next key
                //

                ConsoleKeyInfo   keyInfo;
                ConsoleKey       key;
                ConsoleModifiers mod;
                char             ch;

                Console.SetCursorPosition(col, row);

                keyInfo = ReplReadKey();
                key     = keyInfo.Key;
                mod     = keyInfo.Modifiers;
                ch      = keyInfo.KeyChar;

                switch (key)
                {
                case ConsoleKey.Backspace:
                {
                    if (pos > 0)
                    {
                        --pos;
                        buffer.Remove(pos, 1);
                    }
                    break;
                }

                case ConsoleKey.Delete:
                {
                    if (pos < buffer.Length)
                    {
                        buffer.Remove(pos, 1);
                    }
                    break;
                }

                case ConsoleKey.Enter:
                {
                    var s = buffer.ToString();
                    if (!lispCompletion || (mod != ConsoleModifiers.Control && IsCompleteSourceCode(s)))
                    {
                        pos = buffer.Length;
                        paint();
                        if (crlf)
                        {
                            writeChar('\n');
                        }
                        return(s);
                    }
                    else
                    {
                        writeChar('\n');
                        buffer.Append('\n');
                        ++pos;
                    }
                    break;
                }

                case ConsoleKey.Home:
                {
                    pos = 0;
                    break;
                }

                case ConsoleKey.End:
                {
                    pos = buffer.Length;
                    break;
                }

                case ConsoleKey.LeftArrow:
                {
                    if (pos > 0)
                    {
                        --pos;
                    }
                    break;
                }

                case ConsoleKey.RightArrow:
                {
                    if (pos < buffer.Length)
                    {
                        ++pos;
                    }
                    break;
                }

                case ConsoleKey.UpArrow:
                {
                    if (History != null)
                    {
                        var s = History.Previous();
                        buffer = new StringBuilder(s);
                        pos    = buffer.Length;
                    }
                    break;
                }

                case ConsoleKey.DownArrow:
                {
                    if (History != null)
                    {
                        var s = History.Next();
                        buffer = new StringBuilder(s);
                        pos    = buffer.Length;
                    }
                    break;
                }

                case ConsoleKey.Escape:
                {
                    cursorReset();
                    erase();
                    cursorReset();
                    return(null);
                }

                case ConsoleKey.Tab:
                {
                    if (!symbolCompletion)
                    {
                        break;
                    }
                    var line        = buffer.ToString();
                    var loc         = Runtime.LocateWord(line, pos, false);
                    var prefix      = line.Substring(0, loc.Begin);
                    var searchTerm  = line.Substring(loc.Begin, loc.Span);
                    var suffix      = line.Substring(loc.Begin + loc.Span);
                    var completions = GetCompletions(searchTerm);
                    var common      = FindLongestCommonStringLength(completions);
                    if (common > loc.Span)
                    {
                        // add extra common characters
                        searchTerm = completions[0].Substring(0, common);
                        buffer     = new StringBuilder();
                        buffer.Append(prefix);
                        buffer.Append(searchTerm);
                        pos = buffer.Length;
                        buffer.Append(suffix);
                    }
                    else
                    {
                        // show all options and a new prompt
                        var width = -1;
                        for (var i = 0; i < completions.Count; ++i)
                        {
                            width = Math.Max(width, 1 + completions[i].Length);
                        }
                        var cols = Math.Max(1, Console.BufferWidth / width);
                        Console.WriteLine();
                        Runtime.PrintMultiColumn(GetConsoleOut(), cols, width, completions);
                        setupNewPromptLocation();
                    }
                    break;
                }

                default:
                {
                    if (mod == ConsoleModifiers.Control)
                    {
                        switch (key)
                        {
                        case ConsoleKey.V:
                            var text = Runtime.GetClipboardData();
                            foreach (var ch2 in text)
                            {
                                var ch3 = (ch2 == '\n' || ch2 >= ' ') ? ch2 : ' ';
                                buffer.Insert(pos, ch3);
                                ++pos;
                            }
                            break;

                        case ConsoleKey.U:
                            var text3 = buffer.ToString(0, pos);
                            buffer.Remove(0, pos);
                            pos = 0;
                            break;

                        case ConsoleKey.K:
                            var text4 = buffer.ToString(pos, buffer.Length - pos);
                            buffer.Remove(pos, buffer.Length - pos);
                            break;

                        case ConsoleKey.W:
                            var line  = buffer.ToString();
                            var loc   = Runtime.LocateWord(line, pos, true);
                            var text5 = buffer.ToString(loc.Begin, pos - loc.Begin);
                            buffer.Remove(loc.Begin, pos - loc.Begin);
                            pos = loc.Begin;
                            break;
                        }
                    }
                    else if (ch == '\n')
                    {
                        var s = buffer.ToString();
                        if (mod != ConsoleModifiers.Control && IsCompleteSourceCode(s))
                        {
                            pos = buffer.Length;
                            paint();
                            if (crlf)
                            {
                                writeChar('\n');
                            }
                            return(s);
                        }
                        else
                        {
                            writeChar('\n');
                            buffer.Append('\n');
                            ++pos;
                        }
                    }
                    else if (ch >= ' ')
                    {
                        buffer.Insert(pos, ch);
                        ++pos;
                    }
                    break;
                }
                }
            }
        }