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 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
@ -41,7 +42,7 @@ final class History private(lines: IndexedSeq[String], error: String => Unit) ex
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] =
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 printHelp(): Unit =
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]] =
if(s.isEmpty)
{
printHelp()
Some(Nil)
}
else
{
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
import DefaultParsers._
val MaxLines = 500
lazy val num = token(NatBasic, "<integer>")
lazy val last = Last ^^^ { execute(_ !!) }
lazy val list = ListCommands ~> (num ?? Int.MaxValue) map { show =>
(h: History) => { printHistory(h, MaxLines, show); Some(Nil) }
}
/*
import parse.{Parser,Parsers}
import Parser._
import Parsers._
val historyParser: Parser[complete.History => Option[String]] =
{
Start ~> Specific)
lazy val execStr = flag('?') ~ token(any.+.string, "<string>") map { case (contains, str) =>
execute(h => if(contains) h !? str else h ! str)
}
!! Execute the last command again
!: Show all previous commands
!:n Show the last n commands
!n Execute the command with index n, as shown by the !: command
!-n Execute the nth command before this one
!string Execute the most recent command starting with 'string'
!?string*/
lazy val execInt = flag('-') ~ num map { case (neg, value) =>
execute(h => if(neg) h !- value else h ! value)
}
lazy val help = success( (h: History) => { printHelp(); Some(Nil) } )
def execute(f: History => Option[String]): History => Option[List[String]] = (h: History) =>
{
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 flag[T](p: Parser[T]): Parser[Boolean] = (p ^^^ true) ?? false
def trimmed(p: Parser[String]) = p map { _.trim }
def Uri(ex: Set[URI]) = mapOrFail(URIClass)( uri => new URI(uri)) examples(ex.map(_.toString))
}