[cli-repl] Create wrapper for console reader
This commit is contained in:
committed by
Pavel V. Talanov
parent
4aa5a90370
commit
18304c7d7b
@@ -18,21 +18,19 @@ package org.jetbrains.kotlin.cli.jvm.repl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import jline.console.ConsoleReader;
|
||||
import jline.console.history.FileHistory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.common.KotlinVersion;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeLinebreaksUnescaper;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplErrorLogger;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemInWrapper;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemOutWrapper;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ConsoleReplCommandReader;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.utils.UtilsPackage;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -47,7 +45,7 @@ public class ReplFromTerminal {
|
||||
private final ReplSystemOutWrapper replWriter;
|
||||
private final ReplErrorLogger replErrorLogger;
|
||||
|
||||
private ConsoleReader consoleReader;
|
||||
private ReplCommandReader commandReader;
|
||||
|
||||
public ReplFromTerminal(
|
||||
@NotNull final Disposable disposable,
|
||||
@@ -87,24 +85,19 @@ public class ReplFromTerminal {
|
||||
}.start();
|
||||
|
||||
try {
|
||||
OutputStream outStream = System.out;
|
||||
if (ideMode) {
|
||||
// consoleReader duplicates his input in his output stream;
|
||||
// to prevent such behaviour we redirect his output to dummy output stream
|
||||
VirtualFile consoleOutputRedirect = new LightVirtualFile("kotlinConsoleReplRedirect");
|
||||
outStream = consoleOutputRedirect.getOutputStream(null);
|
||||
}
|
||||
|
||||
consoleReader = new ConsoleReader("kotlin", System.in, outStream, null);
|
||||
consoleReader.setHistoryEnabled(true);
|
||||
consoleReader.setExpandEvents(false);
|
||||
consoleReader.setHistory(new FileHistory(new File(new File(System.getProperty("user.home")), ".kotlin_history")));
|
||||
commandReader = createCommandReader();
|
||||
}
|
||||
catch (Exception e) {
|
||||
replErrorLogger.logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ReplCommandReader createCommandReader() {
|
||||
return ideMode ? new IdeReplCommandReader()
|
||||
: new ConsoleReplCommandReader();
|
||||
}
|
||||
|
||||
private ReplInterpreter getReplInterpreter() {
|
||||
if (replInterpreter != null) {
|
||||
return replInterpreter;
|
||||
@@ -143,7 +136,9 @@ public class ReplFromTerminal {
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
((FileHistory) consoleReader.getHistory()).flush();
|
||||
if (commandReader instanceof ConsoleReplCommandReader) {
|
||||
((ConsoleReplCommandReader) commandReader).getFileHistory().flush();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
replErrorLogger.logException(e);
|
||||
@@ -160,8 +155,8 @@ public class ReplFromTerminal {
|
||||
@NotNull
|
||||
private WhatNextAfterOneLine one(@NotNull WhatNextAfterOneLine next) {
|
||||
try {
|
||||
String prompt = getPrompt(next);
|
||||
String line = readLine(prompt);
|
||||
String prompt = next == WhatNextAfterOneLine.INCOMPLETE ? "... " : ">>> ";
|
||||
String line = commandReader.readLine(prompt);
|
||||
|
||||
if (line == null) {
|
||||
return WhatNextAfterOneLine.QUIT;
|
||||
@@ -185,25 +180,6 @@ public class ReplFromTerminal {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getPrompt(@NotNull WhatNextAfterOneLine next) {
|
||||
String prompt = null;
|
||||
// consoleReader always print prompt; in [ideMode] we don't allow it
|
||||
if (!ideMode) {
|
||||
prompt = next == WhatNextAfterOneLine.INCOMPLETE ? "... " : ">>> ";
|
||||
}
|
||||
return prompt;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String readLine(@Nullable String prompt) throws IOException {
|
||||
String line = consoleReader.readLine(prompt);
|
||||
if (ideMode && line != null) {
|
||||
line = IdeLinebreaksUnescaper.unescapeFromDiez(line).trim();
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ReplInterpreter.LineResultType eval(@NotNull String line) {
|
||||
ReplInterpreter.LineResult lineResult = getReplInterpreter().eval(line);
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ReplSystemInWrapper(
|
||||
private val replWriter: ReplSystemOutWrapper
|
||||
) : InputStream() {
|
||||
private var isXmlIncomplete = true
|
||||
private var isLastScriptByteProcessed = false
|
||||
private var isLastByteProcessed = false
|
||||
private var isReadLineStartSent = false
|
||||
private var byteBuilder = ByteArrayOutputStream()
|
||||
private var curBytePos = 0
|
||||
@@ -36,10 +36,13 @@ public class ReplSystemInWrapper(
|
||||
var isReplScriptExecuting = false
|
||||
|
||||
override fun read(): Int {
|
||||
if (isLastScriptByteProcessed && isReplScriptExecuting) {
|
||||
isLastScriptByteProcessed = false
|
||||
isReadLineStartSent = false
|
||||
replWriter.printlnReadLineEnd()
|
||||
if (isLastByteProcessed) {
|
||||
if (isReplScriptExecuting) {
|
||||
isReadLineStartSent = false
|
||||
replWriter.printlnReadLineEnd()
|
||||
}
|
||||
|
||||
isLastByteProcessed = false
|
||||
return -1
|
||||
}
|
||||
|
||||
@@ -53,7 +56,7 @@ public class ReplSystemInWrapper(
|
||||
|
||||
if (byteBuilder.toString().endsWith(END_LINE)) {
|
||||
isXmlIncomplete = false
|
||||
isLastScriptByteProcessed = false
|
||||
isLastByteProcessed = false
|
||||
|
||||
inputByteArray = unescapedInput().toByteArray()
|
||||
}
|
||||
@@ -81,8 +84,7 @@ public class ReplSystemInWrapper(
|
||||
isXmlIncomplete = true
|
||||
byteBuilder = ByteArrayOutputStream()
|
||||
curBytePos = 0
|
||||
|
||||
if (isReplScriptExecuting) isLastScriptByteProcessed = true
|
||||
isLastByteProcessed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.repl.reader
|
||||
|
||||
import jline.console.ConsoleReader
|
||||
import jline.console.history.FileHistory
|
||||
import java.io.File
|
||||
|
||||
public class ConsoleReplCommandReader : ReplCommandReader {
|
||||
private val consoleReader = ConsoleReader("kotlin", System.`in`, System.`out`, null) apply {
|
||||
isHistoryEnabled = true
|
||||
expandEvents = false
|
||||
history = FileHistory(File(File(System.getProperty("user.home")), ".kotlin_history"))
|
||||
}
|
||||
|
||||
public val fileHistory: FileHistory
|
||||
get() = consoleReader.history as FileHistory
|
||||
|
||||
override fun readLine(prompt: String?) = consoleReader.readLine(prompt)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.repl.reader
|
||||
|
||||
public class IdeReplCommandReader : ReplCommandReader {
|
||||
override fun readLine(prompt: String?) = readLine()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.repl.reader
|
||||
|
||||
public interface ReplCommandReader {
|
||||
public fun readLine(prompt: String?): String?
|
||||
}
|
||||
Reference in New Issue
Block a user