Compare commits
2 commits
ae73c9050d
...
525b9c68cd
Author | SHA1 | Date | |
---|---|---|---|
525b9c68cd | |||
2784a7d80a |
3 changed files with 30 additions and 9 deletions
|
@ -9,7 +9,7 @@ my $ide = IUtils::IDEMode.new();
|
||||||
my @res = $ide.version;
|
my @res = $ide.version;
|
||||||
say @res[0][1][1][1][0];
|
say @res[0][1][1][1][0];
|
||||||
|
|
||||||
@res = $ide.load-file: '.tmp/test.idr';
|
@res = $ide.load-file: '.tmp/test.nope';
|
||||||
say @res.raku;
|
say @res.raku;
|
||||||
|
|
||||||
@res = $ide.interpret: ':exec works >>= print';
|
@res = $ide.interpret: ':exec works >>= print';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#| Utilities for interacting with idris and associated tooling
|
||||||
unit module IUtils;
|
unit module IUtils;
|
||||||
|
|
||||||
need IUtils::IDEMode;
|
need IUtils::IDEMode;
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
#| Interaction wtih Idris 2's IDE Mode
|
||||||
unit class IUtils::IDEMode;
|
unit class IUtils::IDEMode;
|
||||||
|
|
||||||
|
#| The underlying idris process
|
||||||
has $!process;
|
has $!process;
|
||||||
|
#| The port number we are connected via
|
||||||
has $!port;
|
has $!port;
|
||||||
|
#| The socket we are connected via
|
||||||
has $!socket;
|
has $!socket;
|
||||||
|
#| The next request id
|
||||||
has $!request-id = 0;
|
has $!request-id = 0;
|
||||||
|
|
||||||
|
#| Grammar for S-Expressions
|
||||||
grammar SExp {
|
grammar SExp {
|
||||||
rule TOP { <sexp> }
|
rule TOP { <sexp> }
|
||||||
|
|
||||||
|
@ -22,6 +28,7 @@ grammar SExp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Convert a parsed S-Expression into a list of lists
|
||||||
class SExp::Actions {
|
class SExp::Actions {
|
||||||
method TOP($/) { make $<sexp>.made }
|
method TOP($/) { make $<sexp>.made }
|
||||||
|
|
||||||
|
@ -36,11 +43,7 @@ class SExp::Actions {
|
||||||
}
|
}
|
||||||
|
|
||||||
method str-content($/) {
|
method str-content($/) {
|
||||||
if $/.Str && $0 {
|
|
||||||
make $/.Str.subst(/\\(.)/, {$0}, :g)
|
make $/.Str.subst(/\\(.)/, {$0}, :g)
|
||||||
} else {
|
|
||||||
make ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +77,7 @@ submethod TWEAK {
|
||||||
say "IDE Protocol Version: $major.$minor";
|
say "IDE Protocol Version: $major.$minor";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Capture and parse the initial protocol version message
|
||||||
method process-protocol-version() {
|
method process-protocol-version() {
|
||||||
my @resp = self.read-sexp();
|
my @resp = self.read-sexp();
|
||||||
if @resp[0] eq ':protocol-version' {
|
if @resp[0] eq ':protocol-version' {
|
||||||
|
@ -82,13 +86,18 @@ method process-protocol-version() {
|
||||||
die "Expected protocol version, got: ", @resp;
|
die "Expected protocol version, got: ", @resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Read one sexp from the IDE server
|
||||||
method read-sexp() {
|
method read-sexp() {
|
||||||
my $len = $!socket.read(6).decode('utf8');
|
my $len = $!socket.read(6).decode('utf8');
|
||||||
my $msg = $!socket.read(:bin, $len.parse-base(16)).decode('utf8');
|
my $msg = $!socket.read(:bin, $len.parse-base(16)).decode('utf8');
|
||||||
# say "Got: ", $len, $msg;
|
|
||||||
SExp.parse($msg, actions => SExp::Actions).made
|
SExp.parse($msg, actions => SExp::Actions).made
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Send a command to the IDE server, and collect all the responses to that
|
||||||
|
#| command
|
||||||
|
#|
|
||||||
|
#| For convinence, automatically symbolizes the first argument, and will wrap
|
||||||
|
#| the command in parens if there is more than one argument
|
||||||
method send-command(*@cmd) {
|
method send-command(*@cmd) {
|
||||||
my $id = ++$!request-id;
|
my $id = ++$!request-id;
|
||||||
my $cmd-str;
|
my $cmd-str;
|
||||||
|
@ -98,7 +107,6 @@ method send-command(*@cmd) {
|
||||||
$cmd-str = "(" ~ (":" ~ @cmd[0]) ~ " $id)";
|
$cmd-str = "(" ~ (":" ~ @cmd[0]) ~ " $id)";
|
||||||
}
|
}
|
||||||
my $len = sprintf("%06x", $cmd-str.chars);
|
my $len = sprintf("%06x", $cmd-str.chars);
|
||||||
# say "Sending: ", $len, $cmd-str;
|
|
||||||
$!socket.print($len ~ $cmd-str);
|
$!socket.print($len ~ $cmd-str);
|
||||||
|
|
||||||
my @responses;
|
my @responses;
|
||||||
|
@ -106,12 +114,17 @@ method send-command(*@cmd) {
|
||||||
my $resp = self.read-sexp();
|
my $resp = self.read-sexp();
|
||||||
@responses.push($resp);
|
@responses.push($resp);
|
||||||
|
|
||||||
|
if $resp[1][0] eq ':error' && $resp[2] == $id {
|
||||||
|
die "Idris error: ", $resp[1][1];
|
||||||
|
}
|
||||||
|
|
||||||
if $resp[0] eq ':return' && $resp[2] == $id {
|
if $resp[0] eq ':return' && $resp[2] == $id {
|
||||||
return @responses;
|
return @responses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :load-file command
|
||||||
method load-file($filename, $line-number?){
|
method load-file($filename, $line-number?){
|
||||||
if $line-number {
|
if $line-number {
|
||||||
self.send-command('load-file', "\"$filename\"", $line-number.Str)
|
self.send-command('load-file', "\"$filename\"", $line-number.Str)
|
||||||
|
@ -120,28 +133,35 @@ method load-file($filename, $line-number?){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :cd command
|
||||||
method cd($filepath) {
|
method cd($filepath) {
|
||||||
self.send-command('cd', "\"$filepath\"")
|
self.send-command('cd', "\"$filepath\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :interpret command
|
||||||
method interpret($cmd) {
|
method interpret($cmd) {
|
||||||
self.send-command('interpret', "\"$cmd\"")
|
self.send-command('interpret', "\"$cmd\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :type-of command
|
||||||
method type-of($item) {
|
method type-of($item) {
|
||||||
self.send-command('type-of', "\"$item\"")
|
self.send-command('type-of', "\"$item\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :docs-for command
|
||||||
method docs-for($item) {
|
method docs-for($item) {
|
||||||
self.send-command('docs-for', "\"$item\"")
|
self.send-command('docs-for', "\"$item\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :browse-namespace command
|
||||||
|
#|
|
||||||
|
#| Will import $namespace before browsing it to ensure we get results
|
||||||
method browse-namespace($namespace) {
|
method browse-namespace($namespace) {
|
||||||
# Import the namespace first to make sure this works properly
|
|
||||||
self.interpret: ":import $namespace";
|
self.interpret: ":import $namespace";
|
||||||
self.send-command('browse-namespace', "\"$namespace\"")
|
self.send-command('browse-namespace', "\"$namespace\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#| Wrapper for :version command
|
||||||
method version() {
|
method version() {
|
||||||
self.send-command('version')
|
self.send-command('version')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue