Skip to content

Commit 37357e0

Browse files
authored
Change some pickers from "workspace folders" to "server connections" (#1467)
1 parent 96bfb81 commit 37357e0

File tree

4 files changed

+64
-49
lines changed

4 files changed

+64
-49
lines changed

src/commands/newFile.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ export async function newFile(type: NewFileType): Promise<void> {
247247
wsFolder = vscode.workspace.workspaceFolders[0];
248248
} else {
249249
wsFolder = await vscode.window.showWorkspaceFolderPick({
250-
placeHolder: "Pick the workspace folder to create the file in.",
250+
placeHolder: "Pick the workspace folder where you want to create the file",
251251
});
252252
}
253253
if (!wsFolder) {

src/commands/webSocketTerminal.ts

+9-28
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
22
import WebSocket = require("ws");
33

44
import { AtelierAPI } from "../api";
5-
import { connectionTarget, currentFile, handleError, notIsfs, outputChannel } from "../utils";
5+
import { connectionTarget, currentFile, getWsServerConnection, handleError, notIsfs, outputChannel } from "../utils";
66
import { config, iscIcon, resolveConnectionSpec } from "../extension";
77

88
const keys = {
@@ -755,26 +755,6 @@ function terminalConfigForUri(
755755
};
756756
}
757757

758-
async function workspaceUriForTerminal(throwErrors = false) {
759-
let uri: vscode.Uri;
760-
const workspaceFolders = vscode.workspace.workspaceFolders || [];
761-
if (workspaceFolders.length == 0) {
762-
reportError("Lite Terminal requires an open workspace.", throwErrors);
763-
} else if (workspaceFolders.length == 1) {
764-
// Use the current connection
765-
uri = workspaceFolders[0].uri;
766-
} else {
767-
// Pick from the workspace folders
768-
uri = (
769-
await vscode.window.showWorkspaceFolderPick({
770-
ignoreFocusOut: true,
771-
placeHolder: "Pick the workspace folder to get server connection information from",
772-
})
773-
)?.uri;
774-
}
775-
return uri;
776-
}
777-
778758
export async function launchWebSocketTerminal(targetUri?: vscode.Uri): Promise<void> {
779759
// Determine the server to connect to
780760
if (targetUri) {
@@ -784,10 +764,9 @@ export async function launchWebSocketTerminal(targetUri?: vscode.Uri): Promise<v
784764
const serverName = notIsfs(targetUri) ? config("conn", configName).server : configName;
785765
await resolveConnectionSpec(serverName);
786766
} else {
787-
targetUri = currentFile()?.uri;
788-
if (!targetUri) {
789-
targetUri = await workspaceUriForTerminal();
790-
}
767+
// Determine the server connection to use
768+
targetUri = currentFile()?.uri ?? (await getWsServerConnection("2023.2.0"));
769+
if (!targetUri) return;
791770
}
792771
const api = new AtelierAPI(targetUri);
793772

@@ -806,14 +785,16 @@ export async function launchWebSocketTerminal(targetUri?: vscode.Uri): Promise<v
806785
export class WebSocketTerminalProfileProvider implements vscode.TerminalProfileProvider {
807786
async provideTerminalProfile(): Promise<vscode.TerminalProfile> {
808787
// Determine the server connection to use
809-
const uri: vscode.Uri = await workspaceUriForTerminal(true);
788+
const uri: vscode.Uri = await getWsServerConnection("2023.2.0");
810789

811790
if (uri) {
812791
// Get the terminal configuration. Will throw if there's an error.
813792
const terminalOpts = terminalConfigForUri(new AtelierAPI(uri), uri, true);
814793
return new vscode.TerminalProfile(terminalOpts);
815-
} else {
816-
throw new Error("Lite Terminal requires a selected workspace folder.");
794+
} else if (uri == undefined) {
795+
throw new Error(
796+
"Lite Terminal requires an active server connection to InterSystems IRIS version 2023.2 or above."
797+
);
817798
}
818799
}
819800
}

src/extension.ts

+6-20
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ import {
100100
handleError,
101101
cspApps,
102102
otherDocExts,
103+
getWsServerConnection,
103104
} from "./utils";
104105
import { ObjectScriptDiagnosticProvider } from "./providers/ObjectScriptDiagnosticProvider";
105106
import { DocumentLinkProvider } from "./providers/DocumentLinkProvider";
@@ -996,31 +997,14 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
996997
}
997998
if (!connectionUri) {
998999
// May need to ask the user
999-
const workspaceFolders = vscode.workspace.workspaceFolders || [];
1000-
if (workspaceFolders.length == 0) {
1001-
vscode.window.showErrorMessage(`Attaching to a server process requires a workspace to be open.`, {
1002-
modal: true,
1003-
});
1004-
return;
1005-
}
1006-
if (workspaceFolders.length == 1) {
1007-
connectionUri = workspaceFolders[0].uri;
1008-
} else {
1009-
// Pick from the workspace folders
1010-
connectionUri = (
1011-
await vscode.window.showWorkspaceFolderPick({
1012-
ignoreFocusOut: true,
1013-
placeHolder: "Pick the workspace folder to get server connection information from",
1014-
})
1015-
)?.uri;
1016-
}
1000+
connectionUri = await getWsServerConnection();
10171001
}
10181002
if (!connectionUri) {
10191003
return;
10201004
}
10211005
const api = new AtelierAPI(connectionUri);
10221006
if (!api.active) {
1023-
vscode.window.showErrorMessage(`No active server connection.`, {
1007+
vscode.window.showErrorMessage(`Server connection is inactive.`, {
10241008
modal: true,
10251009
});
10261010
return;
@@ -1489,7 +1473,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
14891473
wsFolder = workspaceFolders[0];
14901474
} else if (workspaceFolders.length > 1) {
14911475
// Pick from the workspace folders
1492-
wsFolder = await vscode.window.showWorkspaceFolderPick();
1476+
wsFolder = await vscode.window.showWorkspaceFolderPick({
1477+
placeHolder: "Pick the workspace folder where you want to open a document",
1478+
});
14931479
}
14941480
if (!wsFolder) return;
14951481
const api = new AtelierAPI(wsFolder.uri);

src/utils/index.ts

+48
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path = require("path");
22
import { exec } from "child_process";
33
import * as vscode from "vscode";
4+
import { lt } from "semver";
45
import {
56
config,
67
schemas,
@@ -768,6 +769,53 @@ export function base64EncodeContent(content: Buffer): string[] {
768769
return result;
769770
}
770771

772+
interface ConnQPItem extends vscode.QuickPickItem {
773+
uri: vscode.Uri;
774+
ns: string;
775+
}
776+
777+
/**
778+
* Prompt the user to pick an active server connection that's used in this workspace.
779+
* Returns the uri of the workspace folder corresponding to the chosen connection.
780+
* Returns `undefined` if there are no active server connections in this workspace,
781+
* or if the user dismisses the QuickPick. If there is only one active server
782+
* connection, that will be returned without prompting the user.
783+
*
784+
* @param minVersion Optional minimum server version to enforce, in semantic version form (20XX.Y.Z).
785+
* @returns `undefined` if there were no suitable server connections and `null` if the
786+
* user explicitly escaped from the QuickPick.
787+
*/
788+
export async function getWsServerConnection(minVersion?: string): Promise<vscode.Uri> {
789+
if (!vscode.workspace.workspaceFolders?.length) return;
790+
const conns: ConnQPItem[] = [];
791+
for (const wsFolder of vscode.workspace.workspaceFolders) {
792+
const api = new AtelierAPI(wsFolder.uri);
793+
if (!api.active) continue;
794+
const config = api.config;
795+
if (minVersion && lt(config.serverVersion, minVersion)) continue;
796+
const conn = {
797+
label: api.connInfo,
798+
description: isUnauthenticated(config.username) ? "Unauthenticated" : config.username,
799+
detail: `http${config.https ? "s" : ""}://${config.host}:${config.port}${config.pathPrefix}`,
800+
uri: wsFolder.uri,
801+
ns: api.ns,
802+
};
803+
if (!conns.some((c) => c.detail == conn.detail && c.description == conn.description && c.ns == conn.ns))
804+
conns.push(conn);
805+
}
806+
if (!conns.length) return;
807+
if (conns.length == 1) return conns[0].uri;
808+
return vscode.window
809+
.showQuickPick(conns, {
810+
canPickMany: false,
811+
ignoreFocusOut: true,
812+
matchOnDescription: true,
813+
matchOnDetail: true,
814+
title: "Pick a server connection from the current workspace",
815+
})
816+
.then((c) => c?.uri ?? null);
817+
}
818+
771819
// ---------------------------------------------------------------------
772820
// Source: https://github.com/amsterdamharu/lib/blob/master/src/index.js
773821

0 commit comments

Comments
 (0)