diff --git a/vscode-sbt-scala/client/package.json b/vscode-sbt-scala/client/package.json index 1e729fc32..f4316539e 100644 --- a/vscode-sbt-scala/client/package.json +++ b/vscode-sbt-scala/client/package.json @@ -1,7 +1,7 @@ { "name": "vscode-sbt-scala", "displayName": "Scala (sbt)", - "version": "0.1.0", + "version": "0.2.0", "author": "Lightbend, Inc.", "license": "BSD-3-Clause", "publisher": "lightbend", diff --git a/vscode-sbt-scala/client/src/extension.ts b/vscode-sbt-scala/client/src/extension.ts index c5d3a1282..ff8206a37 100644 --- a/vscode-sbt-scala/client/src/extension.ts +++ b/vscode-sbt-scala/client/src/extension.ts @@ -1,28 +1,39 @@ 'use strict'; import * as path from 'path'; - -let fs = require('fs'); +import * as url from 'url'; +import * as net from 'net'; +let fs = require('fs'), + os = require('os'); import * as vscode from 'vscode'; import { ExtensionContext, workspace } from 'vscode'; // workspace, import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; +let terminal: vscode.Terminal = null; + +function delay(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +export async function deactivate() { + if (terminal != null) { + terminal.sendText("exit"); + await delay(1000); + terminal.dispose(); + } +} + export async function activate(context: ExtensionContext) { // Start sbt - const terminal = vscode.window.createTerminal(`sbt`); + terminal = vscode.window.createTerminal(`sbt`); terminal.show(); terminal.sendText("sbt"); - - function delay(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - // Wait for SBT server to start - let retries = 30; + let retries = 60; while (retries > 0) { retries--; await delay(1000); - if (fs.existsSync(path.join(workspace.rootPath, 'project', 'target', 'active.json'))) { + if (isServerUp()) { break; } } @@ -46,7 +57,47 @@ export async function activate(context: ExtensionContext) { return discoverToken(); } } - + + // Don't start VS Code connection until sbt server is confirmed to be up and running. + function isServerUp(): boolean { + let isFileThere = fs.existsSync(path.join(workspace.rootPath, 'project', 'target', 'active.json')); + if (!isFileThere) { + return false; + } else { + let skt = new net.Socket(); + try { + connectSocket(skt); + } catch(e) { + return false; + } + skt.end(); + return true; + } + } + + function connectSocket(socket: net.Socket):  net.Socket { + let u = discoverUrl(); + // let socket = net.Socket(); + if (u.protocol == 'tcp:') { + socket.connect(+u.port, '127.0.0.1'); + } else if (u.protocol == 'local:' && os.platform() == 'win32') { + let pipePath = '\\\\.\\pipe\\' + u.hostname; + socket.connect(pipePath); + } else if (u.protocol == 'local:') { + socket.connect(u.path); + } else { + throw 'Unknown protocol ' + u.protocol; + } + return socket; + } + + // the port file is hardcoded to a particular location relative to the build. + function discoverUrl(): url.Url { + let pf = path.join(process.cwd(), 'project', 'target', 'active.json'); + let portfile = JSON.parse(fs.readFileSync(pf)); + return url.parse(portfile.uri); + } + // the port file is hardcoded to a particular location relative to the build. function discoverToken(): any { let pf = path.join(workspace.rootPath, 'project', 'target', 'active.json'); diff --git a/vscode-sbt-scala/server/src/server.ts b/vscode-sbt-scala/server/src/server.ts index 05932d451..8404c7b74 100644 --- a/vscode-sbt-scala/server/src/server.ts +++ b/vscode-sbt-scala/server/src/server.ts @@ -2,32 +2,20 @@ import * as path from 'path'; import * as url from 'url'; -let net = require('net'), - fs = require('fs'), +import * as net from 'net'; +let fs = require('fs'), os = require('os'), stdin = process.stdin, stdout = process.stdout; -let u = discoverUrl(); - -let socket = net.Socket(); +let socket = new net.Socket(); socket.on('data', (chunk: any) => { // send it back to stdout stdout.write(chunk); }).on('end', () => { stdin.pause(); }); - -if (u.protocol == 'tcp:') { - socket.connect(u.port, '127.0.0.1'); -} else if (u.protocol == 'local:' && os.platform() == 'win32') { - let pipePath = '\\\\.\\pipe\\' + u.hostname; - socket.connect(pipePath); -} else if (u.protocol == 'local:') { - socket.connect(u.path); -} else { - throw 'Unknown protocol ' + u.protocol; -} +connectSocket(socket); stdin.resume(); stdin.on('data', (chunk: any) => { @@ -36,6 +24,22 @@ stdin.on('data', (chunk: any) => { socket.end(); }); +function connectSocket(socket: net.Socket): net.Socket { + let u = discoverUrl(); + // let socket = net.Socket(); + if (u.protocol == 'tcp:') { + socket.connect(+u.port, '127.0.0.1'); + } else if (u.protocol == 'local:' && os.platform() == 'win32') { + let pipePath = '\\\\.\\pipe\\' + u.hostname; + socket.connect(pipePath); + } else if (u.protocol == 'local:') { + socket.connect(u.path); + } else { + throw 'Unknown protocol ' + u.protocol; + } + return socket; +} + // the port file is hardcoded to a particular location relative to the build. function discoverUrl(): url.Url { let pf = path.join(process.cwd(), 'project', 'target', 'active.json');