Fix #4167: use java.projects context for explorer actions#4450
Conversation
|
This change introduces the java.projects array context and uses it to make the Add/Remove Source Path Explorer actions more precise. These actions are now only shown for Java project folders instead of every folder in the Explorer. |
There was a problem hiding this comment.
Thanks for tackling #4167! The array-context-key approach is the right tool here, but I think it's wired to the wrong set for these two actions. Left a few inline notes.
please also consider adding PR's description.
| }, | ||
| { | ||
| "when": "explorerResourceIsFolder&&javaLSReady", | ||
| "when": "explorerResourceIsFolder&&javaLSReady&&resourcePath in java.projects", |
There was a problem hiding this comment.
java.projects only holds project root paths, and in is an exact-membership check (no prefix/descendant matching). So this only matches when you right-click the project root itself.
But Add/Remove Source Path are mostly used on subfolders (e.g. marking src/test as a source root) — those will now stop showing the action entirely, which is the opposite of what we want. Same applies to the removeFromSourcePath when just below.
For remove, what you probably want is a separate java.sourceFolders context (the actual source paths) and gate on resourcePath in java.sourceFolders. Add is trickier, since "folder is inside a project" can't really be expressed with exact membership.
| try { | ||
| const projectUris = await getAllJavaProjects(); | ||
| const projectPaths = projectUris.map((uriString) => Uri.parse(uriString).fsPath.replace(/[\\/]$/, '')); | ||
| await commands.executeCommand('setContext', 'java.projects', projectPaths); |
There was a problem hiding this comment.
This is only set once, on ServiceReady. Projects change over time (import/delete, classpath updates) and this never refreshes — so newly imported projects won't get the action, and deleted ones keep it until a reload.
Worth extracting a small helper and also calling it from onDidProjectsImport / onDidProjectsDelete (both already used in runtimeStatusBarProvider.ts).
| snippetCompletionProvider.dispose(); | ||
| registerDocumentValidationListener(context, this.languageClient); | ||
| try { | ||
| const projectUris = await getAllJavaProjects(); |
There was a problem hiding this comment.
awaiting this means javaLSReady (set a few lines down) now waits on a full LS round-trip — and gets blocked completely if this call ever hangs. Since javaLSReady gates a lot of menus/keybindings, I'd set it first and then populate java.projects fire-and-forget (it already has its own try/catch).
No description provided.