blob: 9d34bb0f234b14400051da261df6bcfc765d59a8 (
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
|
package dotty.tools
package dotc
package repl
package ammonite.terminal
object Filter {
def apply(id: String)(f: PartialFunction[TermInfo, TermAction]): Filter =
new Filter {
val op = f.lift
def identifier = id
}
def wrap(id: String)(f: TermInfo => Option[TermAction]): Filter =
new Filter {
val op = f
def identifier = id
}
/** Merges multiple [[Filter]]s into one. */
def merge(pfs: Filter*) = new Filter {
val op = (v1: TermInfo) => pfs.iterator.map(_.op(v1)).find(_.isDefined).flatten
def identifier = pfs.iterator.map(_.identifier).mkString(":")
}
val empty = Filter.merge()
}
/**
* The way you configure your terminal behavior; a trivial wrapper around a
* function, though you should provide a good `.toString` method to make
* debugging easier. The [[TermInfo]] and [[TermAction]] types are its
* interface to the terminal.
*
* [[Filter]]s are composed sequentially: if a filter returns `None` the next
* filter is tried, while if a filter returns `Some` that ends the cascade.
* While your `op` function interacts with the terminal purely through
* immutable case classes, the Filter itself is free to maintain its own state
* and mutate it whenever, even when returning `None` to continue the cascade.
*/
trait Filter {
val op: TermInfo => Option[TermAction]
/**
* the `.toString` of this object, except by making it separate we force
* the implementer to provide something and stop them from accidentally
* leaving it as the meaningless default.
*/
def identifier: String
override def toString = identifier
}
/**
* A filter as an abstract class, letting you provide a [[filter]] instead of
* an `op`, automatically providing a good `.toString` for debugging, and
* providing a reasonable "place" inside the inheriting class/object to put
* state or helpers or other logic associated with the filter.
*/
abstract class DelegateFilter() extends Filter {
def filter: Filter
val op = filter.op
}
|