diff options
Diffstat (limited to 'src/dotty/tools/dotc/repl/ammonite/FilterTools.scala')
-rw-r--r-- | src/dotty/tools/dotc/repl/ammonite/FilterTools.scala | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/repl/ammonite/FilterTools.scala b/src/dotty/tools/dotc/repl/ammonite/FilterTools.scala new file mode 100644 index 000000000..c18b6a927 --- /dev/null +++ b/src/dotty/tools/dotc/repl/ammonite/FilterTools.scala @@ -0,0 +1,80 @@ +package dotty.tools +package dotc +package repl +package ammonite.terminal + +/** + * A collection of helpers that to simpify the common case of building filters + */ +object FilterTools { + val ansiRegex = "\u001B\\[[;\\d]*." + + def offsetIndex(buffer: Vector[Char], in: Int) = { + var splitIndex = 0 + var length = 0 + + while(length < in) { + ansiRegex.r.findPrefixOf(buffer.drop(splitIndex)) match { + case None => + splitIndex += 1 + length += 1 + case Some(s) => + splitIndex += s.length + } + } + splitIndex + } + + /** + * Shorthand to construct a filter in the common case where you're + * switching on the prefix of the input stream and want to run some + * transformation on the buffer/cursor + */ + def Case(s: String) + (f: (Vector[Char], Int, TermInfo) => (Vector[Char], Int)) = new Filter { + val op = new PartialFunction[TermInfo, TermAction] { + def isDefinedAt(x: TermInfo) = { + + def rec(i: Int, c: LazyList[Int]): Boolean = { + if (i >= s.length) true + else if (c.head == s(i)) rec(i + 1, c.tail) + else false + } + rec(0, x.ts.inputs) + } + + def apply(v1: TermInfo) = { + val (buffer1, cursor1) = f(v1.ts.buffer, v1.ts.cursor, v1) + TermState( + v1.ts.inputs.dropPrefix(s.map(_.toInt)).get, + buffer1, + cursor1 + ) + } + + }.lift + def identifier = "Case" + } + + /** Shorthand for pattern matching on [[TermState]] */ + val TS = TermState + + def findChunks(b: Vector[Char], c: Int) = { + val chunks = Terminal.splitBuffer(b) + // The index of the first character in each chunk + val chunkStarts = chunks.inits.map(x => x.length + x.sum).toStream.reverse + // Index of the current chunk that contains the cursor + val chunkIndex = chunkStarts.indexWhere(_ > c) match { + case -1 => chunks.length-1 + case x => x - 1 + } + (chunks, chunkStarts, chunkIndex) + } + + def firstRow(cursor: Int, buffer: Vector[Char], width: Int) = + cursor < width && (buffer.indexOf('\n') >= cursor || buffer.indexOf('\n') == -1) + + def lastRow(cursor: Int, buffer: Vector[Char], width: Int) = + (buffer.length - cursor) < width && + (buffer.lastIndexOf('\n') < cursor || buffer.lastIndexOf('\n') == -1) +} |