summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/util/BashCompletion.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/util/BashCompletion.scala')
-rw-r--r--src/compiler/scala/tools/util/BashCompletion.scala132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/util/BashCompletion.scala b/src/compiler/scala/tools/util/BashCompletion.scala
new file mode 100644
index 0000000000..bb36326b7e
--- /dev/null
+++ b/src/compiler/scala/tools/util/BashCompletion.scala
@@ -0,0 +1,132 @@
+/* NSC -- new Scala compiler
+ * Copyright 2006-2010 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools
+package util
+
+import nsc.{ Global, Settings }
+import Settings._
+
+/** Examines Settings and generates a bash completion file
+ * containing both bells and whistles.
+ */
+object BashCompletion {
+ val completionTemplate = """
+# Bash Scala completion
+#
+# Add this file to /etc/bash_completion.d/ (or your local equivalent)
+# or place a line like this in your .bashrc or .profile:
+#
+# . /path/to/file/scala_completion.sh
+#
+# For more information, see:
+#
+# http://bash-completion.alioth.debian.org/
+#
+# This file is generated by running scala.tools.util.BashCompletion.
+#
+
+SCALA_PHASES="@@PHASES@@"
+SCALA_PHASE_SETTINGS=( @@PHASE_SETTINGS@@ )
+SCALA_OPTIONS="@@OPTIONS@@"
+SCALA_OPTIONS_EXPANDED="@@OPTIONS_EXPANDED@@"
+
+_scala_completion()
+{
+ local cur prev opts colonprefixes
+
+ COMPREPLY=()
+ opts=""
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ colonprefixes=${cur%"${cur##*:}"}
+
+ # special case escaping madness because bash treats : as a separator.
+ case "${cur}" in
+ -*:*)
+ precolon=$(echo "${cur}" | sed 's/:.*//g')
+
+ for p in ${SCALA_PHASE_SETTINGS[@]}; do
+ if [[ "${precolon}" == "${p}" ]] ; then
+ cur=$(echo "${cur}" | sed 's/.*://g') # cut cur down to postcolon part
+ opts=${SCALA_PHASES}
+ fi
+ done
+
+ if [ "${opts}" == "" ] ; then
+ opts=${SCALA_OPTIONS_EXPANDED}
+ fi
+ ;;
+ esac
+
+ if [ "${opts}" == "" ] ; then
+ opts=${SCALA_OPTIONS}
+ fi
+
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+
+ local i=${#COMPREPLY[*]}
+ while [ $((--i)) -ge 0 ]; do
+ COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"}
+ done
+
+ return 0
+}
+
+_scala_commands()
+{
+@@PROGRAMS@@
+}
+_scala_commands
+ """.trim
+
+ private lazy val settings = new Settings()
+
+ val phaseNames = "all" :: (new Global(settings) phaseNames)
+ val phaseSettings = settings.visibleSettings partialMap { case x: PhasesSetting => "\"" + x.name + "\"" }
+
+ def settingStrings(s: Setting, expanded: Boolean) = s match {
+ case x: ChoiceSetting => if (expanded) x.choices map (x.name + ":" + _) else List(x.name + ":")
+ case x: PhasesSetting => List(x.name + ":")
+ case x => List(x.name)
+ }
+
+ /** We embed one list which stops at : and another where all choice settings are expanded out
+ * to include the choices.
+ */
+ def settingNames = settings.visibleSettings.toList flatMap (x => settingStrings(x, false)) sorted
+ def settingNamesExpanded = settings.visibleSettings.toList flatMap (x => settingStrings(x, true)) sorted
+
+ def commandForName(name: String) = " complete -o default -F _scala_completion " + name + "\n"
+ def interpolate(template: String, what: (String, String)*) =
+ what.foldLeft(template) {
+ case (text, (key, value)) =>
+ val token = "@@" + key + "@@"
+
+ (text indexOf token) match {
+ case -1 => error("Token '%s' does not exist." format token)
+ case idx => (text take idx) + value + (text drop idx drop token.length)
+ }
+ }
+
+ def create(cmds: List[String]) = {
+ interpolate(completionTemplate,
+ "PROGRAMS" -> (cmds map commandForName mkString ""),
+ "OPTIONS" -> (settingNames mkString " "),
+ "OPTIONS_EXPANDED" -> (settingNamesExpanded mkString " "),
+ "PHASES" -> (phaseNames mkString " "),
+ "PHASE_SETTINGS" -> (phaseSettings mkString " ")
+ )
+ }
+
+ def main(args: Array[String]): Unit = {
+ val commands = if (args.isEmpty) List("fsc", "scala", "scalac", "scaladoc") else args.toList
+ val result = create(commands)
+ if (result contains "@@")
+ error("Some tokens were not replaced: text is " + result)
+
+ println(result)
+ }
+} \ No newline at end of file