Forge
csharpdeeb25a2
1#nullable enable
2using Avalonia.Input;
3
4namespace CascadeIDE.Services;
5
6/// <summary>Разбор корневого жеста CascadeChord из merged <c>hotkeys.toml</c> (ADR 0060).</summary>
7public static class CascadeChordHotkey
8{
9 public const string TomlKey = "cascade_chord";
10 public const string DefaultGestureString = "Ctrl+K";
11
12 /// <summary>
13 /// Жест для первого шага аккорда: ключ <see cref="TomlKey"/> или <see cref="DefaultGestureString"/>;
14 /// при неразборчивой строке — повторный разбор <see cref="DefaultGestureString"/>.
15 /// </summary>
16 public static KeyGesture ResolveRootGesture(IReadOnlyDictionary<string, string> mergedMap)
17 {
18 var s = DefaultGestureString;
19 if (mergedMap.TryGetValue(TomlKey, out var v) && !string.IsNullOrWhiteSpace(v))
20 s = v.Trim();
21 try
22 {
23 return KeyGesture.Parse(s);
24 }
25 catch
26 {
27 return KeyGesture.Parse(DefaultGestureString);
28 }
29 }
30
31 /// <summary>
32 /// Совпадение корня аккорда с событием: сначала <see cref="KeyGesture.Matches(KeyEventArgs)"/>,
33 /// затем fallback по <see cref="KeyEventArgs.PhysicalKey"/> = <see cref="PhysicalKey.K"/> при тех же
34 /// <see cref="KeyEventArgs.KeyModifiers"/>, что у <paramref name="resolved"/>.
35 /// Иначе при русской (и др.) раскладке <c>e.Key</c> ≠ <c>Key.K</c>, хотя нажата та же физическая клавиша — корень не срабатывал.
36 /// </summary>
37 public static bool RootGestureMatches(KeyGesture resolved, KeyEventArgs e) =>
38 KeyGestureChordMatching.Matches(resolved, e);
39
40 /// <summary>Вторая ветка сопоставления (тесты): нормализованные модификаторы + физическая K.</summary>
41 public static bool MatchesPhysicalKeyFallback(KeyGesture resolved, PhysicalKey physicalKey, KeyModifiers modifiers)
42 {
43 if (KeyGestureChordMatching.NormalizeChordModifiers(modifiers) !=
44 KeyGestureChordMatching.NormalizeChordModifiers(resolved.KeyModifiers))
45 return false;
46 return physicalKey == PhysicalKey.K && resolved.Key == Key.K;
47 }
48}
49
View only · write via MCP/CIDE