Skip to content

Commit 7fec4ad

Browse files
committed
Add language server version prompt
PR #127 switched the default `smithy.server.version` from a pinned version to `latest.release`. Users upgrading have no way to discover this change or opt out without knowing the setting name. On first activation, a one-time notification offers "Use latest" or "Pin a version." Choosing to pin opens a QuickPick populated from Maven Central's `maven-metadata.xml`. A persistent status bar item shows the active version (`Smithy LS (latest)` or `Smithy LS v0.8.0`) and lets users switch on click. Status bar text follows VS Code UX guidelines for short labels; full "Smithy Language Server" naming appears in tooltips, notifications, and the QuickPick title. A `smithy.toggleVersionPolicy` command is registered in `package.json` as "Smithy: Change Language Server Version" for command palette access.
1 parent ccc11b4 commit 7fec4ad

2 files changed

Lines changed: 124 additions & 1 deletion

File tree

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@
6868
{
6969
"command": "smithy.clearSelector",
7070
"title": "Smithy:Selector:Clear"
71+
},
72+
{
73+
"command": "smithy.toggleVersionPolicy",
74+
"title": "Smithy: Change Language Server Version"
7175
}
7276
],
7377
"menus": {

src/extension.ts

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ import SelectorHandler from './selector';
77
import getCoursierExecutable from './coursier/coursier';
88

99
let client: lsp.LanguageClient;
10+
let versionStatusBarItem: vscode.StatusBarItem;
11+
12+
const VERSION_POLICY_PROMPTED_KEY = 'smithy.versionPolicyPrompted';
13+
const LATEST_RELEASE = 'latest.release';
1014

1115
export async function activate(context: vscode.ExtensionContext) {
16+
await promptVersionPolicy(context);
17+
createVersionStatusBarItem(context);
18+
1219
const server = await getServer(context);
1320
const clientOptions = getClientOptions();
1421

@@ -21,7 +28,8 @@ export async function activate(context: vscode.ExtensionContext) {
2128
context.subscriptions.push(
2229
vscode.workspace.registerTextDocumentContentProvider('smithyjar', jarFileContentsProvider),
2330
vscode.commands.registerCommand('smithy.runSelector', selectorHandler.run, selectorHandler),
24-
vscode.commands.registerCommand('smithy.clearSelector', selectorHandler.clear, selectorHandler)
31+
vscode.commands.registerCommand('smithy.clearSelector', selectorHandler.clear, selectorHandler),
32+
vscode.commands.registerCommand('smithy.toggleVersionPolicy', () => toggleVersionPolicy(context))
2533
);
2634

2735
// Start the client. This will also launch the server
@@ -35,6 +43,117 @@ export function deactivate(): Thenable<void> | undefined {
3543
return client.stop();
3644
}
3745

46+
async function promptVersionPolicy(context: vscode.ExtensionContext): Promise<void> {
47+
if (context.globalState.get<boolean>(VERSION_POLICY_PROMPTED_KEY)) {
48+
return;
49+
}
50+
51+
const useLatest = 'Use latest';
52+
const pinVersion = 'Pin a version';
53+
const choice = await vscode.window.showInformationMessage(
54+
'The Smithy extension can automatically use the latest Smithy Language Server, or you can pin a specific version.',
55+
useLatest,
56+
pinVersion
57+
);
58+
59+
await context.globalState.update(VERSION_POLICY_PROMPTED_KEY, true);
60+
61+
if (choice === pinVersion) {
62+
await pickAndPinVersion();
63+
}
64+
}
65+
66+
function createVersionStatusBarItem(context: vscode.ExtensionContext): void {
67+
versionStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
68+
versionStatusBarItem.command = 'smithy.toggleVersionPolicy';
69+
updateVersionStatusBarItem();
70+
versionStatusBarItem.show();
71+
context.subscriptions.push(versionStatusBarItem);
72+
73+
// Update status bar when configuration changes
74+
context.subscriptions.push(
75+
vscode.workspace.onDidChangeConfiguration((e) => {
76+
if (e.affectsConfiguration('smithy.server.version')) {
77+
updateVersionStatusBarItem();
78+
}
79+
})
80+
);
81+
}
82+
83+
function updateVersionStatusBarItem(): void {
84+
const version = config.getServerVersion();
85+
if (version === LATEST_RELEASE) {
86+
versionStatusBarItem.text = '$(check) Smithy LS (latest)';
87+
versionStatusBarItem.tooltip =
88+
'Smithy Language Server: using latest from Maven Central. Click to pin a version.';
89+
} else {
90+
versionStatusBarItem.text = '$(pin) Smithy LS v' + version;
91+
versionStatusBarItem.tooltip = 'Smithy Language Server: pinned to v' + version + '. Click to switch to latest.';
92+
}
93+
}
94+
95+
async function fetchAvailableVersions(): Promise<string[]> {
96+
const metadataUrl =
97+
'https://repo1.maven.org/maven2/software/amazon/smithy/smithy-language-server/maven-metadata.xml';
98+
try {
99+
const response = await fetch(metadataUrl);
100+
const text = await response.text();
101+
const versions = [...text.matchAll(/<version>([^<]+)<\/version>/g)].map((m) => m[1]).reverse();
102+
return versions;
103+
} catch {
104+
return [];
105+
}
106+
}
107+
108+
async function pickAndPinVersion(): Promise<void> {
109+
const versions = await vscode.window.withProgress(
110+
{ location: vscode.ProgressLocation.Notification, title: 'Fetching available versions...' },
111+
() => fetchAvailableVersions()
112+
);
113+
114+
if (versions.length === 0) {
115+
vscode.window.showErrorMessage('Could not fetch Smithy Language Server versions from Maven Central.');
116+
return;
117+
}
118+
119+
const picked = await vscode.window.showQuickPick(versions, {
120+
placeHolder: 'Select a Smithy Language Server version to pin',
121+
});
122+
123+
if (picked) {
124+
await vscode.workspace
125+
.getConfiguration('smithy')
126+
.update('server.version', picked, vscode.ConfigurationTarget.Global);
127+
const reload = await vscode.window.showInformationMessage(
128+
'Smithy Language Server pinned to v' + picked + '. Reload window to apply.',
129+
'Reload'
130+
);
131+
if (reload === 'Reload') {
132+
vscode.commands.executeCommand('workbench.action.reloadWindow');
133+
}
134+
}
135+
}
136+
137+
async function toggleVersionPolicy(context: vscode.ExtensionContext): Promise<void> {
138+
const currentVersion = config.getServerVersion();
139+
const isLatest = currentVersion === LATEST_RELEASE;
140+
141+
if (isLatest) {
142+
await pickAndPinVersion();
143+
} else {
144+
await vscode.workspace
145+
.getConfiguration('smithy')
146+
.update('server.version', undefined, vscode.ConfigurationTarget.Global);
147+
const reload = await vscode.window.showInformationMessage(
148+
'Smithy Language Server set to use latest version. Reload window to apply.',
149+
'Reload'
150+
);
151+
if (reload === 'Reload') {
152+
vscode.commands.executeCommand('workbench.action.reloadWindow');
153+
}
154+
}
155+
}
156+
38157
function getClientOptions(): lsp.LanguageClientOptions {
39158
const initializationOptions = {
40159
'diagnostics.minimumSeverity': config.getServerDiagnosticsMinimumSeverity(),

0 commit comments

Comments
 (0)