Skip to content

Commit

Permalink
Merge pull request #14 from rescript-lang/runDumpCommand
Browse files Browse the repository at this point in the history
Hook up command from rescript-editor-support.
  • Loading branch information
IwanKaramazow authored Nov 22, 2020
2 parents 63b37a0 + c42f6e2 commit 9bbacb4
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 15 deletions.
Binary file added server/darwin/rescript-editor-support.exe
Binary file not shown.
Binary file added server/linux/rescript-editor-support.exe
Binary file not shown.
90 changes: 90 additions & 0 deletions server/src/RescriptEditorSupport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { fileURLToPath } from "url";
import { RequestMessage } from "vscode-languageserver";
import * as utils from "./utils";
import * as path from "path";
import { exec } from "child_process";
import * as tmp from "tmp";
import fs from "fs";

let binaryPath = path.join(
path.dirname(__dirname),
process.platform,
"rescript-editor-support.exe"
);

export let binaryExists = fs.existsSync(binaryPath);

let findExecutable = (uri: string) => {
let filePath = fileURLToPath(uri);
let projectRootPath = utils.findProjectRootOfFile(filePath);
if (projectRootPath == null || !binaryExists) {
return null;
} else {
return { binaryPath, filePath, cwd: projectRootPath };
}
};

export function runDumpCommand(
msg: RequestMessage,
onResult: (
result: { hover?: string; definition?: { uri?: string; range: any } } | null
) => void
) {
let executable = findExecutable(msg.params.textDocument.uri);
if (executable == null) {
onResult(null);
} else {
let command =
executable.binaryPath +
" dump " +
executable.filePath +
":" +
msg.params.position.line +
":" +
msg.params.position.character;
exec(command, { cwd: executable.cwd }, function (_error, stdout, _stderr) {
let result = JSON.parse(stdout);
if (result && result[0]) {
onResult(result[0]);
} else {
onResult(null);
}
});
}
}

export function runCompletionCommand(
msg: RequestMessage,
code: string,
onResult: (result: [{ label: string }] | null) => void
) {
let executable = findExecutable(msg.params.textDocument.uri);
if (executable == null) {
onResult(null);
} else {
let tmpobj = tmp.fileSync();
let tmpname = tmpobj.name;
fs.writeFileSync(tmpname, code, { encoding: "utf-8" });

let command =
executable.binaryPath +
" complete " +
executable.filePath +
":" +
msg.params.position.line +
":" +
msg.params.position.character +
" " +
tmpname;

exec(command, { cwd: executable.cwd }, function (_error, stdout, _stderr) {
tmpobj.removeCallback();
let result = JSON.parse(stdout);
if (result && result[0]) {
onResult(result);
} else {
onResult(null);
}
});
}
}
74 changes: 59 additions & 15 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import * as chokidar from "chokidar";
import { assert } from "console";
import { fileURLToPath } from "url";
import { ChildProcess } from "child_process";
import {
binaryExists,
runDumpCommand,
runCompletionCommand,
} from "./RescriptEditorSupport";

// https://microsoft.github.io/language-server-protocol/specification#initialize
// According to the spec, there could be requests before the 'initialize' request. Link in comment tells how to handle them.
Expand Down Expand Up @@ -270,8 +275,11 @@ process.on("message", (msg: m.Message) => {
// TODO: incremental sync?
textDocumentSync: v.TextDocumentSyncKind.Full,
documentFormattingProvider: true,
hoverProvider: true,
definitionProvider: true,
hoverProvider: binaryExists,
definitionProvider: binaryExists,
completionProvider: binaryExists
? { triggerCharacters: ["."] }
: undefined,
},
};
let response: m.ResponseMessage = {
Expand Down Expand Up @@ -315,32 +323,68 @@ process.on("message", (msg: m.Message) => {
process.send!(response);
}
} else if (msg.method === p.HoverRequest.method) {
let dummyHoverResponse: m.ResponseMessage = {
let emptyHoverResponse: m.ResponseMessage = {
jsonrpc: c.jsonrpcVersion,
id: msg.id,
// type result = Hover | null
// type Hover = {contents: MarkedString | MarkedString[] | MarkupContent, range?: Range}
result: { contents: "Time to go for a 20k run!" },
result: null,
};

process.send!(dummyHoverResponse);
runDumpCommand(msg, (result) => {
if (result && result.hover) {
let hoverResponse: m.ResponseMessage = {
...emptyHoverResponse,
result: {
contents: result.hover,
},
};
process.send!(hoverResponse);
} else {
process.send!(emptyHoverResponse);
}
});
} else if (msg.method === p.DefinitionRequest.method) {
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition
let dummyDefinitionResponse: m.ResponseMessage = {
let emptyDefinitionResponse: m.ResponseMessage = {
jsonrpc: c.jsonrpcVersion,
id: msg.id,
// result should be: Location | Array<Location> | Array<LocationLink> | null
result: {
uri: msg.params.textDocument.uri,
range: {
start: { line: 2, character: 4 },
end: { line: 2, character: 12 },
},
},
result: null,
// error: code and message set in case an exception happens during the definition request.
};

process.send!(dummyDefinitionResponse);
runDumpCommand(msg, (result) => {
if (result && result.definition) {
let definitionResponse: m.ResponseMessage = {
...emptyDefinitionResponse,
result: {
uri: result.definition.uri || msg.params.textDocument.uri,
range: result.definition.range,
},
};
process.send!(definitionResponse);
} else {
process.send!(emptyDefinitionResponse);
}
});
} else if (msg.method === p.CompletionRequest.method) {
let emptyCompletionResponse: m.ResponseMessage = {
jsonrpc: c.jsonrpcVersion,
id: msg.id,
result: null,
};
let code = getOpenedFileContent(msg.params.textDocument.uri);
runCompletionCommand(msg, code, (result) => {
if (result) {
let definitionResponse: m.ResponseMessage = {
...emptyCompletionResponse,
result: result,
};
process.send!(definitionResponse);
} else {
process.send!(emptyCompletionResponse);
}
});
} else if (msg.method === p.DocumentFormattingRequest.method) {
// technically, a formatting failure should reply with the error. Sadly
// the LSP alert box for these error replies sucks (e.g. doesn't actually
Expand Down
Binary file added server/win32/rescript-editor-support.exe
Binary file not shown.

0 comments on commit 9bbacb4

Please sign in to comment.