summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interpreter/CompletionAware.scala
blob: c60f402d3da670735ee4b2ccc33e2d4be8af2877 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* NSC -- new Scala compiler
 * Copyright 2005-2010 LAMP/EPFL
 * @author Paul Phillips
 */

package scala.tools.nsc
package interpreter

import scala.util.NameTransformer

/** An interface for objects which are aware of tab completion and
 *  will supply their own candidates and resolve their own paths.
 */
trait CompletionAware {
  /** The complete list of unqualified Strings to which this
   *  object will complete.
   */
  def completions(): List[String]
  def completions(start: String): List[String] = completions filter (_ startsWith start)

  /** Default filter to apply to completions.
   */
  def filterNotFunction(s: String): Boolean = ReflectionCompletion shouldHide s

  /** Default sort.
   */
  def sortFunction(s1: String, s2: String): Boolean = s1 < s2

  /** Default map.
   */
  def mapFunction(s: String): String = s

  /** The next completor in the chain.
   */
  def follow(id: String): Option[CompletionAware] = None

  /** What to return if this completion is given as a command.  It
   *  returns None by default, which means to allow the repl to interpret
   *  the line normally.  Returning Some(_) means the line will never
   *  reach the scala interpreter.
   */
  def execute(id: String): Option[Any] = None

  /** Given string 'buf', return a list of all the strings
   *  to which it can complete.  This may involve delegating
   *  to other CompletionAware objects.
   */
  def completionsFor(buf: String): List[String] = {
    val parsed = new Parsed(buf)
    import parsed._

    (
      if (isEmpty) completions()
      else if (isFirstCharDot) Nil    // XXX for now
      else if (isUnqualified && !isLastCharDot) completions(buf)
      else follow(hd) match {
        case Some(next) => next completionsFor remainder
        case _          => Nil
      }
    ) filterNot filterNotFunction map mapFunction sortWith (sortFunction _)
  }

  def executionFor(buf: String): Option[Any] = {
    val parsed = new Parsed(buf)
    import parsed._

    if (isUnqualified && !isLastCharDot && (completions contains buf)) execute(buf)
    else if (!isQualified) None
    else follow(hd) match {
      case Some(next) => next executionFor remainder
      case _          => None
    }
  }
}

object CompletionAware {
  def unapply(that: Any): Option[CompletionAware] = that match {
    case x: CompletionAware => Some((x))
    case _                  => None
  }

  def apply(xs: List[String]) = new CompletionAware { val completions = xs }
}