summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-02-24 23:17:30 +0000
committerPaul Phillips <paulp@improving.org>2010-02-24 23:17:30 +0000
commit43b68ece9773a551ce8044ad25b7ad35a70545af (patch)
treed244822bc11ad8665f2ecea018de47012d75f244 /src
parentcd5525a9898da03241f978eb3c7fda633d0d0536 (diff)
downloadscala-43b68ece9773a551ce8044ad25b7ad35a70545af.tar.gz
scala-43b68ece9773a551ce8044ad25b7ad35a70545af.tar.bz2
scala-43b68ece9773a551ce8044ad25b7ad35a70545af.zip
Bash completion! The file is automatically crea...
Bash completion! The file is automatically created as part of the build process and placed in $pack/etc. % scala -Xprint -Xprint-icode -Xprint-pos -Xprint-types -Xprint: % scala -Xprint: all flatten mixin tailcalls cleanup icode namer terminal closelim inliner packageobjects typer constructors jvm parser uncurry dce lambdalift pickler erasure lazyvals refchecks explicitouter liftcode superaccessors % scala -g: line none notailcalls source vars % scala -Ystruct-dispatch: invoke-dynamic mono-cache no-cache poly-cache Review by community.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala11
-rw-r--r--src/compiler/scala/tools/util/BashCompletion.scala132
2 files changed, 139 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 0590797e53..4e14ec6fb1 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -549,13 +549,16 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
/* The set of phase objects that is the basis for the compiler phase chain */
protected val phasesSet : HashSet[SubComponent] = new HashSet[SubComponent]
- /** A description of the phases that will run */
- def phaseDescriptions: String = {
+ /** The names of the phases. */
+ lazy val phaseNames = {
new Run // force some initialization
-
- phaseDescriptors map (_.phaseName) mkString "\n" // todo: + " - " + phase.description
+ phaseDescriptors map (_.phaseName)
}
+ /** A description of the phases that will run */
+ def phaseDescriptions: String =
+ phaseNames mkString "\n" // todo: + " - " + phase.description
+
// ----------- Runs ---------------------------------------
private var curRun: Run = null
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