Skip to content

Commit

Permalink
Merge branch 'master' of github.com:lihaoyi/Ammonite
Browse files Browse the repository at this point in the history
  • Loading branch information
Li Haoyi committed Aug 12, 2015
2 parents 5a5f10a + 7a5198b commit d2b4e2b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 10 deletions.
19 changes: 17 additions & 2 deletions repl/src/main/scala/ammonite/repl/Repl.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ammonite.repl

import java.io._
import ammonite.Constants
import ammonite.repl.Util.IvyMap
import ammonite.repl.frontend._
import acyclic.file
Expand Down Expand Up @@ -62,8 +63,22 @@ class Repl(input: InputStream,
out
}

def ammoniteVersion: String =
Constants.version

def scalaVersion: String =
scala.util.Properties.versionString

def javaVersion: String =
System.getProperty("java.version")

def printBanner(): Unit = {
printer.println(s"Welcome to the Ammonite Repl $ammoniteVersion")
printer.println(s"(Scala $scalaVersion Java $javaVersion)")
}

def run() = {
printBanner()
@tailrec def loop(): Unit = {
val res = action()
res match{
Expand Down Expand Up @@ -114,7 +129,7 @@ object Repl{
def defaultAmmoniteHome = Path(System.getProperty("user.home"))/".ammonite"
def main(args: Array[String]) = {
val parser = new scopt.OptionParser[Config]("ammonite") {
head("ammonite", ammonite.Constants.version)
head("ammonite", Constants.version)
opt[String]('p', "predef")
.action((x, c) => c.copy(predef = x))
.text("Any commands you want to execute at the start of the REPL session")
Expand Down Expand Up @@ -142,7 +157,7 @@ object Repl{
)
file match{
case None =>
println("Loading Ammonite Repl...")
println("Loading...")
repl.run()
case Some(path) =>
repl.interp.replApi.load.module(path)
Expand Down
16 changes: 14 additions & 2 deletions terminal/src/main/scala/ammonite/terminal/BasicFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ object BasicFilters {
navFilter orElse
exitFilter orElse
enterFilter orElse
clearFilter orElse
loggingFilter orElse
typingFilter
}
Expand Down Expand Up @@ -73,9 +74,20 @@ object BasicFilters {
case TS(13 ~: 10 ~:rest, b, c) => // Enter
Result(b.mkString)
}

lazy val exitFilter: TermCore.Filter = {
case TS(Ctrl('c') ~: rest, b, c) => Result("")
case TS(Ctrl('d') ~: rest, b, c) => Exit
case TS(Ctrl('c') ~: rest, b, c) =>
Result("")
case TS(Ctrl('d') ~: rest, b, c) =>
// only exit if the line is empty, otherwise, behave like
// "delete" (i.e. delete one char to the right)
if (b.isEmpty) Exit else {
val (first, last) = b.splitAt(c)
TS(rest, first ++ last.drop(1), c)
}
}
lazy val clearFilter: TermCore.Filter = {
case TS(Ctrl('l') ~: rest, b, c) => ClearScreen(TS(rest, b, c))
}

def moveStart(b: Vector[Char],
Expand Down
27 changes: 21 additions & 6 deletions terminal/src/main/scala/ammonite/terminal/ReadlineFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,38 @@ object ReadlineFilters {
def lastRow(cursor: Int, buffer: Vector[Char], width: Int) = {
(buffer.length - cursor) < width && (buffer.lastIndexOf('\n') < cursor || buffer.lastIndexOf('\n') == -1)
}

case class HistoryFilter(history: () => Seq[String]) extends TermCore.DelegateFilter{
var index = -1
var currentHistory = Vector[Char]()

def swapInHistory(b: Vector[Char], newIndex: Int, rest: LazyList[Int], c: Int) = {
def swapInHistory(b: Vector[Char], newIndex: Int, rest: LazyList[Int]): TermState = {
if (index == -1 && newIndex != -1) currentHistory = b

index = newIndex
val h = if (index == -1) currentHistory else history()(index).toVector
TS(rest, h, h.length)
}

if (index == -1) TS(rest, currentHistory, c)
else TS(rest, history()(index).toVector, c)
def constrainIndex(n: Int): Int = {
val max = history().length - 1
if (n < -1) -1 else if (max < n) max else n
}

def previousHistory(b: Vector[Char], rest: LazyList[Int], c: Int): TermState =
swapInHistory(b, constrainIndex(index + 1), rest)

def nextHistory(b: Vector[Char], rest: LazyList[Int], c: Int): TermState =
swapInHistory(b, constrainIndex(index - 1), rest)

def filter = {
case TermInfo(TS(p"\u001b[A$rest", b, c), w) if firstRow(c, b, w) =>
swapInHistory(b, (index + 1) min (history().length - 1), rest, 99999)
previousHistory(b, rest, c)
case TermInfo(TS(p"\u0010$rest", b, c), w) if lastRow(c, b, w) =>
previousHistory(b, rest, c)
case TermInfo(TS(p"\u001b[B$rest", b, c), w) if lastRow(c, b, w) =>
swapInHistory(b, (index - 1) max -1, rest, 0)
nextHistory(b, rest, c)
case TermInfo(TS(p"\u000e$rest", b, c), w) if firstRow(c, b, w) =>
nextHistory(b, rest, c)
}
}
}
5 changes: 5 additions & 0 deletions terminal/src/main/scala/ammonite/terminal/TermCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ object TermCore {
writer.write(13)
writer.flush()
Some(s)
case ClearScreen(ts) =>
ansi.clearScreen(2)
ansi.moveTo(0, 0)
readChar(ts, ups)
case Exit =>
None
}
Expand Down Expand Up @@ -234,5 +238,6 @@ object TermState{
}

}
case class ClearScreen(ts: TermState) extends TermAction
case object Exit extends TermAction
case class Result(s: String) extends TermAction

0 comments on commit d2b4e2b

Please sign in to comment.