Minor refactoring

This commit is contained in:
Nathan McCarty 2024-12-30 13:43:26 +00:00
parent 72393480e3
commit f6c40813d2
4 changed files with 108 additions and 108 deletions

View file

@ -7,6 +7,7 @@
"Nathan McCarty <thatonelutenist@stranger.systems>" "Nathan McCarty <thatonelutenist@stranger.systems>"
], ],
"provides": { "provides": {
"IUtils": "lib/IUtils.rakumod",
"IUtils::IDEMode": "lib/IUtils/IDEMode.rakumod" "IUtils::IDEMode": "lib/IUtils/IDEMode.rakumod"
}, },
"bin": { "bin": {

View file

@ -1,8 +1,8 @@
#!/usr/bin/env raku #!/usr/bin/env raku
use v6.d; use v6.d;
use IUtils::IDEMode; use IUtils;
my $ide = IUtils::IDEMode::IDEMode.new(); my $ide = IUtils::IDEMode.new();
# my @res = $ide.browse-namespace: 'Data.List'; # my @res = $ide.browse-namespace: 'Data.List';
# say @res; # say @res;
@ -14,7 +14,6 @@ say @res.raku;
@res = $ide.interpret: ':exec works >>= print'; @res = $ide.interpret: ':exec works >>= print';
say @res.raku; say @res.raku;
say $ide.read-sexp();
@res = $ide.interpret: ':exec fails'; @res = $ide.interpret: ':exec fails';
say @res.raku; say @res.raku;

3
lib/IUtils.rakumod Normal file
View file

@ -0,0 +1,3 @@
unit module IUtils;
need IUtils::IDEMode;

View file

@ -1,4 +1,9 @@
unit module IUtils::IDEMode; unit class IUtils::IDEMode;
has $!process;
has $!port;
has $!socket;
has $!request-id = 0;
grammar SExp { grammar SExp {
rule TOP { <sexp> } rule TOP { <sexp> }
@ -35,112 +40,104 @@ class SExp::Actions {
} }
} }
class IDEMode { submethod TWEAK {
has $!process; # Start idris2 in IDE mode
has $!port; my $ret = Promise.new;
has $!socket; $!process = Proc::Async.new('idris2', '--ide-mode-socket');
has $!request-id = 0; start {
react {
submethod TWEAK { whenever $!process.stdout.lines {
# Start idris2 in IDE mode $!port = $_.Int;
my $ret = Promise.new; $!socket = IO::Socket::INET.new(:host<localhost>, :port($!port));
$!process = Proc::Async.new('idris2', '--ide-mode-socket'); $ret.keep;
start {
react {
whenever $!process.stdout.lines {
$!port = $_.Int;
$!socket = IO::Socket::INET.new(:host<localhost>, :port($!port));
$ret.keep;
}
whenever $!process.start {
say 'Idris 2 exited, exitcode=', .exitcode, ' signal=', .signal;
done;
}
whenever $!process.ready {
say 'Idris 2 online, PID=', $_;
}
} }
} whenever $!process.start {
await $ret; say 'Idris 2 exited, exitcode=', .exitcode, ' signal=', .signal;
my ($major, $minor) = self.process-protocol-version; done;
my @ret = self.version; }
my @version = @ret[0][1][1][0]; whenever $!process.ready {
my $commit = @ret[0][1][1][1][0]; say 'Idris 2 online, PID=', $_;
say "Idris 2 Version: ", @version[0], ".", @version[1], ".", @version[2],
" (", $commit, ")";
say "IDE Protocol Version: $major.$minor";
}
method process-protocol-version() {
my @resp = self.read-sexp();
if @resp[0] eq ':protocol-version' {
return (@resp[1], @resp[2]);
}
die "Expected protocol version, got: ", @resp;
}
method read-sexp() {
my $len = $!socket.read(6).decode('utf8');
my $msg = $!socket.read(:bin, $len.parse-base(16)).decode('utf8');
# say "Got: ", $len, $msg;
SExp.parse($msg, actions => SExp::Actions).made
}
method send-command(*@cmd) {
my $id = ++$!request-id;
my $cmd-str;
if @cmd.elems > 1 {
$cmd-str = "((" ~ (":" ~ @cmd[0]) ~ " " ~ @cmd[1..*].join(" ") ~ ") $id)";
} else {
$cmd-str = "(" ~ (":" ~ @cmd[0]) ~ " $id)";
}
my $len = sprintf("%06x", $cmd-str.chars);
# say "Sending: ", $len, $cmd-str;
$!socket.print($len ~ $cmd-str);
my @responses;
loop {
my $resp = self.read-sexp();
@responses.push($resp);
if $resp[0] eq ':return' && $resp[2] == $id {
return @responses;
} }
} }
} }
await $ret;
method load-file($filename, $line-number?){ my ($major, $minor) = self.process-protocol-version;
if $line-number { my @ret = self.version;
self.send-command('load-file', "\"$filename\"", $line-number.Str) my @version = @ret[0][1][1][0];
} else { my $commit = @ret[0][1][1][1][0];
self.send-command('load-file', "\"$filename\"") say "Idris 2 Version: ", @version[0], ".", @version[1], ".", @version[2],
} " (", $commit, ")";
} say "IDE Protocol Version: $major.$minor";
}
method cd($filepath) {
self.send-command('cd', "\"$filepath\"") method process-protocol-version() {
} my @resp = self.read-sexp();
if @resp[0] eq ':protocol-version' {
method interpret($cmd) { return (@resp[1], @resp[2]);
self.send-command('interpret', "\"$cmd\"") }
} die "Expected protocol version, got: ", @resp;
}
method type-of($item) {
self.send-command('type-of', "\"$item\"") method read-sexp() {
} my $len = $!socket.read(6).decode('utf8');
my $msg = $!socket.read(:bin, $len.parse-base(16)).decode('utf8');
method docs-for($item) { # say "Got: ", $len, $msg;
self.send-command('docs-for', "\"$item\"") SExp.parse($msg, actions => SExp::Actions).made
} }
method browse-namespace($namespace) { method send-command(*@cmd) {
# Import the namespace first to make sure this works properly my $id = ++$!request-id;
self.interpret: ":import $namespace"; my $cmd-str;
self.send-command('browse-namespace', "\"$namespace\"") if @cmd.elems > 1 {
} $cmd-str = "((" ~ (":" ~ @cmd[0]) ~ " " ~ @cmd[1..*].join(" ") ~ ") $id)";
} else {
method version() { $cmd-str = "(" ~ (":" ~ @cmd[0]) ~ " $id)";
self.send-command('version') }
} my $len = sprintf("%06x", $cmd-str.chars);
# say "Sending: ", $len, $cmd-str;
$!socket.print($len ~ $cmd-str);
my @responses;
loop {
my $resp = self.read-sexp();
@responses.push($resp);
if $resp[0] eq ':return' && $resp[2] == $id {
return @responses;
}
}
}
method load-file($filename, $line-number?){
if $line-number {
self.send-command('load-file', "\"$filename\"", $line-number.Str)
} else {
self.send-command('load-file', "\"$filename\"")
}
}
method cd($filepath) {
self.send-command('cd', "\"$filepath\"")
}
method interpret($cmd) {
self.send-command('interpret', "\"$cmd\"")
}
method type-of($item) {
self.send-command('type-of', "\"$item\"")
}
method docs-for($item) {
self.send-command('docs-for', "\"$item\"")
}
method browse-namespace($namespace) {
# Import the namespace first to make sure this works properly
self.interpret: ":import $namespace";
self.send-command('browse-namespace', "\"$namespace\"")
}
method version() {
self.send-command('version')
} }