Skip to content

Commit e2fb297

Browse files
committed
Make WebSocket Terminal launchable from Command Palette and Server Manager tree
1 parent d835d3e commit e2fb297

File tree

3 files changed

+77
-23
lines changed

3 files changed

+77
-23
lines changed

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
"onCommand:vscode-objectscript.modifyWsFolder",
9191
"onCommand:vscode-objectscript.openErrorLocation",
9292
"onCommand:vscode-objectscript.launchWebSocketTerminal",
93+
"onCommand:vscode-objectscript.intersystems-servermanager.webterminal",
9394
"onTerminalProfile:vscode-objectscript.webSocketTerminal",
9495
"onLanguage:objectscript",
9596
"onLanguage:objectscript-int",
@@ -98,6 +99,7 @@
9899
"onLanguage:xml",
99100
"onView:ObjectScriptExplorer",
100101
"onView:ObjectScriptProjectsExplorer",
102+
"onView:intersystems-community_servermanager",
101103
"onFileSystem:isfs",
102104
"onFileSystem:isfs-readonly",
103105
"onFileSystem:objectscript",
@@ -349,6 +351,10 @@
349351
{
350352
"command": "vscode-objectscript.launchWebSocketTerminal",
351353
"when": "vscode-objectscript.connectActive"
354+
},
355+
{
356+
"command": "vscode-objectscript.intersystems-servermanager.webterminal",
357+
"when": "false"
352358
}
353359
],
354360
"view/title": [
@@ -473,6 +479,11 @@
473479
"command": "vscode-objectscript.explorer.project.closeOtherServerNs",
474480
"when": "view == ObjectScriptProjectsExplorer && viewItem == projectsServerNsNode:extra",
475481
"group": "inline@10"
482+
},
483+
{
484+
"command": "vscode-objectscript.intersystems-servermanager.webterminal",
485+
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
486+
"group": "inline@1"
476487
}
477488
],
478489
"editor/context": [
@@ -1130,6 +1141,11 @@
11301141
"category": "ObjectScript",
11311142
"command": "vscode-objectscript.launchWebSocketTerminal",
11321143
"title": "Launch WebSocket Terminal"
1144+
},
1145+
{
1146+
"command": "vscode-objectscript.intersystems-servermanager.webterminal",
1147+
"title": "Launch WebSocket Terminal",
1148+
"icon": "$(terminal)"
11331149
}
11341150
],
11351151
"keybindings": [

src/commands/webSocketTerminal.ts

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as vscode from "vscode";
22
import WebSocket = require("ws");
33

44
import { AtelierAPI } from "../api";
5-
import { currentFile, outputChannel } from "../utils";
5+
import { connectionTarget, currentFile, outputChannel } from "../utils";
6+
import { config, resolveConnectionSpec } from "../extension";
67

78
const keys = {
89
enter: "\r",
@@ -596,6 +597,7 @@ class WebSocketTerminal implements vscode.Pseudoterminal {
596597
function terminalConfigForUri(
597598
api: AtelierAPI,
598599
extensionUri: vscode.Uri,
600+
targetUri: vscode.Uri,
599601
throwErrors = false
600602
): vscode.ExtensionTerminalOptions | undefined {
601603
const reportError = (msg: string) => {
@@ -619,19 +621,60 @@ function terminalConfigForUri(
619621

620622
return {
621623
name: api.config.serverName && api.config.serverName != "" ? api.config.serverName : "iris",
622-
location: vscode.TerminalLocation.Panel,
624+
location:
625+
// Mimic what a built-in profile does. When it is the default and the Terminal tab is selected while empty,
626+
// an terminal is always created in the Panel.
627+
vscode.workspace.getConfiguration("terminal.integrated", targetUri).get("defaultLocation") === "editor" &&
628+
vscode.window.terminals.length > 0
629+
? vscode.TerminalLocation.Editor
630+
: vscode.TerminalLocation.Panel,
623631
pty: new WebSocketTerminal(api),
624632
isTransient: true,
625633
iconPath: vscode.Uri.joinPath(extensionUri, "images", "fileIcon.svg"),
626634
};
627635
}
628636

629-
export async function launchWebSocketTerminal(extensionUri: vscode.Uri): Promise<void> {
637+
async function workspaceUriForTerminal() {
638+
let uri: vscode.Uri;
639+
const workspaceFolders = vscode.workspace.workspaceFolders || [];
640+
if (workspaceFolders.length == 0) {
641+
throw new Error("WebSocket Terminal requires an open workspace.");
642+
} else if (workspaceFolders.length == 1) {
643+
// Use the current connection
644+
uri = workspaceFolders[0].uri;
645+
} else {
646+
// Pick from the workspace folders
647+
uri = (
648+
await vscode.window.showWorkspaceFolderPick({
649+
ignoreFocusOut: true,
650+
placeHolder: "Pick the workspace folder to get server connection information from",
651+
})
652+
)?.uri;
653+
}
654+
return uri;
655+
}
656+
657+
export async function launchWebSocketTerminal(extensionUri: vscode.Uri, targetUri?: vscode.Uri): Promise<void> {
630658
// Determine the server to connect to
631-
const api = new AtelierAPI(currentFile()?.uri);
659+
if (targetUri) {
660+
// Uri passed as command argument might be for a server we haven't yet resolve connection details such as password,
661+
// so make sure that happens now if needed
662+
const { configName } = connectionTarget(targetUri);
663+
const serverName = targetUri.scheme === "file" ? config("conn", configName).server : configName;
664+
await resolveConnectionSpec(serverName);
665+
} else {
666+
targetUri = currentFile()?.uri;
667+
if (!targetUri) {
668+
targetUri = await workspaceUriForTerminal();
669+
}
670+
}
671+
const api = new AtelierAPI(targetUri);
672+
673+
// Guarantee we know the apiVersion of the server
674+
await api.serverInfo();
632675

633676
// Get the terminal configuration
634-
const terminalOpts = terminalConfigForUri(api, extensionUri);
677+
const terminalOpts = terminalConfigForUri(api, extensionUri, targetUri);
635678
if (terminalOpts) {
636679
// Launch the terminal
637680
const terminal = vscode.window.createTerminal(terminalOpts);
@@ -642,28 +685,13 @@ export async function launchWebSocketTerminal(extensionUri: vscode.Uri): Promise
642685
export class WebSocketTerminalProfileProvider implements vscode.TerminalProfileProvider {
643686
constructor(private readonly _extensionUri: vscode.Uri) {}
644687

645-
async provideTerminalProfile(token: vscode.CancellationToken): Promise<vscode.TerminalProfile> {
688+
async provideTerminalProfile(_token: vscode.CancellationToken): Promise<vscode.TerminalProfile> {
646689
// Determine the server connection to use
647-
let uri: vscode.Uri;
648-
const workspaceFolders = vscode.workspace.workspaceFolders || [];
649-
if (workspaceFolders.length == 0) {
650-
throw new Error("WebSocket Terminal requires an open workspace.");
651-
} else if (workspaceFolders.length == 1) {
652-
// Use the current connection
653-
uri = workspaceFolders[0].uri;
654-
} else {
655-
// Pick from the workspace folders
656-
uri = (
657-
await vscode.window.showWorkspaceFolderPick({
658-
ignoreFocusOut: true,
659-
placeHolder: "Pick the workspace folder to get server connection information from",
660-
})
661-
)?.uri;
662-
}
690+
const uri: vscode.Uri = await workspaceUriForTerminal();
663691

664692
if (uri) {
665693
// Get the terminal configuration. Will throw if there's an error.
666-
const terminalOpts = terminalConfigForUri(new AtelierAPI(uri), this._extensionUri, true);
694+
const terminalOpts = terminalConfigForUri(new AtelierAPI(uri), this._extensionUri, uri, true);
667695
return new vscode.TerminalProfile(terminalOpts);
668696
} else {
669697
throw new Error("WebSocket Terminal requires a selected workspace folder.");

src/extension.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,16 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
13091309
vscode.commands.registerCommand("vscode-objectscript.launchWebSocketTerminal", () =>
13101310
launchWebSocketTerminal(context.extensionUri)
13111311
),
1312+
vscode.commands.registerCommand(
1313+
"vscode-objectscript.intersystems-servermanager.webterminal",
1314+
async (namespaceTreeItem) => {
1315+
const idArray = namespaceTreeItem.id.split(":");
1316+
const serverId = idArray[1];
1317+
const namespace = idArray[3];
1318+
const targetUri = vscode.Uri.from({ scheme: "isfs", authority: `${serverId}:${namespace}` });
1319+
launchWebSocketTerminal(context.extensionUri, targetUri);
1320+
}
1321+
),
13121322
vscode.window.registerTerminalProfileProvider(
13131323
"vscode-objectscript.webSocketTerminal",
13141324
new WebSocketTerminalProfileProvider(context.extensionUri)

0 commit comments

Comments
 (0)