Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrepl: add command to send current form to jacked in REPL #358

Merged
merged 1 commit into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions copy-static-assets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require("fs");
const path = require("path");

// Function to copy a file
function copyFile(source, targetDir) {
// Create the target directory if it doesn't exist
fs.mkdir(targetDir, { recursive: true }, (err) => {
if (err) {
return console.error(`Failed to create directory: ${err.message}`);
}

// Define the target file path
const targetFile = path.join(targetDir, path.basename(source));

// Copy the file
fs.copyFile(source, targetFile, (err) => {
if (err) {
return console.error(`Failed to copy file: ${err.message}`);
}
console.log(`File copied to ${targetFile}`);
});
});
}

copyFile("./tree-sitter-opengoal.wasm", "./dist/");
copyFile("./node_modules/web-tree-sitter/tree-sitter.wasm", "./dist/");
17 changes: 13 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
"format": "npx prettier --write .",
"format:check": "npx prettier --check .",
"postinstall": "patch-package",
"vscode:prepublish": "esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --minify",
"esbuild": "esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --sourcemap",
"dev": "esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --sourcemap --watch"
"wasm-update": "node ./copy-static-assets.js",
"vscode:prepublish": "npm run wasm-update && esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --minify",
"esbuild": "npm run wasm-update && esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --sourcemap",
"dev": "npm run wasm-update && esbuild ./src/extension.ts --bundle --outfile=dist/main.js --external:vscode --format=cjs --platform=node --sourcemap --watch"
},
"devDependencies": {
"@electron/rebuild": "^3.6.0",
"@types/follow-redirects": "^1.14.4",
"@types/glob": "^8.1.0",
"@types/node": "^20.12.12",
Expand All @@ -36,6 +38,7 @@
"esbuild": "^0.21.4",
"patch-package": "^8.0.0",
"prettier": "3.2.5",
"tree-sitter-cli": "^0.22.6",
"typescript": "^5.4.5"
},
"dependencies": {
Expand All @@ -44,7 +47,9 @@
"follow-redirects": "^1.15.6",
"parinfer": "^3.13.1",
"promise-socket": "^7.0.0",
"vscode-languageclient": "^9.0.1"
"tree-sitter-opengoal": "^1.0.1",
"vscode-languageclient": "^9.0.1",
"web-tree-sitter": "^0.22.6"
},
"activationEvents": [],
"contributes": {
Expand Down Expand Up @@ -180,6 +185,10 @@
{
"command": "opengoal.nrepl.unjack",
"title": "OpenGOAL - nREPL - Un-jack"
},
{
"command": "opengoal.nrepl.evalCurrentForm",
"title": "OpenGOAL - nREPL - Eval Current Form"
}
],
"configuration": [
Expand Down
59 changes: 59 additions & 0 deletions src/tools/opengoal/nrepl/opengoal-nrepl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PromiseSocket from "promise-socket";
import * as vscode from "vscode";
import { getConfig } from "../../../config/config";
import { updateStatusBar } from "../../../context";
import Parser from "web-tree-sitter";

let jackedIn = false;
let socket: PromiseSocket<Socket> | undefined = undefined;
Expand Down Expand Up @@ -82,10 +83,68 @@ export async function reloadFile(fileName: string) {
}
}

export async function evalCurrentForm() {
if (getConfig().autoReplJackIn && socket === undefined) {
await jackIn();
}
if (!jackedIn || socket === undefined) {
return;
}
try {
// Find the current form
const currDocument = vscode.window.activeTextEditor?.document;
const currPosition = vscode.window.activeTextEditor?.selection.start;
const documentText = currDocument?.getText();
if (documentText === undefined || currPosition === undefined) {
return;
}

// Parse the document
await Parser.init();
const opengoalParser = new Parser();
const opengoalLang = await Parser.Language.load(
path.join(__dirname, "tree-sitter-opengoal.wasm"),
);
opengoalParser.setLanguage(opengoalLang);
const tree = opengoalParser.parse(documentText);
let foundNode = tree.rootNode.descendantForPosition({
row: currPosition.line,
column: currPosition.character,
});

// Walk back up the tree until we find a `list_lit` node, this is a bit limiting in some ways but is good enough for now
// this prevents you from sending symbol names to the repl
while (foundNode.type !== "list_lit" && foundNode.parent) {
foundNode = foundNode.parent;
}

const form = foundNode.text;
// Define your data
const headerLength = 8;

// Create a buffer
const headerBuffer = Buffer.alloc(headerLength);

// Pack the data into the buffer
headerBuffer.writeUInt32LE(Buffer.byteLength(form), 0);
headerBuffer.writeUInt32LE(10, 4);

const formBuffer = Buffer.from(form, "utf8");

await socket.writeAll(Buffer.concat([headerBuffer, formBuffer]));
} catch (e) {
console.error(e);
}
}

export function registerNReplCommands(context: vscode.ExtensionContext): void {
context.subscriptions.push(
vscode.commands.registerCommand("opengoal.nrepl.jackin", jackIn),
vscode.commands.registerCommand("opengoal.nrepl.unjack", unJack),
vscode.commands.registerCommand(
"opengoal.nrepl.evalCurrentForm",
evalCurrentForm,
),
);
}

Expand Down
Binary file added tree-sitter-opengoal.wasm
Binary file not shown.
Loading