What's wrong
Command has two constructors, and they normalize differently.
CommandRegistry.GetCommandsByCategory (Services/CommandRegistry.cs ~L60-62) trims its input and compares with OrdinalIgnoreCase, so a stored category with padding never matches.
Reproduction (verified)
var cmd = new Command(
CommandId.Create("edit.copy"),
CommandName.Create(" Copy "),
CommandDescription.Create(" "),
CommandCategory.Create("Editing "));
// Stored: Name=" Copy ", Description=" ", Category="Editing "
registry.RegisterCommand(cmd);
registry.GetCommandsByCategory("Editing"); // 0 results
registry.GetCommandsByCategory("Editing "); // 0 results (the input is trimmed)
After SaveAsync() and a reload, the command is rebuilt through the string constructor and trimmed, and it then appears under "Editing". The same command behaves differently before and after a round-trip.
Suggested fix / acceptance criteria
What's wrong
Commandhas two constructors, and they normalize differently.Keybinding/Models/Command.cs~L236-239) trims the name, description and category, and maps a blank description or category tonull.(CommandId, CommandName, CommandDescription?, CommandCategory?)(~L196-214) trims only the id, which was the A Command built from a CommandId with surrounding whitespace registers but can never be found, bound or unregistered #123 fix. The name, description and category are stored exactly as given.CommandRegistry.GetCommandsByCategory(Services/CommandRegistry.cs~L60-62) trims its input and compares withOrdinalIgnoreCase, so a stored category with padding never matches.Reproduction (verified)
After
SaveAsync()and a reload, the command is rebuilt through the string constructor and trimmed, and it then appears under "Editing". The same command behaves differently before and after a round-trip.Suggested fix / acceptance criteria
null. Ideally both constructors share one helper.CommandIdWhitespaceTests: padded name and category are trimmed, a whitespace-only description or category becomesnull, andGetCommandsByCategory("Editing")finds the command without a save and reload.