Пример #1
0
        // Tab across to the next stop, or perform tab completion.
        private void Tab()
        {
            if (TabComplete == null)
            {
                // Add the TAB character and repaint the line.
                AddChar('\t');
            }
            else
            {
                if (_state != ReadlineState.Completing)
                {
                    CollectLastWord('\0');
                    _state = ReadlineState.Completing;
                }

                // Perform tab completion and insert the results.
                var e = new TabCompleteEventArgs(_lastWord.ToString(), ++_tabCount);
                TabComplete(this, e);
                if (e.Insert != null)
                {
                    _savePosn = _posn;
                    // Insert the value that we found.
                    var saveOverwrite = _overwrite;
                    _overwrite = false;
                    _savePosn  = e.Insert.Length;

                    _state = ReadlineState.Completing;
                    foreach (var ch in e.Insert)
                    {
                        AddChar(ch);
                    }
                    _overwrite = saveOverwrite;
                }
                else if (e.Alternatives != null && e.Alternatives.Length > 0)
                {
                    // Print the alternatives for the user.
                    _savePosn = _posn;
                    EndLine();
                    PrintAlternatives?.Invoke(this, new PrintAlternativesEventArgs(e.Alternatives));
                    WritePrompt?.Invoke(this, EventArgs.Empty);

                    _posn  = _savePosn;
                    _state = ReadlineState.Completing;
                    Redraw();
                }
                else
                {
                    if (e.Error)
                    {
                        ResetComplete(ReadlineState.MoreInput);
                    }

                    // No alternatives, or alternatives not supplied yet.
                    Console.Beep();
                }
            }
        }
Пример #2
0
 // Cancel the current line and start afresh with a new prompt.
 private void CancelLine()
 {
     EndLine();
     WritePrompt?.Invoke(this, EventArgs.Empty);
     _posn        = 0;
     _length      = 0;
     _column      = 0;
     _lastColumn  = 0;
     _historyPosn = -1;
 }
Пример #3
0
        public string ReadPassword(Action writePromtAction)
        {
            var readline = new Readline.Readline(History)
            {
                CtrlCInterrupts = CtrlCInterrupts,
                CtrlDIsEOF      = CtrlDIsEOF,
                CtrlZIsEOF      = CtrlZIsEOF
            };

            readline.WritePrompt += (sender, args) => WritePrompt?.Invoke(this, EventArgs.Empty);
            readline.Interrupt   += (sender, args) => ShellInterrupt?.Invoke(this, EventArgs.Empty);

            return(readline.ReadPassword());
        }
Пример #4
0
        public string ReadPassword()
        {
            var treatControlCAsInterrupt = Console.TreatControlCAsInput;

            Console.TreatControlCAsInput = !CtrlCInterrupts;

            try
            {
                // Output the prompt.
                WritePrompt?.Invoke(this, EventArgs.Empty);

                var pass = new Stack();

                for (var consKeyInfo = Console.ReadKey(true);
                     consKeyInfo.Key != ConsoleKey.Enter;
                     consKeyInfo = Console.ReadKey(true))
                {
                    if (consKeyInfo.Key == ConsoleKey.Backspace)
                    {
                        try
                        {
                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                            Console.Write(" ");
                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                            pass.Pop();
                        }
                        catch (InvalidOperationException)
                        {
                            Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
                        }
                    }
                    else
                    {
                        Console.Write("*");
                        pass.Push(consKeyInfo.KeyChar.ToString());
                    }
                }
                var chars    = pass.ToArray();
                var password = new string[chars.Length];
                Array.Copy(chars, password, chars.Length);
                Array.Reverse(password);
                return(string.Join(string.Empty, password));
            }
            finally
            {
                Console.TreatControlCAsInput = treatControlCAsInterrupt;
            }
        }
Пример #5
0
        // Read the next line of input using line editing.  Returns "null"
        // if an EOF indication is encountered in the input.
        public string ReadLine()
        {
            var treatControlCAsInterrupt = Console.TreatControlCAsInput;

            Console.TreatControlCAsInput = !CtrlCInterrupts;

            try
            {
                // Output the prompt.
                WritePrompt?.Invoke(this, EventArgs.Empty);

                // Enter the main character input loop.
                _posn        = 0;
                _length      = 0;
                _column      = 0;
                _lastColumn  = 0;
                _overwrite   = false;
                _historyPosn = -1;
                var ctrlv = false;
                _state = ReadlineState.MoreInput;
                do
                {
                    var key = ConsoleExtensions.ReadKey(true);
                    var ch  = key.KeyChar;
                    if (ctrlv)
                    {
                        ctrlv = false;
                        if ((ch >= 0x0001 && ch <= 0x001F) || ch == 0x007F)
                        {
                            // Insert a control character into the buffer.
                            AddChar(ch);
                            continue;
                        }
                    }
                    if (ch != '\0')
                    {
                        switch (ch)
                        {
                        case '\u0001':
                        {
                            // CTRL-A: move to the home position.
                            MoveHome();
                        }
                        break;

                        case '\u0002':
                        {
                            // CTRL-B: go back one character.
                            MoveLeft();
                        }
                        break;

                        case '\u0003':
                        {
                            // CTRL-C encountered in "raw" mode.
                            if (CtrlCInterrupts)
                            {
                                EndLine();
                                Interrupt?.Invoke(null, EventArgs.Empty);
                                return(null);
                            }
                            CancelLine();
                            _lastWord.Length = 0;
                        }
                        break;

                        case '\u0004':
                        {
                            // CTRL-D: EOF or delete the current character.
                            if (CtrlDIsEOF)
                            {
                                _lastWord.Length = 0;
                                // Signal an EOF if the buffer is empty.
                                if (_length == 0)
                                {
                                    EndLine();
                                    return(null);
                                }
                            }
                            else
                            {
                                Delete();
                                ResetComplete(ReadlineState.MoreInput);
                            }
                        }
                        break;

                        case '\u0005':
                        {
                            // CTRL-E: move to the end position.
                            MoveEnd();
                        }
                        break;

                        case '\u0006':
                        {
                            // CTRL-F: go forward one character.
                            MoveRight();
                        }
                        break;

                        case '\u0007':
                        {
                            // CTRL-G: ring the terminal bell.
                            Console.Beep();
                        }
                        break;

                        case '\u0008':
                        case '\u007F':
                        {
                            if (key.Key == ConsoleKey.Delete)
                            {
                                // Delete the character under the cursor.
                                Delete();
                            }
                            else
                            {
                                // Delete the character before the cursor.
                                Backspace();
                            }
                            ResetComplete(ReadlineState.MoreInput);
                        }
                        break;

                        case '\u0009':
                        {
                            // Process a tab.
                            Tab();
                        }
                        break;

                        case '\u000A':
                        case '\u000D':
                        {
                            // Line termination.
                            EndLine();
                            ResetComplete(ReadlineState.Done);
                            _lastWord.Length = 0;
                        }
                        break;

                        case '\u000B':
                        {
                            // CTRL-K: erase until the end of the line.
                            EraseToEnd();
                        }
                        break;

                        case '\u000C':
                        {
                            // CTRL-L: clear screen and redraw.
                            Console.Clear();
                            WritePrompt?.Invoke(this, EventArgs.Empty);
                            Redraw();
                        }
                        break;

                        case '\u000E':
                        {
                            // CTRL-N: move down in the history.
                            MoveDown();
                        }
                        break;

                        case '\u0010':
                        {
                            // CTRL-P: move up in the history.
                            MoveUp();
                        }
                        break;

                        case '\u0015':
                        {
                            // CTRL-U: erase to the start of the line.
                            EraseToStart();
                            ResetComplete(ReadlineState.None);
                        }
                        break;

                        case '\u0016':
                        {
                            // CTRL-V: prefix a control character.
                            ctrlv = true;
                        }
                        break;

                        case '\u0017':
                        {
                            // CTRL-W: erase the previous word.
                            EraseWord();
                            ResetComplete(ReadlineState.MoreInput);
                        }
                        break;

                        case '\u0019':
                        {
                            // CTRL-Y: yank the last erased string.
                            if (_yankedString != null)
                            {
                                foreach (var ch2 in _yankedString)
                                {
                                    AddChar(ch2);
                                }
                            }
                        }
                        break;

                        case '\u001A':
                        {
                            // CTRL-Z: Windows end of file indication.
                            if (CtrlZIsEOF && _length == 0)
                            {
                                EndLine();
                                return(null);
                            }
                        }
                        break;

                        case '\u001B':
                        {
                            // Escape is "clear line".
                            Clear();
                            ResetComplete(ReadlineState.MoreInput);
                        }
                        break;

                        default:
                        {
                            if (ch >= ' ')
                            {
                                // Ordinary character.
                                AddChar(ch);
                                ResetComplete(ReadlineState.MoreInput);
                            }
                        }
                        break;
                        }
                    }
                    else if (key.Modifiers == 0)
                    {
                        switch (key.Key)
                        {
                        case ConsoleKey.Backspace:
                        {
                            // Delete the character before the cursor.
                            Backspace();
                            ResetComplete(ReadlineState.MoreInput);
                        }
                        break;

                        case ConsoleKey.Delete:
                        {
                            // Delete the character under the cursor.
                            Delete();
                            ResetComplete(ReadlineState.MoreInput);
                        }
                        break;

                        case ConsoleKey.Enter:
                        {
                            // Line termination.
                            EndLine();
                            ResetComplete(ReadlineState.Done);
                        }
                        break;

                        case ConsoleKey.Escape:
                        {
                            // Clear the current line.
                            Clear();
                            ResetComplete(ReadlineState.None);
                        }
                        break;

                        case ConsoleKey.Tab:
                        {
                            // Process a tab.
                            Tab();
                        }
                        break;

                        case ConsoleKey.LeftArrow:
                        {
                            // Move left one character.
                            MoveLeft();
                        }
                        break;

                        case ConsoleKey.RightArrow:
                        {
                            // Move right one character.
                            MoveRight();
                        }
                        break;

                        case ConsoleKey.UpArrow:
                        {
                            // Move up one line in the history.
                            MoveUp();
                        }
                        break;

                        case ConsoleKey.DownArrow:
                        {
                            // Move down one line in the history.
                            MoveDown();
                        }
                        break;

                        case ConsoleKey.Home:
                        {
                            // Move to the beginning of the line.
                            MoveHome();
                        }
                        break;

                        case ConsoleKey.End:
                        {
                            // Move to the end of the line.
                            MoveEnd();
                        }
                        break;

                        case ConsoleKey.Insert:
                        {
                            // Toggle insert/overwrite mode.
                            _overwrite = !_overwrite;
                        }
                        break;
                        }
                    }
                    else if ((key.Modifiers & ConsoleModifiers.Alt) != 0)
                    {
                        switch (key.Key)
                        {
                        case ConsoleKey.F:
                        {
                            // ALT-F: move forward a word.
                            MoveForwardWord();
                        }
                        break;

                        case ConsoleKey.B:
                        {
                            // ALT-B: move backward a word.
                            MoveBackwardWord();
                        }
                        break;

                        case ConsoleKey.D:
                        {
                            // ALT-D: erase until the end of the word.
                            EraseToEndWord();
                        }
                        break;

                        case ConsoleKey.Backspace:
                        case ConsoleKey.Delete:
                        {
                            // ALT-DEL: erase until the start of the word.
                            EraseToStartWord();
                        }
                        break;
                        }
                    }
                } while (_state != ReadlineState.Done);
                return(new string(_buffer, 0, _length));
            }
            finally
            {
                Console.TreatControlCAsInput = treatControlCAsInterrupt;
            }
        }