mirror of https://github.com/sbt/sbt.git
clean up whitespace handling in commands. fixes #97
This commit is contained in:
parent
eb14e97485
commit
cbf7b82cdb
|
|
@ -50,8 +50,8 @@ object Command
|
|||
def single(name: String, briefHelp: (String, String), detail: String)(f: (State, String) => State): Command =
|
||||
single(name, Help(name, briefHelp, detail) )(f)
|
||||
def single(name: String, help: Help*)(f: (State, String) => State): Command =
|
||||
make(name, help : _*)( state => token(trimmed(any.+.string) map apply1(f, state)) )
|
||||
|
||||
make(name, help : _*)( state => token(trimmed(spacedAny(name)) map apply1(f, state)) )
|
||||
|
||||
def custom(parser: State => Parser[() => State], help: Seq[Help] = Nil): Command = new ArbitraryCommand(parser, help, AttributeMap.empty)
|
||||
def arb[T](parser: State => Parser[T], help: Help*)(effect: (State, T) => State): Command = custom(applyEffect(parser)(effect), help)
|
||||
|
||||
|
|
@ -130,6 +130,10 @@ object Command
|
|||
bs.map { b => (b, distance(a, b) ) } filter (_._2 <= maxDistance) sortBy(_._2) take(maxSuggestions) map(_._1)
|
||||
def distance(a: String, b: String): Int =
|
||||
EditDistance.levenshtein(a, b, insertCost = 1, deleteCost = 1, subCost = 2, transposeCost = 1, matchCost = -1, true)
|
||||
|
||||
def spacedAny(name: String): Parser[String] = spacedC(name, any)
|
||||
def spacedC(name: String, c: Parser[Char]): Parser[String] =
|
||||
( (c & opOrIDSpaced(name)) ~ c.+) map { case (f, rem) => (f +: rem).mkString }
|
||||
}
|
||||
|
||||
trait Help
|
||||
|
|
|
|||
|
|
@ -17,8 +17,12 @@ object Cross
|
|||
def switchParser(state: State): Parser[(String, String)] =
|
||||
{
|
||||
val knownVersions = crossVersions(state)
|
||||
token(Switch ~ Space) flatMap { _ => token(NotSpace.examples(knownVersions : _*)) ~ (token(Space ~> matched(state.combinedParser)) ?? "") }
|
||||
lazy val switchArgs = token(OptSpace ~> NotSpace.examples(knownVersions : _*)) ~ (token(Space ~> matched(state.combinedParser)) ?? "")
|
||||
lazy val nextSpaced = spacedFirst(Switch)
|
||||
token(Switch) flatMap { _ => switchArgs & nextSpaced }
|
||||
}
|
||||
def spacedFirst(name: String) = opOrIDSpaced(name) ~ any.+
|
||||
|
||||
lazy val switchVersion = Command.arb(requireSession(switchParser)) { case (state, (version, command)) =>
|
||||
val x = Project.extract(state)
|
||||
import x._
|
||||
|
|
@ -32,7 +36,7 @@ object Cross
|
|||
s.key.key == scalaVersion.key || s.key.key == scalaHome.key
|
||||
|
||||
def crossParser(state: State): Parser[String] =
|
||||
token(Cross ~ Space) flatMap { _ => token(matched(state.combinedParser)) }
|
||||
token(Cross <~ OptSpace) flatMap { _ => token(matched( state.combinedParser & spacedFirst(Cross) )) }
|
||||
|
||||
lazy val crossBuild = Command.arb(requireSession(crossParser)) { (state, command) =>
|
||||
val x = Project.extract(state)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ package sbt.complete
|
|||
// Some predefined parsers
|
||||
trait Parsers
|
||||
{
|
||||
lazy val any: Parser[Char] = charClass(_ => true)
|
||||
lazy val any: Parser[Char] = charClass(_ => true, "any character")
|
||||
|
||||
lazy val DigitSet = Set("0","1","2","3","4","5","6","7","8","9")
|
||||
lazy val Digit = charClass(_.isDigit, "digit") examples DigitSet
|
||||
|
|
@ -23,6 +23,14 @@ trait Parsers
|
|||
lazy val Op = OpChar.+.string
|
||||
lazy val OpOrID = ID | Op
|
||||
|
||||
def opOrIDSpaced(s: String): Parser[Char] =
|
||||
if(DefaultParsers.matches(ID, s))
|
||||
OpChar | SpaceClass
|
||||
else if(DefaultParsers.matches(Op, s))
|
||||
IDStart | SpaceClass
|
||||
else
|
||||
any
|
||||
|
||||
def isOpChar(c: Char) = !isDelimiter(c) && isOpType(getType(c))
|
||||
def isOpType(cat: Int) = cat match { case MATH_SYMBOL | OTHER_SYMBOL | DASH_PUNCTUATION | OTHER_PUNCTUATION | MODIFIER_SYMBOL | CURRENCY_SYMBOL => true; case _ => false }
|
||||
def isIDChar(c: Char) = c.isLetterOrDigit || c == '-' || c == '_'
|
||||
|
|
|
|||
Loading…
Reference in New Issue