Skip to content

GetCommandsByCategory(null) returns nothing, while "" and " " return the uncategorized commands #140

Description

@matt-edmondson

What's wrong

CommandRegistry.GetCommandsByCategory (Keybinding/Services/CommandRegistry.cs, ~line 60):

string? normalizedCategory = category?.Trim();
.Where(c => string.Equals(c.Category, normalizedCategory, StringComparison.OrdinalIgnoreCase))

c.Category is a CommandCategory?, which is a SemanticString. Passing it to string.Equals(string, string, …) goes through the implicit string conversion, and a null CommandCategory converts to "", not null. That gives three different results:

  • category: null: compares "" with null, so nothing ever matches.
  • category: "" or " ": trims to "", so it matches every uncategorized command.

Repro

Register two commands:

  • new Command("file.save", "Save"), with no category
  • new Command("edit.copy", "Copy", null, "Edit")

Then call GetCommandsByCategory with each input:

null   -> []
""     -> [file.save]
"  "   -> [file.save]
"Edit" -> [edit.copy]

The parameter is declared string? category, so null is an intended input, and "commands with no category" is the natural meaning. A UI that groups commands by category and passes command.Category back in gets an empty "Uncategorized" group.

Suggested fix / acceptance criteria

Handle null explicitly instead of relying on the implicit conversion:

string? wanted = string.IsNullOrWhiteSpace(category) ? null : category.Trim();
.Where(c => wanted is null
    ? c.Category is null
    : c.Category is not null && string.Equals(c.Category.ToString(), wanted, StringComparison.OrdinalIgnoreCase))
  • Null, "" and whitespace all return the uncategorized commands, and no others.
  • Add tests for null, "", " " and "Edit".

Activity

  1. matt-edmondson commented on Sep 27, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions