summaryrefslogtreecommitdiff
path: root/project/ParserUtil.scala
diff options
context:
space:
mode:
authorSeth Tisue <seth@tisue.net>2016-02-09 17:18:03 -0800
committerSeth Tisue <seth@tisue.net>2016-02-09 17:18:03 -0800
commit8f8f81b72ef07140952aeb76120bd032e35cc918 (patch)
tree444dc8b428df44195bc84ac22bbb7e1d88996d64 /project/ParserUtil.scala
parentef4ed496c59e4b54266aaf20db917fb41bb9f1e4 (diff)
parentdb0577c840425e699197c409b09674d5ce2039ac (diff)
downloadscala-8f8f81b72ef07140952aeb76120bd032e35cc918.tar.gz
scala-8f8f81b72ef07140952aeb76120bd032e35cc918.tar.bz2
scala-8f8f81b72ef07140952aeb76120bd032e35cc918.zip
Merge pull request #4950 from retronym/topic/sbt-tweaks-3
SBT build improvements
Diffstat (limited to 'project/ParserUtil.scala')
-rw-r--r--project/ParserUtil.scala54
1 files changed, 54 insertions, 0 deletions
diff --git a/project/ParserUtil.scala b/project/ParserUtil.scala
new file mode 100644
index 0000000000..f6658b146b
--- /dev/null
+++ b/project/ParserUtil.scala
@@ -0,0 +1,54 @@
+import sbt._
+import sbt.complete.Parser._
+import sbt.complete.Parsers._
+import sbt.complete._
+
+object ParserUtil {
+ def notStartingWith(parser: Parser[String], c: Char): Parser[String] = parser & not(c ~> any.*, "value cannot start with " + c + ".")
+ def concat(p: Parser[(String, String)]): Parser[String] = {
+ p.map(x => x._1 + x._2)
+ }
+
+ def EitherOr(a: Parser[String], b: Parser[String]): Parser[String] = {
+ a.flatMap[String] {
+ case "" => b
+ case x: String =>
+ concat(Space.string ~ b).map[String]((s: String) => x + s)
+ }
+ }
+ def Opt(a: Parser[String]) = a.?.map(_.getOrElse(""))
+
+ val StringBasicNotStartingWithDash = notStartingWith(StringBasic, '-')
+ val IsDirectoryFilter = new SimpleFileFilter(_.isDirectory)
+ val JarOrDirectoryParser = FileParser(GlobFilter("*.jar") || IsDirectoryFilter)
+ def FileParser(filter: FileFilter, dirFilter: FileFilter = AllPassFilter, base: File = file(".")) = {
+ def matching(prefix: String): List[String] = {
+ val preFile = file(prefix)
+ val cwd = base
+ val parent = Option(preFile.getParentFile).getOrElse(cwd)
+ if (preFile.exists) {
+ if (preFile.isDirectory) {
+ preFile.*(IsDirectoryFilter.&&(dirFilter) || filter).get.map(_.getPath).toList
+ } else {
+ List(preFile).filter(filter.accept).map(_.getPath)
+ }
+ }
+ else if (parent != null) {
+ def ensureSuffix(s: String, suffix: String) = if (s.endsWith(suffix)) s else s + suffix
+ def pathOf(f: File): String = if (f.isDirectory && !filter.accept(f)) ensureSuffix(f.getPath, "/") else f.getPath
+ parent.*(GlobFilter(preFile.name + "*") && ((IsDirectoryFilter && dirFilter) || filter)).get.map(x => pathOf(if (parent == cwd) x.relativeTo(cwd).get else x)).toList
+ } else Nil
+ }
+ def displayPath = Completions.single(Completion.displayOnly("<path>"))
+ token(StringBasic, TokenCompletions.fixed((seen, level) => if (seen.isEmpty) displayPath else matching(seen) match {
+ case Nil => displayPath
+ case x :: Nil =>
+ if (filter.accept(file(x)))
+ Completions.strict(Set(Completion.tokenDisplay(x.stripPrefix(seen), x)))
+ else
+ Completions.strict(Set(Completion.suggestion(x.stripPrefix(seen))))
+ case xs =>
+ Completions.strict(xs.map(x => Completion.tokenDisplay(x.stripPrefix(seen), x)).toSet)
+ })).filter(!_.startsWith("-"), x => x)
+ }
+} \ No newline at end of file