diff --git a/util/complete/Parser.scala b/util/complete/Parser.scala index a23ae3f48..5f9086b58 100644 --- a/util/complete/Parser.scala +++ b/util/complete/Parser.scala @@ -277,6 +277,12 @@ trait ParserMain def unapply[A,B](t: (A,B)): Some[(A,B)] = Some(t) } + def parse[T](str: String, parser: Parser[T]): Either[String, T] = + Parser.result(parser, str).left.map { failures => + val (msgs,pos) = failures() + ProcessError(str, msgs, pos) + } + // intended to be temporary pending proper error feedback def result[T](p: Parser[T], s: String): Either[() => (Seq[String],Int), T] = { diff --git a/util/complete/ProcessError.scala b/util/complete/ProcessError.scala new file mode 100644 index 000000000..76ea2f71d --- /dev/null +++ b/util/complete/ProcessError.scala @@ -0,0 +1,30 @@ +package sbt.complete + +object ProcessError +{ + def apply(command: String, msgs: Seq[String], index: Int): String = + { + val (line, modIndex) = extractLine(command, index) + val point = pointerSpace(command, modIndex) + msgs.mkString("\n") + "\n" + line + "\n" + point + "^" + } + def extractLine(s: String, i: Int): (String, Int) = + { + val notNewline = (c: Char) => c != '\n' && c != '\r' + val left = takeRightWhile( s.substring(0, i) )( notNewline ) + val right = s substring i takeWhile notNewline + (left + right, left.length) + } + def takeRightWhile(s: String)(pred: Char => Boolean): String = + { + def loop(i: Int): String = + if(i < 0) + s + else if( pred(s(i)) ) + loop(i-1) + else + s.substring(i+1) + loop(s.length - 1) + } + def pointerSpace(s: String, i: Int): String = (s take i) map { case '\t' => '\t'; case _ => ' ' } mkString; +} \ No newline at end of file