chore: adopt Dart 3.9 toolchain — honest floor + tall-style reformat (T-353)
Raise the declared minimums in pubspec.yaml to what our deps already require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist 0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is the binding floor. Pin the exact build toolchain in .fvmrc (Flutter 3.44.1). Moving to the Dart 3.9 language level switches `dart format` to the new "tall" style and enables two new lints. This commit is the resulting mechanical churn, isolated from any behaviour change: - whole-tree `dart format` reformat (tall style) - `dart fix` for unnecessary_underscores + use_null_aware_elements No runtime behaviour change; `make test` green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,11 +36,7 @@ void main() {
|
||||
// Build a service whose bundle serves the real shipped preset content.
|
||||
Future<KeymapService> activate(String preset) async {
|
||||
final src = File('assets/keymaps/$preset.yaml').readAsStringSync();
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/$preset.yaml': src}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/$preset.yaml': src}));
|
||||
await svc.setPreset(preset);
|
||||
return svc;
|
||||
}
|
||||
@@ -72,11 +68,13 @@ void main() {
|
||||
|
||||
test('the Ctrl+K Ctrl+T sequence binds the theme picker', () async {
|
||||
final svc = await activate('vscode');
|
||||
final hit = svc.keymap!.effectiveBindings.any((b) =>
|
||||
b.sequence.length == 2 &&
|
||||
b.sequence[0] == KeyChord.parse('ctrl+k') &&
|
||||
b.sequence[1] == KeyChord.parse('ctrl+t') &&
|
||||
isCommand(b.intent, 'theme.pick'));
|
||||
final hit = svc.keymap!.effectiveBindings.any(
|
||||
(b) =>
|
||||
b.sequence.length == 2 &&
|
||||
b.sequence[0] == KeyChord.parse('ctrl+k') &&
|
||||
b.sequence[1] == KeyChord.parse('ctrl+t') &&
|
||||
isCommand(b.intent, 'theme.pick'),
|
||||
);
|
||||
expect(hit, isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -102,29 +102,17 @@ void main() {
|
||||
tearDown(() => kb.clearState());
|
||||
|
||||
test('returns null for non-KeyDown / non-Repeat events', () {
|
||||
final up = KeyUpEvent(
|
||||
physicalKey: PhysicalKeyboardKey.keyA,
|
||||
logicalKey: LogicalKeyboardKey.keyA,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final up = KeyUpEvent(physicalKey: PhysicalKeyboardKey.keyA, logicalKey: LogicalKeyboardKey.keyA, timeStamp: Duration.zero);
|
||||
expect(KeyChord.fromKeyEvent(up, kb), isNull);
|
||||
});
|
||||
|
||||
test('returns null for a bare modifier press', () {
|
||||
final down = KeyDownEvent(
|
||||
physicalKey: PhysicalKeyboardKey.controlLeft,
|
||||
logicalKey: LogicalKeyboardKey.controlLeft,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final down = KeyDownEvent(physicalKey: PhysicalKeyboardKey.controlLeft, logicalKey: LogicalKeyboardKey.controlLeft, timeStamp: Duration.zero);
|
||||
expect(KeyChord.fromKeyEvent(down, kb), isNull);
|
||||
});
|
||||
|
||||
test('maps a plain key down to a modifier-free chord', () {
|
||||
final down = KeyDownEvent(
|
||||
physicalKey: PhysicalKeyboardKey.keyA,
|
||||
logicalKey: LogicalKeyboardKey.keyA,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final down = KeyDownEvent(physicalKey: PhysicalKeyboardKey.keyA, logicalKey: LogicalKeyboardKey.keyA, timeStamp: Duration.zero);
|
||||
final chord = KeyChord.fromKeyEvent(down, kb)!;
|
||||
expect(chord.modifiers, isEmpty);
|
||||
expect(chord.key, LogicalKeyboardKey.keyA);
|
||||
@@ -140,11 +128,7 @@ void main() {
|
||||
]) {
|
||||
kb.handleKeyEvent(KeyDownEvent(physicalKey: m.$1, logicalKey: m.$2, timeStamp: Duration.zero));
|
||||
}
|
||||
final down = KeyDownEvent(
|
||||
physicalKey: PhysicalKeyboardKey.keyP,
|
||||
logicalKey: LogicalKeyboardKey.keyP,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final down = KeyDownEvent(physicalKey: PhysicalKeyboardKey.keyP, logicalKey: LogicalKeyboardKey.keyP, timeStamp: Duration.zero);
|
||||
final chord = KeyChord.fromKeyEvent(down, kb)!;
|
||||
expect(chord.key, LogicalKeyboardKey.keyP);
|
||||
expect(chord.modifiers.toSet(), {KeyModifier.ctrl, KeyModifier.alt, KeyModifier.shift, KeyModifier.meta});
|
||||
|
||||
@@ -33,9 +33,7 @@ void main() {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap, isNotNull);
|
||||
@@ -47,9 +45,7 @@ void main() {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/vscode.yaml': 'name: vscode\nbindings:\n - intent: palette.open\n keys: ctrl+shift+p\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/vscode.yaml': 'name: vscode\nbindings:\n - intent: palette.open\n keys: ctrl+shift+p\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+shift+p'), const {}), isA<PaletteOpenIntent>());
|
||||
@@ -63,33 +59,25 @@ void main() {
|
||||
});
|
||||
|
||||
test('layers a user file on top of the preset', () async {
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString(
|
||||
'name: user\nbindings:\n - intent: activate\n keys: ctrl+p\n',
|
||||
);
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString('name: user\nbindings:\n - intent: activate\n keys: ctrl+p\n');
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: palette.open\n keys: ctrl+p\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: palette.open\n keys: ctrl+p\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+p'), const {}), isA<ActivateIntent>());
|
||||
});
|
||||
|
||||
test('layers a settings overlay above the user file', () async {
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString(
|
||||
'name: user\nbindings:\n - intent: activate\n keys: ctrl+p\n',
|
||||
);
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString('name: user\nbindings:\n - intent: activate\n keys: ctrl+p\n');
|
||||
await settings.set<List<Object?>>(kKeymapOverridesSetting, [
|
||||
{'intent': 'dismiss', 'keys': 'ctrl+p'},
|
||||
]);
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: palette.open\n keys: ctrl+p\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: palette.open\n keys: ctrl+p\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+p'), const {}), isA<DismissIntent>());
|
||||
@@ -100,9 +88,7 @@ void main() {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('escape'), const {}), isA<DismissIntent>());
|
||||
@@ -115,9 +101,7 @@ void main() {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('escape'), const {}), isA<DismissIntent>());
|
||||
@@ -126,11 +110,7 @@ void main() {
|
||||
|
||||
group('registerCommandBinding / unregisterCommandBindings', () {
|
||||
test('adds an InvokeCommandIntent that resolves after load', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.registerCommandBinding('ctrl+shift+g', 'git.commit');
|
||||
final intent = svc.keymap!.resolve(KeyChord.parse('ctrl+shift+g'), const {});
|
||||
@@ -140,11 +120,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('honours a when-clause on the contribution', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.registerCommandBinding('ctrl+s', 'editor.save', when: 'editor.focused');
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+s'), const {}), isNull);
|
||||
@@ -152,25 +128,15 @@ void main() {
|
||||
});
|
||||
|
||||
test('user file overrides a contributed binding for the same chord', () async {
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString(
|
||||
'name: user\nbindings:\n - intent: dismiss\n keys: ctrl+x\n',
|
||||
);
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
await File('${appDir.path}/keybindings.yaml').writeAsString('name: user\nbindings:\n - intent: dismiss\n keys: ctrl+x\n');
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.registerCommandBinding('ctrl+x', 'editor.cut');
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+x'), const {}), isA<DismissIntent>());
|
||||
});
|
||||
|
||||
test('unregisterCommandBindings removes prior contributions', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.registerCommandBinding('ctrl+x', 'editor.cut');
|
||||
expect(svc.keymap!.resolve(KeyChord.parse('ctrl+x'), const {}), isA<InvokeCommandIntent>());
|
||||
@@ -179,11 +145,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('unregister of an unknown command is a no-op', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.unregisterCommandBindings('nothing-registered'); // doesn't throw
|
||||
});
|
||||
@@ -191,11 +153,7 @@ void main() {
|
||||
|
||||
group('scope flags', () {
|
||||
test('setScopeFlag updates the context; notifies listeners on change', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
var notified = 0;
|
||||
svc.addListener(() => notified++);
|
||||
@@ -209,11 +167,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('clearScopeFlag removes the entry; no-op when absent', () async {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}),
|
||||
);
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings: []\n'}));
|
||||
await svc.load();
|
||||
svc.setScopeFlag('foo', true);
|
||||
svc.clearScopeFlag('foo');
|
||||
@@ -243,11 +197,7 @@ void main() {
|
||||
group('resolveEvent', () {
|
||||
test('returns null before load()', () {
|
||||
final svc = KeymapService(settings: settings, appDir: appDir, bundle: _bundle(const {}));
|
||||
final down = KeyDownEvent(
|
||||
physicalKey: PhysicalKeyboardKey.escape,
|
||||
logicalKey: LogicalKeyboardKey.escape,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final down = KeyDownEvent(physicalKey: PhysicalKeyboardKey.escape, logicalKey: LogicalKeyboardKey.escape, timeStamp: Duration.zero);
|
||||
expect(svc.resolveEvent(down, HardwareKeyboard.instance), isNull);
|
||||
});
|
||||
|
||||
@@ -255,16 +205,10 @@ void main() {
|
||||
final svc = KeymapService(
|
||||
settings: settings,
|
||||
appDir: appDir,
|
||||
bundle: _bundle({
|
||||
'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n',
|
||||
}),
|
||||
bundle: _bundle({'assets/keymaps/default.yaml': 'name: default\nbindings:\n - intent: dismiss\n keys: escape\n'}),
|
||||
);
|
||||
await svc.load();
|
||||
final down = KeyDownEvent(
|
||||
physicalKey: PhysicalKeyboardKey.escape,
|
||||
logicalKey: LogicalKeyboardKey.escape,
|
||||
timeStamp: Duration.zero,
|
||||
);
|
||||
final down = KeyDownEvent(physicalKey: PhysicalKeyboardKey.escape, logicalKey: LogicalKeyboardKey.escape, timeStamp: Duration.zero);
|
||||
expect(svc.resolveEvent(down, HardwareKeyboard.instance), isA<DismissIntent>());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,9 +45,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('default.yaml binds Tab / Shift+Tab to focus traversal', () {
|
||||
final layer = KeymapLayer.fromYaml(
|
||||
File('assets/keymaps/default.yaml').readAsStringSync(),
|
||||
);
|
||||
final layer = KeymapLayer.fromYaml(File('assets/keymaps/default.yaml').readAsStringSync());
|
||||
expect(layer.bindings.any((b) => b.intent is NextFocusIntent), isTrue);
|
||||
expect(layer.bindings.any((b) => b.intent is PreviousFocusIntent), isTrue);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user