mirror of https://github.com/sbt/sbt.git
clean up token completions and make providing a general completion function easier
This commit is contained in:
parent
fa97cc0d22
commit
e5ffceaef8
|
|
@ -346,12 +346,39 @@ trait ParserMain
|
|||
success(seen.mkString)
|
||||
}
|
||||
|
||||
def token[T](t: Parser[T]): Parser[T] = token(t, "", true, const(false))
|
||||
def token[T](t: Parser[T], hide: Int => Boolean): Parser[T] = token(t, "", true, hide)
|
||||
def token[T](t: Parser[T], description: String): Parser[T] = token(t, description, false, const(false))
|
||||
/** Establishes delegate parser `t` as a single token of tab completion.
|
||||
* When tab completion of part of this token is requested, the completions provided by the delegate `t` or a later derivative are appended to
|
||||
* the prefix String already seen by this parser. */
|
||||
def token[T](t: Parser[T]): Parser[T] = token(t, TokenCompletions.default)
|
||||
|
||||
/** Establishes delegate parser `t` as a single token of tab completion.
|
||||
* When tab completion of part of this token is requested, no completions are returned if `hide` returns true for the current tab completion level.
|
||||
* Otherwise, the completions provided by the delegate `t` or a later derivative are appended to the prefix String already seen by this parser.*/
|
||||
def token[T](t: Parser[T], hide: Int => Boolean): Parser[T] = token(t, TokenCompletions.default.hideWhen(hide))
|
||||
|
||||
/** Establishes delegate parser `t` as a single token of tab completion.
|
||||
* When tab completion of part of this token is requested, `description` is displayed for suggestions and no completions are ever performed. */
|
||||
def token[T](t: Parser[T], description: String): Parser[T] = token(t, TokenCompletions.displayOnly(description))
|
||||
|
||||
/** Establishes delegate parser `t` as a single token of tab completion.
|
||||
* When tab completion of part of this token is requested, `display` is used as the printed suggestion, but the completions from the delegate
|
||||
* parser `t` are used to complete if unambiguous. */
|
||||
def tokenDisplay[T](t: Parser[T], display: String): Parser[T] =
|
||||
token(t, TokenCompletions.overrideDisplay(display))
|
||||
|
||||
def token[T](t: Parser[T], complete: TokenCompletions): Parser[T] =
|
||||
mkToken(t, "", complete)
|
||||
|
||||
@deprecated("Use a different `token` overload.", "0.12.1")
|
||||
def token[T](t: Parser[T], seen: String, track: Boolean, hide: Int => Boolean): Parser[T] =
|
||||
{
|
||||
val base = if(track) TokenCompletions.default else TokenCompletions.displayOnly(seen)
|
||||
token(t, base.hideWhen(hide))
|
||||
}
|
||||
|
||||
private[sbt] def mkToken[T](t: Parser[T], seen: String, complete: TokenCompletions): Parser[T] =
|
||||
if(t.valid && !t.isTokenStart)
|
||||
if(t.result.isEmpty) new TokenStart(t, seen, track, hide) else t
|
||||
if(t.result.isEmpty) new TokenStart(t, seen, complete) else t
|
||||
else
|
||||
t
|
||||
|
||||
|
|
@ -512,23 +539,17 @@ private final class MatchedString(delegate: Parser[_], seenV: Vector[Char], part
|
|||
override def isTokenStart = delegate.isTokenStart
|
||||
override def toString = "matched(" + partial + ", " + seen + ", " + delegate + ")"
|
||||
}
|
||||
private final class TokenStart[T](delegate: Parser[T], seen: String, track: Boolean, hide: Int => Boolean) extends ValidParser[T]
|
||||
private final class TokenStart[T](delegate: Parser[T], seen: String, complete: TokenCompletions) extends ValidParser[T]
|
||||
{
|
||||
def derive(c: Char) = token( delegate derive c, if(track) seen + c else seen, track, hide)
|
||||
def completions(level: Int) =
|
||||
if(hide(level)) Completions.nil
|
||||
else if(track)
|
||||
{
|
||||
val dcs = delegate.completions(level)
|
||||
Completions( for(c <- dcs.get) yield Completion.token(seen, c.append) )
|
||||
}
|
||||
else
|
||||
Completions.single(Completion.displayStrict(seen))
|
||||
|
||||
def derive(c: Char) = mkToken( delegate derive c, seen + c, complete)
|
||||
def completions(level: Int) = complete match {
|
||||
case dc: TokenCompletions.Delegating => dc.completions(seen, level, delegate.completions(level))
|
||||
case fc: TokenCompletions.Fixed => fc.completions(seen, level)
|
||||
}
|
||||
def result = delegate.result
|
||||
def resultEmpty = delegate.resultEmpty
|
||||
override def isTokenStart = true
|
||||
override def toString = "token('" + seen + "', " + track + ", " + delegate + ")"
|
||||
override def toString = "token('" + complete + ", " + delegate + ")"
|
||||
}
|
||||
private final class And[T](a: Parser[T], b: Parser[_]) extends ValidParser[T]
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package sbt.complete
|
||||
|
||||
import Completion.{displayStrict, token => ctoken, tokenDisplay}
|
||||
|
||||
sealed trait TokenCompletions {
|
||||
def hideWhen(f: Int => Boolean): TokenCompletions
|
||||
}
|
||||
object TokenCompletions
|
||||
{
|
||||
private[sbt] abstract class Delegating extends TokenCompletions { outer =>
|
||||
def completions(seen: String, level: Int, delegate: Completions): Completions
|
||||
final def hideWhen(hide: Int => Boolean): TokenCompletions = new Delegating {
|
||||
def completions(seen: String, level: Int, delegate: Completions): Completions =
|
||||
if(hide(level)) Completions.nil else outer.completions(seen, level, delegate)
|
||||
}
|
||||
}
|
||||
private[sbt] abstract class Fixed extends TokenCompletions { outer =>
|
||||
def completions(seen: String, level: Int): Completions
|
||||
final def hideWhen(hide: Int => Boolean): TokenCompletions = new Fixed {
|
||||
def completions(seen: String, level: Int) =
|
||||
if(hide(level)) Completions.nil else outer.completions(seen, level)
|
||||
}
|
||||
}
|
||||
|
||||
val default: TokenCompletions = mapDelegateCompletions((seen,level,c) => ctoken(seen, c.append))
|
||||
|
||||
def displayOnly(msg: String): TokenCompletions = new Fixed {
|
||||
def completions(seen: String, level: Int) = Completions.single(displayStrict(msg))
|
||||
}
|
||||
def overrideDisplay(msg: String): TokenCompletions = mapDelegateCompletions((seen,level,c) => tokenDisplay(display = msg, append = c.append))
|
||||
|
||||
def fixed(f: (String, Int) => Completions): TokenCompletions = new Fixed {
|
||||
def completions(seen: String, level: Int) = f(seen, level)
|
||||
}
|
||||
def mapDelegateCompletions(f: (String, Int, Completion) => Completion): TokenCompletions = new Delegating {
|
||||
def completions(seen: String, level: Int, delegate: Completions) = Completions( delegate.get.map(c => f(seen, level, c)) )
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue