示例#1
0
        public void AddBinding()
        {
            const ConsoleInputOperation op = ConsoleInputOperation.Undo;

            var bindings = new ConsoleKeyBindingSet();

            bindings.Bind(ConsoleKey.D, ConsoleModifiers.Control, op);

            var keyInfo = new ConsoleKeyInfo('\x04', ConsoleKey.D, false, false, true);

            bindings.Count.Should().Be(1);
            bindings.ContainsKey(keyInfo).Should().BeTrue();
            bindings.Keys.Should().Equal(keyInfo);
            bindings.Values.Should().Equal(op);

            bindings[keyInfo].Should().Be(op);

            var    nonExistentKeyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false);
            Action lookupAction       = () => { var x = bindings[nonExistentKeyInfo]; };

            lookupAction.Should().Throw <KeyNotFoundException>();

            var pairs = bindings.ToList();

            pairs.Should().ContainSingle();
            pairs.Should().Equal(new KeyValuePair <ConsoleKeyInfo, ConsoleInputOperation>(keyInfo, op));
        }
        private static bool TryGetValue(
            IReadOnlyDictionary <char, ConsoleInputOperation> charBindings,
            IReadOnlyDictionary <ConsoleKey, ConsoleInputOperation> keyBindings,
            IReadOnlyDictionary <ConsoleKey, ConsoleInputOperation> shiftKeyBindings,
            ConsoleKey key,
            ConsoleModifiers modifiers,
            out ConsoleInputOperation op)
        {
            var shiftModifiers = modifiers & ConsoleModifiers.Shift;
            var charWithoutNonShiftModifiers = InputUtilities.TryGetSingleChar(key, shiftModifiers);

            // It's important that we try the character bindings first.
            if (charWithoutNonShiftModifiers.HasValue &&
                charBindings.TryGetValue(char.ToLowerInvariant(charWithoutNonShiftModifiers.Value), out op))
            {
                return(true);
            }

            if (modifiers.HasFlag(ConsoleModifiers.Shift) &&
                (shiftKeyBindings != null) &&
                shiftKeyBindings.TryGetValue(key, out op))
            {
                return(true);
            }

            return(keyBindings.TryGetValue(key, out op));
        }
        /// <summary>
        /// Try to find the operation mapped to the specified key press.
        /// </summary>
        /// <param name="key">The key info.</param>
        /// <param name="value">On success, receives the mapped operation.</param>
        /// <returns>True if the key press is mapped; false otherwise.</returns>
        public bool TryGetValue(ConsoleKeyInfo key, out ConsoleInputOperation value)
        {
            if (_ignoredModifierKeyBindings.TryGetValue(key.Key, out value))
            {
                return(true);
            }

            var ctrl  = key.Modifiers.HasFlag(ConsoleModifiers.Control);
            var alt   = key.Modifiers.HasFlag(ConsoleModifiers.Alt);
            var shift = key.Modifiers.HasFlag(ConsoleModifiers.Shift);

            var modifiers = (ConsoleModifiers)0;

            if (ctrl)
            {
                modifiers |= ConsoleModifiers.Control;
            }
            if (alt)
            {
                modifiers |= ConsoleModifiers.Alt;
            }
            if (shift)
            {
                modifiers |= ConsoleModifiers.Shift;
            }

            IReadOnlyDictionary <char, ConsoleInputOperation>       charBindings;
            IReadOnlyDictionary <ConsoleKey, ConsoleInputOperation> keyBindings;
            IReadOnlyDictionary <ConsoleKey, ConsoleInputOperation> shiftKeyBindings;

            if (ctrl && alt)
            {
                charBindings     = _controlAltCharBindings;
                keyBindings      = _controlAltKeyBindings;
                shiftKeyBindings = null;
            }
            else if (alt)
            {
                charBindings     = _altCharBindings;
                keyBindings      = _altKeyBindings;
                shiftKeyBindings = null;
            }
            else if (ctrl)
            {
                charBindings     = _controlCharBindings;
                keyBindings      = _controlKeyBindings;
                shiftKeyBindings = null;
            }
            else
            {
                charBindings     = _plainCharBindings;
                keyBindings      = _plainKeyBindings;
                shiftKeyBindings = _shiftKeyBindings;
            }

            return(TryGetValue(charBindings, keyBindings, shiftKeyBindings, key.Key, modifiers, out value));
        }
示例#4
0
        public void RemoveCharBinding()
        {
            const ConsoleInputOperation op = ConsoleInputOperation.Undo;

            var bindings = new ConsoleKeyBindingSet();

            bindings.Bind('@', ConsoleModifiers.Control, op);

            bindings.Bind('@', ConsoleModifiers.Control, null);
            bindings.Values.Should().BeEmpty();
        }
        private static KeyValuePair <ConsoleKeyInfo, ConsoleInputOperation> CreatePair(
            char value,
            ConsoleModifiers modifiers,
            ConsoleInputOperation op)
        {
            var key = GetKey(value);

            var keyInfo = new ConsoleKeyInfo(
                value,
                key,
                modifiers.HasFlag(ConsoleModifiers.Shift),
                modifiers.HasFlag(ConsoleModifiers.Alt),
                modifiers.HasFlag(ConsoleModifiers.Control));

            return(new KeyValuePair <ConsoleKeyInfo, ConsoleInputOperation>(keyInfo, op));
        }
        private static KeyValuePair <ConsoleKeyInfo, ConsoleInputOperation> CreatePair(
            ConsoleKey key,
            ConsoleModifiers modifiers,
            ConsoleInputOperation op)
        {
            var c = InputUtilities.TryGetSingleChar(key, modifiers);

            var keyInfo = new ConsoleKeyInfo(
                c.GetValueOrDefault('\0'),
                key,
                modifiers.HasFlag(ConsoleModifiers.Shift),
                modifiers.HasFlag(ConsoleModifiers.Alt),
                modifiers.HasFlag(ConsoleModifiers.Control));

            return(new KeyValuePair <ConsoleKeyInfo, ConsoleInputOperation>(keyInfo, op));
        }
示例#7
0
        public void ReplaceBinding()
        {
            const ConsoleInputOperation oldOp = ConsoleInputOperation.Undo;
            const ConsoleInputOperation newOp = ConsoleInputOperation.Abort;

            var bindings = new ConsoleKeyBindingSet();

            bindings.Bind(ConsoleKey.D, ConsoleModifiers.Control, oldOp);
            bindings.Bind(ConsoleKey.D, ConsoleModifiers.Control, newOp);

            bindings.Values.Should().HaveCount(1);

            var keyInfo = new ConsoleKeyInfo('\x04', ConsoleKey.D, false, false, true);

            bindings[keyInfo].Should().Be(newOp);
        }
示例#8
0
        public void ReplaceBinding()
        {
            const ConsoleInputOperation oldOp = ConsoleInputOperation.Undo;
            const ConsoleInputOperation newOp = ConsoleInputOperation.Abort;
            var anyKey = Any.Enum <ConsoleKey>();

            var bindings = new ConsoleKeyBindingSet();

            bindings.Bind(anyKey, ConsoleModifiers.Control, oldOp);
            bindings.Bind(anyKey, ConsoleModifiers.Control, newOp);

            bindings.Values.Should().ContainSingle();

            var keyInfo = new ConsoleKeyInfo('\x04', anyKey, false, false, true);

            bindings[keyInfo].Should().Be(newOp);
        }
示例#9
0
        internal ConsoleInputOperationResult Process(ConsoleInputOperation op, ConsoleKeyInfo key)
        {
            var result = ConsoleInputOperationResult.Normal;

            switch (op)
            {
            case ConsoleInputOperation.NoOp:
                break;

            case ConsoleInputOperation.ProcessCharacter:
                ProcessCharacterKey(key.KeyChar);
                break;

            //
            // Standard readline operations.
            //

            case ConsoleInputOperation.AcceptLine:
                result = ConsoleInputOperationResult.EndOfInputLine;
                break;

            case ConsoleInputOperation.EndOfFile:
                if (string.IsNullOrEmpty(LineInput.Contents))
                {
                    ConsoleOutput.WriteLine(string.Empty);
                    result = ConsoleInputOperationResult.EndOfInputStream;
                }
                break;

            case ConsoleInputOperation.BeginningOfLine:
                LineInput.MoveCursorToStart();
                break;

            case ConsoleInputOperation.EndOfLine:
                LineInput.MoveCursorToEnd();
                break;

            case ConsoleInputOperation.ForwardChar:
                LineInput.MoveCursorForward(1);
                break;

            case ConsoleInputOperation.BackwardChar:
                LineInput.MoveCursorBackward(1);
                break;

            case ConsoleInputOperation.ClearScreen:
                LineInput.ClearScreen();
                break;

            case ConsoleInputOperation.PreviousHistory:
                LineInput.ReplaceWithLastLineInHistory();
                break;

            case ConsoleInputOperation.NextHistory:
                LineInput.ReplaceWithNextLineInHistory();
                break;

            case ConsoleInputOperation.KillLine:
                LineInput.CutToEnd();
                break;

            case ConsoleInputOperation.UnixWordRubout:
                LineInput.DeleteBackwardThroughLastWord();
                break;

            case ConsoleInputOperation.Yank:
                LineInput.Paste();
                break;

            case ConsoleInputOperation.Abort:
                LineInput.ClearLine(true);
                result = ConsoleInputOperationResult.EndOfInputLine;
                break;

            case ConsoleInputOperation.ForwardWord:
                LineInput.MoveCursorForwardOneWord();
                break;

            case ConsoleInputOperation.BackwardWord:
                LineInput.MoveCursorBackwardOneWord();
                break;

            case ConsoleInputOperation.BeginningOfHistory:
                LineInput.ReplaceWithOldestLineInHistory();
                break;

            case ConsoleInputOperation.EndOfHistory:
                LineInput.ReplaceWithYoungestLineInHistory();
                break;

            case ConsoleInputOperation.UpcaseWord:
                LineInput.TransformCurrentWord(word => word.ToUpper());
                break;

            case ConsoleInputOperation.DowncaseWord:
                LineInput.TransformCurrentWord(word => word.ToLower());
                break;

            case ConsoleInputOperation.CapitalizeWord:
                LineInput.TransformCurrentWord(Capitalize);
                break;

            case ConsoleInputOperation.KillWord:
                LineInput.DeleteForwardToNextWord();
                break;

            case ConsoleInputOperation.PossibleCompletions:
                LineInput.DisplayAllCompletions();
                break;

            case ConsoleInputOperation.InsertCompletions:
                LineInput.ReplaceCurrentTokenWithAllCompletions();
                break;

            case ConsoleInputOperation.RevertLine:
                LineInput.ClearLine(false);
                break;

            case ConsoleInputOperation.InsertComment:
                if (CommentCharacter.HasValue)
                {
                    LineInput.MoveCursorToStart();
                    LineInput.Insert(CommentCharacter.Value);

                    return(ConsoleInputOperationResult.EndOfInputLine);
                }
                break;

            case ConsoleInputOperation.TabInsert:
                ProcessCharacterKey('\t');
                break;

            case ConsoleInputOperation.BackwardKillWord:
                LineInput.DeleteBackwardThroughLastWord();
                break;

            //
            // Extensions:
            //

            case ConsoleInputOperation.CompleteTokenNext:
            {
                var lastOpWasCompleteToken =
                    _lastOp.HasValue &&
                    ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) ||
                     (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious));

                ProcessTabKeyPress(false, lastOpWasCompleteToken);
                break;
            }

            case ConsoleInputOperation.CompleteTokenPrevious:
            {
                var lastOpWasCompleteToken =
                    _lastOp.HasValue &&
                    ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) ||
                     (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious));

                ProcessTabKeyPress(true, lastOpWasCompleteToken);
                break;
            }

            case ConsoleInputOperation.DeletePreviousChar:
                LineInput.DeletePrecedingChar();
                break;

            case ConsoleInputOperation.DeleteChar:
                LineInput.Delete();
                break;

            case ConsoleInputOperation.ToggleInsertMode:
                LineInput.InsertMode = !LineInput.InsertMode;
                UpdateCursorSize();
                break;

            //
            // Unimplemented standard readline operations:
            //

            case ConsoleInputOperation.ReverseSearchHistory:
            // TODO: implement ReverseSearchHistory
            case ConsoleInputOperation.ForwardSearchHistory:
            // TODO: implement ForwardSearchHistory
            case ConsoleInputOperation.QuotedInsert:
            // TODO: implement QuotedInsert
            case ConsoleInputOperation.TransposeChars:
            // TODO: implement TransposeChars
            case ConsoleInputOperation.UnixLineDiscard:
            // TODO: implement UnixLineDiscard
            case ConsoleInputOperation.Undo:
            // TODO: implement Undo
            case ConsoleInputOperation.SetMark:
            // TODO: implement SetMark
            case ConsoleInputOperation.CharacterSearch:
            // TODO: implement CharacterSearch
            case ConsoleInputOperation.YankLastArg:
            // TODO: implement YankLastArg
            case ConsoleInputOperation.NonIncrementalReverseSearchHistory:
            // TODO: implement NonIncrementalReverseSearchHistory
            case ConsoleInputOperation.NonIncrementalForwardSearchHistory:
            // TODO: implement NonIncrementalForwardSearchHistory
            case ConsoleInputOperation.YankPop:
            // TODO: implement YankPop
            case ConsoleInputOperation.TildeExpand:
            // TODO: implement TildeExpand
            case ConsoleInputOperation.YankNthArg:
            // TODO: implement YankNthArg
            case ConsoleInputOperation.CharacterSearchBackward:
                // TODO: implement CharacterSearchBackward
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(op));
            }

            return(result);
        }
示例#10
0
        internal ConsoleInputOperationResult Process(ConsoleInputOperation op, ConsoleKeyInfo key)
        {
            var result = ConsoleInputOperationResult.Normal;

            switch (op)
            {
                case ConsoleInputOperation.NoOp:
                    break;

                case ConsoleInputOperation.Char:
                    ProcessCharacterKey(key.KeyChar);
                    break;

                //
                // Standard readline operations.
                //

                case ConsoleInputOperation.AcceptLine:
                    result = ConsoleInputOperationResult.EndOfInputLine;
                    break;
                case ConsoleInputOperation.EndOfFile:
                    if (string.IsNullOrEmpty(LineInput.Contents))
                    {
                        ConsoleOutput.WriteLine(string.Empty);
                        result = ConsoleInputOperationResult.EndOfInputStream;
                    }
                    break;
                case ConsoleInputOperation.BeginningOfLine:
                    LineInput.MoveCursorToStart();
                    break;
                case ConsoleInputOperation.EndOfLine:
                    LineInput.MoveCursorToEnd();
                    break;
                case ConsoleInputOperation.ForwardChar:
                    LineInput.MoveCursorForward(1);
                    break;
                case ConsoleInputOperation.BackwardChar:
                    LineInput.MoveCursorBackward(1);
                    break;
                case ConsoleInputOperation.ClearScreen:
                    LineInput.ClearScreen();
                    break;
                case ConsoleInputOperation.PreviousHistory:
                    LineInput.ReplaceWithLastLineInHistory();
                    break;
                case ConsoleInputOperation.NextHistory:
                    LineInput.ReplaceWithNextLineInHistory();
                    break;
                case ConsoleInputOperation.KillLine:
                    LineInput.CutToEnd();
                    break;
                case ConsoleInputOperation.UnixWordRubout:
                    LineInput.DeleteBackwardThroughLastWord();
                    break;
                case ConsoleInputOperation.Yank:
                    LineInput.Paste();
                    break;
                case ConsoleInputOperation.Abort:
                    LineInput.ClearLine(true);
                    result = ConsoleInputOperationResult.EndOfInputLine;
                    break;
                case ConsoleInputOperation.ForwardWord:
                    LineInput.MoveCursorForwardOneWord();
                    break;
                case ConsoleInputOperation.BackwardWord:
                    LineInput.MoveCursorBackwardOneWord();
                    break;
                case ConsoleInputOperation.BeginningOfHistory:
                    LineInput.ReplaceWithOldestLineInHistory();
                    break;
                case ConsoleInputOperation.EndOfHistory:
                    LineInput.ReplaceWithYoungestLineInHistory();
                    break;
                case ConsoleInputOperation.UpcaseWord:
                    LineInput.TransformCurrentWord(word => word.ToUpper(CultureInfo.CurrentCulture));
                    break;
                case ConsoleInputOperation.DowncaseWord:
                    LineInput.TransformCurrentWord(word => word.ToLower(CultureInfo.CurrentCulture));
                    break;
                case ConsoleInputOperation.CapitalizeWord:
                    LineInput.TransformCurrentWord(Capitalize);
                    break;
                case ConsoleInputOperation.KillWord:
                    LineInput.DeleteForwardToNextWord();
                    break;
                case ConsoleInputOperation.PossibleCompletions:
                    LineInput.DisplayAllCompletions();
                    break;
                case ConsoleInputOperation.InsertCompletions:
                    LineInput.ReplaceCurrentTokenWithAllCompletions();
                    break;
                case ConsoleInputOperation.RevertLine:
                    LineInput.ClearLine(false);
                    break;
                case ConsoleInputOperation.InsertComment:
                    if (CommentCharacter.HasValue)
                    {
                        LineInput.MoveCursorToStart();
                        LineInput.Insert(CommentCharacter.Value);

                        return ConsoleInputOperationResult.EndOfInputLine;
                    }
                    break;
                case ConsoleInputOperation.TabInsert:
                    ProcessCharacterKey('\t');
                    break;
                case ConsoleInputOperation.BackwardKillWord:
                    LineInput.DeleteBackwardThroughLastWord();
                    break;

                //
                // Extensions:
                //

                case ConsoleInputOperation.CompleteTokenNext:
                {
                    var lastOpWasCompleteToken =
                        _lastOp.HasValue &&
                        ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) ||
                            (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious));

                    ProcessTabKeyPress(false, lastOpWasCompleteToken);
                    break;
                }

                case ConsoleInputOperation.CompleteTokenPrevious:
                {
                    var lastOpWasCompleteToken =
                        _lastOp.HasValue &&
                        ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) ||
                            (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious));

                    ProcessTabKeyPress(true, lastOpWasCompleteToken);
                    break;
                }

                case ConsoleInputOperation.DeletePreviousChar:
                    LineInput.DeletePrecedingChar();
                    break;
                case ConsoleInputOperation.DeleteChar:
                    LineInput.Delete();
                    break;
                case ConsoleInputOperation.ToggleInsertMode:
                    LineInput.InsertMode = !LineInput.InsertMode;
                    UpdateCursorSize();
                    break;

                //
                // Unimplemented standard readline operations:
                //

                case ConsoleInputOperation.ReverseSearchHistory:
                    // TODO: implement ReverseSearchHistory
                case ConsoleInputOperation.ForwardSearchHistory:
                    // TODO: implement ForwardSearchHistory
                case ConsoleInputOperation.QuotedInsert:
                    // TODO: implement QuotedInsert
                case ConsoleInputOperation.TransposeChars:
                    // TODO: implement TransposeChars
                case ConsoleInputOperation.UnixLineDiscard:
                    // TODO: implement UnixLineDiscard
                case ConsoleInputOperation.Undo:
                    // TODO: implement Undo
                case ConsoleInputOperation.SetMark:
                    // TODO: implement SetMark
                case ConsoleInputOperation.CharacterSearch:
                    // TODO: implement CharacterSearch
                case ConsoleInputOperation.YankLastArg:
                    // TODO: implement YankLastArg
                case ConsoleInputOperation.NonIncrementalReverseSearchHistory:
                    // TODO: implement NonIncrementalReverseSearchHistory
                case ConsoleInputOperation.NonIncrementalForwardSearchHistory:
                    // TODO: implement NonIncrementalForwardSearchHistory
                case ConsoleInputOperation.YankPop:
                    // TODO: implement YankPop
                case ConsoleInputOperation.TildeExpand:
                    // TODO: implement TildeExpand
                case ConsoleInputOperation.YankNthArg:
                    // TODO: implement YankNthArg
                case ConsoleInputOperation.CharacterSearchBackward:
                    // TODO: implement CharacterSearchBackward
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(op));
            }

            return result;
        }