diff --git a/util/complete/History.scala b/util/complete/History.scala index e792454f7..9c36f2605 100644 --- a/util/complete/History.scala +++ b/util/complete/History.scala @@ -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) } diff --git a/util/complete/HistoryCommands.scala b/util/complete/HistoryCommands.scala index 16a359f9a..906aa328a 100644 --- a/util/complete/HistoryCommands.scala +++ b/util/complete/HistoryCommands.scala @@ -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, "") + 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, "") 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 } \ No newline at end of file diff --git a/util/complete/Parsers.scala b/util/complete/Parsers.scala index 78cce0271..096614ad9 100644 --- a/util/complete/Parsers.scala +++ b/util/complete/Parsers.scala @@ -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)) }