reintegrate history commands, add proper parsing for recursive commands

This commit is contained in:
Mark Harrah 2011-03-11 16:52:44 -05:00
parent 1f2c066639
commit 309bc5caeb
3 changed files with 33 additions and 59 deletions

View File

@ -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) }

View File

@ -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
} }

View File

@ -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))
} }