Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,11 @@
"command": "java.action.copyFullyQualifiedName",
"title": "%java.action.copyFullyQualifiedName%",
"category": "Java"
},
{
"command": "java.jbang.recommend",
"title": "%java.jbang.recommend%",
"category": "Java"
}
],
"keybindings": [
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
"java.change.searchScope": "Change Search Scope",
"java.action.showExtendedOutline": "Open Extended Outline",
"java.runtimes.add": "Add Java Runtime",
"java.action.copyFullyQualifiedName": "Copy Fully Qualified Name"
"java.action.copyFullyQualifiedName": "Copy Fully Qualified Name",
"java.jbang.recommend": "Recommend JBang"
}
5 changes: 5 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ export namespace Commands {
*/
export const COPY_FULLY_QUALIFIED_NAME = 'java.action.copyFullyQualifiedName';
export const GET_FULLY_QUALIFIED_NAME = 'java.getFullyQualifiedName';

/**
* Recommend JBang for single Java file usage.
*/
export const JBANG_RECOMMEND = 'java.jbang.recommend';
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,15 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
cleanWorkspaceExists
);

// Recommend JBang when working with a single Java file (issue #3111)
void showJBangRecommendation(context);

context.subscriptions.push(workspace.onDidOpenTextDocument(async (document) => {
if (document.languageId === 'java') {
await showJBangRecommendation(context);
}
}));

return apiManager.getApiInstance();
}

Expand Down Expand Up @@ -1412,3 +1421,49 @@ function addRevealCommand(client: LanguageClient, codeAction: CodeAction, lspEdi
}
return codeAction;
}

const JBANG_RECOMMENDATION_KEY = 'jbangRecommendationShown';
const JBANG_EXTENSION_ID = 'jbangdev.jbang-vscode';

function shouldRecommendJBang(): boolean {
// Case 1: No workspace folder (standalone file mode)
if (!workspace.workspaceFolders) {
return true;
}
// Case 2: Workspace folder with just a single Java file
if (workspace.workspaceFolders.length === 1) {
const javaFileCount = workspace.textDocuments.filter(doc => doc.languageId === 'java').length;
if (javaFileCount <= 1) {
return true;
}
}
return false;
}

async function showJBangRecommendation(context: ExtensionContext): Promise<void> {
const alreadyShown = context.globalState.get<boolean>(JBANG_RECOMMENDATION_KEY, false);
if (alreadyShown) {
return;
}

if (!shouldRecommendJBang()) {
return;
}

const install = 'Install JBang';
const maybeLater = 'Maybe Later';
const dontShowAgain = "Don't Show Again";

const choice = await window.showInformationMessage(
'You are working with a single Java file. JBang makes it easy to run Java scripts. Would you like to install the JBang extension?',
install, maybeLater, dontShowAgain
);

if (choice === install) {
await commands.executeCommand('workbench.extensions.installExtension', JBANG_EXTENSION_ID);
}

if (choice === dontShowAgain || choice === install) {
await context.globalState.update(JBANG_RECOMMENDATION_KEY, true);
}
}