From f6c40813d270aee5ba05491dab680fc7746d5cfc Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Mon, 30 Dec 2024 13:43:26 +0000 Subject: [PATCH] Minor refactoring --- META6.json | 1 + bin/iutils | 5 +- lib/IUtils.rakumod | 3 + lib/IUtils/IDEMode.rakumod | 207 ++++++++++++++++++------------------- 4 files changed, 108 insertions(+), 108 deletions(-) create mode 100644 lib/IUtils.rakumod diff --git a/META6.json b/META6.json index df9998c..702d193 100644 --- a/META6.json +++ b/META6.json @@ -7,6 +7,7 @@ "Nathan McCarty " ], "provides": { + "IUtils": "lib/IUtils.rakumod", "IUtils::IDEMode": "lib/IUtils/IDEMode.rakumod" }, "bin": { diff --git a/bin/iutils b/bin/iutils index 56ce699..abd5b22 100755 --- a/bin/iutils +++ b/bin/iutils @@ -1,8 +1,8 @@ #!/usr/bin/env raku 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'; # say @res; @@ -14,7 +14,6 @@ say @res.raku; @res = $ide.interpret: ':exec works >>= print'; say @res.raku; -say $ide.read-sexp(); @res = $ide.interpret: ':exec fails'; say @res.raku; diff --git a/lib/IUtils.rakumod b/lib/IUtils.rakumod new file mode 100644 index 0000000..fd1aa1e --- /dev/null +++ b/lib/IUtils.rakumod @@ -0,0 +1,3 @@ +unit module IUtils; + +need IUtils::IDEMode; diff --git a/lib/IUtils/IDEMode.rakumod b/lib/IUtils/IDEMode.rakumod index 5e0da6a..276fc9b 100644 --- a/lib/IUtils/IDEMode.rakumod +++ b/lib/IUtils/IDEMode.rakumod @@ -1,4 +1,9 @@ -unit module IUtils::IDEMode; +unit class IUtils::IDEMode; + +has $!process; +has $!port; +has $!socket; +has $!request-id = 0; grammar SExp { rule TOP { } @@ -35,112 +40,104 @@ class SExp::Actions { } } -class IDEMode { - has $!process; - has $!port; - has $!socket; - has $!request-id = 0; - - submethod TWEAK { - # Start idris2 in IDE mode - my $ret = Promise.new; - $!process = Proc::Async.new('idris2', '--ide-mode-socket'); - start { - react { - whenever $!process.stdout.lines { - $!port = $_.Int; - $!socket = IO::Socket::INET.new(:host, :port($!port)); - $ret.keep; - } - whenever $!process.start { - say 'Idris 2 exited, exitcode=', .exitcode, ' signal=', .signal; - done; - } - whenever $!process.ready { - say 'Idris 2 online, PID=', $_; - } +submethod TWEAK { + # Start idris2 in IDE mode + my $ret = Promise.new; + $!process = Proc::Async.new('idris2', '--ide-mode-socket'); + start { + react { + whenever $!process.stdout.lines { + $!port = $_.Int; + $!socket = IO::Socket::INET.new(:host, :port($!port)); + $ret.keep; } - } - await $ret; - my ($major, $minor) = self.process-protocol-version; - my @ret = self.version; - my @version = @ret[0][1][1][0]; - my $commit = @ret[0][1][1][1][0]; - 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; + whenever $!process.start { + say 'Idris 2 exited, exitcode=', .exitcode, ' signal=', .signal; + done; + } + whenever $!process.ready { + say 'Idris 2 online, PID=', $_; } } } - - 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') - } - + await $ret; + my ($major, $minor) = self.process-protocol-version; + my @ret = self.version; + my @version = @ret[0][1][1][0]; + my $commit = @ret[0][1][1][1][0]; + 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; + } + } +} + +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') }