diff options
Diffstat (limited to 'src/dotty/tools/dotc/repl/ammonite/Filter.scala')
-rw-r--r-- | src/dotty/tools/dotc/repl/ammonite/Filter.scala | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/repl/ammonite/Filter.scala b/src/dotty/tools/dotc/repl/ammonite/Filter.scala new file mode 100644 index 000000000..9d34bb0f2 --- /dev/null +++ b/src/dotty/tools/dotc/repl/ammonite/Filter.scala @@ -0,0 +1,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 +} |