diff options
Diffstat (limited to 'src/dotty/tools/dotc/repl/ammonite/filters/GUILikeFilters.scala')
-rw-r--r-- | src/dotty/tools/dotc/repl/ammonite/filters/GUILikeFilters.scala | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/src/dotty/tools/dotc/repl/ammonite/filters/GUILikeFilters.scala b/src/dotty/tools/dotc/repl/ammonite/filters/GUILikeFilters.scala deleted file mode 100644 index 69a9769c6..000000000 --- a/src/dotty/tools/dotc/repl/ammonite/filters/GUILikeFilters.scala +++ /dev/null @@ -1,170 +0,0 @@ -package dotty.tools -package dotc -package repl -package ammonite -package terminal -package filters - -import terminal.FilterTools._ -import terminal.LazyList.~: -import terminal.SpecialKeys._ -import terminal.DelegateFilter -import terminal._ - -/** - * Filters have hook into the various {Ctrl,Shift,Fn,Alt}x{Up,Down,Left,Right} - * combination keys, and make them behave similarly as they would on a normal - * GUI text editor: alt-{left, right} for word movement, hold-down-shift for - * text selection, etc. - */ -object GUILikeFilters { - case class SelectionFilter(indent: Int) extends DelegateFilter { - def identifier = "SelectionFilter" - var mark: Option[Int] = None - - def setMark(c: Int) = { - Debug("setMark\t" + mark + "\t->\t" + c) - if (mark == None) mark = Some(c) - } - - def doIndent( - b: Vector[Char], - c: Int, - rest: LazyList[Int], - slicer: Vector[Char] => Int - ) = { - - val markValue = mark.get - val (chunks, chunkStarts, chunkIndex) = FilterTools.findChunks(b, c) - val min = chunkStarts.lastIndexWhere(_ <= math.min(c, markValue)) - val max = chunkStarts.indexWhere(_ > math.max(c, markValue)) - val splitPoints = chunkStarts.slice(min, max) - val frags = (0 +: splitPoints :+ 99999).sliding(2).zipWithIndex - - var firstOffset = 0 - val broken = - for((Seq(l, r), i) <- frags) yield { - val slice = b.slice(l, r) - if (i == 0) slice - else { - val cut = slicer(slice) - - if (i == 1) firstOffset = cut - - if (cut < 0) slice.drop(-cut) - else Vector.fill(cut)(' ') ++ slice - } - } - val flattened = broken.flatten.toVector - val deeperOffset = flattened.length - b.length - - val (newMark, newC) = - if (mark.get > c) (mark.get + deeperOffset, c + firstOffset) - else (mark.get + firstOffset, c + deeperOffset) - - mark = Some(newMark) - TS(rest, flattened, newC) - } - - def filter = Filter.merge( - - Case(ShiftUp) {(b, c, m) => setMark(c); BasicFilters.moveUp(b, c, m.width)}, - Case(ShiftDown) {(b, c, m) => setMark(c); BasicFilters.moveDown(b, c, m.width)}, - Case(ShiftRight) {(b, c, m) => setMark(c); (b, c + 1)}, - Case(ShiftLeft) {(b, c, m) => setMark(c); (b, c - 1)}, - Case(AltShiftUp) {(b, c, m) => setMark(c); BasicFilters.moveUp(b, c, m.width)}, - Case(AltShiftDown) {(b, c, m) => setMark(c); BasicFilters.moveDown(b, c, m.width)}, - Case(AltShiftRight) {(b, c, m) => setMark(c); wordRight(b, c)}, - Case(AltShiftLeft) {(b, c, m) => setMark(c); wordLeft(b, c)}, - Case(FnShiftRight) {(b, c, m) => setMark(c); BasicFilters.moveEnd(b, c, m.width)}, - Case(FnShiftLeft) {(b, c, m) => setMark(c); BasicFilters.moveStart(b, c, m.width)}, - Filter("fnOtherFilter") { - case TS(27 ~: 91 ~: 90 ~: rest, b, c, _) if mark.isDefined => - doIndent(b, c, rest, - slice => -math.min(slice.iterator.takeWhile(_ == ' ').size, indent) - ) - - case TS(9 ~: rest, b, c, _) if mark.isDefined => // Tab - doIndent(b, c, rest, - slice => indent - ) - - // Intercept every other character. - case TS(char ~: inputs, buffer, cursor, _) if mark.isDefined => - // If it's a special command, just cancel the current selection. - if (char.toChar.isControl && - char != 127 /*backspace*/ && - char != 13 /*enter*/ && - char != 10 /*enter*/) { - mark = None - TS(char ~: inputs, buffer, cursor) - } else { - // If it's a printable character, delete the current - // selection and write the printable character. - val Seq(min, max) = Seq(mark.get, cursor).sorted - mark = None - val newBuffer = buffer.take(min) ++ buffer.drop(max) - val newInputs = - if (char == 127) inputs - else char ~: inputs - TS(newInputs, newBuffer, min) - } - } - ) - } - - object SelectionFilter { - def mangleBuffer( - selectionFilter: SelectionFilter, - string: Ansi.Str, - cursor: Int, - startColor: Ansi.Attr - ) = { - selectionFilter.mark match { - case Some(mark) if mark != cursor => - val Seq(min, max) = Seq(cursor, mark).sorted - val displayOffset = if (cursor < mark) 0 else -1 - val newStr = string.overlay(startColor, min, max) - (newStr, displayOffset) - case _ => (string, 0) - } - } - } - - val fnFilter = Filter.merge( - Case(FnUp)((b, c, m) => (b, c - 9999)), - Case(FnDown)((b, c, m) => (b, c + 9999)), - Case(FnRight)((b, c, m) => BasicFilters.moveEnd(b, c, m.width)), - Case(FnLeft)((b, c, m) => BasicFilters.moveStart(b, c, m.width)) - ) - val altFilter = Filter.merge( - Case(AltUp) {(b, c, m) => BasicFilters.moveUp(b, c, m.width)}, - Case(AltDown) {(b, c, m) => BasicFilters.moveDown(b, c, m.width)}, - Case(AltRight) {(b, c, m) => wordRight(b, c)}, - Case(AltLeft) {(b, c, m) => wordLeft(b, c)} - ) - - val fnAltFilter = Filter.merge( - Case(FnAltUp) {(b, c, m) => (b, c)}, - Case(FnAltDown) {(b, c, m) => (b, c)}, - Case(FnAltRight) {(b, c, m) => (b, c)}, - Case(FnAltLeft) {(b, c, m) => (b, c)} - ) - val fnAltShiftFilter = Filter.merge( - Case(FnAltShiftRight) {(b, c, m) => (b, c)}, - Case(FnAltShiftLeft) {(b, c, m) => (b, c)} - ) - - - def consumeWord(b: Vector[Char], c: Int, delta: Int, offset: Int) = { - var current = c - while(b.isDefinedAt(current) && !b(current).isLetterOrDigit) current += delta - while(b.isDefinedAt(current) && b(current).isLetterOrDigit) current += delta - current + offset - } - - // c -1 to move at least one character! Otherwise you get stuck at the start of - // a word. - def wordLeft(b: Vector[Char], c: Int) = b -> consumeWord(b, c - 1, -1, 1) - def wordRight(b: Vector[Char], c: Int) = b -> consumeWord(b, c, 1, 0) -} |