resolveKeyWithChordState method
ChordResolveResult
resolveKeyWithChordState(
- ParsedKeystroke keystroke,
- List<
KeybindingContext> activeContexts
Resolve a keystroke with chord state support. Handles multi-keystroke chord bindings like "ctrl+k ctrl+s".
Implementation
ChordResolveResult resolveKeyWithChordState(
ParsedKeystroke keystroke,
List<KeybindingContext> activeContexts,
) {
// Cancel chord on escape.
if (keystroke.key == 'escape' && _pendingChord != null) {
_pendingChord = null;
return const ChordCancelledResult();
}
// Build the full chord sequence to test.
final testChord = _pendingChord != null
? [..._pendingChord!, keystroke]
: [keystroke];
// Filter bindings by active contexts.
final ctxSet = activeContexts.toSet();
final contextBindings = _bindings
.where((b) => ctxSet.contains(b.context))
.toList();
// Check if this could be a prefix for longer chords. Track null-overrides
// to avoid entering chord-wait for bindings that have been unbound.
final chordWinners = <String, String?>{};
for (final binding in contextBindings) {
if (binding.chord.length > testChord.length &&
chordPrefixMatches(testChord, binding)) {
chordWinners[chordToString(binding.chord)] = binding.action;
}
}
var hasLongerChords = false;
for (final action in chordWinners.values) {
if (action != null) {
hasLongerChords = true;
break;
}
}
// If this keystroke could start a longer chord, prefer that.
if (hasLongerChords) {
_pendingChord = testChord;
return ChordStartedResult(testChord);
}
// Check for exact matches (last one wins).
ParsedBinding? exactMatch;
for (final binding in contextBindings) {
if (chordExactlyMatches(testChord, binding)) {
exactMatch = binding;
}
}
if (exactMatch != null) {
_pendingChord = null;
if (exactMatch.action == null) return const ChordUnboundResult();
return ChordMatchResult(exactMatch.action!);
}
// No match and no potential longer chords.
if (_pendingChord != null) {
_pendingChord = null;
return const ChordCancelledResult();
}
return const ChordNoMatchResult();
}