feat(i18n): i18n key fields on command + settings contributions (T-462)

Lets manifest labels (command-palette/menu titles, settings labels) localize,
not just displayed widget strings. Adds optional titleKey/i18nNamespace to
CommandContribution and labelKey/helpKey/titleKey + a category i18nNamespace to
the settings schema. The command palette and menu bar now resolve titles via a
shared localizedCommandTitle helper — and the palette's fuzzy search matches
the localized title too (PaletteController.titleResolver). No behaviour change
until the per-extension keys + catalog entries land (placeholder == English).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-19 09:44:35 +02:00
co-authored by Claude Opus 4.8
parent 33a8a74240
commit 198c8b18b5
9 changed files with 91 additions and 11 deletions
+8 -2
View File
@@ -8,6 +8,12 @@ class PaletteController extends ChangeNotifier {
final CommandRegistry _registry;
/// Resolves a command's display title (the widget sets this to an i18n-aware
/// resolver so both the rendered title AND fuzzy search use the localized
/// string, T-462). Defaults to the English title/id.
String Function(CommandContribution cmd)? titleResolver;
String _titleOf(CommandContribution c) => titleResolver?.call(c) ?? c.title ?? c.command;
bool _open = false;
String _filter = '';
int _selectedIndex = 0;
@@ -103,7 +109,7 @@ class PaletteController extends ChangeNotifier {
final scored = <({CommandContribution cmd, int score})>[];
for (final c in all) {
final s = fuzzyScore((c.title ?? c.command).toLowerCase(), q);
final s = fuzzyScore(_titleOf(c).toLowerCase(), q);
if (s != null) scored.add((cmd: c, score: s));
}
scored.sort((a, b) {
@@ -111,7 +117,7 @@ class PaletteController extends ChangeNotifier {
if (byScore != 0) return byScore;
final byRecent = rank(a.cmd.command).compareTo(rank(b.cmd.command));
if (byRecent != 0) return byRecent;
return (a.cmd.title ?? a.cmd.command).toLowerCase().compareTo((b.cmd.title ?? b.cmd.command).toLowerCase());
return _titleOf(a.cmd).toLowerCase().compareTo(_titleOf(b.cmd).toLowerCase());
});
return [for (final s in scored) s.cmd];
}