瀏覽代碼

Finished integrated tznind's work.

Tig 7 月之前
父節點
當前提交
2b8884a881

+ 6 - 5
Terminal.Gui/Application/Application.Keyboard.cs

@@ -64,16 +64,17 @@ public static partial class Application // Keyboard handling
             }
             else
             {
-                if (!KeyBindings.TryGet (key, out KeyBinding appBinding))
+                // BUGBUG: this seems unneeded.
+                if (!KeyBindings.TryGet (key, out KeyBinding keybinding))
                 {
                     return false;
                 }
 
                 bool? toReturn = null;
 
-                foreach (Command command in appBinding.Commands)
+                foreach (Command command in keybinding.Commands)
                 {
-                    toReturn = InvokeCommand (command, key, appBinding);
+                    toReturn = InvokeCommand (command, key, keybinding);
                 }
 
                 return toReturn ?? true;
@@ -82,7 +83,7 @@ public static partial class Application // Keyboard handling
 
         return false;
 
-        static bool? InvokeCommand (Command command, Key key, KeyBinding appBinding)
+        static bool? InvokeCommand (Command command, Key key, KeyBinding binding)
         {
             if (!_commandImplementations!.ContainsKey (command))
             {
@@ -93,7 +94,7 @@ public static partial class Application // Keyboard handling
 
             if (_commandImplementations.TryGetValue (command, out View.CommandImplementation? implementation))
             {
-                CommandContext<KeyBinding> context = new (command, appBinding); // Create the context here
+                CommandContext<KeyBinding> context = new (command, binding); // Create the context here
 
                 return implementation (context);
             }

+ 4 - 4
Terminal.Gui/Application/Application.Navigation.cs

@@ -22,7 +22,7 @@ public static partial class Application // Navigation stuff
         {
             if (_nextTabGroupKey != value)
             {
-                KeyBindings.ReplaceKey (_nextTabGroupKey, value);
+                KeyBindings.Replace (_nextTabGroupKey, value);
                 _nextTabGroupKey = value;
             }
         }
@@ -37,7 +37,7 @@ public static partial class Application // Navigation stuff
         {
             if (_nextTabKey != value)
             {
-                KeyBindings.ReplaceKey (_nextTabKey, value);
+                KeyBindings.Replace (_nextTabKey, value);
                 _nextTabKey = value;
             }
         }
@@ -66,7 +66,7 @@ public static partial class Application // Navigation stuff
         {
             if (_prevTabGroupKey != value)
             {
-                KeyBindings.ReplaceKey (_prevTabGroupKey, value);
+                KeyBindings.Replace (_prevTabGroupKey, value);
                 _prevTabGroupKey = value;
             }
         }
@@ -81,7 +81,7 @@ public static partial class Application // Navigation stuff
         {   
             if (_prevTabKey != value)
             {
-                KeyBindings.ReplaceKey (_prevTabKey, value);
+                KeyBindings.Replace (_prevTabKey, value);
                 _prevTabKey = value;
             }
         }

+ 2 - 2
Terminal.Gui/Application/Application.Run.cs

@@ -19,7 +19,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
         {
             if (_quitKey != value)
             {
-                KeyBindings.ReplaceKey (_quitKey, value);
+                KeyBindings.Replace (_quitKey, value);
                 _quitKey = value;
             }
         }
@@ -37,7 +37,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
         {
             if (_arrangeKey != value)
             {
-                KeyBindings.ReplaceKey (_arrangeKey, value);
+                KeyBindings.Replace (_arrangeKey, value);
                 _arrangeKey = value;
             }
         }

+ 0 - 150
Terminal.Gui/Input/Bindings.cs

@@ -1,150 +0,0 @@
-#nullable enable
-using System;
-
-namespace Terminal.Gui;
-
-/// <summary>
-///     Abstract base class for <see cref="KeyBindings"/> and <see cref="MouseBindings"/>.
-/// </summary>
-/// <typeparam name="TEvent">The type of the event (e.g. <see cref="Key"/> or <see cref="MouseEventArgs"/>).</typeparam>
-/// <typeparam name="TBinding">The binding type (e.g. <see cref="KeyBinding"/>).</typeparam>
-public abstract class Bindings<TEvent, TBinding>  where TBinding : IInputBinding, new() where TEvent : notnull
-{
-    /// <summary>
-    ///     The bindings.
-    /// </summary>
-    protected readonly Dictionary<TEvent, TBinding> _bindings;
-
-    private readonly Func<Command [], TEvent, TBinding> _constructBinding;
-
-    /// <summary>
-    ///     Initializes a new instance.
-    /// </summary>
-    /// <param name="constructBinding"></param>
-    /// <param name="equalityComparer"></param>
-    protected Bindings (Func<Command [], TEvent, TBinding> constructBinding, IEqualityComparer<TEvent> equalityComparer)
-    {
-        _constructBinding = constructBinding;
-        _bindings = new (equalityComparer);
-    }
-
-    /// <summary>Adds a <see cref="TEvent"/> bound to <see cref="TBinding"/> to the collection.</summary>
-    /// <param name="eventArgs"></param>
-    /// <param name="binding"></param>
-    public void Add (TEvent eventArgs, TBinding binding)
-    { 
-        if (TryGet (eventArgs, out TBinding _))
-        {
-            throw new InvalidOperationException (@$"A binding for {eventArgs} exists ({binding}).");
-        }
-
-        // IMPORTANT: Add a COPY of the mouseEventArgs. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy 
-        // IMPORTANT: update the memory referenced by the key, and Dictionary uses caching for performance, and thus 
-        // IMPORTANT: Apply will update the Dictionary with the new mouseEventArgs, but the old mouseEventArgs will still be in the dictionary.
-        // IMPORTANT: See the ConfigurationManager.Illustrate_DeepMemberWiseCopy_Breaks_Dictionary test for details.
-        _bindings.Add (eventArgs, binding);
-    }
-
-
-    /// <summary>Gets the commands bound with the specified <see cref="TEvent"/>.</summary>
-    /// <remarks></remarks>
-    /// <param name="eventArgs">The args to check.</param>
-    /// <param name="binding">
-    ///     When this method returns, contains the commands bound with the specified mouse flags, if the mouse flags are
-    ///     found; otherwise, null. This parameter is passed uninitialized.
-    /// </param>
-    /// <returns><see langword="true"/> if the mouse flags are bound; otherwise <see langword="false"/>.</returns>
-    public bool TryGet (TEvent eventArgs, out TBinding? binding)
-    {
-         return _bindings.TryGetValue (eventArgs, out binding);
-    }
-
-
-    /// <summary>
-    ///     <para>Adds a new mouse flag combination that will trigger the commands in <paramref name="commands"/>.</para>
-    ///     <para>
-    ///         If the key is already bound to a different array of <see cref="Command"/>s it will be rebound
-    ///         <paramref name="commands"/>.
-    ///     </para>
-    /// </summary>
-    /// <remarks>
-    ///     Commands are only ever applied to the current <see cref="View"/> (i.e. this feature cannot be used to switch
-    ///     focus to another view and perform multiple commands there).
-    /// </remarks>
-    /// <param name="eventArgs">The mouse flags to check.</param>
-    /// <param name="commands">
-    ///     The command to invoked on the <see cref="View"/> when <paramref name="eventArgs"/> is received. When
-    ///     multiple commands are provided,they will be applied in sequence. The bound <paramref name="eventArgs"/> event
-    ///     will be
-    ///     consumed if any took effect.
-    /// </param>
-    public void Add (TEvent eventArgs, params Command [] commands)
-    {
-        if (commands.Length == 0)
-        {
-            throw new ArgumentException (@"At least one command must be specified", nameof (commands));
-        }
-
-        if (TryGet (eventArgs, out var binding))
-        {
-            throw new InvalidOperationException (@$"A binding for {eventArgs} exists ({binding}).");
-        }
-
-        Add (eventArgs, _constructBinding(commands,eventArgs));
-    }
-
-    /// <summary>
-    ///     Gets the bindings.
-    /// </summary>
-    /// <returns></returns>
-    public IEnumerable<KeyValuePair<TEvent, TBinding>> GetBindings ()
-    {
-        return _bindings;
-    }
-
-    /// <summary>Removes all <see cref="TEvent"/> objects from the collection.</summary>
-    public void Clear () { _bindings.Clear (); }
-
-    /// <summary>
-    ///     Removes all bindings that trigger the given command set. Views can have multiple different events bound to
-    ///     the same command sets and this method will clear all of them.
-    /// </summary>
-    /// <param name="command"></param>
-    public void Clear (params Command [] command)
-    {
-        KeyValuePair<TEvent, TBinding> [] kvps = _bindings
-                                            .Where (kvp => kvp.Value.Commands.SequenceEqual (command))
-                                            .ToArray ();
-
-        foreach (KeyValuePair<TEvent, TBinding> kvp in kvps)
-        {
-            Remove (kvp.Key);
-        }
-    }
-
-    /// <summary>Gets the <see cref="TBinding"/> for the specified <see cref="TEvent"/>.</summary>
-    /// <param name="eventArgs"></param>
-    /// <returns></returns>
-    public TBinding? Get (TEvent eventArgs)
-    {
-        if (TryGet (eventArgs, out var binding))
-        {
-            return binding;
-        }
-
-        throw new InvalidOperationException ($"{eventArgs} is not bound.");
-    }
-
-
-    /// <summary>Removes a <see cref="MouseBinding"/> from the collection.</summary>
-    /// <param name="mouseEventArgs"></param>
-    public void Remove (TEvent mouseEventArgs)
-    {
-        if (!TryGet (mouseEventArgs, out var _))
-        {
-            return;
-        }
-
-        _bindings.Remove (mouseEventArgs);
-    }
-}

+ 6 - 0
Terminal.Gui/Input/IInputBinding.cs

@@ -1,7 +1,13 @@
 #nullable enable
 namespace Terminal.Gui;
 
+/// <summary>
+///     Describes an input binding. Used to bind a set of <see cref="Command"/> objects to a specific input event.
+/// </summary>
 public interface IInputBinding
 {
+    /// <summary>
+    ///     Gets or sets the commands this input binding will invoke.
+    /// </summary>
     Command [] Commands { get; set; }
 }

+ 233 - 0
Terminal.Gui/Input/InputBindings.cs

@@ -0,0 +1,233 @@
+#nullable enable
+namespace Terminal.Gui;
+
+/// <summary>
+///     Abstract base class for <see cref="KeyBindings"/> and <see cref="MouseBindings"/>.
+/// </summary>
+/// <typeparam name="TEvent">The type of the event (e.g. <see cref="Key"/> or <see cref="MouseFlags"/>).</typeparam>
+/// <typeparam name="TBinding">The binding type (e.g. <see cref="KeyBinding"/>).</typeparam>
+public abstract class InputBindings<TEvent, TBinding> where TBinding : IInputBinding, new () where TEvent : notnull
+{
+    /// <summary>
+    ///     The bindings.
+    /// </summary>
+    private readonly Dictionary<TEvent, TBinding> _bindings;
+
+    private readonly Func<Command [], TEvent, TBinding> _constructBinding;
+
+    /// <summary>
+    ///     Initializes a new instance.
+    /// </summary>
+    /// <param name="constructBinding"></param>
+    /// <param name="equalityComparer"></param>
+    protected InputBindings (Func<Command [], TEvent, TBinding> constructBinding, IEqualityComparer<TEvent> equalityComparer)
+    {
+        _constructBinding = constructBinding;
+        _bindings = new (equalityComparer);
+    }
+
+    /// <summary>
+    ///     Tests whether <paramref name="eventArgs"/> is valid or not.
+    /// </summary>
+    /// <param name="eventArgs"></param>
+    /// <returns></returns>
+    public abstract bool IsValid (TEvent eventArgs);
+
+    /// <summary>Adds a <typeparamref name="TEvent"/> bound to <typeparamref name="TBinding"/> to the collection.</summary>
+    /// <param name="eventArgs"></param>
+    /// <param name="binding"></param>
+    public void Add (TEvent eventArgs, TBinding binding)
+    {
+        if (!IsValid (eventArgs))
+        {
+            throw new ArgumentException (@"Invalid newEventArgs", nameof (eventArgs));
+        }
+
+        if (TryGet (eventArgs, out TBinding _))
+        {
+            throw new InvalidOperationException (@$"A binding for {eventArgs} exists ({binding}).");
+        }
+
+        // IMPORTANT: Add a COPY of the eventArgs. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy 
+        // IMPORTANT: update the memory referenced by the key, and Dictionary uses caching for performance, and thus 
+        // IMPORTANT: Apply will update the Dictionary with the new eventArgs, but the old eventArgs will still be in the dictionary.
+        // IMPORTANT: See the ConfigurationManager.Illustrate_DeepMemberWiseCopy_Breaks_Dictionary test for details.
+        _bindings.Add (eventArgs, binding);
+    }
+
+    /// <summary>
+    ///     <para>Adds a new <typeparamref name="TEvent"/> that will trigger the commands in <paramref name="commands"/>.</para>
+    ///     <para>
+    ///         If the <typeparamref name="TEvent"/> is already bound to a different set of <see cref="Command"/>s it will be rebound
+    ///         <paramref name="commands"/>.
+    ///     </para>
+    /// </summary>
+    /// <param name="eventArgs">The event to check.</param>
+    /// <param name="commands">
+    ///     The command to invoked on the <see cref="View"/> when <paramref name="eventArgs"/> is received. When
+    ///     multiple commands are provided,they will be applied in sequence. The bound <paramref name="eventArgs"/> event
+    ///     will be
+    ///     consumed if any took effect.
+    /// </param>
+    public void Add (TEvent eventArgs, params Command [] commands)
+    {
+        if (commands.Length == 0)
+        {
+            throw new ArgumentException (@"At least one command must be specified", nameof (commands));
+        }
+
+        if (TryGet (eventArgs, out TBinding? binding))
+        {
+            throw new InvalidOperationException (@$"A binding for {eventArgs} exists ({binding}).");
+        }
+
+        Add (eventArgs, _constructBinding (commands, eventArgs));
+    }
+
+    /// <summary>
+    ///     Gets the bindings.
+    /// </summary>
+    /// <returns></returns>
+    public IEnumerable<KeyValuePair<TEvent, TBinding>> GetBindings () { return _bindings; }
+
+    /// <summary>Removes all <typeparamref name="TEvent"/> objects from the collection.</summary>
+    public void Clear () { _bindings.Clear (); }
+
+    /// <summary>
+    ///     Removes all bindings that trigger the given command set. Views can have multiple different <typeparamref name="TEvent"/>
+    ///     bound to
+    ///     the same command sets and this method will clear all of them.
+    /// </summary>
+    /// <param name="command"></param>
+    public void Clear (params Command [] command)
+    {
+        KeyValuePair<TEvent, TBinding> [] kvps = _bindings
+                                                 .Where (kvp => kvp.Value.Commands.SequenceEqual (command))
+                                                 .ToArray ();
+
+        foreach (KeyValuePair<TEvent, TBinding> kvp in kvps)
+        {
+            Remove (kvp.Key);
+        }
+    }
+
+    /// <summary>Gets the <typeparamref name="TBinding"/> for the specified <typeparamref name="TEvent"/>.</summary>
+    /// <param name="eventArgs"></param>
+    /// <returns></returns>
+    public TBinding? Get (TEvent eventArgs)
+    {
+        if (TryGet (eventArgs, out TBinding? binding))
+        {
+            return binding;
+        }
+
+        throw new InvalidOperationException ($"{eventArgs} is not bound.");
+    }
+
+    /// <summary>Gets the commands bound with the specified <typeparamref name="TEvent"/>.</summary>
+    /// <remarks></remarks>
+    /// <param name="eventArgs">The <typeparamref name="TEvent"/> to check.</param>
+    /// <param name="binding">
+    ///     When this method returns, contains the commands bound with the <typeparamref name="TEvent"/>, if the <typeparamref name="TEvent"/> is
+    ///     not
+    ///     found; otherwise, null. This parameter is passed uninitialized.
+    /// </param>
+    /// <returns><see langword="true"/> if the <typeparamref name="TEvent"/> is bound; otherwise <see langword="false"/>.</returns>
+    public bool TryGet (TEvent eventArgs, out TBinding? binding) { return _bindings.TryGetValue (eventArgs, out binding); }
+
+    /// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="eventArgs"/> if it exists.</summary>
+    /// <param name="eventArgs">The key to check.</param>
+    /// <returns>
+    ///     The array of <see cref="Command"/>s if <paramref name="eventArgs"/> is bound. An empty <see cref="Command"/> array
+    ///     if not.
+    /// </returns>
+    public Command [] GetCommands (TEvent eventArgs)
+    {
+        if (TryGet (eventArgs, out TBinding? bindings))
+        {
+            return bindings!.Commands;
+        }
+
+        return [];
+    }
+
+    /// <summary>
+    ///     Gets the first matching <typeparamref name="TEvent"/> bound to the set of commands specified by
+    ///     <paramref name="commands"/>.
+    /// </summary>
+    /// <param name="commands">The set of commands to search.</param>
+    /// <returns>
+    ///     The first matching <typeparamref name="TEvent"/> bound to the set of commands specified by
+    ///     <paramref name="commands"/>. <see langword="null"/> if the set of caommands was not found.
+    /// </returns>
+    public TEvent GetFirstFromCommands (params Command [] commands) { return _bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key; }
+
+    /// <summary>Gets all <typeparamref name="TEvent"/> bound to the set of commands specified by <paramref name="commands"/>.</summary>
+    /// <param name="commands">The set of commands to search.</param>
+    /// <returns>
+    ///     The <typeparamref name="TEvent"/>s bound to the set of commands specified by <paramref name="commands"/>. An empty list if
+    ///     the
+    ///     set of caommands was not found.
+    /// </returns>
+    public IEnumerable<TEvent> GetAllFromCommands (params Command [] commands)
+    {
+        return _bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
+    }
+
+    /// <summary>Replaces a <typeparamref name="TEvent"/> combination already bound to a set of <see cref="Command"/>s.</summary>
+    /// <remarks></remarks>
+    /// <param name="oldEventArgs">The <typeparamref name="TEvent"/> to be replaced.</param>
+    /// <param name="newEventArgs">
+    ///     The new <typeparamref name="TEvent"/> to be used.
+    /// </param>
+    public void Replace (TEvent oldEventArgs, TEvent newEventArgs)
+    {
+        if (!IsValid (newEventArgs))
+        {
+            throw new ArgumentException (@"Invalid newEventArgs", nameof (newEventArgs));
+        }
+
+        if (TryGet (oldEventArgs, out TBinding? binding))
+        {
+            Remove (oldEventArgs);
+            Add (newEventArgs, binding!);
+        }
+        else
+        {
+            Add (newEventArgs, binding!);
+        }
+    }
+
+    /// <summary>Replaces the commands already bound to a combination of <typeparamref name="TEvent"/>.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         If the of <typeparamref name="TEvent"/> is not already bound, it will be added.
+    ///     </para>
+    /// </remarks>
+    /// <param name="eventArgs">The combination of <typeparamref name="TEvent"/> bound to the command to be replaced.</param>
+    /// <param name="newCommands">The set of commands to replace the old ones with.</param>
+    public void ReplaceCommands (TEvent eventArgs, params Command [] newCommands)
+    {
+        if (TryGet (eventArgs, out TBinding _))
+        {
+            Remove (eventArgs);
+            Add (eventArgs, newCommands);
+        }
+        else
+        {
+            Add (eventArgs, newCommands);
+        }
+    }
+
+    /// <summary>Removes a <typeparamref name="TEvent"/> from the collection.</summary>
+    /// <param name="eventArgs"></param>
+    public void Remove (TEvent eventArgs)
+    {
+        if (!TryGet (eventArgs, out _))
+        {
+            return;
+        }
+
+        _bindings.Remove (eventArgs);
+    }
+}

+ 6 - 167
Terminal.Gui/Input/Keyboard/KeyBindings.cs

@@ -2,21 +2,22 @@
 namespace Terminal.Gui;
 
 /// <summary>
-///     Provides a collection of <see cref="KeyBinding"/> objects bound to a <see cref="Key"/>.
+///     Provides a collection of <see cref="Key"/>s bound to <see cref="Command"/>s.
 /// </summary>
 /// <seealso cref="Application.KeyBindings"/>
 /// <seealso cref="View.KeyBindings"/>
 /// <seealso cref="Command"/>
-public class KeyBindings : Bindings<Key, KeyBinding>
+public class KeyBindings : InputBindings<Key, KeyBinding>
 {
     /// <summary>Initializes a new instance bound to <paramref name="target"/>.</summary>
-    public KeyBindings (View? target) : base (
-                                              (commands, key) => new (commands),
-                                              new KeyEqualityComparer ())
+    public KeyBindings (View? target) : base ((commands, key) => new (commands), new KeyEqualityComparer ())
     {
         Target = target;
     }
 
+    /// <inheritdoc />
+    public override bool IsValid (Key eventArgs) { return eventArgs.IsValid; }
+
     /// <summary>
     ///     <para>
     ///         Adds a new key combination that will trigger the commands in <paramref name="commands"/> on the View
@@ -45,18 +46,6 @@ public class KeyBindings : Bindings<Key, KeyBinding>
         Add (key, binding);
     }
 
-    /// <summary>
-    ///     Gets the bindings.
-    /// </summary>
-    /// <returns></returns>
-    public IEnumerable<KeyValuePair<Key, KeyBinding>> GetBindings () { return _bindings; }
-
-    /// <summary>
-    ///     Gets the keys that are bound.
-    /// </summary>
-    /// <returns></returns>
-    public IEnumerable<Key> GetBoundKeys () { return _bindings.Keys; }
-
     /// <summary>
     ///     The view that the <see cref="KeyBindings"/> are bound to.
     /// </summary>
@@ -64,154 +53,4 @@ public class KeyBindings : Bindings<Key, KeyBinding>
     ///     If <see langword="null"/> the KeyBindings object is being used for Application.KeyBindings.
     /// </remarks>
     public View? Target { get; init; }
-
-    /// <summary>Removes all <see cref="KeyBinding"/> objects from the collection.</summary>
-    public void Clear () { _bindings.Clear (); }
-
-    /// <summary>
-    ///     Removes all key bindings that trigger the given command set. Views can have multiple different keys bound to
-    ///     the same command sets and this method will clear all of them.
-    /// </summary>
-    /// <param name="command"></param>
-    public void Clear (params Command [] command)
-    {
-        KeyValuePair<Key, KeyBinding> [] kvps = _bindings
-                                                .Where (kvp => kvp.Value.Commands.SequenceEqual (command))
-                                                .ToArray ();
-
-        foreach (KeyValuePair<Key, KeyBinding> kvp in kvps)
-        {
-            Remove (kvp.Key);
-        }
-    }
-
-    /// <summary>Gets the <see cref="KeyBinding"/> for the specified <see cref="Key"/>.</summary>
-    /// <param name="key"></param>
-    /// <returns></returns>
-    public KeyBinding Get (Key key)
-    {
-        if (TryGet (key, out KeyBinding binding))
-        {
-            return binding;
-        }
-
-        throw new InvalidOperationException ($"Key {key} is not bound.");
-    }
-
-    /// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="key"/> if it exists.</summary>
-    /// <param name="key">The key to check.</param>
-    /// <returns>
-    ///     The array of <see cref="Command"/>s if <paramref name="key"/> is bound. An empty <see cref="Command"/> array
-    ///     if not.
-    /// </returns>
-    public Command [] GetCommands (Key key)
-    {
-        if (TryGet (key, out KeyBinding bindings))
-        {
-            return bindings.Commands;
-        }
-
-        return [];
-    }
-
-    /// <summary>Gets the first Key bound to the set of commands specified by <paramref name="commands"/>.</summary>
-    /// <param name="commands">The set of commands to search.</param>
-    /// <returns>
-    ///     The first <see cref="Key"/> bound to the set of commands specified by <paramref name="commands"/>.
-    ///     <see langword="null"/> if the set of caommands was not found.
-    /// </returns>
-    public Key? GetKeyFromCommands (params Command [] commands) { return _bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key; }
-
-    /// <summary>Gets Keys bound to the set of commands specified by <paramref name="commands"/>.</summary>
-    /// <param name="commands">The set of commands to search.</param>
-    /// <returns>
-    ///     The <see cref="Key"/>s bound to the set of commands specified by <paramref name="commands"/>. An empty list if the
-    ///     set of caommands was not found.
-    /// </returns>
-    public IEnumerable<Key> GetKeysFromCommands (params Command [] commands)
-    {
-        return _bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
-    }
-
-    /// <summary>Removes a <see cref="KeyBinding"/> from the collection.</summary>
-    /// <param name="key"></param>
-    public void Remove (Key key)
-    {
-        if (!TryGet (key, out KeyBinding _))
-        {
-            return;
-        }
-
-        _bindings.Remove (key);
-    }
-
-    /// <summary>Replaces the commands already bound to a key.</summary>
-    /// <remarks>
-    ///     <para>
-    ///         If the key is not already bound, it will be added.
-    ///     </para>
-    /// </remarks>
-    /// <param name="key">The key bound to the command to be replaced.</param>
-    /// <param name="newCommands">The set of commands to replace the old ones with.</param>
-    public void ReplaceCommands (Key key, params Command [] newCommands)
-    {
-        if (TryGet (key, out KeyBinding binding))
-        {
-            Remove (key);
-            Add (key, newCommands);
-        }
-        else
-        {
-            Add (key, newCommands);
-        }
-    }
-
-    /// <summary>Replaces a key combination already bound to a set of <see cref="Command"/>s.</summary>
-    /// <remarks></remarks>
-    /// <param name="oldKey">The key to be replaced.</param>
-    /// <param name="newKey">The new key to be used. If <see cref="Key.Empty"/> no action will be taken.</param>
-    public void ReplaceKey (Key oldKey, Key newKey)
-    {
-        if (!newKey.IsValid)
-        {
-            throw new InvalidOperationException ($"Key {newKey} is is not valid.");
-        }
-
-        if (newKey == Key.Empty)
-        {
-            Remove (oldKey);
-
-            return;
-        }
-
-        if (TryGet (oldKey, out KeyBinding binding))
-        {
-            Remove (oldKey);
-            Add (newKey, binding);
-        }
-        else
-        {
-            Add (newKey, binding);
-        }
-    }
-
-    /// <summary>Gets the commands bound with the specified Key.</summary>
-    /// <remarks></remarks>
-    /// <param name="key">The key to check.</param>
-    /// <param name="binding">
-    ///     When this method returns, contains the commands bound with the specified Key, if the Key is
-    ///     found; otherwise, null. This parameter is passed uninitialized.
-    /// </param>
-    /// <returns><see langword="true"/> if the Key is bound; otherwise <see langword="false"/>.</returns>
-    public bool TryGet (Key key, out KeyBinding binding)
-    {
-        binding = new ([], null);
-
-        if (key.IsValid)
-        {
-            return _bindings.TryGetValue (key, out binding);
-        }
-
-        return false;
-    }
 }

+ 3 - 2
Terminal.Gui/Input/Mouse/MouseBinding.cs

@@ -3,8 +3,9 @@
 namespace Terminal.Gui;
 
 /// <summary>
-/// Provides a collection of <see cref="Command"/> objects for mouse events.
+///     Provides a collection of <see cref="MouseFlags"/> bound to <see cref="Command"/>s.
 /// </summary>
+/// <seealso cref="MouseBindings"/>
 /// <seealso cref="Command"/>
 public record struct MouseBinding : IInputBinding
 {
@@ -21,7 +22,7 @@ public record struct MouseBinding : IInputBinding
         };
     }
 
-    /// <summary>The commands this key binding will invoke.</summary>
+    /// <summary>The commands this binding will invoke.</summary>
     public Command [] Commands { get; set; }
 
     /// <summary>

+ 3 - 112
Terminal.Gui/Input/Mouse/MouseBindings.cs

@@ -6,7 +6,7 @@ namespace Terminal.Gui;
 /// </summary>
 /// <seealso cref="View.MouseBindings"/>
 /// <seealso cref="Command"/>
-public class MouseBindings : Bindings<MouseFlags, MouseBinding>
+public class MouseBindings : InputBindings<MouseFlags, MouseBinding>
 {
     /// <summary>
     ///     Initializes a new instance.
@@ -16,115 +16,6 @@ public class MouseBindings : Bindings<MouseFlags, MouseBinding>
                                     EqualityComparer<MouseFlags>.Default)
     { }
 
-    /// <summary>
-    ///     Gets combination of <see cref="MouseFlags"/> bound to the set of commands specified by
-    ///     <paramref name="commands"/>.
-    /// </summary>
-    /// <param name="commands">The set of commands to search.</param>
-    /// <returns>
-    ///     The combination of <see cref="MouseFlags"/> bound to the set of commands specified by
-    ///     <paramref name="commands"/>. An empty list if the set of caommands was not found.
-    /// </returns>
-    public IEnumerable<MouseFlags> GetAllMouseFlagsFromCommands (params Command [] commands)
-    {
-        return _bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
-    }
-
-    /// <summary>
-    ///     Gets the <see cref="MouseFlags"/> that are bound.
-    /// </summary>
-    /// <returns></returns>
-    public IEnumerable<MouseFlags> GetBoundMouseFlags () { return _bindings.Keys; }
-
-    /// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="mouseFlags"/> if it exists.</summary>
-    /// <param name="mouseFlags">The key to check.</param>
-    /// <returns>
-    ///     The array of <see cref="Command"/>s if <paramref name="mouseFlags"/> is bound. An empty <see cref="Command"/>
-    ///     array
-    ///     if not.
-    /// </returns>
-    public Command [] GetCommands (MouseFlags mouseFlags)
-    {
-        if (TryGet (mouseFlags, out MouseBinding bindings))
-        {
-            return bindings.Commands;
-        }
-
-        return [];
-    }
-
-    /// <summary>
-    ///     Gets the first combination of <see cref="MouseFlags"/> bound to the set of commands specified by
-    ///     <paramref name="commands"/>.
-    /// </summary>
-    /// <param name="commands">The set of commands to search.</param>
-    /// <returns>
-    ///     The first combination of <see cref="MouseFlags"/> bound to the set of commands specified by
-    ///     <paramref name="commands"/>. <see langword="null"/> if the set of caommands was not found.
-    /// </returns>
-    public MouseFlags GetMouseFlagsFromCommands (params Command [] commands)
-    {
-        return _bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key;
-    }
-
-    /// <summary>Replaces the commands already bound to a combination of <see cref="MouseFlags"/>.</summary>
-    /// <remarks>
-    ///     <para>
-    ///         If the combination of <see cref="MouseFlags"/> is not already bound, it will be added.
-    ///     </para>
-    /// </remarks>
-    /// <param name="mouseEventArgs">The combination of <see cref="MouseFlags"/> bound to the command to be replaced.</param>
-    /// <param name="newCommands">The set of commands to replace the old ones with.</param>
-    public void ReplaceCommands (MouseFlags mouseEventArgs, params Command [] newCommands)
-    {
-        if (TryGet (mouseEventArgs, out MouseBinding binding))
-        {
-            Remove (mouseEventArgs);
-            Add (mouseEventArgs, newCommands);
-        }
-        else
-        {
-            Add (mouseEventArgs, newCommands);
-        }
-    }
-
-    /// <summary>Replaces a <see cref="MouseFlags"/> combination already bound to a set of <see cref="Command"/>s.</summary>
-    /// <remarks></remarks>
-    /// <param name="oldMouseFlags">The <see cref="MouseFlags"/> to be replaced.</param>
-    /// <param name="newMouseFlags">
-    ///     The new <see cref="MouseFlags"/> to be used. If <see cref="Key.Empty"/> no action
-    ///     will be taken.
-    /// </param>
-    public void ReplaceMouseFlag (MouseFlags oldMouseFlags, MouseFlags newMouseFlags)
-    {
-        if (newMouseFlags == MouseFlags.None)
-        {
-            throw new ArgumentException (@"Invalid MouseFlag", nameof (newMouseFlags));
-        }
-
-        if (TryGet (oldMouseFlags, out MouseBinding binding))
-        {
-            Remove (oldMouseFlags);
-            Add (newMouseFlags, binding);
-        }
-        else
-        {
-            Add (newMouseFlags, binding);
-        }
-    }
-
-    /// <summary>Gets the commands bound with the specified <see cref="MouseFlags"/>.</summary>
-    /// <remarks></remarks>
-    /// <param name="mouseEventArgs">The key to check.</param>
-    /// <param name="binding">
-    ///     When this method returns, contains the commands bound with the specified mouse flags, if the mouse flags are
-    ///     found; otherwise, null. This parameter is passed uninitialized.
-    /// </param>
-    /// <returns><see langword="true"/> if the mouse flags are bound; otherwise <see langword="false"/>.</returns>
-    public bool TryGet (MouseFlags mouseEventArgs, out MouseBinding binding)
-    {
-        binding = new ([], mouseEventArgs);
-
-        return _bindings.TryGetValue (mouseEventArgs, out binding);
-    }
+    /// <inheritdoc />
+    public override bool IsValid (MouseFlags eventArgs) { return eventArgs != MouseFlags.None; }
 }

+ 0 - 12
Terminal.Gui/View/View.Keyboard.cs

@@ -358,10 +358,6 @@ public partial class View // Keyboard APIs
     ///     and processing should stop.
     /// </returns>
     /// <remarks>
-    ///     <para>
-    ///         For processing <see cref="HotKey"/>s and commands, use <see cref="Command"/> and
-    ///         <see cref="KeyBindings.Add(Key, Command[])"/>instead.
-    ///     </para>
     ///     <para>Fires the <see cref="KeyDown"/> event.</para>
     /// </remarks>
     protected virtual bool OnKeyDown (Key key) { return false; }
@@ -387,10 +383,6 @@ public partial class View // Keyboard APIs
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         For processing <see cref="HotKey"/>s and commands, use <see cref="Command"/> and
-    ///         <see cref="KeyBindings.Add(Key, Command[])"/>instead.
-    ///     </para>
-    ///     <para>
     ///         Not all terminals support distinct key up notifications; applications should avoid depending on distinct
     ///         KeyUp events.
     ///     </para>
@@ -407,10 +399,6 @@ public partial class View // Keyboard APIs
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         For processing <see cref="HotKey"/>s and commands, use <see cref="Command"/> and
-    ///         <see cref="KeyBindings.Add(Key, Command[])"/>instead.
-    ///     </para>
-    ///     <para>
     ///         SubViews can use the <see cref="KeyDownNotHandled"/> of their super view override the default behavior of when
     ///         key bindings are invoked.
     ///     </para>

+ 4 - 4
Terminal.Gui/Views/ColorPicker.16.cs

@@ -67,7 +67,7 @@ public class ColorPicker16 : View
 
     /// <summary>Moves the selected item index to the next row.</summary>
     /// <returns></returns>
-    private bool MoveDown (ICommandContext commandContext)
+    private bool MoveDown (ICommandContext? commandContext)
     {
         if (RaiseSelecting (commandContext) == true)
         {
@@ -83,7 +83,7 @@ public class ColorPicker16 : View
 
     /// <summary>Moves the selected item index to the previous column.</summary>
     /// <returns></returns>
-    private bool MoveLeft (ICommandContext commandContext)
+    private bool MoveLeft (ICommandContext? commandContext)
     {
         if (RaiseSelecting (commandContext) == true)
         {
@@ -100,7 +100,7 @@ public class ColorPicker16 : View
 
     /// <summary>Moves the selected item index to the next column.</summary>
     /// <returns></returns>
-    private bool MoveRight (ICommandContext commandContext)
+    private bool MoveRight (ICommandContext? commandContext)
     {
         if (RaiseSelecting (commandContext) == true)
         {
@@ -116,7 +116,7 @@ public class ColorPicker16 : View
 
     /// <summary>Moves the selected item index to the previous row.</summary>
     /// <returns></returns>
-    private bool MoveUp (ICommandContext commandContext)
+    private bool MoveUp (ICommandContext? commandContext)
     {
         if (RaiseSelecting (commandContext) == true)
         {

+ 2 - 2
Terminal.Gui/Views/ListView.cs

@@ -813,14 +813,14 @@ public class ListView : View, IDesignable
         // at it
         if (AllowsMarking)
         {
-            var keys = KeyBindings.GetKeysFromCommands (Command.Select);
+            var keys = KeyBindings.GetAllFromCommands (Command.Select);
 
             if (keys.Contains (a))
             {
                 return false;
             }
 
-            keys = KeyBindings.GetKeysFromCommands ([Command.Select, Command.Down]);
+            keys = KeyBindings.GetAllFromCommands ([Command.Select, Command.Down]);
 
             if (keys.Contains (a))
             {

+ 1 - 1
Terminal.Gui/Views/Shortcut.cs

@@ -69,7 +69,7 @@ public class Shortcut : View, IOrientation, IDesignable
     /// <param name="helpText">The help text to display.</param>
     public Shortcut (View targetView, Command command, string commandText, string? helpText = null)
         : this (
-                targetView?.HotKeyBindings.GetKeyFromCommands (command)!,
+                targetView?.HotKeyBindings.GetFirstFromCommands (command)!,
                 commandText,
                 null,
                 helpText)

+ 2 - 2
Terminal.Gui/Views/TableView/TableView.cs

@@ -293,7 +293,7 @@ public class TableView : View, IDesignable
             {
                 if (KeyBindings.TryGet (cellActivationKey, out _))
                 {
-                    KeyBindings.ReplaceKey (cellActivationKey, value);
+                    KeyBindings.Replace (cellActivationKey, value);
                 }
                 else
                 {
@@ -1013,7 +1013,7 @@ public class TableView : View, IDesignable
         if (CollectionNavigator != null
             && HasFocus
             && Table.Rows != 0
-            && key != KeyBindings.GetKeyFromCommands (Command.Accept)
+            && key != KeyBindings.GetFirstFromCommands (Command.Accept)
             && key != CellActivationKey
             && CollectionNavigatorBase.IsCompatibleKey (key)
             && !key.KeyCode.HasFlag (KeyCode.CtrlMask)

+ 8 - 8
Terminal.Gui/Views/TextField.cs

@@ -1236,7 +1236,7 @@ public class TextField : View
                              () => SelectAll (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.SelectAll)
                             ),
                         new (
                              Strings.ctxDeleteAll,
@@ -1244,7 +1244,7 @@ public class TextField : View
                              () => DeleteAll (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.DeleteAll)
                             ),
                         new (
                              Strings.ctxCopy,
@@ -1252,7 +1252,7 @@ public class TextField : View
                              () => Copy (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Copy)
                             ),
                         new (
                              Strings.ctxCut,
@@ -1260,7 +1260,7 @@ public class TextField : View
                              () => Cut (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Cut)
                             ),
                         new (
                              Strings.ctxPaste,
@@ -1268,7 +1268,7 @@ public class TextField : View
                              () => Paste (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Paste)
                             ),
                         new (
                              Strings.ctxUndo,
@@ -1276,7 +1276,7 @@ public class TextField : View
                              () => Undo (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Undo)
                             ),
                         new (
                              Strings.ctxRedo,
@@ -1284,13 +1284,13 @@ public class TextField : View
                              () => Redo (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Redo)
                             )
                     }
                    );
     }
 
-    private void ContextMenu_KeyChanged (object sender, KeyChangedEventArgs e) { KeyBindings.ReplaceKey (e.OldKey.KeyCode, e.NewKey.KeyCode); }
+    private void ContextMenu_KeyChanged (object sender, KeyChangedEventArgs e) { KeyBindings.Replace (e.OldKey.KeyCode, e.NewKey.KeyCode); }
 
     private List<Rune> DeleteSelectedText ()
     {

+ 9 - 9
Terminal.Gui/Views/TextView.cs

@@ -4163,7 +4163,7 @@ public class TextView : View
                              SelectAll,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.SelectAll)
                             ),
                         new (
                              Strings.ctxDeleteAll,
@@ -4171,7 +4171,7 @@ public class TextView : View
                              DeleteAll,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.DeleteAll)
                             ),
                         new (
                              Strings.ctxCopy,
@@ -4179,7 +4179,7 @@ public class TextView : View
                              Copy,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Copy)
                             ),
                         new (
                              Strings.ctxCut,
@@ -4187,7 +4187,7 @@ public class TextView : View
                              Cut,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Cut)
                             ),
                         new (
                              Strings.ctxPaste,
@@ -4195,7 +4195,7 @@ public class TextView : View
                              Paste,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Paste)
                             ),
                         new (
                              Strings.ctxUndo,
@@ -4203,7 +4203,7 @@ public class TextView : View
                              Undo,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Undo)
                             ),
                         new (
                              Strings.ctxRedo,
@@ -4211,7 +4211,7 @@ public class TextView : View
                              Redo,
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Redo)
                             ),
                         new (
                              Strings.ctxColors,
@@ -4219,7 +4219,7 @@ public class TextView : View
                              () => PromptForColors (),
                              null,
                              null,
-                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Open)
+                             (KeyCode)KeyBindings.GetFirstFromCommands (Command.Open)
                             )
                     }
                    );
@@ -4333,7 +4333,7 @@ public class TextView : View
         DoNeededAction ();
     }
 
-    private void ContextMenu_KeyChanged (object sender, KeyChangedEventArgs e) { KeyBindings.ReplaceKey (e.OldKey, e.NewKey); }
+    private void ContextMenu_KeyChanged (object sender, KeyChangedEventArgs e) { KeyBindings.Replace (e.OldKey, e.NewKey); }
 
     private bool DeleteTextBackwards ()
     {

+ 1 - 1
Terminal.Gui/Views/TreeView/TreeView.cs

@@ -375,7 +375,7 @@ public class TreeView<T> : View, ITreeView where T : class
         {
             if (objectActivationKey != value)
             {
-                KeyBindings.ReplaceKey (ObjectActivationKey, value);
+                KeyBindings.Replace (ObjectActivationKey, value);
                 objectActivationKey = value;
                 SetNeedsDraw ();
             }

+ 1 - 1
UICatalog/Scenarios/KeyBindings.cs

@@ -80,7 +80,7 @@ public sealed class KeyBindings : Scenario
         };
         appWindow.Add (appBindingsListView);
 
-        foreach (var key in Application.KeyBindings.GetBoundKeys ())
+        foreach (Key key in Application.KeyBindings.GetBindings().ToDictionary().Keys)
         {
             var binding = Application.KeyBindings.Get (key);
             appBindings.Add ($"{key} -> {binding.Target?.GetType ().Name} - {binding.Commands [0]}");

+ 2 - 2
UICatalog/Scenarios/Text.cs

@@ -148,8 +148,8 @@ public class Text : Scenario
                                     }
                                 };
 
-        Key keyTab = textView.KeyBindings.GetKeyFromCommands (Command.Tab);
-        Key keyBackTab = textView.KeyBindings.GetKeyFromCommands (Command.BackTab);
+        Key keyTab = textView.KeyBindings.GetFirstFromCommands (Command.Tab);
+        Key keyBackTab = textView.KeyBindings.GetFirstFromCommands (Command.BackTab);
 
         chxCaptureTabs.CheckedStateChanging += (s, e) =>
                                   {

+ 20 - 20
UnitTests/Input/Keyboard/KeyBindingsTests.cs

@@ -27,13 +27,13 @@ public class KeyBindingsTests ()
         Assert.Contains (Command.Left, resultCommands);
     }
 
-    //[Fact]
-    //public void Add_Invalid_Key_Throws ()
-    //{
-    //    var keyBindings = new KeyBindings (new View ());
-    //    List<Command> commands = new ();
-    //    Assert.Throws<ArgumentException> (() => keyBindings.Add (Key.Empty, Command.Accept));
-    //}
+    [Fact]
+    public void Add_Invalid_Key_Throws ()
+    {
+        var keyBindings = new KeyBindings (new View ());
+        List<Command> commands = new ();
+        Assert.Throws<ArgumentException> (() => keyBindings.Add (Key.Empty, Command.Accept));
+    }
 
     [Fact]
     public void Add_Multiple_Commands_Adds ()
@@ -132,7 +132,7 @@ public class KeyBindingsTests ()
     {
         var keyBindings = new KeyBindings (new ());
         Assert.Empty (keyBindings.GetBindings ());
-        Assert.Null (keyBindings.GetKeyFromCommands (Command.Accept));
+        Assert.Null (keyBindings.GetFirstFromCommands (Command.Accept));
         Assert.NotNull (keyBindings.Target);
     }
 
@@ -198,10 +198,10 @@ public class KeyBindingsTests ()
         Command [] commands2 = { Command.Up, Command.Down };
         keyBindings.Add (Key.B, commands2);
 
-        Key key = keyBindings.GetKeyFromCommands (commands1);
+        Key key = keyBindings.GetFirstFromCommands (commands1);
         Assert.Equal (Key.A, key);
 
-        key = keyBindings.GetKeyFromCommands (commands2);
+        key = keyBindings.GetFirstFromCommands (commands2);
         Assert.Equal (Key.B, key);
     }
 
@@ -211,7 +211,7 @@ public class KeyBindingsTests ()
         var keyBindings = new KeyBindings (new ());
         keyBindings.Add (Key.A, Command.Right);
 
-        Key key = keyBindings.GetKeyFromCommands (Command.Right);
+        Key key = keyBindings.GetFirstFromCommands (Command.Right);
         Assert.Equal (Key.A, key);
     }
 
@@ -220,7 +220,7 @@ public class KeyBindingsTests ()
     public void GetKeyFromCommands_Unknown_Returns_Key_Empty ()
     {
         var keyBindings = new KeyBindings (new ());
-        Assert.Null (keyBindings.GetKeyFromCommands (Command.Accept));
+        Assert.Null (keyBindings.GetFirstFromCommands (Command.Accept));
     }
 
     [Fact]
@@ -228,7 +228,7 @@ public class KeyBindingsTests ()
     {
         var keyBindings = new KeyBindings (new ());
         keyBindings.Add (Key.A, Command.HotKey);
-        Key resultKey = keyBindings.GetKeyFromCommands (Command.HotKey);
+        Key resultKey = keyBindings.GetFirstFromCommands (Command.HotKey);
         Assert.Equal (Key.A, resultKey);
     }
 
@@ -241,19 +241,19 @@ public class KeyBindingsTests ()
         keyBindings.Add (Key.C, Command.HotKey);
         keyBindings.Add (Key.D, Command.HotKey);
 
-        keyBindings.ReplaceKey (Key.A, Key.E);
+        keyBindings.Replace (Key.A, Key.E);
         Assert.Empty (keyBindings.GetCommands (Key.A));
         Assert.Contains (Command.HotKey, keyBindings.GetCommands (Key.E));
 
-        keyBindings.ReplaceKey (Key.B, Key.F);
+        keyBindings.Replace (Key.B, Key.F);
         Assert.Empty (keyBindings.GetCommands (Key.B));
         Assert.Contains (Command.HotKey, keyBindings.GetCommands (Key.F));
 
-        keyBindings.ReplaceKey (Key.C, Key.G);
+        keyBindings.Replace (Key.C, Key.G);
         Assert.Empty (keyBindings.GetCommands (Key.C));
         Assert.Contains (Command.HotKey, keyBindings.GetCommands (Key.G));
 
-        keyBindings.ReplaceKey (Key.D, Key.H);
+        keyBindings.Replace (Key.D, Key.H);
         Assert.Empty (keyBindings.GetCommands (Key.D));
         Assert.Contains (Command.HotKey, keyBindings.GetCommands (Key.H));
     }
@@ -265,7 +265,7 @@ public class KeyBindingsTests ()
         keyBindings.Add (Key.A, Command.Accept);
         keyBindings.Add (Key.B, Command.HotKey);
 
-        keyBindings.ReplaceKey (keyBindings.GetKeyFromCommands (Command.Accept), Key.C);
+        keyBindings.Replace (keyBindings.GetFirstFromCommands (Command.Accept), Key.C);
         Assert.Empty (keyBindings.GetCommands (Key.A));
         Assert.Contains (Command.Accept, keyBindings.GetCommands (Key.C));
     }
@@ -274,7 +274,7 @@ public class KeyBindingsTests ()
     public void ReplaceKey_Adds_If_DoesNotContain_Old ()
     {
         var keyBindings = new KeyBindings (new ());
-        keyBindings.ReplaceKey (Key.A, Key.B);
+        keyBindings.Replace (Key.A, Key.B);
         Assert.True (keyBindings.TryGet (Key.B, out _));
     }
 
@@ -283,7 +283,7 @@ public class KeyBindingsTests ()
     {
         var keyBindings = new KeyBindings (new ());
         keyBindings.Add (Key.A, Command.HotKey);
-        Assert.Throws<InvalidOperationException> (() => keyBindings.ReplaceKey (Key.A, Key.Empty));
+        Assert.Throws<ArgumentException> (() => keyBindings.Replace (Key.A, Key.Empty));
     }
 
     [Fact]

+ 20 - 20
UnitTests/Input/Mouse/MouseBindingsTests.cs

@@ -23,13 +23,13 @@ public class MouseBindingsTests
         Assert.Contains (Command.Left, resultCommands);
     }
 
-    //[Fact]
-    //public void Add_Invalid_Flag_Throws ()
-    //{
-    //    var mouseBindings = new MouseBindings ();
-    //    List<Command> commands = new ();
-    //    Assert.Throws<ArgumentException> (() => mouseBindings.Add (MouseFlags.None, Command.Accept));
-    //}
+    [Fact]
+    public void Add_Invalid_Flag_Throws ()
+    {
+        var mouseBindings = new MouseBindings ();
+        List<Command> commands = new ();
+        Assert.Throws<ArgumentException> (() => mouseBindings.Add (MouseFlags.None, Command.Accept));
+    }
 
     [Fact]
     public void Add_Multiple_Commands_Adds ()
@@ -131,7 +131,7 @@ public class MouseBindingsTests
     {
         var mouseBindings = new MouseBindings ();
         Assert.Empty (mouseBindings.GetBindings ());
-        Assert.Equal (MouseFlags.None, mouseBindings.GetMouseFlagsFromCommands (Command.Accept));
+        Assert.Equal (MouseFlags.None, mouseBindings.GetFirstFromCommands (Command.Accept));
     }
 
     [Fact]
@@ -196,10 +196,10 @@ public class MouseBindingsTests
         Command [] commands2 = { Command.Up, Command.Down };
         mouseBindings.Add (MouseFlags.Button2Clicked, commands2);
 
-        MouseFlags mouseFlags = mouseBindings.GetMouseFlagsFromCommands (commands1);
+        MouseFlags mouseFlags = mouseBindings.GetFirstFromCommands (commands1);
         Assert.Equal (MouseFlags.Button1Clicked, mouseFlags);
 
-        mouseFlags = mouseBindings.GetMouseFlagsFromCommands (commands2);
+        mouseFlags = mouseBindings.GetFirstFromCommands (commands2);
         Assert.Equal (MouseFlags.Button2Clicked, mouseFlags);
     }
 
@@ -209,7 +209,7 @@ public class MouseBindingsTests
         var mouseBindings = new MouseBindings ();
         mouseBindings.Add (MouseFlags.Button1Clicked, Command.Right);
 
-        MouseFlags mouseFlags = mouseBindings.GetMouseFlagsFromCommands (Command.Right);
+        MouseFlags mouseFlags = mouseBindings.GetFirstFromCommands (Command.Right);
         Assert.Equal (MouseFlags.Button1Clicked, mouseFlags);
     }
 
@@ -218,7 +218,7 @@ public class MouseBindingsTests
     public void GetMouseFlagsFromCommands_Unknown_Returns_Key_Empty ()
     {
         var mouseBindings = new MouseBindings ();
-        Assert.Equal (MouseFlags.None, mouseBindings.GetMouseFlagsFromCommands (Command.Accept));
+        Assert.Equal (MouseFlags.None, mouseBindings.GetFirstFromCommands (Command.Accept));
     }
 
     [Fact]
@@ -226,7 +226,7 @@ public class MouseBindingsTests
     {
         var mouseBindings = new MouseBindings ();
         mouseBindings.Add (MouseFlags.Button1Clicked, Command.HotKey);
-        MouseFlags mouseFlags = mouseBindings.GetMouseFlagsFromCommands (Command.HotKey);
+        MouseFlags mouseFlags = mouseBindings.GetFirstFromCommands (Command.HotKey);
         Assert.Equal (MouseFlags.Button1Clicked, mouseFlags);
     }
 
@@ -239,19 +239,19 @@ public class MouseBindingsTests
         mouseBindings.Add (MouseFlags.Button3Clicked, Command.HotKey);
         mouseBindings.Add (MouseFlags.Button4Clicked, Command.HotKey);
 
-        mouseBindings.ReplaceMouseFlag (MouseFlags.Button1Clicked, MouseFlags.Button1DoubleClicked);
+        mouseBindings.Replace (MouseFlags.Button1Clicked, MouseFlags.Button1DoubleClicked);
         Assert.Empty (mouseBindings.GetCommands (MouseFlags.Button1Clicked));
         Assert.Contains (Command.HotKey, mouseBindings.GetCommands (MouseFlags.Button1DoubleClicked));
 
-        mouseBindings.ReplaceMouseFlag (MouseFlags.Button2Clicked, MouseFlags.Button2DoubleClicked);
+        mouseBindings.Replace (MouseFlags.Button2Clicked, MouseFlags.Button2DoubleClicked);
         Assert.Empty (mouseBindings.GetCommands (MouseFlags.Button2Clicked));
         Assert.Contains (Command.HotKey, mouseBindings.GetCommands (MouseFlags.Button2DoubleClicked));
 
-        mouseBindings.ReplaceMouseFlag (MouseFlags.Button3Clicked, MouseFlags.Button3DoubleClicked);
+        mouseBindings.Replace (MouseFlags.Button3Clicked, MouseFlags.Button3DoubleClicked);
         Assert.Empty (mouseBindings.GetCommands (MouseFlags.Button3Clicked));
         Assert.Contains (Command.HotKey, mouseBindings.GetCommands (MouseFlags.Button3DoubleClicked));
 
-        mouseBindings.ReplaceMouseFlag (MouseFlags.Button4Clicked, MouseFlags.Button4DoubleClicked);
+        mouseBindings.Replace (MouseFlags.Button4Clicked, MouseFlags.Button4DoubleClicked);
         Assert.Empty (mouseBindings.GetCommands (MouseFlags.Button4Clicked));
         Assert.Contains (Command.HotKey, mouseBindings.GetCommands (MouseFlags.Button4DoubleClicked));
     }
@@ -263,7 +263,7 @@ public class MouseBindingsTests
         mouseBindings.Add (MouseFlags.Button1Clicked, Command.Accept);
         mouseBindings.Add (MouseFlags.Button2Clicked, Command.HotKey);
 
-        mouseBindings.ReplaceMouseFlag (mouseBindings.GetMouseFlagsFromCommands (Command.Accept), MouseFlags.Button3Clicked);
+        mouseBindings.Replace (mouseBindings.GetFirstFromCommands (Command.Accept), MouseFlags.Button3Clicked);
         Assert.Empty (mouseBindings.GetCommands (MouseFlags.Button1Clicked));
         Assert.Contains (Command.Accept, mouseBindings.GetCommands (MouseFlags.Button3Clicked));
     }
@@ -272,7 +272,7 @@ public class MouseBindingsTests
     public void ReplaceMouseFlags_Adds_If_DoesNotContain_Old ()
     {
         var mouseBindings = new MouseBindings ();
-        mouseBindings.ReplaceMouseFlag (MouseFlags.Button1Clicked, MouseFlags.Button2Clicked);
+        mouseBindings.Replace (MouseFlags.Button1Clicked, MouseFlags.Button2Clicked);
         Assert.True (mouseBindings.TryGet (MouseFlags.Button2Clicked, out _));
     }
 
@@ -281,7 +281,7 @@ public class MouseBindingsTests
     {
         var mouseBindings = new MouseBindings ();
         mouseBindings.Add (MouseFlags.Button1Clicked, Command.HotKey);
-        Assert.Throws<ArgumentException> (() => mouseBindings.ReplaceMouseFlag (MouseFlags.Button1Clicked, MouseFlags.None));
+        Assert.Throws<ArgumentException> (() => mouseBindings.Replace (MouseFlags.Button1Clicked, MouseFlags.None));
     }
 
     [Fact]

+ 1 - 1
UnitTests/View/Keyboard/HotKeyTests.cs

@@ -102,7 +102,7 @@ public class HotKeyTests
         commands = view.HotKeyBindings.GetCommands (KeyCode.Null);
         Assert.Empty (commands);
 
-        Assert.Empty (view.HotKeyBindings.GetBoundKeys ());
+        Assert.Empty (view.HotKeyBindings.GetBindings ());
     }
 
     [Theory]