summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-29 19:27:13 +0000
committerPaul Phillips <paulp@improving.org>2011-01-29 19:27:13 +0000
commitf89016a8736f7b09ea1dd74baa6c45bb39e47444 (patch)
tree332c043a83574c6c2e1e9788439dacadceafb6f9 /src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
parent80488e4218a0a72dec3ba727e6de276da87f1398 (diff)
downloadscala-f89016a8736f7b09ea1dd74baa6c45bb39e47444.tar.gz
scala-f89016a8736f7b09ea1dd74baa6c45bb39e47444.tar.bz2
scala-f89016a8736f7b09ea1dd74baa6c45bb39e47444.zip
Bringing lots more encapsulation to the repl.
interfaces from implementations and isolating jline better so it doesn't become an accidental dependency or have other unexpected effects. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala')
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala58
1 files changed, 32 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index 3f2003a2f7..148b80df12 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -264,7 +264,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
def completions(buf: String): List[String] =
topLevelFor(Parsed.dotted(buf + ".", buf.length + 1))
- def completer() = new JLineCompleterClass
+ def completer(): ScalaCompleter = new JLineTabCompletion
/** This gets a little bit hairy. It's no small feat delegating everything
* and also keeping track of exactly where the cursor is and where it's supposed
@@ -272,7 +272,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
* string in the list of completions, that means we are expanding a unique
* completion, so don't update the "last" buffer because it'll be wrong.
*/
- class JLineCompleterClass extends Instance with Completer {
+ class JLineTabCompletion extends ScalaCompleter {
// For recording the buffer on the last tab hit
private var lastBuf: String = ""
private var lastCursor: Int = -1
@@ -281,35 +281,43 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
def isConsecutiveTabs(buf: String, cursor: Int) =
cursor == lastCursor && buf == lastBuf
+ def sameHead(xs: List[String]) = {
+ if (xs.isEmpty || xs.head.length == 0) false
+ else {
+ val y :: ys = xs
+ val ch = y.head
+ ys forall (s => s.length > 0 && s.head == ch)
+ }
+ }
// Longest common prefix
- def commonPrefix(xs: List[String]) =
- if (xs.isEmpty) ""
- else xs.reduceLeft(_ zip _ takeWhile (x => x._1 == x._2) map (_._1) mkString)
+ def commonPrefix(xs: List[String]): String = {
+ if (sameHead(xs)) xs.head + commonPrefix(xs map (_.tail))
+ else ""
+ }
// This is jline's entry point for completion.
- override def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
- val buf = if (_buf == null) "" else _buf
+ override def complete(buf: String, cursor: Int): Candidates = {
verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0
DBG("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity))
// we don't try lower priority completions unless higher ones return no results.
- def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Int] = {
+ def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = {
completionFunction(p) match {
case Nil => None
case xs =>
- // modify in place and return the position
- xs foreach (candidates add _)
-
- // update the last buffer unless this is an alternatives list
- if (xs contains "") Some(p.cursor)
- else {
- val advance = commonPrefix(xs)
- lastCursor = p.position + advance.length
- lastBuf = (buf take p.position) + advance
-
- DBG("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(p, lastBuf, lastCursor, p.position))
- Some(p.position)
- }
+ Some(Candidates(
+ if (xs contains "") p.cursor
+ else {
+ // update the last buffer unless this is an alternatives list
+ val advance = commonPrefix(xs)
+ lastCursor = p.position + advance.length
+ lastBuf = (buf take p.position) + advance
+ DBG("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(
+ p, lastBuf, lastCursor, p.position))
+ p.position
+ },
+ xs)
+ )
}
}
@@ -332,14 +340,12 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
* compiler still throws some Errors it may not be.
*/
try {
- (lastResultCompletion orElse regularCompletion orElse fileCompletion) getOrElse cursor
+ (lastResultCompletion orElse regularCompletion orElse fileCompletion) getOrElse Candidates(cursor, Nil)
}
catch {
case ex: Exception =>
- DBG("Error: complete(%s, %s, _) provoked %s".format(_buf, cursor, ex))
- candidates add " "
- candidates add "<completion error>"
- cursor
+ DBG("Error: complete(%s, %s) provoked %s".format(buf, cursor, ex))
+ Candidates(cursor, List(" ", "<completion error>"))
}
}
}