Skip to content

Conversation

@conventoangelo
Copy link
Owner

@conventoangelo conventoangelo commented Dec 31, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for custom key aliases—define reusable keyboard shortcuts with modifiers (Control, Shift, Alt, Win) and reference them in keyboard layouts. Aliases highlight constituent keys when triggered.
  • Documentation

    • Added comprehensive guide for configuring and using custom aliases with configuration steps and examples.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 31, 2025

📝 Walkthrough

Walkthrough

Adds support for custom key aliases in OverKeys through documentation, configuration models, and key event detection. Extends UserConfig, KeyboardState, and ConfigService to handle custom aliases, implements loading during configuration initialization, and adds logic to detect alias key combinations during key press handling.

Changes

Cohort / File(s) Summary
Documentation
docs/advanced/custom-aliases.md, docs/examples/sample_config.json, docs/index.md
New guide for custom aliases covering configuration via JSON (mapping alias names to key lists), advanced settings setup, modifier syntax (Control, Shift, Alt, Win), and usage examples. Sample config updated with example custom aliases. Index navigation extended with link to new guide.
Configuration Models
lib/models/user_config.dart, lib/services/config_service.dart
UserConfig extended with customAliases field and JSON serialization/deserialization. ConfigService adds getCustomAliases() method to retrieve and parse aliases from config; _cachedConfig converted to static field.
State Management
lib/providers/keyboard_provider.dart
KeyboardState adds customAliases: Map<String, List<String>>? field with wiring through constructor, copyWith, and JSON serialization. KeyboardNotifier adds updateCustomAliases() method to update state.
Configuration Loading
lib/services/configuration_loader.dart, lib/services/method_call_handler.dart, lib/app.dart
ConfigurationLoader introduces loadCustomAliases() to fetch aliases from ConfigService and push to KeyboardNotifier; called during loadAllConfiguration. MethodCallHandler signature extended with loadAllConfiguration parameter used in advanced settings branch. App wires _loadConfiguration to method call handler.
Key Event Detection
lib/services/key_event_service.dart
Adds custom alias triggering logic: after key press state updates, iterates over custom aliases and checks if all constituent keys are pressed (with special handling for Control, Shift, Alt, Win modifiers), updating alias state. Refines held-layer release logic with explicit matching and removal logic.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant MethodCallHandler
    participant ConfigurationLoader
    participant ConfigService
    participant KeyboardNotifier
    participant KeyEventService

    App->>MethodCallHandler: handleMethodCall(loadAllConfiguration)
    MethodCallHandler->>ConfigurationLoader: loadAllConfiguration()
    ConfigurationLoader->>ConfigService: getCustomAliases()
    ConfigService-->>ConfigurationLoader: Map<String, List<String>>
    ConfigurationLoader->>KeyboardNotifier: updateCustomAliases(aliases)
    KeyboardNotifier-->>ConfigurationLoader: state updated
    
    Note over KeyEventService: On key press
    KeyEventService->>KeyboardNotifier: read keyboard state
    KeyEventService->>KeyEventService: iterate customAliases
    rect rgb(230, 245, 230)
        Note over KeyEventService: For each alias, check if all<br/>constituent keys are pressed
        KeyEventService->>KeyEventService: compute alias trigger condition
    end
    KeyEventService->>KeyboardNotifier: updateCustomAliases state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Aliases spring forth, keys held tight,
Custom combos dance in light,
Control, Shift, Alt in perfect row,
Every binding steals the show!

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: add support for custom aliases' clearly and concisely summarizes the main objective of the changeset, which is to implement custom aliases functionality across the application.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
lib/services/method_call_handler.dart (1)

45-45: Good refactoring - consolidates configuration loading.

Adding the loadAllConfiguration parameter is a solid improvement that consolidates multiple configuration loading calls into a single, coordinated operation. This reduces duplication and ensures all configuration is loaded consistently.

lib/services/config_service.dart (1)

13-13: Static cache may cause unexpected shared state across instances.

Changing _cachedConfig to a static field means all ConfigService instances share the same cache. While clearCache() still works, instantiating multiple ConfigService objects now shares state unexpectedly. If singleton behavior is intended, consider making ConfigService a singleton explicitly for clarity.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c860aad and f3ef974.

📒 Files selected for processing (10)
  • docs/advanced/custom-aliases.md
  • docs/examples/sample_config.json
  • docs/index.md
  • lib/app.dart
  • lib/models/user_config.dart
  • lib/providers/keyboard_provider.dart
  • lib/services/config_service.dart
  • lib/services/configuration_loader.dart
  • lib/services/key_event_service.dart
  • lib/services/method_call_handler.dart
🧰 Additional context used
🪛 Biome (2.1.2)
docs/examples/sample_config.json

[error] 95-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

🪛 LanguageTool
docs/advanced/custom-aliases.md

[style] ~70-~70: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... key labeled "Item 1" will light up.

  • When you press X, the key labeled "ULT" wi...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (14)
docs/examples/sample_config.json (1)

92-98: LGTM! Static analysis warnings are false positives.

The custom aliases configuration looks good and provides useful examples for different use cases (system commands like UNDO/PASTE and gaming shortcuts). The static analysis errors from Biome are false positives—this file uses JSONC format (JSON with Comments), as noted on line 4, which supports trailing commas and comments that strict JSON parsers reject.

lib/app.dart (1)

510-510: LGTM! Properly connects configuration loading.

The addition of _loadConfiguration as a parameter correctly integrates the new consolidated configuration loading flow into the method call handler. The implementation (lines 166-170) appropriately clears the cache before loading, ensuring fresh configuration data.

lib/services/method_call_handler.dart (1)

429-433: LGTM! Cleaner configuration loading flow.

The refactored approach using a single loadAllConfiguration() call is much cleaner than the previous implementation that required multiple conditional config loads. This delegates the responsibility for loading order and conditional logic to the ConfigurationLoader, which is the appropriate place for such logic.

docs/index.md (1)

24-24: Documentation file exists with appropriate content.

The docs/advanced/custom-aliases.md file is present and contains clear setup instructions with a practical JSON configuration example for defining custom key aliases. The link in the documentation index is valid and properly integrated.

lib/services/configuration_loader.dart (1)

50-53: Unconditional loading of custom aliases is intentional and properly implemented.

Both getCustomAliases() and updateCustomAliases() methods exist and are correctly implemented. The unconditional loading of custom aliases matches the design pattern of loadCustomShiftMappings—both are treated as basic configuration features loaded before the advancedSettingsEnabled check. Advanced features (user layouts, alt layouts, custom fonts, Kanata) are the only ones gated by advancedSettingsEnabled on line 26. Custom aliases are actively used in key event handling in key_event_service.dart, confirming this is the intended behavior.

docs/advanced/custom-aliases.md (1)

1-75: Documentation looks comprehensive and well-structured.

The setup instructions, configuration details, and usage examples clearly explain the custom aliases feature. The documentation correctly describes the modifier handling (Control, Shift, Alt, Win) which matches the implementation in key_event_service.dart.

lib/services/key_event_service.dart (2)

324-338: LGTM!

The held layer release logic correctly handles the edge case where a user toggles another layer while holding a held-layer key. The comment clearly explains the scenario.


109-112: No changes needed. The Win modifier handling is correct.

The Windows key mapping in key_code.dart defines VK_LWIN'Win' (not 'LWin') and VK_RWIN'RWin'. The code at lines 109-112 correctly checks for 'Win' and 'RWin', matching the actual key mappings returned by the key code utilities.

Likely an incorrect or invalid review comment.

lib/services/config_service.dart (1)

146-162: LGTM!

The getCustomAliases() method properly loads and converts the aliases with appropriate error handling. The try-catch ensures malformed configuration data doesn't crash the application.

lib/providers/keyboard_provider.dart (3)

59-59: LGTM!

The customAliases field is properly integrated into KeyboardState with consistent handling in the constructor and copyWith method, following the established patterns for other similar fields.

Also applies to: 111-111, 164-164, 220-220


350-357: LGTM!

The fromJson deserialization correctly handles the nested structure, converting the dynamic list values to List<String>. The pattern is consistent with other map fields in the class.


373-375: LGTM!

The updateCustomAliases method follows the same pattern as other updaters in KeyboardNotifier.

lib/models/user_config.dart (2)

12-12: LGTM!

The customAliases field is properly added to UserConfig with appropriate JSON parsing. Using Map<String, dynamic>? at the config layer is appropriate since the type conversion to Map<String, List<String>>? is handled by ConfigService.getCustomAliases().

Also applies to: 23-23, 53-56, 67-67


95-96: LGTM!

The toJson correctly conditionally includes customAliases only when non-null and non-empty, consistent with other optional fields.

@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 27.77778% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lib/services/config_service.dart 0.00% 6 Missing ⚠️
lib/providers/keyboard_provider.dart 37.50% 5 Missing ⚠️
lib/models/user_config.dart 50.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@conventoangelo conventoangelo merged commit ca4f1ad into main Dec 31, 2025
4 checks passed
@conventoangelo conventoangelo deleted the feat/custom-alias branch December 31, 2025 20:16
@github-actions github-actions bot mentioned this pull request Dec 31, 2025
@conventoangelo conventoangelo linked an issue Dec 31, 2025 that may be closed by this pull request
@github-actions github-actions bot mentioned this pull request Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Custom aliases

3 participants