diff --git a/rascal-lsp/pom.xml b/rascal-lsp/pom.xml
index 08450614..2c6a83f1 100644
--- a/rascal-lsp/pom.xml
+++ b/rascal-lsp/pom.xml
@@ -65,7 +65,7 @@
org.rascalmpl
rascal
- 0.40.17
+ 0.41.0-RC10
org.rascalmpl
diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ParserOnlyContribution.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ParserOnlyContribution.java
index 708b8d4f..73fe5fa4 100644
--- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ParserOnlyContribution.java
+++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ParserOnlyContribution.java
@@ -27,8 +27,9 @@
package org.rascalmpl.vscode.lsp.parametric;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
import java.util.concurrent.CompletableFuture;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -88,7 +89,7 @@ public CompletableFuture parsing(ISourceLocation loc, String input) {
private static Either loadParser(ParserSpecification spec) {
// the next two object are scaffolding. we only need them temporarily, and they will not be used by the returned IFunction if the (internal) _call_ methods are not used from ICallableValue.
GlobalEnvironment unusedHeap = new GlobalEnvironment();
- Evaluator unusedEvaluator = new Evaluator(VF, InputStream.nullInputStream(), OutputStream.nullOutputStream(), OutputStream.nullOutputStream(), new NullRascalMonitor(), new ModuleEnvironment("***unused***", unusedHeap), unusedHeap);
+ Evaluator unusedEvaluator = new Evaluator(VF, Reader.nullReader(), new PrintWriter(Writer.nullWriter()), new PrintWriter(Writer.nullWriter()), new NullRascalMonitor(), new ModuleEnvironment("***unused***", unusedHeap), unusedHeap);
// this is what we are after: a factory that can load back parsers.
IRascalValueFactory vf = new RascalFunctionValueFactory(unusedEvaluator /*can not be null unfortunately*/);
IConstructor reifiedType = makeReifiedType(spec, vf);
diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/LSPTerminalREPL.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/LSPTerminalREPL.java
index 6b05142e..862d838f 100644
--- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/LSPTerminalREPL.java
+++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/LSPTerminalREPL.java
@@ -28,48 +28,47 @@
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+import org.jline.utils.OSUtils;
import org.rascalmpl.debug.IRascalMonitor;
import org.rascalmpl.ideservices.IDEServices;
import org.rascalmpl.interpreter.Evaluator;
-import org.rascalmpl.interpreter.env.GlobalEnvironment;
-import org.rascalmpl.interpreter.env.ModuleEnvironment;
-import org.rascalmpl.interpreter.load.StandardLibraryContributor;
-import org.rascalmpl.interpreter.result.IRascalResult;
-import org.rascalmpl.interpreter.result.ResultFactory;
import org.rascalmpl.interpreter.utils.RascalManifest;
-import org.rascalmpl.jline.Terminal;
-import org.rascalmpl.jline.TerminalFactory;
import org.rascalmpl.library.util.PathConfig;
import org.rascalmpl.library.util.PathConfig.RascalConfigMode;
+import org.rascalmpl.parser.gtd.exception.ParseError;
import org.rascalmpl.repl.BaseREPL;
-import org.rascalmpl.repl.ILanguageProtocol;
-import org.rascalmpl.repl.RascalInterpreterREPL;
-import org.rascalmpl.shell.RascalShell;
+import org.rascalmpl.repl.StopREPLException;
+import org.rascalmpl.repl.output.ICommandOutput;
+import org.rascalmpl.repl.output.impl.AsciiStringOutputPrinter;
+import org.rascalmpl.repl.rascal.RascalInterpreterREPL;
+import org.rascalmpl.repl.rascal.RascalReplServices;
import org.rascalmpl.shell.ShellEvaluatorFactory;
import org.rascalmpl.uri.ISourceLocationWatcher.ISourceLocationChanged;
import org.rascalmpl.uri.URIResolverRegistry;
import org.rascalmpl.uri.URIUtil;
import org.rascalmpl.uri.classloaders.SourceLocationClassLoader;
-import org.rascalmpl.values.ValueFactoryFactory;
import org.rascalmpl.vscode.lsp.dap.DebugSocketServer;
import org.rascalmpl.vscode.lsp.uri.ProjectURIResolver;
import org.rascalmpl.vscode.lsp.uri.TargetURIResolver;
import org.rascalmpl.vscode.lsp.uri.jsonrpc.impl.VSCodeVFSClient;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IValue;
-import io.usethesource.vallang.IValueFactory;
import io.usethesource.vallang.io.StandardTextWriter;
/**
@@ -77,197 +76,157 @@
* connects to a running LSP server instance to
* provide IDE feature to the user of a terminal instance.
*/
-public class LSPTerminalREPL extends BaseREPL {
- private static final InputStream stdin = System.in;
- private static final OutputStream stderr = System.err;
- private static final boolean prettyPrompt = true;
- private static final boolean allowColors = true;
-
- public LSPTerminalREPL(Terminal terminal, IDEServices services, OutputStream stdout) throws IOException, URISyntaxException {
- super(makeInterpreter(terminal, services), null, stdin, stderr, stdout, true, terminal.isAnsiSupported(), getHistoryFile(), terminal, services);
+public class LSPTerminalREPL extends RascalInterpreterREPL {
+ private final int ideServicePort;
+ private final Set dirtyModules = ConcurrentHashMap.newKeySet();
+ private DebugSocketServer debugServer;
+
+ private LSPTerminalREPL(int ideServicesPort) {
+ this.ideServicePort = ideServicesPort;
}
- private static String getRascalLspVersion() {
+ @Override
+ public Map availableCommandLineOptions() {
+ var result = super.availableCommandLineOptions();
+ result.put("debugging", "enable debugging (true/false)");
+ return result;
+ }
+
+ @Override
+ protected IDEServices buildIDEService(PrintWriter err, IRascalMonitor monitor, Terminal term) {
try {
- return new Manifest(URIResolverRegistry.getInstance()
- .getInputStream(URIUtil.correctLocation("lib", "rascal-lsp", "META-INF/MANIFEST.MF")))
- .getMainAttributes().getValue("Specification-Version");
+ return new TerminalIDEClient(ideServicePort, err, monitor, term);
} catch (IOException e) {
- return "Unknown";
+ throw new RuntimeException("Could not build IDE service for REPL", e);
}
}
+ @Override
+ protected Evaluator buildEvaluator(Reader input, PrintWriter stdout, PrintWriter stderr, IDEServices services) {
+ var evaluator = super.buildEvaluator(input, stdout, stderr, services);
+ evaluator.addRascalSearchPath(URIUtil.correctLocation("lib", "rascal-lsp", ""));
- private static ILanguageProtocol makeInterpreter(Terminal terminal, final IDEServices services) throws IOException, URISyntaxException {
- RascalInterpreterREPL repl =
- new RascalInterpreterREPL(prettyPrompt, allowColors, getHistoryFile()) {
- private final Set dirtyModules = ConcurrentHashMap.newKeySet();
- private DebugSocketServer debugServer;
- private final Pattern debuggingCommandPattern = Pattern.compile("^\\s*:set\\s+debugging\\s+(true|false)");
+ URIResolverRegistry reg = URIResolverRegistry.getInstance();
- @Override
- protected SortedSet getCommandLineOptions() {
- SortedSet options = super.getCommandLineOptions();
- options.add("debugging");
- return options;
- }
+ ISourceLocation projectDir = ShellEvaluatorFactory.inferProjectRoot(new File(System.getProperty("user.dir")));
+ String projectName = "unknown-project";
+ if (projectDir != null) {
+ projectName = new RascalManifest().getProjectName(projectDir);
+ }
- @Override
- public IRascalResult evalStatement(String statement, String lastLine) throws InterruptedException {
- Matcher matcher = debuggingCommandPattern.matcher(statement);
- if (matcher.find()) {
- if(matcher.group(1).equals("true")){
- if(!debugServer.isClientConnected()){
- ((TerminalIDEClient) services).startDebuggingSession(debugServer.getPort());
- getOutputWriter().println("Debugging session started.");
- return ResultFactory.nothing();
- }
- getOutputWriter().println("Debugging session was already running.");
- return ResultFactory.nothing();
- }
- if(debugServer.isClientConnected()){
- debugServer.terminateDebugSession();
- getOutputWriter().println("Debugging session stopped.");
- return ResultFactory.nothing();
- }
- getOutputWriter().println("Debugging session was not running.");
- return ResultFactory.nothing();
- }
-
- return super.evalStatement(statement, lastLine);
- }
+ reg.registerLogical(new ProjectURIResolver(services::resolveProjectLocation));
+ reg.registerLogical(new TargetURIResolver(services::resolveProjectLocation));
- @Override
- protected Evaluator constructEvaluator(InputStream input, OutputStream stdout, OutputStream stderr, IDEServices services) {
- GlobalEnvironment heap = new GlobalEnvironment();
- ModuleEnvironment root = heap.addModule(new ModuleEnvironment(ModuleEnvironment.SHELL_MODULE, heap));
- IValueFactory vf = ValueFactoryFactory.getValueFactory();
- Evaluator evaluator = new Evaluator(vf, input, stderr, stdout, services, root, heap);
- evaluator.addRascalSearchPathContributor(StandardLibraryContributor.getInstance());
- evaluator.addRascalSearchPath(URIUtil.correctLocation("lib", "rascal-lsp", ""));
-
- URIResolverRegistry reg = URIResolverRegistry.getInstance();
-
- ISourceLocation projectDir = ShellEvaluatorFactory.inferProjectRoot(new File(System.getProperty("user.dir")));
- String projectName = "unknown-project";
- if (projectDir != null) {
- projectName = new RascalManifest().getProjectName(projectDir);
- }
-
- reg.registerLogical(new ProjectURIResolver(services::resolveProjectLocation));
- reg.registerLogical(new TargetURIResolver(services::resolveProjectLocation));
-
- debugServer = new DebugSocketServer(evaluator, (TerminalIDEClient) services);
-
- try {
- PathConfig pcfg;
- if (projectDir != null) {
- pcfg = PathConfig.fromSourceProjectRascalManifest(projectDir, RascalConfigMode.INTERPETER);
- }
- else {
- pcfg = new PathConfig();
- pcfg.addSourceLoc(URIUtil.rootLocation("std"));
- }
-
- evaluator.getErrorPrinter().println("Rascal Version: " + RascalManifest.getRascalVersionNumber());
- evaluator.getErrorPrinter().println("Rascal-lsp Version: " + getRascalLspVersion());
- new StandardTextWriter(true).write(pcfg.asConstructor(), evaluator.getErrorPrinter());
-
- for (IValue srcPath : pcfg.getSrcs()) {
- ISourceLocation path = (ISourceLocation)srcPath;
- evaluator.addRascalSearchPath(path);
- reg.watch(path, true, d -> sourceLocationChanged(path, d));
- }
-
- ClassLoader cl = new SourceLocationClassLoader(
- pcfg.getClassloaders()
- .append(URIUtil.correctLocation("lib", "rascal",""))
- .append(URIUtil.correctLocation("lib", "rascal-lsp",""))
- .append(URIUtil.correctLocation("target", projectName, "")),
- ClassLoader.getSystemClassLoader()
- );
-
- evaluator.addClassLoader(cl);
- }
- catch (IOException e) {
- e.printStackTrace(new PrintStream(stderr));
- }
-
- // this is very important since it hooks up the languageRegistration feature
- evaluator.setMonitor(services);
-
- return evaluator;
- }
+ debugServer = new DebugSocketServer(evaluator, (TerminalIDEClient) services);
- private void sourceLocationChanged(ISourceLocation srcPath, ISourceLocationChanged d) {
- if (URIUtil.isParentOf(srcPath, d.getLocation()) && d.getLocation().getPath().endsWith(".rsc")) {
- ISourceLocation relative = URIUtil.relativize(srcPath, d.getLocation());
- relative = URIUtil.removeExtension(relative);
-
- String modName = relative.getPath();
- if (modName.startsWith("/")) {
- modName = modName.substring(1);
- }
- modName = modName.replace("/", "::");
- modName = modName.replace("\\", "::");
- dirtyModules.add(modName);
- }
- }
+ try {
+ PathConfig pcfg;
+ if (projectDir != null) {
+ pcfg = PathConfig.fromSourceProjectRascalManifest(projectDir, RascalConfigMode.INTERPETER);
+ }
+ else {
+ pcfg = new PathConfig();
+ pcfg.addSourceLoc(URIUtil.rootLocation("std"));
+ }
- @Override
- public void handleInput(String line, Map output, Map metadata)
- throws InterruptedException {
- try {
- Set changes = new HashSet<>();
- changes.addAll(dirtyModules);
- dirtyModules.removeAll(changes);
- eval.reloadModules(eval.getMonitor(), changes, URIUtil.rootLocation("reloader"));
- }
- catch (Throwable e) {
- getErrorWriter().println("Error during reload: " + e.getMessage());
- // in which case the dirty modules are not cleared and the system will try
- // again at the next command
- return;
- }
-
- super.handleInput(line, output, metadata);
-
- for (String mimetype : output.keySet()) {
- if (!mimetype.contains("html") && !mimetype.startsWith("image/")) {
- continue;
- }
-
- services.browse(
- URIUtil.assumeCorrect(metadata.get("url")),
- metadata.containsKey("title") ? metadata.get("title") : metadata.get("url"),
- metadata.containsKey("viewColumn") ? Integer.parseInt(metadata.get("viewColumn")) : 1
- );
- }
- }
- };
+ stdout.println("Rascal Version: " + RascalManifest.getRascalVersionNumber());
+ stdout.println("Rascal-lsp Version: " + getRascalLspVersion());
+ new StandardTextWriter(true).write(pcfg.asConstructor(), stdout);
- repl.setMeasureCommandTime(false);
+ for (IValue srcPath : pcfg.getSrcs()) {
+ ISourceLocation path = (ISourceLocation)srcPath;
+ evaluator.addRascalSearchPath(path);
+ reg.watch(path, true, d -> sourceLocationChanged(path, d));
+ }
+
+ ClassLoader cl = new SourceLocationClassLoader(
+ pcfg.getClassloaders()
+ .append(URIUtil.correctLocation("lib", "rascal",""))
+ .append(URIUtil.correctLocation("lib", "rascal-lsp",""))
+ .append(URIUtil.correctLocation("target", projectName, "")),
+ ClassLoader.getSystemClassLoader()
+ );
+
+ evaluator.addClassLoader(cl);
+ }
+ catch (IOException e) {
+ e.printStackTrace(stderr);
+ }
- return repl;
+ return evaluator;
}
+ private final Pattern debuggingCommandPattern = Pattern.compile("^\\s*:set\\s+debugging\\s+(true|false)");
+ private ICommandOutput handleDebuggerCommand(String command) {
+ Matcher matcher = debuggingCommandPattern.matcher(command);
+ if (matcher.find()) {
+ if(matcher.group(1).equals("true")){
+ if(!debugServer.isClientConnected()){
+ ((TerminalIDEClient) services).startDebuggingSession(debugServer.getPort());
+ return () -> new AsciiStringOutputPrinter("Debugging session started.");
+ }
+ return () -> new AsciiStringOutputPrinter("Debugging session was already running.");
+ }
+ if(debugServer.isClientConnected()){
+ debugServer.terminateDebugSession();
+ return () -> new AsciiStringOutputPrinter("Debugging session stopped.");
+ }
+ return () -> new AsciiStringOutputPrinter("Debugging session was not running.");
+ }
+ return null;
+ }
- @SuppressWarnings("java:S899") // it's fine to ignore the result of createNewFile
- private static File getHistoryFile() throws IOException {
- File home = new File(System.getProperty("user.home"));
- File rascal = new File(home, ".rascal");
+ @Override
+ public ICommandOutput handleInput(String command) throws InterruptedException, ParseError, StopREPLException {
+ var result = handleDebuggerCommand(command);
+ if (result != null) {
+ return result;
+ }
+ Set changes = new HashSet<>();
+ changes.addAll(dirtyModules);
+ dirtyModules.removeAll(changes);
+ eval.reloadModules(eval.getMonitor(), changes, URIUtil.rootLocation("reloader"));
+ return super.handleInput(command);
+ }
- if (!rascal.exists()) {
- rascal.mkdirs();
+ private void sourceLocationChanged(ISourceLocation srcPath, ISourceLocationChanged d) {
+ if (URIUtil.isParentOf(srcPath, d.getLocation()) && d.getLocation().getPath().endsWith(".rsc")) {
+ ISourceLocation relative = URIUtil.relativize(srcPath, d.getLocation());
+ relative = URIUtil.removeExtension(relative);
+
+ String modName = relative.getPath();
+ if (modName.startsWith("/")) {
+ modName = modName.substring(1);
+ }
+ modName = modName.replace("/", "::");
+ modName = modName.replace("\\", "::");
+ dirtyModules.add(modName);
}
+ }
- File historyFile = new File(rascal, ".repl-history-rascal-terminal");
- if (!historyFile.exists()) {
- historyFile.createNewFile();
+ private static String getRascalLspVersion() {
+ try {
+ return new Manifest(URIResolverRegistry.getInstance()
+ .getInputStream(URIUtil.correctLocation("lib", "rascal-lsp", "META-INF/MANIFEST.MF")))
+ .getMainAttributes().getValue("Specification-Version");
+ } catch (IOException e) {
+ return "Unknown";
}
+ }
+
- return historyFile;
+
+ @SuppressWarnings("java:S899") // it's fine to ignore the result of createNewFile
+ private static Path getHistoryFile() throws IOException {
+ var home = Paths.get(System.getProperty("user.home"));
+ var rascal = home.resolve(".rascal");
+
+ if (!Files.exists(rascal)) {
+ Files.createDirectories(rascal);
+ }
+
+ return rascal.resolve(".repl-history-rascal-terminal-jline3");
}
@@ -275,8 +234,6 @@ private static File getHistoryFile() throws IOException {
public static void main(String[] args) throws InterruptedException, IOException {
int ideServicesPort = -1;
int vfsPort = -1;
- String loadModule = null;
- boolean runModule = false;
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
@@ -286,12 +243,6 @@ public static void main(String[] args) throws InterruptedException, IOException
case "--vfsPort":
vfsPort = Integer.parseInt(args[++i]);
break;
- case "--loadModule":
- loadModule = args[++i];
- break;
- case "--runModule":
- runModule = true;
- break;
}
}
@@ -299,28 +250,24 @@ public static void main(String[] args) throws InterruptedException, IOException
throw new IllegalArgumentException("missing --ideServicesPort commandline parameter");
}
- RascalShell.setupWindowsCodepage();
- RascalShell.enableWindowsAnsiEscapesIfPossible();
-
if (vfsPort != -1) {
VSCodeVFSClient.buildAndRegister(vfsPort);
}
+ var terminalBuilder = TerminalBuilder.builder()
+ .dumb(true) // enable fallback
+ .system(true);
+
+ if (OSUtils.IS_WINDOWS) {
+ terminalBuilder.encoding(StandardCharsets.UTF_8);
+ }
+
try {
- IRascalMonitor monitor = IRascalMonitor.buildConsoleMonitor(System.in, System.out, false);
-
- LSPTerminalREPL terminal =
- new LSPTerminalREPL(TerminalFactory.get(), new TerminalIDEClient(ideServicesPort, monitor), monitor instanceof OutputStream ? (OutputStream) monitor : System.out);
- if (loadModule != null) {
- terminal.queueCommand("import " + loadModule + ";");
- if (runModule) {
- terminal.queueCommand("main()");
- }
- }
- terminal.run();
+ var repl = new BaseREPL(new RascalReplServices(new LSPTerminalREPL(ideServicesPort), getHistoryFile()), terminalBuilder.build());
+ repl.run();
System.exit(0); // kill the other threads
}
- catch (IOException | URISyntaxException e) {
+ catch (IOException e) {
e.printStackTrace();
System.err.println("Rascal terminal terminated exceptionally; press any key to exit process.");
System.in.read();
diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/TerminalIDEClient.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/TerminalIDEClient.java
index 248efca4..9820b1a1 100644
--- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/TerminalIDEClient.java
+++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/terminal/TerminalIDEClient.java
@@ -37,6 +37,7 @@
import org.apache.logging.log4j.Logger;
import org.eclipse.lsp4j.ShowDocumentParams;
import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.jline.terminal.Terminal;
import org.rascalmpl.debug.IRascalMonitor;
import org.rascalmpl.ideservices.IDEServices;
import org.rascalmpl.library.Prelude;
@@ -67,8 +68,10 @@ public class TerminalIDEClient implements IDEServices {
private static final Logger logger = LogManager.getLogger(TerminalIDEClient.class);
private final ColumnMaps columns = new ColumnMaps(this::getContents);
private final IRascalMonitor monitor;
+ private final Terminal terminal;
+ private final PrintWriter err;
- public TerminalIDEClient(int port, IRascalMonitor monitor) throws IOException {
+ public TerminalIDEClient(int port, PrintWriter err, IRascalMonitor monitor, Terminal term) throws IOException {
@SuppressWarnings({"resource"}) // we don't have to close the socket, we are passing it off to the lsp4j framework
Socket socket = new Socket(InetAddress.getLoopbackAddress(), port);
socket.setTcpNoDelay(true);
@@ -80,13 +83,15 @@ public TerminalIDEClient(int port, IRascalMonitor monitor) throws IOException {
.create();
launch.startListening();
server = launch.getRemoteProxy();
+ this.err = err;
this.monitor = monitor;
+ this.terminal = term;
}
+
@Override
public PrintWriter stderr() {
- assert false: "this method should not be used";
- return new PrintWriter(System.err);
+ return err;
}
@Override
@@ -213,4 +218,10 @@ public void registerDebugServerPort(int processID, int serverPort){
server.registerDebugServerPort(processID, serverPort);
}
+ @Override
+ public Terminal activeTerminal() {
+ return terminal;
+ }
+
+
}
diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/EvaluatorUtil.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/EvaluatorUtil.java
index 0567c6ef..a466793c 100644
--- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/EvaluatorUtil.java
+++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/EvaluatorUtil.java
@@ -30,6 +30,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.io.Reader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
@@ -237,9 +238,9 @@ public static CompletableFuture makeFutureEvaluator(ExecutorService e
String jobName = "Loading " + label;
try {
services.jobStart(jobName, imports.length);
- Evaluator eval = ShellEvaluatorFactory.getDefaultEvaluator(new ByteArrayInputStream(new byte[0]),
- IoBuilder.forLogger(customLog).setLevel(Level.INFO).buildOutputStream(),
- IoBuilder.forLogger(customLog).setLevel(Level.ERROR).buildOutputStream(), services);
+ Evaluator eval = ShellEvaluatorFactory.getDefaultEvaluator(Reader.nullReader(),
+ IoBuilder.forLogger(customLog).setLevel(Level.INFO).buildPrintWriter(),
+ IoBuilder.forLogger(customLog).setLevel(Level.ERROR).buildPrintWriter(), services);
eval.getConfiguration().setRascalJavaClassPathProperty(System.getProperty("rascal.compilerClasspath"));
eval.addClassLoader(RascalLanguageServer.class.getClassLoader());
diff --git a/rascal-vscode-extension/src/RascalExtension.ts b/rascal-vscode-extension/src/RascalExtension.ts
index 4220f8b3..dbef56c5 100644
--- a/rascal-vscode-extension/src/RascalExtension.ts
+++ b/rascal-vscode-extension/src/RascalExtension.ts
@@ -86,7 +86,7 @@ export class RascalExtension implements vscode.Disposable {
if (!text.document.uri || !moduleName) {
return;
}
- this.startTerminal(text.document.uri, "--loadModule", moduleName, "--runModule");
+ this.startTerminal(text.document.uri, `import ${moduleName};\nmain();\n`);
})
);
}
@@ -98,12 +98,12 @@ export class RascalExtension implements vscode.Disposable {
if (!text.document.uri || !moduleName) {
return;
}
- this.startTerminal(text.document.uri, "--loadModule", moduleName);
+ this.startTerminal(text.document.uri, `import ${moduleName};\n`);
})
);
}
- private async startTerminal(uri: vscode.Uri | undefined, ...extraArgs: string[]) {
+ private async startTerminal(uri: vscode.Uri | undefined, command?: string | undefined) {
try {
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
@@ -112,7 +112,7 @@ export class RascalExtension implements vscode.Disposable {
}, async (progress) => {
progress.report({message: "Starting rascal-lsp"});
const rascal = await this.rascal.rascalClient;
- console.log(`Starting Rascal REPL: on ${uri} and with args: ${extraArgs}`);
+ console.log(`Starting Rascal REPL: on ${uri} and with command: ${command}`);
if (uri && !uri.path.endsWith(".rsc")) {
// do not try to figure out a rascal project path when the focus is not a rascal file
uri = undefined;
@@ -134,12 +134,15 @@ export class RascalExtension implements vscode.Disposable {
const terminal = vscode.window.createTerminal({
iconPath: this.icon,
shellPath: await getJavaExecutable(),
- shellArgs: this.buildShellArgs(compilationPath, serverConfig, ...extraArgs),
+ shellArgs: this.buildShellArgs(compilationPath, serverConfig),
isTransient: false, // right now we don't support transient terminals yet
- name: `Rascal terminal (${this.getTerminalOrigin(uri, extraArgs)})`,
+ name: `Rascal terminal (${this.getTerminalOrigin(uri, command??"")})`,
});
terminal.show(false);
+ if (command) {
+ terminal.sendText(command);
+ }
progress.report({increment: 25, message: "Finished creating terminal"});
});
} catch (err) {
@@ -147,7 +150,7 @@ export class RascalExtension implements vscode.Disposable {
}
}
- private getTerminalOrigin(uri: vscode.Uri | undefined, extraArgs: string[]): string {
+ private getTerminalOrigin(uri: vscode.Uri | undefined, startCommand: string): string {
if (uri) {
const config = vscode.workspace.getConfiguration();
const originFormat = config.get('rascal.terminal.name.originFormat');
@@ -160,18 +163,19 @@ export class RascalExtension implements vscode.Disposable {
return "no project";
}
case 'Module (qualified)': {
- if (extraArgs[0] === '--loadModule' &&
- extraArgs[1] && extraArgs[1].match(this.qualifiedName)) {
- return extraArgs[1];
+ const name = startCommand.match(this.qualifiedName);
+ if (name && name[1]) {
+ if (name[0] !== '') {
+ return name[0] + "::" + name[1];
+ }
+ return name[1];
}
return "no module";
}
case 'Module (unqualified)': {
- if (extraArgs[0] === '--loadModule' && extraArgs[1]) {
- const name = extraArgs[1].match(this.qualifiedName);
- if (name && name[1]) {
- return name[1];
- }
+ const name = startCommand.match(this.qualifiedName);
+ if (name && name[1]) {
+ return name[1];
}
return "no module";
}
@@ -187,7 +191,7 @@ export class RascalExtension implements vscode.Disposable {
const name2 = '(?:\\\\[A-Z_a-z][\\-0-9A-Z_a-z]*)';
const name = `(?:${name1}|${name2})`;
const qualifiedName = `(?:(?:${name}::)*(${name}))`;
- return new RegExp(`^${qualifiedName}$`);
+ return new RegExp(`^import ${qualifiedName};`);
})(); // Build the regex only once
private async reportTerminalStartError(msg: string, detail: string = "", config : {modal?: boolean, showOutput?: boolean, canContinue?: boolean}) : Promise {