Skip to content

Commit

Permalink
Pop open the terminal and run UCM if we dont find it (#7)
Browse files Browse the repository at this point in the history
* Pop open the terminal and run UCM if we dont find it

* Try to fix weird spacing

* Fixing it for real without autocorrect adding a period?

* Just kidding, 4 spaces not 2

* Remove metadata that snuck in

* Merging in changes from main

* Actually set haveOpenedTerminal

* Turns out haveOpenedTerminal has to live higher up otherwise we still try to reopen the terminal when you close it

* Add ucmCommand config and adjust message pop-ups

Co-authored-by: Chris Penner <[email protected]>
  • Loading branch information
tapegram and ChrisPenner authored Nov 7, 2022
1 parent 498bbad commit 43d4459
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "Unison Language",
"publisher": "unison-lang",
"description": "Official extension for unison language support",
"version": "0.0.7",
"version": "0.0.8",
"icon": "images/unison.png",
"main": "./out/main.js",
"engines": {
Expand Down Expand Up @@ -67,6 +67,18 @@
],
"default": "off",
"description": "Traces the communication between VSCode and the language server."
},
"unison.automaticallyOpenUCM": {
"scope": "window",
"type": "boolean",
"default": true,
"description": "Automatically open an embedded terminal and start UCM if no existing UCM session is detected."
},
"unison.ucmCommand": {
"scope": "window",
"type": "string",
"default": "ucm",
"description": "Which command to run when automatically opening ucm in a terminal."
}
}
}
Expand Down
35 changes: 29 additions & 6 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { connect } from "node:net";

const outputChannel: OutputChannel = window.createOutputChannel("Unison");
const clients: Map<string, LanguageClient> = new Map();
// This is global mutable state so that when the extension host gets restarted after
// the terminal is closed, we don't immediately open another one.
let shouldOpenTerminal = true;

function log(msg: string) {
outputChannel.appendLine(msg)
outputChannel.appendLine(msg);
}

exports.activate = function () {
Expand All @@ -31,7 +34,7 @@ async function addWorkspaceFolder(workspaceFolder: WorkspaceFolder) {
documentSelector: [{ language: "unison" }],
});

log(`Activating unison language server at ${folderPath}`)
log(`Activating unison language server at ${folderPath}`);
clients.set(folderPath, client);
await client.start();
}
Expand All @@ -40,7 +43,7 @@ async function removeWorkspaceFolder(workspaceFolder: WorkspaceFolder) {
let folderPath = workspaceFolder.uri.fsPath;
let client = clients.get(folderPath);
if (client) {
log(`Deactivating unison language server at ${folderPath}`)
log(`Deactivating unison language server at ${folderPath}`);
clients.delete(folderPath);
await client.stop();
}
Expand All @@ -52,15 +55,19 @@ async function sleep(ms: number): Promise<void> {

async function connectToServer() {
let haveShownError = false;

while (true) {
try {
const host = "127.0.0.1";
const port = workspace.getConfiguration("unison").lspPort;

log(`Trying to connect to ucm lsp server at ${host}:${port}`);
let socket = connect({ port, host: "127.0.0.1" });
await new Promise((resolve, reject) =>
socket.once("connect", resolve).once("error", reject)
);

shouldOpenTerminal = false;
// Show a success message, but only if we were in an error state
const okMsg = `Unison: Connected to Language Server at ${host}:${port}.`;
log(okMsg);
Expand All @@ -70,10 +77,26 @@ async function connectToServer() {
return { reader: socket, writer: socket };
} catch (e) {
const errMsg = "Language server failed to connect";
log(`${errMsg}, cause: ${e}`)
if (!haveShownError) {
log(`${errMsg}, cause: ${e}`);

// Only ever try to open the terminal once, so we don't get stuck in weird loops
// or in a strange state if the user tries to quit UCM or close the terminal.
if (
shouldOpenTerminal &&
workspace.getConfiguration("unison").automaticallyOpenUCM
) {
let ucmCommand = workspace.getConfiguration("unison").ucmCommand;
shouldOpenTerminal = false;
log("Opening ucm terminal");
// Start up a new terminal in the IDE, tell it to run UCM, and then show it.
const terminal = window.createTerminal();
terminal.sendText(ucmCommand);
terminal.show();
} else if (!haveShownError) {
haveShownError = true;
window.showErrorMessage(`Unison: ${errMsg}, is there a UCM running? (version M4a or later)`);
window.showErrorMessage(
`Unison: ${errMsg}, is there a UCM running? (version M4a or later)`
);
}
await sleep(2000);
continue;
Expand Down

0 comments on commit 43d4459

Please sign in to comment.