mirror of https://github.com/sbt/sbt.git
reintegrate history commands, add proper parsing for recursive commands
This commit is contained in:
parent
1f2c066639
commit
309bc5caeb
|
|
@ -4,9 +4,10 @@
|
||||||
package sbt
|
package sbt
|
||||||
package complete
|
package complete
|
||||||
|
|
||||||
import History.number
|
import History.number
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
final class History private(lines: IndexedSeq[String], error: String => Unit) extends NotNull
|
final class History private(val lines: IndexedSeq[String], val path: Option[File], error: String => Unit) extends NotNull
|
||||||
{
|
{
|
||||||
private def reversed = lines.reverse
|
private def reversed = lines.reverse
|
||||||
|
|
||||||
|
|
@ -41,7 +42,7 @@ final class History private(lines: IndexedSeq[String], error: String => Unit) ex
|
||||||
|
|
||||||
object History
|
object History
|
||||||
{
|
{
|
||||||
def apply(lines: Seq[String], error: String => Unit): History = new History(lines.toIndexedSeq, error)
|
def apply(lines: Seq[String], path: Option[File], error: String => Unit): History = new History(lines.toIndexedSeq, path, error)
|
||||||
|
|
||||||
def number(s: String): Option[Int] =
|
def number(s: String): Option[Int] =
|
||||||
try { Some(s.toInt) }
|
try { Some(s.toInt) }
|
||||||
|
|
|
||||||
|
|
@ -39,63 +39,34 @@ object HistoryCommands
|
||||||
def helpString = "History commands:\n " + (descriptions.map{ case (c,d) => c + " " + d}).mkString("\n ")
|
def helpString = "History commands:\n " + (descriptions.map{ case (c,d) => c + " " + d}).mkString("\n ")
|
||||||
def printHelp(): Unit =
|
def printHelp(): Unit =
|
||||||
println(helpString)
|
println(helpString)
|
||||||
|
def printHistory(history: complete.History, historySize: Int, show: Int): Unit =
|
||||||
|
history.list(historySize, show).foreach(println)
|
||||||
|
|
||||||
def apply(s: String, historyPath: Option[File], maxLines: Int, error: String => Unit): Option[List[String]] =
|
import DefaultParsers._
|
||||||
if(s.isEmpty)
|
|
||||||
{
|
val MaxLines = 500
|
||||||
printHelp()
|
lazy val num = token(NatBasic, "<integer>")
|
||||||
Some(Nil)
|
lazy val last = Last ^^^ { execute(_ !!) }
|
||||||
}
|
lazy val list = ListCommands ~> (num ?? Int.MaxValue) map { show =>
|
||||||
else
|
(h: History) => { printHistory(h, MaxLines, show); Some(Nil) }
|
||||||
{
|
|
||||||
val lines = historyPath.toList.flatMap( p => IO.readLines(p) ).toArray
|
|
||||||
if(lines.isEmpty)
|
|
||||||
{
|
|
||||||
error("No history")
|
|
||||||
None
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val history = complete.History(lines, error)
|
|
||||||
if(s.startsWith(ListCommands))
|
|
||||||
{
|
|
||||||
val rest = s.substring(ListCommands.length)
|
|
||||||
val show = complete.History.number(rest).getOrElse(lines.length)
|
|
||||||
printHistory(history, maxLines, show)
|
|
||||||
Some(Nil)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val command = historyCommand(history, s)
|
|
||||||
command.foreach(lines(lines.length - 1) = _)
|
|
||||||
historyPath foreach { h => IO.writeLines(h, lines) }
|
|
||||||
Some(command.toList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def printHistory(history: complete.History, historySize: Int, show: Int): Unit = history.list(historySize, show).foreach(println)
|
|
||||||
def historyCommand(history: complete.History, s: String): Option[String] =
|
|
||||||
{
|
|
||||||
if(s == Last)
|
|
||||||
history !!
|
|
||||||
else if(s.startsWith(Contains))
|
|
||||||
history !? s.substring(Contains.length)
|
|
||||||
else
|
|
||||||
history ! s
|
|
||||||
}
|
}
|
||||||
/*
|
lazy val execStr = flag('?') ~ token(any.+.string, "<string>") map { case (contains, str) =>
|
||||||
import parse.{Parser,Parsers}
|
execute(h => if(contains) h !? str else h ! str)
|
||||||
import Parser._
|
|
||||||
import Parsers._
|
|
||||||
val historyParser: Parser[complete.History => Option[String]] =
|
|
||||||
{
|
|
||||||
Start ~> Specific)
|
|
||||||
}
|
}
|
||||||
!! Execute the last command again
|
lazy val execInt = flag('-') ~ num map { case (neg, value) =>
|
||||||
!: Show all previous commands
|
execute(h => if(neg) h !- value else h ! value)
|
||||||
!:n Show the last n commands
|
}
|
||||||
!n Execute the command with index n, as shown by the !: command
|
lazy val help = success( (h: History) => { printHelp(); Some(Nil) } )
|
||||||
!-n Execute the nth command before this one
|
|
||||||
!string Execute the most recent command starting with 'string'
|
def execute(f: History => Option[String]): History => Option[List[String]] = (h: History) =>
|
||||||
!?string*/
|
{
|
||||||
|
val command = f(h)
|
||||||
|
val lines = h.lines.toArray
|
||||||
|
command.foreach(lines(lines.length - 1) = _)
|
||||||
|
h.path foreach { h => IO.writeLines(h, lines) }
|
||||||
|
Some(command.toList)
|
||||||
|
}
|
||||||
|
|
||||||
|
val actionParser: Parser[complete.History => Option[List[String]]] =
|
||||||
|
Start ~> (help | last | execInt | list | execStr ) // execStr must come last
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +52,8 @@ trait Parsers
|
||||||
|
|
||||||
def spaceDelimited(display: String): Parser[Seq[String]] = (token(Space) ~> token(NotSpace, display)).* <~ SpaceClass.*
|
def spaceDelimited(display: String): Parser[Seq[String]] = (token(Space) ~> token(NotSpace, display)).* <~ SpaceClass.*
|
||||||
|
|
||||||
|
def flag[T](p: Parser[T]): Parser[Boolean] = (p ^^^ true) ?? false
|
||||||
|
|
||||||
def trimmed(p: Parser[String]) = p map { _.trim }
|
def trimmed(p: Parser[String]) = p map { _.trim }
|
||||||
def Uri(ex: Set[URI]) = mapOrFail(URIClass)( uri => new URI(uri)) examples(ex.map(_.toString))
|
def Uri(ex: Set[URI]) = mapOrFail(URIClass)( uri => new URI(uri)) examples(ex.map(_.toString))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue