mirror of https://github.com/sbt/sbt.git
Fix switching between raw and canonical input
There were a number of issues with swithcing between raw and canonical issues that affected both the server and the thin client. These were reported in #5863 and #5856. In both cases, there were issues with reading input or having the input be displayed. Debugging those issues revealed a number of issues with how we were using the jline 3 system terminal and the hybrid interaction with the jline 2 terminal. This commit eliminates all of our internal jline 2 usage. The only remaining jline 2 usage is that we create and override the global terminal for the scala console for scala versions < 2.13. By moving away from jline 2, I was also able to fix #5828, which reported that the home, end and delete keys were not working. One of the big issues that this commit addresses is that the NetworkClient was always performing blocking reads on System.in. This was problematic because it turns out that you can't switch between raw and canonical modes when there is a read present. To fix this, the server now sends a message to the client when it wants to read bytes and only then does the client create a background thread to read a single byte. I also figured out how to set the terminal type properly for the thin client on windows where we had been manually setting the capabilities to ansi, which only worked for some keys. This fix required switching to the WindowsInputStream that I introduced in a prior commit. Before we were using the jline 2 wrapped input stream which was converting some system events, like home and end, to the wrong escape sequence mappings. The remainder of the commit is mostly just converting from jline 2 apis to jline 3 apis. I verified that tab completions, the scala console, the ammonite console and a run task that read from System.in all work with both the server and the thin client on mac, linux and windows after these changes. Fixes #5828, #5863, #5856
This commit is contained in:
parent
410a8dd4b1
commit
bb8b9a1c99
|
|
@ -21,6 +21,7 @@ import org.jline.reader.{
|
||||||
ParsedLine,
|
ParsedLine,
|
||||||
UserInterruptException,
|
UserInterruptException,
|
||||||
}
|
}
|
||||||
|
import org.jline.utils.ClosedException
|
||||||
import sbt.internal.util.complete.Parser
|
import sbt.internal.util.complete.Parser
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
@ -87,7 +88,7 @@ object LineReader {
|
||||||
case e: EndOfFileException =>
|
case e: EndOfFileException =>
|
||||||
if (terminal == Terminal.console && System.console == null) None
|
if (terminal == Terminal.console && System.console == null) None
|
||||||
else Some("exit")
|
else Some("exit")
|
||||||
case _: IOError => Some("exit")
|
case _: IOError | _: ClosedException => Some("exit")
|
||||||
case _: UserInterruptException | _: ClosedByInterruptException |
|
case _: UserInterruptException | _: ClosedByInterruptException |
|
||||||
_: UncheckedIOException =>
|
_: UncheckedIOException =>
|
||||||
throw new InterruptedException
|
throw new InterruptedException
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||||
import org.jline.utils.InfoCmp.Capability
|
import org.jline.utils.InfoCmp.Capability
|
||||||
import org.jline.utils.{ ClosedException, NonBlockingReader }
|
import org.jline.utils.{ ClosedException, NonBlockingReader }
|
||||||
import org.jline.terminal.{ Attributes, Size, Terminal => JTerminal }
|
import org.jline.terminal.{ Attributes, Size, Terminal => JTerminal }
|
||||||
|
import org.jline.terminal.Attributes.{ InputFlag, LocalFlag }
|
||||||
import org.jline.terminal.Terminal.SignalHandler
|
import org.jline.terminal.Terminal.SignalHandler
|
||||||
import org.jline.terminal.impl.{ AbstractTerminal, DumbTerminal }
|
import org.jline.terminal.impl.{ AbstractTerminal, DumbTerminal }
|
||||||
import org.jline.terminal.impl.jansi.JansiSupportImpl
|
import org.jline.terminal.impl.jansi.JansiSupportImpl
|
||||||
|
|
@ -24,12 +25,7 @@ import scala.util.Try
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
|
||||||
private[sbt] object JLine3 {
|
private[sbt] object JLine3 {
|
||||||
private val capabilityMap = Capability
|
private[util] val initialAttributes = new AtomicReference[Attributes]
|
||||||
.values()
|
|
||||||
.map { c =>
|
|
||||||
c.toString -> c
|
|
||||||
}
|
|
||||||
.toMap
|
|
||||||
|
|
||||||
private[this] val forceWindowsJansiHolder = new AtomicBoolean(false)
|
private[this] val forceWindowsJansiHolder = new AtomicBoolean(false)
|
||||||
private[sbt] def forceWindowsJansi(): Unit = forceWindowsJansiHolder.set(true)
|
private[sbt] def forceWindowsJansi(): Unit = forceWindowsJansiHolder.set(true)
|
||||||
|
|
@ -51,18 +47,24 @@ private[sbt] object JLine3 {
|
||||||
term
|
term
|
||||||
}
|
}
|
||||||
private[util] def system: org.jline.terminal.Terminal = {
|
private[util] def system: org.jline.terminal.Terminal = {
|
||||||
if (forceWindowsJansiHolder.get) windowsJansi()
|
val term =
|
||||||
else {
|
if (forceWindowsJansiHolder.get) windowsJansi()
|
||||||
// Only use jna on windows. Both jna and jansi use illegal reflective
|
else {
|
||||||
// accesses on posix system.
|
// Only use jna on windows. Both jna and jansi use illegal reflective
|
||||||
org.jline.terminal.TerminalBuilder
|
// accesses on posix system.
|
||||||
.builder()
|
org.jline.terminal.TerminalBuilder
|
||||||
.system(System.console != null)
|
.builder()
|
||||||
.jna(Util.isNonCygwinWindows)
|
.system(System.console != null)
|
||||||
.jansi(false)
|
.jna(Util.isNonCygwinWindows)
|
||||||
.paused(true)
|
.jansi(false)
|
||||||
.build()
|
.paused(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
initialAttributes.get match {
|
||||||
|
case null => initialAttributes.set(term.getAttributes)
|
||||||
|
case _ =>
|
||||||
}
|
}
|
||||||
|
term
|
||||||
}
|
}
|
||||||
private[sbt] def apply(term: Terminal): JTerminal = {
|
private[sbt] def apply(term: Terminal): JTerminal = {
|
||||||
if (System.getProperty("jline.terminal", "") == "none" || !Terminal.formatEnabledInEnv)
|
if (System.getProperty("jline.terminal", "") == "none" || !Terminal.formatEnabledInEnv)
|
||||||
|
|
@ -70,7 +72,12 @@ private[sbt] object JLine3 {
|
||||||
else wrapTerminal(term)
|
else wrapTerminal(term)
|
||||||
}
|
}
|
||||||
private[this] def wrapTerminal(term: Terminal): JTerminal = {
|
private[this] def wrapTerminal(term: Terminal): JTerminal = {
|
||||||
new AbstractTerminal(term.name, "ansi", Charset.forName("UTF-8"), SignalHandler.SIG_DFL) {
|
new AbstractTerminal(
|
||||||
|
term.name,
|
||||||
|
"nocapabilities",
|
||||||
|
Charset.forName("UTF-8"),
|
||||||
|
SignalHandler.SIG_DFL
|
||||||
|
) {
|
||||||
val closed = new AtomicBoolean(false)
|
val closed = new AtomicBoolean(false)
|
||||||
setOnClose { () =>
|
setOnClose { () =>
|
||||||
doClose()
|
doClose()
|
||||||
|
|
@ -84,7 +91,6 @@ private[sbt] object JLine3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parseInfoCmp()
|
|
||||||
override val input: InputStream = new InputStream {
|
override val input: InputStream = new InputStream {
|
||||||
override def read: Int = {
|
override def read: Int = {
|
||||||
val res = term.inputStream match {
|
val res = term.inputStream match {
|
||||||
|
|
@ -166,45 +172,47 @@ private[sbt] object JLine3 {
|
||||||
* are the same.
|
* are the same.
|
||||||
*/
|
*/
|
||||||
override def getStringCapability(cap: Capability): String = {
|
override def getStringCapability(cap: Capability): String = {
|
||||||
term.getStringCapability(cap.toString, jline3 = true)
|
term.getStringCapability(cap.toString)
|
||||||
}
|
|
||||||
override def getNumericCapability(cap: Capability): Integer = {
|
|
||||||
term.getNumericCapability(cap.toString, jline3 = true)
|
|
||||||
}
|
|
||||||
override def getBooleanCapability(cap: Capability): Boolean = {
|
|
||||||
term.getBooleanCapability(cap.toString, jline3 = true)
|
|
||||||
}
|
}
|
||||||
|
override def getNumericCapability(cap: Capability): Integer =
|
||||||
|
term.getNumericCapability(cap.toString)
|
||||||
|
override def getBooleanCapability(cap: Capability): Boolean =
|
||||||
|
term.getBooleanCapability(cap.toString)
|
||||||
def getAttributes(): Attributes = attributesFromMap(term.getAttributes)
|
def getAttributes(): Attributes = attributesFromMap(term.getAttributes)
|
||||||
def getSize(): Size = new Size(term.getWidth, term.getHeight)
|
def getSize(): Size = new Size(term.getWidth, term.getHeight)
|
||||||
def setAttributes(a: Attributes): Unit = term.setAttributes(toMap(a))
|
def setAttributes(a: Attributes): Unit = {} // don't allow the jline line reader to change attributes
|
||||||
def setSize(size: Size): Unit = term.setSize(size.getColumns, size.getRows)
|
def setSize(size: Size): Unit = term.setSize(size.getColumns, size.getRows)
|
||||||
|
|
||||||
/**
|
override def enterRawMode(): Attributes = {
|
||||||
* Override enterRawMode because the default implementation modifies System.in
|
// don't actually modify the term, that is handled by LineReader
|
||||||
* to be non-blocking which means it immediately returns -1 if there is no
|
attributesFromMap(term.getAttributes)
|
||||||
* data available, which is not desirable for us.
|
}
|
||||||
*/
|
|
||||||
override def enterRawMode(): Attributes = enterRawModeImpl(this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private def enterRawModeImpl(term: JTerminal): Attributes = {
|
private def enterRawModeImpl(term: JTerminal): Attributes = {
|
||||||
val prvAttr = term.getAttributes()
|
val prvAttr = term.getAttributes()
|
||||||
val newAttr = new Attributes(prvAttr)
|
val newAttr = new Attributes(prvAttr)
|
||||||
newAttr.setLocalFlags(
|
newAttr.setLocalFlags(EnumSet.of(LocalFlag.ICANON, LocalFlag.ECHO, LocalFlag.IEXTEN), false)
|
||||||
EnumSet
|
newAttr.setInputFlags(EnumSet.of(InputFlag.IXON, InputFlag.ICRNL, InputFlag.INLCR), false)
|
||||||
.of(Attributes.LocalFlag.ICANON, Attributes.LocalFlag.ECHO, Attributes.LocalFlag.IEXTEN),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
newAttr.setInputFlags(
|
|
||||||
EnumSet
|
|
||||||
.of(Attributes.InputFlag.IXON, Attributes.InputFlag.ICRNL, Attributes.InputFlag.INLCR),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
term.setAttributes(newAttr)
|
term.setAttributes(newAttr)
|
||||||
prvAttr
|
prvAttr
|
||||||
}
|
}
|
||||||
private[util] def enterRawMode(term: JTerminal): Map[String, String] =
|
private[util] def enterRawMode(term: JTerminal): Unit = {
|
||||||
toMap(enterRawModeImpl(term))
|
val prevAttr = initialAttributes.get
|
||||||
|
val newAttr = new Attributes(prevAttr)
|
||||||
|
// These flags are copied from the jline3 enterRawMode but the jline implementation
|
||||||
|
// also puts the input stream in non blocking mode, which we do not want.
|
||||||
|
newAttr.setLocalFlags(EnumSet.of(LocalFlag.ICANON, LocalFlag.IEXTEN, LocalFlag.ECHO), false)
|
||||||
|
newAttr.setInputFlags(EnumSet.of(InputFlag.IXON, InputFlag.ICRNL, InputFlag.INLCR), false)
|
||||||
|
term.setAttributes(newAttr)
|
||||||
|
()
|
||||||
|
}
|
||||||
|
private[util] def exitRawMode(term: JTerminal): Unit = {
|
||||||
|
val initAttr = initialAttributes.get
|
||||||
|
val newAttr = new Attributes(initAttr)
|
||||||
|
newAttr.setLocalFlags(EnumSet.of(LocalFlag.ICANON, LocalFlag.ECHO), true)
|
||||||
|
term.setAttributes(newAttr)
|
||||||
|
}
|
||||||
private[util] def toMap(jattributes: Attributes): Map[String, String] = {
|
private[util] def toMap(jattributes: Attributes): Map[String, String] = {
|
||||||
val result = new java.util.LinkedHashMap[String, String]
|
val result = new java.util.LinkedHashMap[String, String]
|
||||||
result.put(
|
result.put(
|
||||||
|
|
@ -233,14 +241,14 @@ private[sbt] object JLine3 {
|
||||||
)
|
)
|
||||||
result.asScala.toMap
|
result.asScala.toMap
|
||||||
}
|
}
|
||||||
private[this] val iflagMap: Map[String, Attributes.InputFlag] =
|
private[this] val iflagMap: Map[String, InputFlag] =
|
||||||
Attributes.InputFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
InputFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[this] val oflagMap: Map[String, Attributes.OutputFlag] =
|
private[this] val oflagMap: Map[String, Attributes.OutputFlag] =
|
||||||
Attributes.OutputFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
Attributes.OutputFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[this] val cflagMap: Map[String, Attributes.ControlFlag] =
|
private[this] val cflagMap: Map[String, Attributes.ControlFlag] =
|
||||||
Attributes.ControlFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
Attributes.ControlFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[this] val lflagMap: Map[String, Attributes.LocalFlag] =
|
private[this] val lflagMap: Map[String, LocalFlag] =
|
||||||
Attributes.LocalFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
LocalFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[this] val charMap: Map[String, Attributes.ControlChar] =
|
private[this] val charMap: Map[String, Attributes.ControlChar] =
|
||||||
Attributes.ControlChar.values().map(f => f.name.toLowerCase -> f).toMap
|
Attributes.ControlChar.values().map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[util] def attributesFromMap(map: Map[String, String]): Attributes = {
|
private[util] def attributesFromMap(map: Map[String, String]): Attributes = {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import java.util.{ Arrays, Locale }
|
||||||
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||||
import java.util.concurrent.{ Executors, LinkedBlockingQueue, TimeUnit }
|
import java.util.concurrent.{ Executors, LinkedBlockingQueue, TimeUnit }
|
||||||
|
|
||||||
import jline.DefaultTerminal2
|
|
||||||
import jline.console.ConsoleReader
|
import jline.console.ConsoleReader
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -104,6 +103,13 @@ trait Terminal extends AutoCloseable {
|
||||||
*/
|
*/
|
||||||
def isSupershellEnabled: Boolean
|
def isSupershellEnabled: Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles whether or not the terminal should echo characters back to stdout
|
||||||
|
*
|
||||||
|
* @return the previous value of the toggle
|
||||||
|
*/
|
||||||
|
def setEchoEnabled(toggle: Boolean): Unit
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The methods below this comment are implementation details that are in
|
* The methods below this comment are implementation details that are in
|
||||||
* some cases specific to jline2. These methods may need to change or be
|
* some cases specific to jline2. These methods may need to change or be
|
||||||
|
|
@ -126,15 +132,21 @@ trait Terminal extends AutoCloseable {
|
||||||
*/
|
*/
|
||||||
private[sbt] def getLines: Seq[String]
|
private[sbt] def getLines: Seq[String]
|
||||||
|
|
||||||
private[sbt] def getBooleanCapability(capability: String, jline3: Boolean): Boolean
|
private[sbt] def getBooleanCapability(capability: String): Boolean
|
||||||
private[sbt] def getNumericCapability(capability: String, jline3: Boolean): Integer
|
private[sbt] def getNumericCapability(capability: String): Integer
|
||||||
private[sbt] def getStringCapability(capability: String, jline3: Boolean): String
|
private[sbt] def getStringCapability(capability: String): String
|
||||||
private[sbt] def getAttributes: Map[String, String]
|
private[sbt] def getAttributes: Map[String, String]
|
||||||
private[sbt] def setAttributes(attributes: Map[String, String]): Unit
|
private[sbt] def setAttributes(attributes: Map[String, String]): Unit
|
||||||
private[sbt] def setSize(width: Int, height: Int): Unit
|
private[sbt] def setSize(width: Int, height: Int): Unit
|
||||||
|
|
||||||
private[sbt] def name: String
|
private[sbt] def name: String
|
||||||
private[sbt] def withRawInput[T](f: => T): T = f
|
private[sbt] final def withRawInput[T](f: => T): T = {
|
||||||
|
enterRawMode()
|
||||||
|
try f
|
||||||
|
catch { case e: InterruptedIOException => throw new InterruptedException } finally exitRawMode()
|
||||||
|
}
|
||||||
|
private[sbt] def enterRawMode(): Unit
|
||||||
|
private[sbt] def exitRawMode(): Unit
|
||||||
private[sbt] def write(bytes: Int*): Unit
|
private[sbt] def write(bytes: Int*): Unit
|
||||||
private[sbt] def printStream: PrintStream
|
private[sbt] def printStream: PrintStream
|
||||||
private[sbt] def withPrintStream[T](f: PrintStream => T): T
|
private[sbt] def withPrintStream[T](f: PrintStream => T): T
|
||||||
|
|
@ -188,7 +200,6 @@ object Terminal {
|
||||||
* terminal.
|
* terminal.
|
||||||
*/
|
*/
|
||||||
private[sbt] def toJLine: jline.Terminal with jline.Terminal2 = term match {
|
private[sbt] def toJLine: jline.Terminal with jline.Terminal2 = term match {
|
||||||
case t: ConsoleTerminal => t.term
|
|
||||||
case _ =>
|
case _ =>
|
||||||
new jline.Terminal with jline.Terminal2 {
|
new jline.Terminal with jline.Terminal2 {
|
||||||
override def init(): Unit = {}
|
override def init(): Unit = {}
|
||||||
|
|
@ -206,15 +217,12 @@ object Terminal {
|
||||||
override def disableInterruptCharacter(): Unit = {}
|
override def disableInterruptCharacter(): Unit = {}
|
||||||
override def enableInterruptCharacter(): Unit = {}
|
override def enableInterruptCharacter(): Unit = {}
|
||||||
override def getOutputEncoding: String = null
|
override def getOutputEncoding: String = null
|
||||||
override def getBooleanCapability(capability: String): Boolean = {
|
override def getBooleanCapability(capability: String): Boolean =
|
||||||
term.getBooleanCapability(capability, jline3 = false)
|
term.getBooleanCapability(capability)
|
||||||
}
|
override def getNumericCapability(capability: String): Integer =
|
||||||
override def getNumericCapability(capability: String): Integer = {
|
term.getNumericCapability(capability)
|
||||||
term.getNumericCapability(capability, jline3 = false)
|
override def getStringCapability(capability: String): String =
|
||||||
}
|
term.getStringCapability(capability)
|
||||||
override def getStringCapability(capability: String): String = {
|
|
||||||
term.getStringCapability(capability, jline3 = false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -318,7 +326,7 @@ object Terminal {
|
||||||
// In ci environments, don't touch the io streams unless run with -Dsbt.io.virtual=true
|
// In ci environments, don't touch the io streams unless run with -Dsbt.io.virtual=true
|
||||||
if (System.getProperty("sbt.io.virtual", "") == "true" || (logFormatEnabled.getOrElse(true) && !isCI)) {
|
if (System.getProperty("sbt.io.virtual", "") == "true" || (logFormatEnabled.getOrElse(true) && !isCI)) {
|
||||||
hasProgress.set(isServer)
|
hasProgress.set(isServer)
|
||||||
consoleTerminalHolder.set(wrap(jline.TerminalFactory.get))
|
consoleTerminalHolder.set(newConsoleTerminal())
|
||||||
activeTerminal.set(consoleTerminalHolder.get)
|
activeTerminal.set(consoleTerminalHolder.get)
|
||||||
try withOut(withIn(f))
|
try withOut(withIn(f))
|
||||||
finally {
|
finally {
|
||||||
|
|
@ -333,7 +341,7 @@ object Terminal {
|
||||||
* back to blocking mode. We can then close the console. We do
|
* back to blocking mode. We can then close the console. We do
|
||||||
* this on a background thread in case the read blocks indefinitely.
|
* this on a background thread in case the read blocks indefinitely.
|
||||||
*/
|
*/
|
||||||
val prev = c.system.enterRawMode()
|
c.system.enterRawMode()
|
||||||
val runnable: Runnable = () => {
|
val runnable: Runnable = () => {
|
||||||
try Util.ignoreResult(c.inputStream.read)
|
try Util.ignoreResult(c.inputStream.read)
|
||||||
catch { case _: InterruptedException => }
|
catch { case _: InterruptedException => }
|
||||||
|
|
@ -344,7 +352,6 @@ object Terminal {
|
||||||
// The thread should exit almost instantly but give it 200ms to spin up
|
// The thread should exit almost instantly but give it 200ms to spin up
|
||||||
thread.join(200)
|
thread.join(200)
|
||||||
if (thread.isAlive) thread.interrupt()
|
if (thread.isAlive) thread.interrupt()
|
||||||
c.system.setAttributes(prev)
|
|
||||||
c.close()
|
c.close()
|
||||||
case c => c.close()
|
case c => c.close()
|
||||||
}
|
}
|
||||||
|
|
@ -357,6 +364,8 @@ object Terminal {
|
||||||
private[this] object ProxyTerminal extends Terminal {
|
private[this] object ProxyTerminal extends Terminal {
|
||||||
private def t: Terminal = activeTerminal.get
|
private def t: Terminal = activeTerminal.get
|
||||||
override private[sbt] def progressState: ProgressState = t.progressState
|
override private[sbt] def progressState: ProgressState = t.progressState
|
||||||
|
override private[sbt] def enterRawMode(): Unit = t.enterRawMode()
|
||||||
|
override private[sbt] def exitRawMode(): Unit = t.exitRawMode()
|
||||||
override def getWidth: Int = t.getWidth
|
override def getWidth: Int = t.getWidth
|
||||||
override def getHeight: Int = t.getHeight
|
override def getHeight: Int = t.getHeight
|
||||||
override def getLineHeightAndWidth(line: String): (Int, Int) = t.getLineHeightAndWidth(line)
|
override def getLineHeightAndWidth(line: String): (Int, Int) = t.getLineHeightAndWidth(line)
|
||||||
|
|
@ -369,17 +378,17 @@ object Terminal {
|
||||||
override def isEchoEnabled: Boolean = t.isEchoEnabled
|
override def isEchoEnabled: Boolean = t.isEchoEnabled
|
||||||
override def isSuccessEnabled: Boolean = t.isSuccessEnabled
|
override def isSuccessEnabled: Boolean = t.isSuccessEnabled
|
||||||
override def isSupershellEnabled: Boolean = t.isSupershellEnabled
|
override def isSupershellEnabled: Boolean = t.isSupershellEnabled
|
||||||
override def getBooleanCapability(capability: String, jline3: Boolean): Boolean =
|
override def setEchoEnabled(toggle: Boolean): Unit = t.setEchoEnabled(toggle)
|
||||||
t.getBooleanCapability(capability, jline3)
|
override def getBooleanCapability(capability: String): Boolean =
|
||||||
override def getNumericCapability(capability: String, jline3: Boolean): Integer =
|
t.getBooleanCapability(capability)
|
||||||
t.getNumericCapability(capability, jline3)
|
override def getNumericCapability(capability: String): Integer =
|
||||||
override def getStringCapability(capability: String, jline3: Boolean): String =
|
t.getNumericCapability(capability)
|
||||||
t.getStringCapability(capability, jline3)
|
override def getStringCapability(capability: String): String =
|
||||||
|
t.getStringCapability(capability)
|
||||||
override private[sbt] def getAttributes: Map[String, String] = t.getAttributes
|
override private[sbt] def getAttributes: Map[String, String] = t.getAttributes
|
||||||
override private[sbt] def setAttributes(attributes: Map[String, String]): Unit =
|
override private[sbt] def setAttributes(attributes: Map[String, String]): Unit =
|
||||||
t.setAttributes(attributes)
|
t.setAttributes(attributes)
|
||||||
override private[sbt] def setSize(width: Int, height: Int): Unit = t.setSize(width, height)
|
override private[sbt] def setSize(width: Int, height: Int): Unit = t.setSize(width, height)
|
||||||
override def withRawInput[T](f: => T): T = t.withRawInput(f)
|
|
||||||
override def printStream: PrintStream = t.printStream
|
override def printStream: PrintStream = t.printStream
|
||||||
override def withPrintStream[T](f: PrintStream => T): T = t.withPrintStream(f)
|
override def withPrintStream[T](f: PrintStream => T): T = t.withPrintStream(f)
|
||||||
override private[sbt] def withRawOutput[R](f: => R): R = t.withRawOutput(f)
|
override private[sbt] def withRawOutput[R](f: => R): R = t.withRawOutput(f)
|
||||||
|
|
@ -438,6 +447,10 @@ object Terminal {
|
||||||
final def write(bytes: Int*): Unit = readThread.synchronized {
|
final def write(bytes: Int*): Unit = readThread.synchronized {
|
||||||
bytes.foreach(b => buffer.put(b))
|
bytes.foreach(b => buffer.put(b))
|
||||||
}
|
}
|
||||||
|
def setRawMode(toggle: Boolean): Unit = in match {
|
||||||
|
case win: WindowsInputStream => win.setRawMode(toggle)
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
private[this] val executor =
|
private[this] val executor =
|
||||||
Executors.newSingleThreadExecutor(r => new Thread(r, s"sbt-$name-input-reader"))
|
Executors.newSingleThreadExecutor(r => new Thread(r, s"sbt-$name-input-reader"))
|
||||||
private[this] val buffer = new LinkedBlockingQueue[Integer]
|
private[this] val buffer = new LinkedBlockingQueue[Integer]
|
||||||
|
|
@ -500,8 +513,10 @@ object Terminal {
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private[this] lazy val nonBlockingIn: WriteableInputStream =
|
private[this] def nonBlockingIn(term: org.jline.terminal.Terminal): WriteableInputStream = {
|
||||||
new WriteableInputStream(jline.TerminalFactory.get.wrapInIfNeeded(originalIn), "console")
|
val in = if (Util.isNonCygwinWindows) new WindowsInputStream(term, originalIn) else originalIn
|
||||||
|
new WriteableInputStream(in, "console")
|
||||||
|
}
|
||||||
|
|
||||||
private[this] val inputStream = new AtomicReference[InputStream](System.in)
|
private[this] val inputStream = new AtomicReference[InputStream](System.in)
|
||||||
private[this] def withOut[T](f: => T): T = {
|
private[this] def withOut[T](f: => T): T = {
|
||||||
|
|
@ -699,75 +714,16 @@ object Terminal {
|
||||||
}
|
}
|
||||||
private[sbt] def startedByRemoteClient = props.isDefined
|
private[sbt] def startedByRemoteClient = props.isDefined
|
||||||
|
|
||||||
/**
|
private[this] def newConsoleTerminal(): Terminal = {
|
||||||
* Creates an instance of [[Terminal]] that delegates most of its methods to an underlying
|
val system = JLine3.system
|
||||||
* jline.Terminal2 instance. In the long run, sbt should upgrade to jline3, which has a
|
val in = if (System.console == null) nullWriteableInputStream else nonBlockingIn(system)
|
||||||
* completely different terminal interface so whereever possible, we should avoid
|
new ConsoleTerminal(in, originalOut, system)
|
||||||
* directly referencing jline.Terminal. Wrapping jline Terminal in sbt terminal helps
|
|
||||||
* with that goal.
|
|
||||||
*
|
|
||||||
* @param terminal the jline terminal to wrap
|
|
||||||
* @return an sbt Terminal
|
|
||||||
*/
|
|
||||||
private[this] def wrap(terminal: jline.Terminal): Terminal = {
|
|
||||||
val term: jline.Terminal with jline.Terminal2 = new jline.Terminal with jline.Terminal2 {
|
|
||||||
private[this] val hasConsole = System.console != null
|
|
||||||
private[this] def alive = hasConsole && attached.get
|
|
||||||
private[this] val term2: jline.Terminal2 = terminal match {
|
|
||||||
case t: jline.Terminal2 => t
|
|
||||||
case _ => new DefaultTerminal2(terminal)
|
|
||||||
}
|
|
||||||
override def init(): Unit =
|
|
||||||
if (alive)
|
|
||||||
try terminal.init()
|
|
||||||
catch {
|
|
||||||
case _: InterruptedException | _: java.io.IOError =>
|
|
||||||
}
|
|
||||||
override def restore(): Unit =
|
|
||||||
try terminal.restore()
|
|
||||||
catch {
|
|
||||||
case _: InterruptedException | _: java.io.IOError =>
|
|
||||||
}
|
|
||||||
override def reset(): Unit =
|
|
||||||
try terminal.reset()
|
|
||||||
catch { case _: InterruptedException => }
|
|
||||||
override def isSupported: Boolean = terminal.isSupported
|
|
||||||
override def getWidth: Int = props.map(_.width).getOrElse(terminal.getWidth)
|
|
||||||
override def getHeight: Int = props.map(_.height).getOrElse(terminal.getHeight)
|
|
||||||
override val isAnsiSupported: Boolean = terminal.isAnsiSupported && formatEnabledInEnv
|
|
||||||
override def wrapOutIfNeeded(out: OutputStream): OutputStream = terminal.wrapOutIfNeeded(out)
|
|
||||||
override def wrapInIfNeeded(in: InputStream): InputStream = terminal.wrapInIfNeeded(in)
|
|
||||||
override def hasWeirdWrap: Boolean = terminal.hasWeirdWrap
|
|
||||||
override def isEchoEnabled: Boolean = terminal.isEchoEnabled
|
|
||||||
|
|
||||||
override def setEchoEnabled(enabled: Boolean): Unit =
|
|
||||||
if (alive) terminal.setEchoEnabled(enabled)
|
|
||||||
override def disableInterruptCharacter(): Unit =
|
|
||||||
if (alive) terminal.disableInterruptCharacter()
|
|
||||||
override def enableInterruptCharacter(): Unit =
|
|
||||||
if (alive) terminal.enableInterruptCharacter()
|
|
||||||
override def getOutputEncoding: String = terminal.getOutputEncoding
|
|
||||||
override def getBooleanCapability(capability: String): Boolean =
|
|
||||||
term2.getBooleanCapability(capability)
|
|
||||||
override def getNumericCapability(capability: String): Integer =
|
|
||||||
term2.getNumericCapability(capability)
|
|
||||||
override def getStringCapability(capability: String): String = {
|
|
||||||
term2.getStringCapability(capability)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
term.restore()
|
|
||||||
term.setEchoEnabled(true)
|
|
||||||
new ConsoleTerminal(
|
|
||||||
term,
|
|
||||||
if (System.console == null) nullWriteableInputStream else nonBlockingIn,
|
|
||||||
originalOut
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def reset(): Unit = {
|
private[sbt] def reset(): Unit = {
|
||||||
jline.TerminalFactory.reset()
|
jline.TerminalFactory.reset()
|
||||||
console.close()
|
console.close()
|
||||||
consoleTerminalHolder.set(wrap(jline.TerminalFactory.get))
|
consoleTerminalHolder.set(newConsoleTerminal())
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate explicit class names to type in order to support
|
// translate explicit class names to type in order to support
|
||||||
|
|
@ -813,52 +769,56 @@ object Terminal {
|
||||||
|
|
||||||
@deprecated("For compatibility only", "1.4.0")
|
@deprecated("For compatibility only", "1.4.0")
|
||||||
private[sbt] def deprecatedTeminal: jline.Terminal = console.toJLine
|
private[sbt] def deprecatedTeminal: jline.Terminal = console.toJLine
|
||||||
private class ConsoleTerminal(
|
private[util] class ConsoleTerminal(
|
||||||
val term: jline.Terminal with jline.Terminal2,
|
|
||||||
in: WriteableInputStream,
|
in: WriteableInputStream,
|
||||||
out: OutputStream
|
out: OutputStream,
|
||||||
|
private[util] val system: org.jline.terminal.Terminal,
|
||||||
) extends TerminalImpl(in, out, originalErr, "console0") {
|
) extends TerminalImpl(in, out, originalErr, "console0") {
|
||||||
private[util] lazy val system = JLine3.system
|
private[this] val rawMode = new AtomicBoolean(false)
|
||||||
|
enterRawMode()
|
||||||
override private[sbt] def getSizeImpl: (Int, Int) = {
|
override private[sbt] def getSizeImpl: (Int, Int) = {
|
||||||
val size = system.getSize
|
val size = system.getSize
|
||||||
(size.getColumns, size.getRows)
|
(size.getColumns, size.getRows)
|
||||||
}
|
}
|
||||||
override lazy val isAnsiSupported: Boolean = term.isAnsiSupported && !isCI
|
override lazy val isAnsiSupported: Boolean = formatEnabledInEnv && !isCI
|
||||||
override private[sbt] def progressState: ProgressState = consoleProgressState.get
|
override private[sbt] def progressState: ProgressState = consoleProgressState.get
|
||||||
override def isEchoEnabled: Boolean = system.echo()
|
override def isEchoEnabled: Boolean =
|
||||||
|
try system.echo()
|
||||||
|
catch { case _: InterruptedIOException => false }
|
||||||
override def isSuccessEnabled: Boolean = true
|
override def isSuccessEnabled: Boolean = true
|
||||||
override def getBooleanCapability(capability: String, jline3: Boolean): Boolean =
|
override def setEchoEnabled(toggle: Boolean): Unit =
|
||||||
if (jline3) capabilityMap.get(capability).fold(false)(system.getBooleanCapability)
|
try Util.ignoreResult(system.echo(toggle))
|
||||||
else term.getBooleanCapability(capability)
|
catch { case _: InterruptedIOException => }
|
||||||
override def getNumericCapability(capability: String, jline3: Boolean): Integer =
|
override def getBooleanCapability(capability: String): Boolean =
|
||||||
if (jline3) capabilityMap.get(capability).fold(null: Integer)(system.getNumericCapability)
|
capabilityMap.get(capability).fold(false)(system.getBooleanCapability)
|
||||||
else term.getNumericCapability(capability)
|
override def getNumericCapability(capability: String): Integer =
|
||||||
override def getStringCapability(capability: String, jline3: Boolean): String =
|
capabilityMap.get(capability).fold(null: Integer)(system.getNumericCapability)
|
||||||
if (jline3) capabilityMap.get(capability).fold(null: String)(system.getStringCapability)
|
override def getStringCapability(capability: String): String = {
|
||||||
else term.getStringCapability(capability)
|
val res = capabilityMap.get(capability).fold(null: String)(system.getStringCapability)
|
||||||
override private[sbt] def restore(): Unit = term.restore()
|
res
|
||||||
|
}
|
||||||
|
override private[sbt] def restore(): Unit = exitRawMode()
|
||||||
|
|
||||||
override private[sbt] def getAttributes: Map[String, String] =
|
override private[sbt] def getAttributes: Map[String, String] =
|
||||||
Try(JLine3.toMap(system.getAttributes)).getOrElse(Map.empty)
|
Try(JLine3.toMap(system.getAttributes)).getOrElse(Map.empty)
|
||||||
override private[sbt] def setAttributes(attributes: Map[String, String]): Unit =
|
override private[sbt] def setAttributes(attributes: Map[String, String]): Unit = {
|
||||||
system.setAttributes(JLine3.attributesFromMap(attributes))
|
system.setAttributes(JLine3.attributesFromMap(attributes))
|
||||||
|
}
|
||||||
override private[sbt] def setSize(width: Int, height: Int): Unit =
|
override private[sbt] def setSize(width: Int, height: Int): Unit =
|
||||||
system.setSize(new org.jline.terminal.Size(width, height))
|
system.setSize(new org.jline.terminal.Size(width, height))
|
||||||
|
|
||||||
override def withRawInput[T](f: => T): T = term.synchronized {
|
override private[sbt] def enterRawMode(): Unit = if (rawMode.compareAndSet(false, true)) {
|
||||||
try {
|
in.setRawMode(true)
|
||||||
term.init()
|
JLine3.enterRawMode(system)
|
||||||
term.setEchoEnabled(false)
|
}
|
||||||
f
|
override private[sbt] def exitRawMode(): Unit = if (rawMode.compareAndSet(true, false)) {
|
||||||
} catch { case _: InterruptedIOException => throw new InterruptedException } finally {
|
in.setRawMode(false)
|
||||||
term.restore()
|
JLine3.exitRawMode(system)
|
||||||
term.setEchoEnabled(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
override def isColorEnabled: Boolean =
|
override def isColorEnabled: Boolean =
|
||||||
props
|
props
|
||||||
.map(_.color)
|
.map(_.color)
|
||||||
.getOrElse(isColorEnabledProp.getOrElse(term.isAnsiSupported && formatEnabledInEnv))
|
.getOrElse(isColorEnabledProp.getOrElse(formatEnabledInEnv))
|
||||||
|
|
||||||
override def isSupershellEnabled: Boolean =
|
override def isSupershellEnabled: Boolean =
|
||||||
props
|
props
|
||||||
|
|
@ -871,8 +831,9 @@ object Terminal {
|
||||||
})
|
})
|
||||||
override def close(): Unit = {
|
override def close(): Unit = {
|
||||||
try {
|
try {
|
||||||
|
system.setAttributes(JLine3.initialAttributes.get)
|
||||||
system.close()
|
system.close()
|
||||||
term.restore()
|
in.close()
|
||||||
} catch { case NonFatal(_) => }
|
} catch { case NonFatal(_) => }
|
||||||
super.close()
|
super.close()
|
||||||
}
|
}
|
||||||
|
|
@ -972,13 +933,15 @@ object Terminal {
|
||||||
private[sbt] class DefaultTerminal extends Terminal {
|
private[sbt] class DefaultTerminal extends Terminal {
|
||||||
override def close(): Unit = {}
|
override def close(): Unit = {}
|
||||||
override private[sbt] def progressState: ProgressState = new ProgressState(1)
|
override private[sbt] def progressState: ProgressState = new ProgressState(1)
|
||||||
override def getBooleanCapability(capability: String, jline3: Boolean): Boolean = false
|
override private[sbt] def enterRawMode(): Unit = {}
|
||||||
|
override private[sbt] def exitRawMode(): Unit = {}
|
||||||
|
override def getBooleanCapability(capability: String): Boolean = false
|
||||||
override def getHeight: Int = 0
|
override def getHeight: Int = 0
|
||||||
override def getLastLine: Option[String] = None
|
override def getLastLine: Option[String] = None
|
||||||
override def getLines: Seq[String] = Nil
|
override def getLines: Seq[String] = Nil
|
||||||
override def getLineHeightAndWidth(line: String): (Int, Int) = (0, 0)
|
override def getLineHeightAndWidth(line: String): (Int, Int) = (0, 0)
|
||||||
override def getNumericCapability(capability: String, jline3: Boolean): Integer = null
|
override def getNumericCapability(capability: String): Integer = null
|
||||||
override def getStringCapability(capability: String, jline3: Boolean): String = null
|
override def getStringCapability(capability: String): String = null
|
||||||
override def getWidth: Int = 0
|
override def getWidth: Int = 0
|
||||||
override def inputStream: InputStream = nullInputStream
|
override def inputStream: InputStream = nullInputStream
|
||||||
override def isAnsiSupported: Boolean = false
|
override def isAnsiSupported: Boolean = false
|
||||||
|
|
@ -986,6 +949,7 @@ object Terminal {
|
||||||
override def isEchoEnabled: Boolean = false
|
override def isEchoEnabled: Boolean = false
|
||||||
override def isSuccessEnabled: Boolean = true
|
override def isSuccessEnabled: Boolean = true
|
||||||
override def isSupershellEnabled: Boolean = false
|
override def isSupershellEnabled: Boolean = false
|
||||||
|
override def setEchoEnabled(toggle: Boolean): Unit = {}
|
||||||
override def outputStream: OutputStream = _ => {}
|
override def outputStream: OutputStream = _ => {}
|
||||||
override def errorStream: OutputStream = _ => {}
|
override def errorStream: OutputStream = _ => {}
|
||||||
override private[sbt] def getAttributes: Map[String, String] = Map.empty
|
override private[sbt] def getAttributes: Map[String, String] = Map.empty
|
||||||
|
|
@ -1000,7 +964,7 @@ object Terminal {
|
||||||
}
|
}
|
||||||
private[sbt] object NullTerminal extends DefaultTerminal
|
private[sbt] object NullTerminal extends DefaultTerminal
|
||||||
private[sbt] object SimpleTerminal extends DefaultTerminal {
|
private[sbt] object SimpleTerminal extends DefaultTerminal {
|
||||||
override lazy val inputStream: InputStream = nonBlockingIn
|
override lazy val inputStream: InputStream = originalIn
|
||||||
override lazy val outputStream: OutputStream = originalOut
|
override lazy val outputStream: OutputStream = originalOut
|
||||||
override lazy val errorStream: OutputStream = originalErr
|
override lazy val errorStream: OutputStream = originalErr
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ public class BootServerSocket implements AutoCloseable {
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
private final LinkedBlockingQueue<ClientSocket> clientSocketReads = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<ClientSocket> clientSocketReads = new LinkedBlockingQueue<>();
|
||||||
private final Path socketFile;
|
private final Path socketFile;
|
||||||
|
private final AtomicBoolean needInput = new AtomicBoolean(false);
|
||||||
|
|
||||||
private class ClientSocket implements AutoCloseable {
|
private class ClientSocket implements AutoCloseable {
|
||||||
final Socket socket;
|
final Socket socket;
|
||||||
|
|
@ -116,13 +117,20 @@ public class BootServerSocket implements AutoCloseable {
|
||||||
final InputStream inputStream = socket.getInputStream();
|
final InputStream inputStream = socket.getInputStream();
|
||||||
while (alive.get()) {
|
while (alive.get()) {
|
||||||
try {
|
try {
|
||||||
int b = inputStream.read();
|
synchronized (needInput) {
|
||||||
if (b != -1) {
|
while (!needInput.get() && alive.get()) needInput.wait();
|
||||||
bytes.put(b);
|
|
||||||
clientSocketReads.put(ClientSocket.this);
|
|
||||||
} else {
|
|
||||||
alive.set(false);
|
|
||||||
}
|
}
|
||||||
|
if (alive.get()) {
|
||||||
|
socket.getOutputStream().write(5);
|
||||||
|
int b = inputStream.read();
|
||||||
|
if (b != -1) {
|
||||||
|
bytes.put(b);
|
||||||
|
clientSocketReads.put(ClientSocket.this);
|
||||||
|
} else {
|
||||||
|
alive.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
alive.set(false);
|
alive.set(false);
|
||||||
}
|
}
|
||||||
|
|
@ -209,10 +217,18 @@ public class BootServerSocket implements AutoCloseable {
|
||||||
@Override
|
@Override
|
||||||
public int read() {
|
public int read() {
|
||||||
try {
|
try {
|
||||||
|
synchronized (needInput) {
|
||||||
|
needInput.set(true);
|
||||||
|
needInput.notifyAll();
|
||||||
|
}
|
||||||
ClientSocket clientSocket = clientSocketReads.take();
|
ClientSocket clientSocket = clientSocketReads.take();
|
||||||
return clientSocket.bytes.take();
|
return clientSocket.bytes.take();
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
return -1;
|
return -1;
|
||||||
|
} finally {
|
||||||
|
synchronized (needInput) {
|
||||||
|
needInput.set(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,10 @@ import scala.util.{ Failure, Properties, Success, Try }
|
||||||
import Serialization.{
|
import Serialization.{
|
||||||
CancelAll,
|
CancelAll,
|
||||||
attach,
|
attach,
|
||||||
|
cancelReadSystemIn,
|
||||||
cancelRequest,
|
cancelRequest,
|
||||||
promptChannel,
|
promptChannel,
|
||||||
|
readSystemIn,
|
||||||
systemIn,
|
systemIn,
|
||||||
systemErr,
|
systemErr,
|
||||||
systemOut,
|
systemOut,
|
||||||
|
|
@ -50,6 +52,8 @@ import Serialization.{
|
||||||
terminalGetSize,
|
terminalGetSize,
|
||||||
terminalPropertiesQuery,
|
terminalPropertiesQuery,
|
||||||
terminalPropertiesResponse,
|
terminalPropertiesResponse,
|
||||||
|
terminalSetEcho,
|
||||||
|
terminalSetRawMode,
|
||||||
terminalSetSize,
|
terminalSetSize,
|
||||||
getTerminalAttributes,
|
getTerminalAttributes,
|
||||||
setTerminalAttributes,
|
setTerminalAttributes,
|
||||||
|
|
@ -149,11 +153,15 @@ class NetworkClient(
|
||||||
|
|
||||||
private[this] val stdinBytes = new LinkedBlockingQueue[Int]
|
private[this] val stdinBytes = new LinkedBlockingQueue[Int]
|
||||||
private[this] val inLock = new Object
|
private[this] val inLock = new Object
|
||||||
private[this] val inputThread = new AtomicReference(new RawInputThread)
|
private[this] val inputThread = new AtomicReference[RawInputThread]
|
||||||
private[this] val exitClean = new AtomicBoolean(true)
|
private[this] val exitClean = new AtomicBoolean(true)
|
||||||
private[this] val sbtProcess = new AtomicReference[Process](null)
|
private[this] val sbtProcess = new AtomicReference[Process](null)
|
||||||
private class ConnectionRefusedException(t: Throwable) extends Throwable(t)
|
private class ConnectionRefusedException(t: Throwable) extends Throwable(t)
|
||||||
private class ServerFailedException extends Exception
|
private class ServerFailedException extends Exception
|
||||||
|
private[this] def startInputThread(): Unit = inputThread.get match {
|
||||||
|
case null => inputThread.set(new RawInputThread)
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
|
||||||
// Open server connection based on the portfile
|
// Open server connection based on the portfile
|
||||||
def init(promptCompleteUsers: Boolean, retry: Boolean): ServerConnection =
|
def init(promptCompleteUsers: Boolean, retry: Boolean): ServerConnection =
|
||||||
|
|
@ -165,6 +173,7 @@ class NetworkClient(
|
||||||
if (noStdErr) System.exit(0)
|
if (noStdErr) System.exit(0)
|
||||||
else if (noTab) waitForServer(portfile, log = true, startServer = true)
|
else if (noTab) waitForServer(portfile, log = true, startServer = true)
|
||||||
else {
|
else {
|
||||||
|
startInputThread()
|
||||||
stdinBytes.take match {
|
stdinBytes.take match {
|
||||||
case 9 =>
|
case 9 =>
|
||||||
errorStream.println("\nStarting server...")
|
errorStream.println("\nStarting server...")
|
||||||
|
|
@ -250,8 +259,13 @@ class NetworkClient(
|
||||||
Option(inputThread.get).foreach(_.close())
|
Option(inputThread.get).foreach(_.close())
|
||||||
Option(interactiveThread.get).foreach(_.interrupt)
|
Option(interactiveThread.get).foreach(_.interrupt)
|
||||||
}
|
}
|
||||||
case "readInput" =>
|
case `readSystemIn` => startInputThread()
|
||||||
case _ => self.onNotification(msg)
|
case `cancelReadSystemIn` =>
|
||||||
|
inputThread.get match {
|
||||||
|
case null =>
|
||||||
|
case t => t.close()
|
||||||
|
}
|
||||||
|
case _ => self.onNotification(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override def onRequest(msg: JsonRpcRequestMessage): Unit = self.onRequest(msg)
|
override def onRequest(msg: JsonRpcRequestMessage): Unit = self.onRequest(msg)
|
||||||
|
|
@ -289,9 +303,10 @@ class NetworkClient(
|
||||||
var socket: Option[Socket] =
|
var socket: Option[Socket] =
|
||||||
if (!Properties.isLinux) Try(ClientSocket.localSocket(bootSocketName, useJNI)).toOption
|
if (!Properties.isLinux) Try(ClientSocket.localSocket(bootSocketName, useJNI)).toOption
|
||||||
else None
|
else None
|
||||||
|
val term = Terminal.console
|
||||||
|
term.exitRawMode()
|
||||||
val process = socket match {
|
val process = socket match {
|
||||||
case None if startServer =>
|
case None if startServer =>
|
||||||
val term = Terminal.console
|
|
||||||
if (log) console.appendLog(Level.Info, "server was not detected. starting an instance")
|
if (log) console.appendLog(Level.Info, "server was not detected. starting an instance")
|
||||||
|
|
||||||
val props =
|
val props =
|
||||||
|
|
@ -349,6 +364,7 @@ class NetworkClient(
|
||||||
s.getInputStream.read match {
|
s.getInputStream.read match {
|
||||||
case -1 | 0 => readThreadAlive.set(false)
|
case -1 | 0 => readThreadAlive.set(false)
|
||||||
case 2 => gotInputBack = true
|
case 2 => gotInputBack = true
|
||||||
|
case 5 => term.enterRawMode(); startInputThread()
|
||||||
case 3 if gotInputBack => readThreadAlive.set(false)
|
case 3 if gotInputBack => readThreadAlive.set(false)
|
||||||
case i if gotInputBack => stdinBytes.offer(i)
|
case i if gotInputBack => stdinBytes.offer(i)
|
||||||
case i => printStream.write(i)
|
case i => printStream.write(i)
|
||||||
|
|
@ -381,9 +397,6 @@ class NetworkClient(
|
||||||
while (!gotInputBack && !stdinBytes.isEmpty && socket.isDefined) {
|
while (!gotInputBack && !stdinBytes.isEmpty && socket.isDefined) {
|
||||||
val out = s.getOutputStream
|
val out = s.getOutputStream
|
||||||
val b = stdinBytes.poll
|
val b = stdinBytes.poll
|
||||||
// echo stdin during boot
|
|
||||||
printStream.write(b)
|
|
||||||
printStream.flush()
|
|
||||||
out.write(b)
|
out.write(b)
|
||||||
out.flush()
|
out.flush()
|
||||||
}
|
}
|
||||||
|
|
@ -610,18 +623,13 @@ class NetworkClient(
|
||||||
case (`terminalCapabilities`, Some(json)) =>
|
case (`terminalCapabilities`, Some(json)) =>
|
||||||
Converter.fromJson[TerminalCapabilitiesQuery](json) match {
|
Converter.fromJson[TerminalCapabilitiesQuery](json) match {
|
||||||
case Success(terminalCapabilitiesQuery) =>
|
case Success(terminalCapabilitiesQuery) =>
|
||||||
val jline3 = terminalCapabilitiesQuery.jline3
|
|
||||||
val response = TerminalCapabilitiesResponse(
|
val response = TerminalCapabilitiesResponse(
|
||||||
terminalCapabilitiesQuery.boolean
|
terminalCapabilitiesQuery.boolean
|
||||||
.map(Terminal.console.getBooleanCapability(_, jline3)),
|
.map(Terminal.console.getBooleanCapability(_)),
|
||||||
terminalCapabilitiesQuery.numeric
|
terminalCapabilitiesQuery.numeric
|
||||||
.map(
|
.map(c => Option(Terminal.console.getNumericCapability(c)).fold(-1)(_.toInt)),
|
||||||
c => Option(Terminal.console.getNumericCapability(c, jline3)).fold(-1)(_.toInt)
|
|
||||||
),
|
|
||||||
terminalCapabilitiesQuery.string
|
terminalCapabilitiesQuery.string
|
||||||
.map(
|
.map(s => Option(Terminal.console.getStringCapability(s)).getOrElse("null")),
|
||||||
s => Option(Terminal.console.getStringCapability(s, jline3)).getOrElse("null")
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
sendCommandResponse(
|
sendCommandResponse(
|
||||||
terminalCapabilitiesResponse,
|
terminalCapabilitiesResponse,
|
||||||
|
|
@ -677,6 +685,21 @@ class NetworkClient(
|
||||||
sendCommandResponse("", TerminalSetSizeResponse(), msg.id)
|
sendCommandResponse("", TerminalSetSizeResponse(), msg.id)
|
||||||
case Failure(_) =>
|
case Failure(_) =>
|
||||||
}
|
}
|
||||||
|
case (`terminalSetEcho`, Some(json)) =>
|
||||||
|
Converter.fromJson[TerminalSetEchoCommand](json) match {
|
||||||
|
case Success(echo) =>
|
||||||
|
Terminal.console.setEchoEnabled(echo.toggle)
|
||||||
|
sendCommandResponse("", TerminalSetEchoResponse(), msg.id)
|
||||||
|
case Failure(_) =>
|
||||||
|
}
|
||||||
|
case (`terminalSetRawMode`, Some(json)) =>
|
||||||
|
Converter.fromJson[TerminalSetRawModeCommand](json) match {
|
||||||
|
case Success(raw) =>
|
||||||
|
if (raw.toggle) Terminal.console.enterRawMode()
|
||||||
|
else Terminal.console.exitRawMode()
|
||||||
|
sendCommandResponse("", TerminalSetRawModeResponse(), msg.id)
|
||||||
|
case Failure(_) =>
|
||||||
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -787,6 +810,7 @@ class NetworkClient(
|
||||||
else if (noTab) updateCompletions()
|
else if (noTab) updateCompletions()
|
||||||
else {
|
else {
|
||||||
errorStream.print(s"\nNo cached $label names found. Press '<tab>' to compile: ")
|
errorStream.print(s"\nNo cached $label names found. Press '<tab>' to compile: ")
|
||||||
|
startInputThread()
|
||||||
stdinBytes.take match {
|
stdinBytes.take match {
|
||||||
case 9 => updateCompletions()
|
case 9 => updateCompletions()
|
||||||
case _ => Nil
|
case _ => Nil
|
||||||
|
|
@ -901,17 +925,18 @@ class NetworkClient(
|
||||||
start()
|
start()
|
||||||
val stopped = new AtomicBoolean(false)
|
val stopped = new AtomicBoolean(false)
|
||||||
override final def run(): Unit = {
|
override final def run(): Unit = {
|
||||||
@tailrec def read(): Unit = {
|
def read(): Unit = {
|
||||||
inputStream.read match {
|
inputStream.read match {
|
||||||
case -1 =>
|
case -1 =>
|
||||||
case b =>
|
case b =>
|
||||||
inLock.synchronized(stdinBytes.offer(b))
|
inLock.synchronized(stdinBytes.offer(b))
|
||||||
if (attached.get()) drain()
|
if (attached.get()) drain()
|
||||||
if (!stopped.get()) read()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try Terminal.console.withRawInput(read())
|
try read()
|
||||||
catch { case _: InterruptedException | NonFatal(_) => stopped.set(true) }
|
catch { case _: InterruptedException | NonFatal(_) => stopped.set(true) } finally {
|
||||||
|
inputThread.set(null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def drain(): Unit = inLock.synchronized {
|
def drain(): Unit = inLock.synchronized {
|
||||||
|
|
@ -1095,6 +1120,7 @@ object NetworkClient {
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
})
|
})
|
||||||
Runtime.getRuntime.addShutdownHook(hook)
|
Runtime.getRuntime.addShutdownHook(hook)
|
||||||
|
if (Util.isNonCygwinWindows) sbt.internal.util.JLine3.forceWindowsJansi()
|
||||||
System.exit(Terminal.withStreams(false) {
|
System.exit(Terminal.withStreams(false) {
|
||||||
val term = Terminal.console
|
val term = Terminal.console
|
||||||
try client(base, restOfArgs, term.inputStream, System.err, term, useJNI)
|
try client(base, restOfArgs, term.inputStream, System.err, term, useJNI)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ import scala.collection.mutable
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.util.Try
|
import scala.util.Try
|
||||||
import scala.util.control.NonFatal
|
import scala.util.control.NonFatal
|
||||||
import Serialization.attach
|
import Serialization.{ attach, cancelReadSystemIn, readSystemIn }
|
||||||
|
|
||||||
import sjsonnew._
|
import sjsonnew._
|
||||||
import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter }
|
import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter }
|
||||||
|
|
@ -643,12 +643,19 @@ final class NetworkChannel(
|
||||||
|
|
||||||
private[this] lazy val inputStream: InputStream = new InputStream {
|
private[this] lazy val inputStream: InputStream = new InputStream {
|
||||||
override def read(): Int = {
|
override def read(): Int = {
|
||||||
|
import sjsonnew.BasicJsonProtocol._
|
||||||
try {
|
try {
|
||||||
|
jsonRpcNotify(readSystemIn, "")
|
||||||
inputBuffer.take & 0xFF match {
|
inputBuffer.take & 0xFF match {
|
||||||
case -1 => throw new ClosedChannelException()
|
case -1 => throw new ClosedChannelException()
|
||||||
case b => b
|
case b => b
|
||||||
}
|
}
|
||||||
} catch { case e: IOException => -1 }
|
} catch {
|
||||||
|
case e: IOException =>
|
||||||
|
try jsonRpcNotify(cancelReadSystemIn, "")
|
||||||
|
catch { case _: IOException => }
|
||||||
|
-1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
override def available(): Int = inputBuffer.size
|
override def available(): Int = inputBuffer.size
|
||||||
}
|
}
|
||||||
|
|
@ -816,34 +823,19 @@ final class NetworkChannel(
|
||||||
Some(result(queue.take))
|
Some(result(queue.take))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override def getBooleanCapability(capability: String, jline3: Boolean): Boolean =
|
override def getBooleanCapability(capability: String): Boolean =
|
||||||
getCapability(
|
getCapability(
|
||||||
TerminalCapabilitiesQuery(
|
TerminalCapabilitiesQuery(boolean = Some(capability), numeric = None, string = None),
|
||||||
boolean = Some(capability),
|
|
||||||
numeric = None,
|
|
||||||
string = None,
|
|
||||||
jline3
|
|
||||||
),
|
|
||||||
_.boolean.getOrElse(false)
|
_.boolean.getOrElse(false)
|
||||||
).getOrElse(false)
|
).getOrElse(false)
|
||||||
override def getNumericCapability(capability: String, jline3: Boolean): Integer =
|
override def getNumericCapability(capability: String): Integer =
|
||||||
getCapability(
|
getCapability(
|
||||||
TerminalCapabilitiesQuery(
|
TerminalCapabilitiesQuery(boolean = None, numeric = Some(capability), string = None),
|
||||||
boolean = None,
|
|
||||||
numeric = Some(capability),
|
|
||||||
string = None,
|
|
||||||
jline3
|
|
||||||
),
|
|
||||||
(_: TerminalCapabilitiesResponse).numeric.map(Integer.valueOf).getOrElse(-1: Integer)
|
(_: TerminalCapabilitiesResponse).numeric.map(Integer.valueOf).getOrElse(-1: Integer)
|
||||||
).getOrElse(-1: Integer)
|
).getOrElse(-1: Integer)
|
||||||
override def getStringCapability(capability: String, jline3: Boolean): String =
|
override def getStringCapability(capability: String): String =
|
||||||
getCapability(
|
getCapability(
|
||||||
TerminalCapabilitiesQuery(
|
TerminalCapabilitiesQuery(boolean = None, numeric = None, string = Some(capability)),
|
||||||
boolean = None,
|
|
||||||
numeric = None,
|
|
||||||
string = Some(capability),
|
|
||||||
jline3
|
|
||||||
),
|
|
||||||
_.string.flatMap {
|
_.string.flatMap {
|
||||||
case "null" => None
|
case "null" => None
|
||||||
case s => Some(s)
|
case s => Some(s)
|
||||||
|
|
@ -899,6 +891,25 @@ final class NetworkChannel(
|
||||||
try queue.take
|
try queue.take
|
||||||
catch { case _: InterruptedException => }
|
catch { case _: InterruptedException => }
|
||||||
}
|
}
|
||||||
|
private[this] def setRawMode(toggle: Boolean): Unit = {
|
||||||
|
if (!closed.get || false) {
|
||||||
|
import sbt.protocol.codec.JsonProtocol._
|
||||||
|
val raw = TerminalSetRawModeCommand(toggle)
|
||||||
|
val queue = VirtualTerminal.setTerminalRawMode(name, jsonRpcRequest, raw)
|
||||||
|
try queue.take
|
||||||
|
catch { case _: InterruptedException => }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override private[sbt] def enterRawMode(): Unit = setRawMode(true)
|
||||||
|
override private[sbt] def exitRawMode(): Unit = setRawMode(false)
|
||||||
|
override def setEchoEnabled(toggle: Boolean): Unit =
|
||||||
|
if (!closed.get) {
|
||||||
|
import sbt.protocol.codec.JsonProtocol._
|
||||||
|
val echo = TerminalSetEchoCommand(toggle)
|
||||||
|
val queue = VirtualTerminal.setTerminalEcho(name, jsonRpcRequest, echo)
|
||||||
|
try queue.take
|
||||||
|
catch { case _: InterruptedException => () }
|
||||||
|
}
|
||||||
|
|
||||||
override def flush(): Unit = doFlush()
|
override def flush(): Unit = doFlush()
|
||||||
override def toString: String = s"NetworkTerminal($name)"
|
override def toString: String = s"NetworkTerminal($name)"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ import sbt.protocol.Serialization.{
|
||||||
terminalCapabilities,
|
terminalCapabilities,
|
||||||
terminalGetSize,
|
terminalGetSize,
|
||||||
terminalPropertiesQuery,
|
terminalPropertiesQuery,
|
||||||
|
terminalSetEcho,
|
||||||
terminalSetSize,
|
terminalSetSize,
|
||||||
|
terminalSetRawMode,
|
||||||
}
|
}
|
||||||
import sjsonnew.support.scalajson.unsafe.Converter
|
import sjsonnew.support.scalajson.unsafe.Converter
|
||||||
import sbt.protocol.{
|
import sbt.protocol.{
|
||||||
|
|
@ -35,7 +37,9 @@ import sbt.protocol.{
|
||||||
TerminalGetSizeQuery,
|
TerminalGetSizeQuery,
|
||||||
TerminalGetSizeResponse,
|
TerminalGetSizeResponse,
|
||||||
TerminalSetAttributesCommand,
|
TerminalSetAttributesCommand,
|
||||||
|
TerminalSetEchoCommand,
|
||||||
TerminalSetSizeCommand,
|
TerminalSetSizeCommand,
|
||||||
|
TerminalSetRawModeCommand,
|
||||||
}
|
}
|
||||||
import sbt.protocol.codec.JsonProtocol._
|
import sbt.protocol.codec.JsonProtocol._
|
||||||
import sbt.protocol.TerminalGetSizeResponse
|
import sbt.protocol.TerminalGetSizeResponse
|
||||||
|
|
@ -53,6 +57,10 @@ object VirtualTerminal {
|
||||||
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[Unit]]
|
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[Unit]]
|
||||||
private[this] val pendingTerminalGetSize =
|
private[this] val pendingTerminalGetSize =
|
||||||
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[TerminalGetSizeResponse]]
|
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[TerminalGetSizeResponse]]
|
||||||
|
private[this] val pendingTerminalSetEcho =
|
||||||
|
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[Unit]]
|
||||||
|
private[this] val pendingTerminalSetRawMode =
|
||||||
|
new ConcurrentHashMap[(String, String), ArrayBlockingQueue[Unit]]
|
||||||
private[sbt] def sendTerminalPropertiesQuery(
|
private[sbt] def sendTerminalPropertiesQuery(
|
||||||
channelName: String,
|
channelName: String,
|
||||||
jsonRpcRequest: (String, String, String) => Unit
|
jsonRpcRequest: (String, String, String) => Unit
|
||||||
|
|
@ -134,6 +142,30 @@ object VirtualTerminal {
|
||||||
queue
|
queue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private[sbt] def setTerminalEcho(
|
||||||
|
channelName: String,
|
||||||
|
jsonRpcRequest: (String, String, TerminalSetEchoCommand) => Unit,
|
||||||
|
query: TerminalSetEchoCommand
|
||||||
|
): ArrayBlockingQueue[Unit] = {
|
||||||
|
val id = UUID.randomUUID.toString
|
||||||
|
val queue = new ArrayBlockingQueue[Unit](1)
|
||||||
|
pendingTerminalSetEcho.put((channelName, id), queue)
|
||||||
|
jsonRpcRequest(id, terminalSetEcho, query)
|
||||||
|
queue
|
||||||
|
}
|
||||||
|
|
||||||
|
private[sbt] def setTerminalRawMode(
|
||||||
|
channelName: String,
|
||||||
|
jsonRpcRequest: (String, String, TerminalSetRawModeCommand) => Unit,
|
||||||
|
query: TerminalSetRawModeCommand
|
||||||
|
): ArrayBlockingQueue[Unit] = {
|
||||||
|
val id = UUID.randomUUID.toString
|
||||||
|
val queue = new ArrayBlockingQueue[Unit](1)
|
||||||
|
pendingTerminalSetEcho.put((channelName, id), queue)
|
||||||
|
jsonRpcRequest(id, terminalSetRawMode, query)
|
||||||
|
queue
|
||||||
|
}
|
||||||
|
|
||||||
val handler = ServerHandler { cb =>
|
val handler = ServerHandler { cb =>
|
||||||
ServerIntent(requestHandler(cb), responseHandler(cb), notificationHandler(cb))
|
ServerIntent(requestHandler(cb), responseHandler(cb), notificationHandler(cb))
|
||||||
}
|
}
|
||||||
|
|
@ -193,6 +225,16 @@ object VirtualTerminal {
|
||||||
case null =>
|
case null =>
|
||||||
case buffer => buffer.put(response.getOrElse(TerminalGetSizeResponse(1, 1)))
|
case buffer => buffer.put(response.getOrElse(TerminalGetSizeResponse(1, 1)))
|
||||||
}
|
}
|
||||||
|
case r if pendingTerminalSetEcho.get((callback.name, r.id)) != null =>
|
||||||
|
pendingTerminalSetEcho.remove((callback.name, r.id)) match {
|
||||||
|
case null =>
|
||||||
|
case buffer => buffer.put(())
|
||||||
|
}
|
||||||
|
case r if pendingTerminalSetRawMode.get((callback.name, r.id)) != null =>
|
||||||
|
pendingTerminalSetRawMode.remove((callback.name, r.id)) match {
|
||||||
|
case null =>
|
||||||
|
case buffer => buffer.put(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private val notificationHandler: Handler[JsonRpcNotificationMessage] =
|
private val notificationHandler: Handler[JsonRpcNotificationMessage] =
|
||||||
callback => {
|
callback => {
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ object Dependencies {
|
||||||
val jline3Version = "3.16.0" // Once the base jline version is upgraded, we can use the official jline-terminal
|
val jline3Version = "3.16.0" // Once the base jline version is upgraded, we can use the official jline-terminal
|
||||||
val jline3Terminal = "org.scala-sbt.jline3" % "jline-terminal" % s"$jline3Version-sbt-211a082ed6326908dc84ca017ce4430728f18a8a"
|
val jline3Terminal = "org.scala-sbt.jline3" % "jline-terminal" % s"$jline3Version-sbt-211a082ed6326908dc84ca017ce4430728f18a8a"
|
||||||
val jline3Jansi = "org.jline" % "jline-terminal-jansi" % jline3Version
|
val jline3Jansi = "org.jline" % "jline-terminal-jansi" % jline3Version
|
||||||
|
val jline3JNA = "org.jline" % "jline-terminal-jna" % jline3Version
|
||||||
val jline3Reader = "org.jline" % "jline-reader" % jline3Version
|
val jline3Reader = "org.jline" % "jline-reader" % jline3Version
|
||||||
val jansi = "org.fusesource.jansi" % "jansi" % "1.18"
|
val jansi = "org.fusesource.jansi" % "jansi" % "1.18"
|
||||||
val scalatest = "org.scalatest" %% "scalatest" % "3.0.8"
|
val scalatest = "org.scalatest" %% "scalatest" % "3.0.8"
|
||||||
|
|
|
||||||
|
|
@ -7,23 +7,22 @@ package sbt.protocol
|
||||||
final class TerminalCapabilitiesQuery private (
|
final class TerminalCapabilitiesQuery private (
|
||||||
val boolean: Option[String],
|
val boolean: Option[String],
|
||||||
val numeric: Option[String],
|
val numeric: Option[String],
|
||||||
val string: Option[String],
|
val string: Option[String]) extends sbt.protocol.CommandMessage() with Serializable {
|
||||||
val jline3: Boolean) extends sbt.protocol.CommandMessage() with Serializable {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override def equals(o: Any): Boolean = o match {
|
override def equals(o: Any): Boolean = o match {
|
||||||
case x: TerminalCapabilitiesQuery => (this.boolean == x.boolean) && (this.numeric == x.numeric) && (this.string == x.string) && (this.jline3 == x.jline3)
|
case x: TerminalCapabilitiesQuery => (this.boolean == x.boolean) && (this.numeric == x.numeric) && (this.string == x.string)
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
override def hashCode: Int = {
|
override def hashCode: Int = {
|
||||||
37 * (37 * (37 * (37 * (37 * (17 + "sbt.protocol.TerminalCapabilitiesQuery".##) + boolean.##) + numeric.##) + string.##) + jline3.##)
|
37 * (37 * (37 * (37 * (17 + "sbt.protocol.TerminalCapabilitiesQuery".##) + boolean.##) + numeric.##) + string.##)
|
||||||
}
|
}
|
||||||
override def toString: String = {
|
override def toString: String = {
|
||||||
"TerminalCapabilitiesQuery(" + boolean + ", " + numeric + ", " + string + ", " + jline3 + ")"
|
"TerminalCapabilitiesQuery(" + boolean + ", " + numeric + ", " + string + ")"
|
||||||
}
|
}
|
||||||
private[this] def copy(boolean: Option[String] = boolean, numeric: Option[String] = numeric, string: Option[String] = string, jline3: Boolean = jline3): TerminalCapabilitiesQuery = {
|
private[this] def copy(boolean: Option[String] = boolean, numeric: Option[String] = numeric, string: Option[String] = string): TerminalCapabilitiesQuery = {
|
||||||
new TerminalCapabilitiesQuery(boolean, numeric, string, jline3)
|
new TerminalCapabilitiesQuery(boolean, numeric, string)
|
||||||
}
|
}
|
||||||
def withBoolean(boolean: Option[String]): TerminalCapabilitiesQuery = {
|
def withBoolean(boolean: Option[String]): TerminalCapabilitiesQuery = {
|
||||||
copy(boolean = boolean)
|
copy(boolean = boolean)
|
||||||
|
|
@ -43,12 +42,9 @@ final class TerminalCapabilitiesQuery private (
|
||||||
def withString(string: String): TerminalCapabilitiesQuery = {
|
def withString(string: String): TerminalCapabilitiesQuery = {
|
||||||
copy(string = Option(string))
|
copy(string = Option(string))
|
||||||
}
|
}
|
||||||
def withJline3(jline3: Boolean): TerminalCapabilitiesQuery = {
|
|
||||||
copy(jline3 = jline3)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
object TerminalCapabilitiesQuery {
|
object TerminalCapabilitiesQuery {
|
||||||
|
|
||||||
def apply(boolean: Option[String], numeric: Option[String], string: Option[String], jline3: Boolean): TerminalCapabilitiesQuery = new TerminalCapabilitiesQuery(boolean, numeric, string, jline3)
|
def apply(boolean: Option[String], numeric: Option[String], string: Option[String]): TerminalCapabilitiesQuery = new TerminalCapabilitiesQuery(boolean, numeric, string)
|
||||||
def apply(boolean: String, numeric: String, string: String, jline3: Boolean): TerminalCapabilitiesQuery = new TerminalCapabilitiesQuery(Option(boolean), Option(numeric), Option(string), jline3)
|
def apply(boolean: String, numeric: String, string: String): TerminalCapabilitiesQuery = new TerminalCapabilitiesQuery(Option(boolean), Option(numeric), Option(string))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetEchoCommand.scala
generated
Normal file
32
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetEchoCommand.scala
generated
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol
|
||||||
|
final class TerminalSetEchoCommand private (
|
||||||
|
val toggle: Boolean) extends sbt.protocol.CommandMessage() with Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = o match {
|
||||||
|
case x: TerminalSetEchoCommand => (this.toggle == x.toggle)
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
override def hashCode: Int = {
|
||||||
|
37 * (37 * (17 + "sbt.protocol.TerminalSetEchoCommand".##) + toggle.##)
|
||||||
|
}
|
||||||
|
override def toString: String = {
|
||||||
|
"TerminalSetEchoCommand(" + toggle + ")"
|
||||||
|
}
|
||||||
|
private[this] def copy(toggle: Boolean = toggle): TerminalSetEchoCommand = {
|
||||||
|
new TerminalSetEchoCommand(toggle)
|
||||||
|
}
|
||||||
|
def withToggle(toggle: Boolean): TerminalSetEchoCommand = {
|
||||||
|
copy(toggle = toggle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object TerminalSetEchoCommand {
|
||||||
|
|
||||||
|
def apply(toggle: Boolean): TerminalSetEchoCommand = new TerminalSetEchoCommand(toggle)
|
||||||
|
}
|
||||||
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetEchoResponse.scala
generated
Normal file
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetEchoResponse.scala
generated
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol
|
||||||
|
final class TerminalSetEchoResponse private () extends sbt.protocol.EventMessage() with Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = o match {
|
||||||
|
case _: TerminalSetEchoResponse => true
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
override def hashCode: Int = {
|
||||||
|
37 * (17 + "sbt.protocol.TerminalSetEchoResponse".##)
|
||||||
|
}
|
||||||
|
override def toString: String = {
|
||||||
|
"TerminalSetEchoResponse()"
|
||||||
|
}
|
||||||
|
private[this] def copy(): TerminalSetEchoResponse = {
|
||||||
|
new TerminalSetEchoResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
object TerminalSetEchoResponse {
|
||||||
|
|
||||||
|
def apply(): TerminalSetEchoResponse = new TerminalSetEchoResponse()
|
||||||
|
}
|
||||||
32
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeCommand.scala
generated
Normal file
32
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeCommand.scala
generated
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol
|
||||||
|
final class TerminalSetRawModeCommand private (
|
||||||
|
val toggle: Boolean) extends sbt.protocol.CommandMessage() with Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = o match {
|
||||||
|
case x: TerminalSetRawModeCommand => (this.toggle == x.toggle)
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
override def hashCode: Int = {
|
||||||
|
37 * (37 * (17 + "sbt.protocol.TerminalSetRawModeCommand".##) + toggle.##)
|
||||||
|
}
|
||||||
|
override def toString: String = {
|
||||||
|
"TerminalSetRawModeCommand(" + toggle + ")"
|
||||||
|
}
|
||||||
|
private[this] def copy(toggle: Boolean = toggle): TerminalSetRawModeCommand = {
|
||||||
|
new TerminalSetRawModeCommand(toggle)
|
||||||
|
}
|
||||||
|
def withToggle(toggle: Boolean): TerminalSetRawModeCommand = {
|
||||||
|
copy(toggle = toggle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object TerminalSetRawModeCommand {
|
||||||
|
|
||||||
|
def apply(toggle: Boolean): TerminalSetRawModeCommand = new TerminalSetRawModeCommand(toggle)
|
||||||
|
}
|
||||||
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeReponse.scala
generated
Normal file
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeReponse.scala
generated
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol
|
||||||
|
final class TerminalSetRawModeReponse private () extends sbt.protocol.EventMessage() with Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = o match {
|
||||||
|
case _: TerminalSetRawModeReponse => true
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
override def hashCode: Int = {
|
||||||
|
37 * (17 + "sbt.protocol.TerminalSetRawModeReponse".##)
|
||||||
|
}
|
||||||
|
override def toString: String = {
|
||||||
|
"TerminalSetRawModeReponse()"
|
||||||
|
}
|
||||||
|
private[this] def copy(): TerminalSetRawModeReponse = {
|
||||||
|
new TerminalSetRawModeReponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
object TerminalSetRawModeReponse {
|
||||||
|
|
||||||
|
def apply(): TerminalSetRawModeReponse = new TerminalSetRawModeReponse()
|
||||||
|
}
|
||||||
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeResponse.scala
generated
Normal file
29
protocol/src/main/contraband-scala/sbt/protocol/TerminalSetRawModeResponse.scala
generated
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol
|
||||||
|
final class TerminalSetRawModeResponse private () extends sbt.protocol.EventMessage() with Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = o match {
|
||||||
|
case _: TerminalSetRawModeResponse => true
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
override def hashCode: Int = {
|
||||||
|
37 * (17 + "sbt.protocol.TerminalSetRawModeResponse".##)
|
||||||
|
}
|
||||||
|
override def toString: String = {
|
||||||
|
"TerminalSetRawModeResponse()"
|
||||||
|
}
|
||||||
|
private[this] def copy(): TerminalSetRawModeResponse = {
|
||||||
|
new TerminalSetRawModeResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
object TerminalSetRawModeResponse {
|
||||||
|
|
||||||
|
def apply(): TerminalSetRawModeResponse = new TerminalSetRawModeResponse()
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,6 @@
|
||||||
package sbt.protocol.codec
|
package sbt.protocol.codec
|
||||||
|
|
||||||
import _root_.sjsonnew.JsonFormat
|
import _root_.sjsonnew.JsonFormat
|
||||||
trait CommandMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats with sbt.protocol.codec.AttachFormats with sbt.protocol.codec.TerminalCapabilitiesQueryFormats with sbt.protocol.codec.TerminalSetAttributesCommandFormats with sbt.protocol.codec.TerminalAttributesQueryFormats with sbt.protocol.codec.TerminalGetSizeQueryFormats with sbt.protocol.codec.TerminalSetSizeCommandFormats =>
|
trait CommandMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats with sbt.protocol.codec.AttachFormats with sbt.protocol.codec.TerminalCapabilitiesQueryFormats with sbt.protocol.codec.TerminalSetAttributesCommandFormats with sbt.protocol.codec.TerminalAttributesQueryFormats with sbt.protocol.codec.TerminalGetSizeQueryFormats with sbt.protocol.codec.TerminalSetSizeCommandFormats with sbt.protocol.codec.TerminalSetEchoCommandFormats with sbt.protocol.codec.TerminalSetRawModeCommandFormats =>
|
||||||
implicit lazy val CommandMessageFormat: JsonFormat[sbt.protocol.CommandMessage] = flatUnionFormat9[sbt.protocol.CommandMessage, sbt.protocol.InitCommand, sbt.protocol.ExecCommand, sbt.protocol.SettingQuery, sbt.protocol.Attach, sbt.protocol.TerminalCapabilitiesQuery, sbt.protocol.TerminalSetAttributesCommand, sbt.protocol.TerminalAttributesQuery, sbt.protocol.TerminalGetSizeQuery, sbt.protocol.TerminalSetSizeCommand]("type")
|
implicit lazy val CommandMessageFormat: JsonFormat[sbt.protocol.CommandMessage] = flatUnionFormat11[sbt.protocol.CommandMessage, sbt.protocol.InitCommand, sbt.protocol.ExecCommand, sbt.protocol.SettingQuery, sbt.protocol.Attach, sbt.protocol.TerminalCapabilitiesQuery, sbt.protocol.TerminalSetAttributesCommand, sbt.protocol.TerminalAttributesQuery, sbt.protocol.TerminalGetSizeQuery, sbt.protocol.TerminalSetSizeCommand, sbt.protocol.TerminalSetEchoCommand, sbt.protocol.TerminalSetRawModeCommand]("type")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@
|
||||||
package sbt.protocol.codec
|
package sbt.protocol.codec
|
||||||
|
|
||||||
import _root_.sjsonnew.JsonFormat
|
import _root_.sjsonnew.JsonFormat
|
||||||
trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.internal.util.codec.JValueFormats with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats with sbt.protocol.codec.TerminalPropertiesResponseFormats with sbt.protocol.codec.TerminalCapabilitiesResponseFormats with sbt.protocol.codec.TerminalSetAttributesResponseFormats with sbt.protocol.codec.TerminalAttributesResponseFormats with sbt.protocol.codec.TerminalGetSizeResponseFormats with sbt.protocol.codec.TerminalSetSizeResponseFormats =>
|
trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.internal.util.codec.JValueFormats with sbt.protocol.codec.SettingQuerySuccessFormats with sbt.protocol.codec.SettingQueryFailureFormats with sbt.protocol.codec.TerminalPropertiesResponseFormats with sbt.protocol.codec.TerminalCapabilitiesResponseFormats with sbt.protocol.codec.TerminalSetAttributesResponseFormats with sbt.protocol.codec.TerminalAttributesResponseFormats with sbt.protocol.codec.TerminalGetSizeResponseFormats with sbt.protocol.codec.TerminalSetSizeResponseFormats with sbt.protocol.codec.TerminalSetEchoResponseFormats with sbt.protocol.codec.TerminalSetRawModeResponseFormats =>
|
||||||
implicit lazy val EventMessageFormat: JsonFormat[sbt.protocol.EventMessage] = flatUnionFormat11[sbt.protocol.EventMessage, sbt.protocol.ChannelAcceptedEvent, sbt.protocol.LogEvent, sbt.protocol.ExecStatusEvent, sbt.protocol.SettingQuerySuccess, sbt.protocol.SettingQueryFailure, sbt.protocol.TerminalPropertiesResponse, sbt.protocol.TerminalCapabilitiesResponse, sbt.protocol.TerminalSetAttributesResponse, sbt.protocol.TerminalAttributesResponse, sbt.protocol.TerminalGetSizeResponse, sbt.protocol.TerminalSetSizeResponse]("type")
|
implicit lazy val EventMessageFormat: JsonFormat[sbt.protocol.EventMessage] = flatUnionFormat13[sbt.protocol.EventMessage, sbt.protocol.ChannelAcceptedEvent, sbt.protocol.LogEvent, sbt.protocol.ExecStatusEvent, sbt.protocol.SettingQuerySuccess, sbt.protocol.SettingQueryFailure, sbt.protocol.TerminalPropertiesResponse, sbt.protocol.TerminalCapabilitiesResponse, sbt.protocol.TerminalSetAttributesResponse, sbt.protocol.TerminalAttributesResponse, sbt.protocol.TerminalGetSizeResponse, sbt.protocol.TerminalSetSizeResponse, sbt.protocol.TerminalSetEchoResponse, sbt.protocol.TerminalSetRawModeResponse]("type")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
|
||||||
with sbt.protocol.codec.TerminalAttributesQueryFormats
|
with sbt.protocol.codec.TerminalAttributesQueryFormats
|
||||||
with sbt.protocol.codec.TerminalGetSizeQueryFormats
|
with sbt.protocol.codec.TerminalGetSizeQueryFormats
|
||||||
with sbt.protocol.codec.TerminalSetSizeCommandFormats
|
with sbt.protocol.codec.TerminalSetSizeCommandFormats
|
||||||
|
with sbt.protocol.codec.TerminalSetEchoCommandFormats
|
||||||
|
with sbt.protocol.codec.TerminalSetRawModeCommandFormats
|
||||||
with sbt.protocol.codec.CommandMessageFormats
|
with sbt.protocol.codec.CommandMessageFormats
|
||||||
with sbt.protocol.codec.CompletionParamsFormats
|
with sbt.protocol.codec.CompletionParamsFormats
|
||||||
with sbt.protocol.codec.ChannelAcceptedEventFormats
|
with sbt.protocol.codec.ChannelAcceptedEventFormats
|
||||||
|
|
@ -28,6 +30,8 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
|
||||||
with sbt.protocol.codec.TerminalAttributesResponseFormats
|
with sbt.protocol.codec.TerminalAttributesResponseFormats
|
||||||
with sbt.protocol.codec.TerminalGetSizeResponseFormats
|
with sbt.protocol.codec.TerminalGetSizeResponseFormats
|
||||||
with sbt.protocol.codec.TerminalSetSizeResponseFormats
|
with sbt.protocol.codec.TerminalSetSizeResponseFormats
|
||||||
|
with sbt.protocol.codec.TerminalSetEchoResponseFormats
|
||||||
|
with sbt.protocol.codec.TerminalSetRawModeResponseFormats
|
||||||
with sbt.protocol.codec.EventMessageFormats
|
with sbt.protocol.codec.EventMessageFormats
|
||||||
with sbt.protocol.codec.SettingQueryResponseFormats
|
with sbt.protocol.codec.SettingQueryResponseFormats
|
||||||
with sbt.protocol.codec.CompletionResponseFormats
|
with sbt.protocol.codec.CompletionResponseFormats
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,8 @@ implicit lazy val TerminalCapabilitiesQueryFormat: JsonFormat[sbt.protocol.Termi
|
||||||
val boolean = unbuilder.readField[Option[String]]("boolean")
|
val boolean = unbuilder.readField[Option[String]]("boolean")
|
||||||
val numeric = unbuilder.readField[Option[String]]("numeric")
|
val numeric = unbuilder.readField[Option[String]]("numeric")
|
||||||
val string = unbuilder.readField[Option[String]]("string")
|
val string = unbuilder.readField[Option[String]]("string")
|
||||||
val jline3 = unbuilder.readField[Boolean]("jline3")
|
|
||||||
unbuilder.endObject()
|
unbuilder.endObject()
|
||||||
sbt.protocol.TerminalCapabilitiesQuery(boolean, numeric, string, jline3)
|
sbt.protocol.TerminalCapabilitiesQuery(boolean, numeric, string)
|
||||||
case None =>
|
case None =>
|
||||||
deserializationError("Expected JsObject but found None")
|
deserializationError("Expected JsObject but found None")
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +25,6 @@ implicit lazy val TerminalCapabilitiesQueryFormat: JsonFormat[sbt.protocol.Termi
|
||||||
builder.addField("boolean", obj.boolean)
|
builder.addField("boolean", obj.boolean)
|
||||||
builder.addField("numeric", obj.numeric)
|
builder.addField("numeric", obj.numeric)
|
||||||
builder.addField("string", obj.string)
|
builder.addField("string", obj.string)
|
||||||
builder.addField("jline3", obj.jline3)
|
|
||||||
builder.endObject()
|
builder.endObject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetEchoCommandFormats.scala
generated
Normal file
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetEchoCommandFormats.scala
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol.codec
|
||||||
|
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||||
|
trait TerminalSetEchoCommandFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||||
|
implicit lazy val TerminalSetEchoCommandFormat: JsonFormat[sbt.protocol.TerminalSetEchoCommand] = new JsonFormat[sbt.protocol.TerminalSetEchoCommand] {
|
||||||
|
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.TerminalSetEchoCommand = {
|
||||||
|
__jsOpt match {
|
||||||
|
case Some(__js) =>
|
||||||
|
unbuilder.beginObject(__js)
|
||||||
|
val toggle = unbuilder.readField[Boolean]("toggle")
|
||||||
|
unbuilder.endObject()
|
||||||
|
sbt.protocol.TerminalSetEchoCommand(toggle)
|
||||||
|
case None =>
|
||||||
|
deserializationError("Expected JsObject but found None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override def write[J](obj: sbt.protocol.TerminalSetEchoCommand, builder: Builder[J]): Unit = {
|
||||||
|
builder.beginObject()
|
||||||
|
builder.addField("toggle", obj.toggle)
|
||||||
|
builder.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetEchoResponseFormats.scala
generated
Normal file
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetEchoResponseFormats.scala
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol.codec
|
||||||
|
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||||
|
trait TerminalSetEchoResponseFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||||
|
implicit lazy val TerminalSetEchoResponseFormat: JsonFormat[sbt.protocol.TerminalSetEchoResponse] = new JsonFormat[sbt.protocol.TerminalSetEchoResponse] {
|
||||||
|
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.TerminalSetEchoResponse = {
|
||||||
|
__jsOpt match {
|
||||||
|
case Some(__js) =>
|
||||||
|
unbuilder.beginObject(__js)
|
||||||
|
|
||||||
|
unbuilder.endObject()
|
||||||
|
sbt.protocol.TerminalSetEchoResponse()
|
||||||
|
case None =>
|
||||||
|
deserializationError("Expected JsObject but found None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override def write[J](obj: sbt.protocol.TerminalSetEchoResponse, builder: Builder[J]): Unit = {
|
||||||
|
builder.beginObject()
|
||||||
|
|
||||||
|
builder.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeCommandFormats.scala
generated
Normal file
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeCommandFormats.scala
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol.codec
|
||||||
|
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||||
|
trait TerminalSetRawModeCommandFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||||
|
implicit lazy val TerminalSetRawModeCommandFormat: JsonFormat[sbt.protocol.TerminalSetRawModeCommand] = new JsonFormat[sbt.protocol.TerminalSetRawModeCommand] {
|
||||||
|
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.TerminalSetRawModeCommand = {
|
||||||
|
__jsOpt match {
|
||||||
|
case Some(__js) =>
|
||||||
|
unbuilder.beginObject(__js)
|
||||||
|
val toggle = unbuilder.readField[Boolean]("toggle")
|
||||||
|
unbuilder.endObject()
|
||||||
|
sbt.protocol.TerminalSetRawModeCommand(toggle)
|
||||||
|
case None =>
|
||||||
|
deserializationError("Expected JsObject but found None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override def write[J](obj: sbt.protocol.TerminalSetRawModeCommand, builder: Builder[J]): Unit = {
|
||||||
|
builder.beginObject()
|
||||||
|
builder.addField("toggle", obj.toggle)
|
||||||
|
builder.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeReponseFormats.scala
generated
Normal file
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeReponseFormats.scala
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol.codec
|
||||||
|
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||||
|
trait TerminalSetRawModeReponseFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||||
|
implicit lazy val TerminalSetRawModeReponseFormat: JsonFormat[sbt.protocol.TerminalSetRawModeReponse] = new JsonFormat[sbt.protocol.TerminalSetRawModeReponse] {
|
||||||
|
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.TerminalSetRawModeReponse = {
|
||||||
|
__jsOpt match {
|
||||||
|
case Some(__js) =>
|
||||||
|
unbuilder.beginObject(__js)
|
||||||
|
|
||||||
|
unbuilder.endObject()
|
||||||
|
sbt.protocol.TerminalSetRawModeReponse()
|
||||||
|
case None =>
|
||||||
|
deserializationError("Expected JsObject but found None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override def write[J](obj: sbt.protocol.TerminalSetRawModeReponse, builder: Builder[J]): Unit = {
|
||||||
|
builder.beginObject()
|
||||||
|
|
||||||
|
builder.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeResponseFormats.scala
generated
Normal file
27
protocol/src/main/contraband-scala/sbt/protocol/codec/TerminalSetRawModeResponseFormats.scala
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DO NOT EDIT MANUALLY
|
||||||
|
package sbt.protocol.codec
|
||||||
|
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||||
|
trait TerminalSetRawModeResponseFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||||
|
implicit lazy val TerminalSetRawModeResponseFormat: JsonFormat[sbt.protocol.TerminalSetRawModeResponse] = new JsonFormat[sbt.protocol.TerminalSetRawModeResponse] {
|
||||||
|
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.TerminalSetRawModeResponse = {
|
||||||
|
__jsOpt match {
|
||||||
|
case Some(__js) =>
|
||||||
|
unbuilder.beginObject(__js)
|
||||||
|
|
||||||
|
unbuilder.endObject()
|
||||||
|
sbt.protocol.TerminalSetRawModeResponse()
|
||||||
|
case None =>
|
||||||
|
deserializationError("Expected JsObject but found None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override def write[J](obj: sbt.protocol.TerminalSetRawModeResponse, builder: Builder[J]): Unit = {
|
||||||
|
builder.beginObject()
|
||||||
|
|
||||||
|
builder.endObject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -97,7 +97,6 @@ type TerminalCapabilitiesQuery implements CommandMessage {
|
||||||
boolean: String
|
boolean: String
|
||||||
numeric: String
|
numeric: String
|
||||||
string: String
|
string: String
|
||||||
jline3: Boolean!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TerminalCapabilitiesResponse implements EventMessage {
|
type TerminalCapabilitiesResponse implements EventMessage {
|
||||||
|
|
@ -138,3 +137,15 @@ type TerminalSetSizeCommand implements CommandMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TerminalSetSizeResponse implements EventMessage {}
|
type TerminalSetSizeResponse implements EventMessage {}
|
||||||
|
|
||||||
|
type TerminalSetEchoCommand implements CommandMessage {
|
||||||
|
toggle: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type TerminalSetEchoResponse implements EventMessage {}
|
||||||
|
|
||||||
|
type TerminalSetRawModeCommand implements CommandMessage {
|
||||||
|
toggle: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type TerminalSetRawModeResponse implements EventMessage {}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import sbt.internal.protocol.{
|
||||||
|
|
||||||
object Serialization {
|
object Serialization {
|
||||||
private[sbt] val VsCode = "application/vscode-jsonrpc; charset=utf-8"
|
private[sbt] val VsCode = "application/vscode-jsonrpc; charset=utf-8"
|
||||||
|
val readSystemIn = "sbt/readSystemIn"
|
||||||
|
val cancelReadSystemIn = "sbt/cancelReadSystemIn"
|
||||||
val systemIn = "sbt/systemIn"
|
val systemIn = "sbt/systemIn"
|
||||||
val systemOut = "sbt/systemOut"
|
val systemOut = "sbt/systemOut"
|
||||||
val systemErr = "sbt/systemErr"
|
val systemErr = "sbt/systemErr"
|
||||||
|
|
@ -41,6 +43,8 @@ object Serialization {
|
||||||
val getTerminalAttributes = "sbt/getTerminalAttributes"
|
val getTerminalAttributes = "sbt/getTerminalAttributes"
|
||||||
val terminalGetSize = "sbt/terminalGetSize"
|
val terminalGetSize = "sbt/terminalGetSize"
|
||||||
val terminalSetSize = "sbt/terminalSetSize"
|
val terminalSetSize = "sbt/terminalSetSize"
|
||||||
|
val terminalSetEcho = "sbt/terminalSetEcho"
|
||||||
|
val terminalSetRawMode = "sbt/terminalSetRawMode"
|
||||||
val CancelAll = "__CancelAll"
|
val CancelAll = "__CancelAll"
|
||||||
|
|
||||||
@deprecated("unused", since = "1.4.0")
|
@deprecated("unused", since = "1.4.0")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue