ktsu.Keybinding
2.0.3
Prefix Reserved
dotnet add package ktsu.Keybinding --version 2.0.3
NuGet\Install-Package ktsu.Keybinding -Version 2.0.3
<PackageReference Include="ktsu.Keybinding" Version="2.0.3" />
<PackageVersion Include="ktsu.Keybinding" Version="2.0.3" />
<PackageReference Include="ktsu.Keybinding" />
paket add ktsu.Keybinding --version 2.0.3
#r "nuget: ktsu.Keybinding, 2.0.3"
#:package ktsu.Keybinding@2.0.3
#addin nuget:?package=ktsu.Keybinding&version=2.0.3
#tool nuget:?package=ktsu.Keybinding&version=2.0.3
Keybinding Management Library
A comprehensive .NET library for managing keyboard shortcuts and keybindings with support for multiple profiles, command registration, and persistent storage.
Features
- Multi-Profile Support: Create and manage multiple keybinding profiles
- Command Registry: Register and organize commands with categories
- Flexible Key Combinations: Support for complex key combinations with multiple modifiers
- Persistent Storage: Automatic saving and loading of profiles and commands
- Thread-Safe Operations: Concurrent access support for multi-threaded applications
- SOLID Architecture: Clean, extensible design following SOLID principles
- Comprehensive API: Full-featured interfaces for all operations
Quick Start
Installation
Add a reference to the Keybinding project in your application.
Basic Usage
using ktsu.Keybinding.Core;
using ktsu.Keybinding.Core.Models;
// Initialize the keybinding manager
var manager = new KeybindingManager("./keybinding-data");
await manager.InitializeAsync();
// Create a default profile if none exist
manager.CreateDefaultProfile();
// Register some commands
var commands = new[]
{
new Command("file.new", "New File", "Create a new file", "File"),
new Command("file.save", "Save File", "Save the current file", "File"),
new Command("edit.copy", "Copy", "Copy selected text", "Edit")
};
manager.RegisterCommands(commands);
// Set chord bindings
manager.Keybindings.BindChord("file.new", manager.Keybindings.ParseChord("Ctrl+N"));
manager.Keybindings.BindChord("file.save", manager.Keybindings.ParseChord("Ctrl+S"));
manager.Keybindings.BindChord("edit.copy", manager.Keybindings.ParseChord("Ctrl+C"));
// Find commands by chord
var chord = manager.Keybindings.ParseChord("Ctrl+S");
var commandId = manager.Keybindings.FindCommandByChord(chord);
// Save changes
await manager.SaveAsync();
Core Concepts
Commands
Commands represent actions that can be bound to keyboard shortcuts:
var command = new Command(
id: "file.save", // Unique identifier
name: "Save File", // Display name
description: "Save the current file", // Optional description
category: "File" // Optional category for organization
);
Chords (Key Combinations)
Chords represent musical-style key combinations using the Note and Chord classes:
// Parse from string
var chord = manager.Keybindings.ParseChord("Ctrl+Alt+S");
// Create programmatically
var chord = new Chord([
new Note("CTRL"),
new Note("ALT"),
new Note("S")
]);
// Supported modifiers: Ctrl, Alt, Shift, Meta (Windows/Cmd key)
Profiles
Profiles allow different keybinding configurations:
// Create a new profile
var profile = new Profile("gaming", "Gaming Profile", "Keybindings for gaming");
manager.Profiles.CreateProfile(profile);
// Switch active profile
manager.Profiles.SetActiveProfile("gaming");
// Duplicate a profile
var newProfile = manager.Profiles.DuplicateProfile("default", "custom", "Custom Profile");
Architecture
The library follows a clean architecture with clear separation of concerns:
Models
Command: Represents a named action that can be bound to keysChord: Represents a keyboard shortcut with modifiers and primary key using musical paradigmNote: Represents individual keys in a chordPhrase: Represents sequences of chords for complex key combinationsProfile: Contains a set of chord bindings for commands
Contracts (Interfaces)
ICommandRegistry: Command management operationsIProfileManager: Profile management operationsIKeybindingService: Keybinding coordination and validationIKeybindingRepository: Persistence operations
Services
CommandRegistry: Thread-safe command storage and retrievalProfileManager: Profile lifecycle managementKeybindingService: Coordinates keybinding operations across profiles and commandsJsonKeybindingRepository: JSON-based persistence implementation
Main Facade
KeybindingManager: Main entry point that coordinates all services
Advanced Usage
Custom Repository
Implement your own storage mechanism:
public class DatabaseKeybindingRepository : IKeybindingRepository
{
// Implement async persistence methods
public async Task SaveProfileAsync(Profile profile) { /* ... */ }
public async Task<IEnumerable<Profile>> LoadAllProfilesAsync() { /* ... */ }
// ... other methods
}
// Use with custom repository
var manager = new KeybindingManager(
new CommandRegistry(),
new ProfileManager(),
new DatabaseKeybindingRepository()
);
Batch Operations
// Register multiple commands at once
var commands = new[]
{
new Command("edit.cut", "Cut", "Cut to clipboard", "Edit"),
new Command("edit.copy", "Copy", "Copy to clipboard", "Edit"),
new Command("edit.paste", "Paste", "Paste from clipboard", "Edit")
};
int registered = manager.RegisterCommands(commands);
// Set multiple chord bindings
var chords = new Dictionary<string, Chord>
{
{ "edit.cut", manager.Keybindings.ParseChord("Ctrl+X") },
{ "edit.copy", manager.Keybindings.ParseChord("Ctrl+C") },
{ "edit.paste", manager.Keybindings.ParseChord("Ctrl+V") }
};
int set = manager.SetChords(chords);
Profile Management
// Create specialized profiles
var vimProfile = new Profile("vim", "Vim Emulation", "Vim-style keybindings");
manager.Profiles.CreateProfile(vimProfile);
// Switch between profiles
manager.Profiles.SetActiveProfile("vim");
// ... set vim-style keybindings
manager.Profiles.SetActiveProfile("default");
// ... back to default keybindings
// Duplicate and customize
var customProfile = manager.Profiles.DuplicateProfile("default", "custom", "My Custom Profile");
Command Organization
// Search commands by name
var fileCommands = manager.Commands.SearchCommands("file");
// Filter by category
var editCommands = manager.Commands.GetCommandsByCategory("Edit");
// Check if command exists
if (manager.Commands.CommandExists("file.save"))
{
// Command is registered
}
Sample Application
Interactive Demo (Keybinding.Demo)
An interactive console application demonstrating all library features:
dotnet run --project Keybinding.Demo
The demo includes:
- Status overview
- Profile management
- Command registration
- Keybinding configuration
- Phrase binding and lookup
- Profile switching demonstration
Data Storage
By default, the library stores data in JSON format in the specified directory:
data-directory/
├── commands.json # Registered commands
├── active-profile.json # Currently active profile ID
└── profiles/
├── default.json # Default profile keybindings
├── gaming.json # Gaming profile keybindings
└── custom.json # Custom profile keybindings
Thread Safety
All services are designed to be thread-safe:
CommandRegistryusesConcurrentDictionaryfor command storageProfileManageruses locking for profile operationsKeybindingServicecoordinates safely across services
Error Handling
The library provides comprehensive error handling:
- Invalid key combinations are rejected during parsing
- Duplicate command IDs are prevented
- Profile operations validate existence and constraints
- Repository operations handle I/O errors gracefully
Testing
The solution includes comprehensive unit tests in the Keybinding.Test project:
dotnet test
Tests cover:
- Key combination parsing and validation
- Command registration and retrieval
- Profile management operations
- Keybinding service coordination
- Repository persistence operations
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE.md file for details.
Architecture Principles
This library follows SOLID principles:
- Single Responsibility: Each class has a focused purpose
- Open/Closed: Extensible through interfaces without modification
- Liskov Substitution: Implementations are interchangeable
- Interface Segregation: Focused, specific interfaces
- Dependency Inversion: Depends on abstractions, not concretions
The design also follows DRY (Don't Repeat Yourself) principles with consistent patterns across the codebase.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ktsu.Semantics.Strings (>= 5.7.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
-
net8.0
- ktsu.Semantics.Strings (>= 5.7.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- System.Text.Json (>= 10.0.12)
-
net9.0
- ktsu.Semantics.Strings (>= 5.7.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- System.Text.Json (>= 10.0.12)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ktsu.Keybinding:
| Package | Downloads |
|---|---|
|
ktsu.ImGui.NodeEditor
A visual node editor for Dear ImGui built on ImNodes, with the graph kept away from the drawing: the engine owns nodes, links and layout and knows nothing about ImGui, while the renderer draws what it holds and the input handler turns interactions into requests the engine can accept or refuse. Nodes can be declared as ordinary types decorated with ktsu.NodeGraph attributes and instantiated by reflection, with connections checked against the rules that metadata declares. Optional force-directed layout settles the graph, and the view zooms from quarter to double scale. Every edit can be undone through a ktsu.UndoRedo history, keyboard commands follow a ktsu.Keybinding keymap, dragged nodes can snap to the grid, and labelled comment boxes group regions of the graph and carry their nodes when moved. |
GitHub repositories
This package is not used by any popular GitHub repositories.
## v2.0.3 (patch)
Changes since v2.0.2:
- Bump the ktsu group with 1 update ([@dependabot[bot]](https://github.com/dependabot[bot]))