@@ -2,7 +2,8 @@ import * as vscode from "vscode";
22import WebSocket = require( "ws" ) ;
33
44import { AtelierAPI } from "../api" ;
5- import { currentFile , outputChannel } from "../utils" ;
5+ import { connectionTarget , currentFile , outputChannel } from "../utils" ;
6+ import { config , resolveConnectionSpec } from "../extension" ;
67
78const keys = {
89 enter : "\r" ,
@@ -593,45 +594,87 @@ class WebSocketTerminal implements vscode.Pseudoterminal {
593594 }
594595}
595596
597+ function reportError ( msg : string , throwErrors = false ) {
598+ if ( throwErrors ) {
599+ throw new Error ( msg ) ;
600+ } else {
601+ vscode . window . showErrorMessage ( msg , "Dismiss" ) ;
602+ }
603+ }
604+
596605function terminalConfigForUri (
597606 api : AtelierAPI ,
598607 extensionUri : vscode . Uri ,
608+ targetUri : vscode . Uri ,
599609 throwErrors = false
600610) : vscode . ExtensionTerminalOptions | undefined {
601- const reportError = ( msg : string ) => {
602- if ( throwErrors ) {
603- throw new Error ( msg ) ;
604- } else {
605- vscode . window . showErrorMessage ( msg , "Dismiss" ) ;
606- }
607- } ;
608-
609611 // Make sure the server connection is active
610612 if ( ! api . active || api . ns == "" ) {
611- reportError ( "WebSocket Terminal requires an active server connection." ) ;
613+ reportError ( "WebSocket Terminal requires an active server connection." , throwErrors ) ;
612614 return ;
613615 }
614616 // Make sure the server has the terminal endpoint
615617 if ( api . config . apiVersion < 7 ) {
616- reportError ( "WebSocket Terminal requires InterSystems IRIS version 2023.2 or above." ) ;
618+ reportError ( "WebSocket Terminal requires InterSystems IRIS version 2023.2 or above." , throwErrors ) ;
617619 return ;
618620 }
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+ // a 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 ( throwErrors = false ) {
638+ let uri : vscode . Uri ;
639+ const workspaceFolders = vscode . workspace . workspaceFolders || [ ] ;
640+ if ( workspaceFolders . length == 0 ) {
641+ reportError ( "WebSocket Terminal requires an open workspace." , throwErrors ) ;
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
642685export 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 ( true ) ;
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." ) ;
0 commit comments