Merge pull request #5839 from eatkins/play-shell-prompt

Honor shellPrompt override
This commit is contained in:
eugene yokota 2020-09-12 08:24:41 -04:00 committed by GitHub
commit a7f00ecd7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 19 deletions

View File

@ -13,7 +13,7 @@ import com.github.ghik.silencer.silent
import sbt.internal.inc.classpath.{ ClassLoaderCache => IncClassLoaderCache }
import sbt.internal.classpath.ClassLoaderCache
import sbt.internal.server.ServerHandler
import sbt.internal.util.{ AttributeKey, Terminal }
import sbt.internal.util.AttributeKey
import sbt.librarymanagement.ModuleID
import sbt.util.Level
import scala.concurrent.duration.FiniteDuration
@ -36,8 +36,8 @@ object BasicKeys {
"The function that constructs the command prompt from the current build state.",
10000
)
val terminalShellPrompt = AttributeKey[(Terminal, State) => String](
"new-shell-prompt",
val colorShellPrompt = AttributeKey[(Boolean, State) => String](
"color-shell-prompt",
"The function that constructs the command prompt from the current build state for a given terminal.",
10000
)

View File

@ -12,7 +12,7 @@ import java.nio.channels.ClosedChannelException
import java.util.concurrent.atomic.AtomicBoolean
import sbt.BasicCommandStrings.{ Cancel, TerminateAction, Shutdown }
import sbt.BasicKeys.{ historyPath, terminalShellPrompt }
import sbt.BasicKeys.{ historyPath, colorShellPrompt }
import sbt.State
import sbt.internal.CommandChannel
import sbt.internal.util.ConsoleAppender.{ ClearPromptLine, ClearScreenAfterCursor, DeleteLine }
@ -44,6 +44,9 @@ private[sbt] trait UITask extends Runnable with AutoCloseable {
}
private[sbt] object UITask {
case object NoShellPrompt extends (State => String) {
override def apply(state: State): String = ""
}
trait Reader extends AutoCloseable {
def readLine(): Either[String, String]
override def close(): Unit = {}
@ -93,11 +96,15 @@ private[sbt] object UITask {
private[this] def history(s: State): Option[File] =
s.get(historyPath).getOrElse(Some(new File(s.baseDir, ".history")))
private[sbt] def shellPrompt(terminal: Terminal, s: State): String =
s.get(terminalShellPrompt) match {
case Some(pf) => pf(terminal, s)
case None =>
def ansi(s: String): String = if (terminal.isAnsiSupported) s"$s" else ""
s"${ansi(DeleteLine)}> ${ansi(ClearScreenAfterCursor)}"
s.get(sbt.BasicKeys.shellPrompt) match {
case Some(NoShellPrompt) | None =>
s.get(colorShellPrompt) match {
case Some(pf) => pf(terminal.isColorEnabled, s)
case None =>
def color(s: String): String = if (terminal.isColorEnabled) s"$s" else ""
s"${color(DeleteLine)}> ${color(ClearScreenAfterCursor)}"
}
case Some(p) => p(s)
}
private[sbt] class AskUserTask(
state: State,

View File

@ -2558,9 +2558,12 @@ object Classpaths {
val base = ModuleID(id.groupID, id.name, sbtVersion.value).withCrossVersion(cross)
CrossVersion(scalaVersion, binVersion)(base).withCrossVersion(Disabled())
},
shellPrompt := shellPromptFromState,
terminalShellPrompt := { (t, s) =>
shellPromptFromState(t)(s)
shellPrompt := sbt.internal.ui.UITask.NoShellPrompt,
colorShellPrompt := { (c, s) =>
shellPrompt.value match {
case sbt.internal.ui.UITask.NoShellPrompt => shellPromptFromState(c)(s)
case p => p(s)
}
},
dynamicDependency := { (): Unit },
transitiveClasspathDependency := { (): Unit },
@ -3861,12 +3864,12 @@ object Classpaths {
}
}
def shellPromptFromState: State => String = shellPromptFromState(Terminal.console)
def shellPromptFromState(terminal: Terminal): State => String = { s: State =>
def shellPromptFromState: State => String = shellPromptFromState(Terminal.console.isColorEnabled)
def shellPromptFromState(isColorEnabled: Boolean): State => String = { s: State =>
val extracted = Project.extract(s)
(name in extracted.currentRef).get(extracted.structure.data) match {
case Some(name) =>
s"sbt:$name" + Def.withColor(s"> ", Option(scala.Console.CYAN), terminal.isColorEnabled)
s"sbt:$name" + Def.withColor(s"> ", Option(scala.Console.CYAN), isColorEnabled)
case _ => "> "
}
}

View File

@ -93,7 +93,7 @@ object Keys {
// Command keys
val historyPath = SettingKey(BasicKeys.historyPath)
val shellPrompt = SettingKey(BasicKeys.shellPrompt)
val terminalShellPrompt = SettingKey(BasicKeys.terminalShellPrompt)
val colorShellPrompt = SettingKey(BasicKeys.colorShellPrompt)
val autoStartServer = SettingKey(BasicKeys.autoStartServer)
val serverPort = SettingKey(BasicKeys.serverPort)
val serverHost = SettingKey(BasicKeys.serverHost)

View File

@ -14,12 +14,12 @@ import Project._
import BasicKeys.serverLogLevel
import Keys.{
stateBuildStructure,
colorShellPrompt,
commands,
configuration,
historyPath,
projectCommand,
sessionSettings,
terminalShellPrompt,
shellPrompt,
templateResolverInfos,
autoStartServer,
@ -512,7 +512,7 @@ object Project extends ProjectExtra {
val allCommands = commandsIn(ref) ++ commandsIn(BuildRef(ref.build)) ++ (commands in Global get structure.data toList)
val history = get(historyPath) flatMap idFun
val prompt = get(shellPrompt)
val newPrompt = get(terminalShellPrompt)
val newPrompt = get(colorShellPrompt)
val trs = (templateResolverInfos in Global get structure.data).toList.flatten
val startSvr: Option[Boolean] = get(autoStartServer)
val host: Option[String] = get(serverHost)
@ -541,7 +541,7 @@ object Project extends ProjectExtra {
.put(historyPath.key, history)
.put(templateResolverInfos.key, trs)
.setCond(shellPrompt.key, prompt)
.setCond(terminalShellPrompt.key, newPrompt)
.setCond(colorShellPrompt.key, newPrompt)
.setCond(serverLogLevel, srvLogLevel)
.setCond(fullServerHandlers.key, hs)
s.copy(