diff --git a/CHANGELOG.md b/CHANGELOG.md index 35569262..2690be35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Added alphabetical sorting to the "Select Project" dropdown (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/21) - Fixed Default profile settings (API key, connection type, proxy, etc.) not being saved when edited in Tools → Options → Claude Code → Profiles - Fixed MCP config not working on Windows due to quote stripping in CreateProcess (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/13) - Improved error panel on process start failure: shows Working Directory and CLAUDE_CONFIG_DIR fields (before Command and Error) for easier diagnosis; all fields have a right-click Copy menu; fixed "Restart Advanced…" not dismissing the error panel diff --git a/pom.xml b/pom.xml index 76c0ac7c..69c8dd62 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.nbclaudecodegui netbeans-claude-code-gui - 0.21.40-SNAPSHOT + 0.21.41-SNAPSHOT nbm Netbeans Claude Code GUI NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE. diff --git a/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanel.java b/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanel.java index 2653cc81..6de68d64 100644 --- a/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanel.java +++ b/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanel.java @@ -13,6 +13,8 @@ import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.logging.Logger; import java.util.prefs.Preferences; @@ -494,7 +496,13 @@ private void populateProjectCombo() { DefaultComboBoxModel cbModel = new DefaultComboBoxModel<>(); cbModel.addElement(new ProjectItem(null, NbBundle.getMessage(ClaudeSessionSelectorPanel.class, "LBL_SelectProject"))); - for (Project p : OpenProjects.getDefault().getOpenProjects()) { + // Sort projects alphabetically (case-insensitive) so the user can find + // their project quickly regardless of the order NetBeans returns them. + Project[] projects = OpenProjects.getDefault().getOpenProjects(); + Arrays.sort(projects, Comparator.comparing( + p -> ProjectUtils.getInformation(p).getDisplayName(), + String.CASE_INSENSITIVE_ORDER)); + for (Project p : projects) { cbModel.addElement(new ProjectItem(p, ProjectUtils.getInformation(p).getDisplayName())); } diff --git a/src/test/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanelTest.java b/src/test/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanelTest.java index 0f723191..fff5ec92 100644 --- a/src/test/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanelTest.java +++ b/src/test/java/io/github/nbclaudecodegui/ui/ClaudeSessionSelectorPanelTest.java @@ -3,6 +3,8 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.Arrays; +import java.util.Comparator; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -157,6 +159,36 @@ void resolveTabLabelNonProjectDirReturnsFallback() throws IOException { } } + // ------------------------------------------------------------------------- + // Project combo sorting (issue #21) + // ------------------------------------------------------------------------- + + /** + * Verifies that the comparator used in {@code populateProjectCombo()} sorts + * project names case-insensitively. The test stands in for the full UI + * flow (which requires a live NetBeans module system) and confirms that + * the sorting algorithm itself is correct. + */ + @Test + void projectComboSortIsCaseInsensitive() { + String[] names = {"Zebra", "apple", "Banana", "cherry"}; + Arrays.sort(names, Comparator.comparing(s -> s, String.CASE_INSENSITIVE_ORDER)); + assertArrayEquals(new String[]{"apple", "Banana", "cherry", "Zebra"}, names, + "Projects must be sorted alphabetically, case-insensitive"); + } + + @Test + void projectComboSortIsStableForEqualCaseNames() { + String[] names = {"Beta", "alpha", "ALPHA", "beta"}; + Arrays.sort(names, Comparator.comparing(s -> s, String.CASE_INSENSITIVE_ORDER)); + // All alpha-variants before beta-variants; relative order within a group + // is preserved (Arrays.sort is stable). + assertEquals("alpha", names[0].toLowerCase(), + "First group must be 'alpha' variants"); + assertEquals("beta", names[2].toLowerCase(), + "Second group must be 'beta' variants"); + } + // ------------------------------------------------------------------------- // History persistence helpers // -------------------------------------------------------------------------