diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplFromTerminal.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplFromTerminal.java index 72f09af9c9a..796ba69e256 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplFromTerminal.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplFromTerminal.java @@ -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); diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemInWrapper.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemInWrapper.kt index 91c23b765a6..e5687ecd550 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemInWrapper.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemInWrapper.kt @@ -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 } } } \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ConsoleReplCommandReader.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ConsoleReplCommandReader.kt new file mode 100644 index 00000000000..29f52ded962 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ConsoleReplCommandReader.kt @@ -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) +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/IdeReplCommandReader.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/IdeReplCommandReader.kt new file mode 100644 index 00000000000..6e257555357 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/IdeReplCommandReader.kt @@ -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() +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ReplCommandReader.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ReplCommandReader.kt new file mode 100644 index 00000000000..4a842e74819 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/reader/ReplCommandReader.kt @@ -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? +} \ No newline at end of file