summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-30 02:45:31 +0000
committerPaul Phillips <paulp@improving.org>2011-01-30 02:45:31 +0000
commit3ef8ef6606a5919deb9824fbae37a28a15999322 (patch)
tree3272ba1a232cd7703e3b5b4cc5ba30d737567350
parent42eee5f32569f40e4f28992ee304fff2df4bd67b (diff)
downloadscala-3ef8ef6606a5919deb9824fbae37a28a15999322.tar.gz
scala-3ef8ef6606a5919deb9824fbae37a28a15999322.tar.bz2
scala-3ef8ef6606a5919deb9824fbae37a28a15999322.zip
Added a :keybindings command to the repl which ...
Added a :keybindings command to the repl which shows what each ctrl- key does. Thanks to mark harrah for the patch even though I wrote it afresh. Would be interested to know if it outputs anything remotely sensible on platforms which aren't OSX. Closes #3245, no review.
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala24
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/KeyBinding.scala39
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala1
5 files changed, 64 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 8e1f883b91..03ce7b182b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -193,6 +193,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
NoArgs("help", "print this help message", printHelp),
VarArgs("history", "show the history (optional arg: lines to show)", printHistory),
LineArg("h?", "search the history", searchHistory),
+ LineArg("keybindings", "show how ctrl-[A-Z] and other keys are bound", keybindingsCommand),
OneArg("load", "load and interpret a Scala file", load),
NoArgs("power", "enable power user mode", powerCmd),
NoArgs("quit", "exit the interpreter", () => Result(false, None)),
@@ -211,16 +212,19 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
LineArg("wrap", "code to wrap around all executions", wrapCommand)
)
}
- private def wrapCommand(line: String): Result = {
- if (line == "") {
- intp.setExecutionWrapper("")
- "Cleared wrapper."
- }
+ private def keybindingsCommand(line: String): Result = {
+ if (in.keyBindings.isEmpty) "Key bindings unavailable."
else {
- intp.setExecutionWrapper(line)
- "Set wrapper to '" + line + "'"
+ println("Reading jline properties for default key bindings.")
+ println("Accuracy not guaranteed: treat this as a guideline only.\n")
+ in.keyBindings foreach println
}
}
+ private def wrapCommand(line: String): Result = {
+ intp setExecutionWrapper line
+ if (line == "") "Cleared wrapper."
+ else "Set wrapper to '" + line + "'"
+ }
private def symfilterCmd(line: String): Result = {
if (line == "") {
@@ -404,7 +408,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
commands.filter(_.name startsWith cmd) match {
case List(x) => x(args)
case Nil => withError("Unknown command. Type :help for help.")
- case xs => withError(ambiguous(xs))
+ case xs =>
+ xs find (_.name == cmd) match {
+ case Some(exact) => exact(args)
+ case _ => withError(ambiguous(xs))
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
index 1a67cc647d..1ee04a4090 100644
--- a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
@@ -18,6 +18,7 @@ trait InteractiveReader {
def history: History
def completion: Completion
+ def keyBindings: List[KeyBinding]
def init(): Unit
def reset(): Unit
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
index 7652e6646b..f0868046b1 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
@@ -17,14 +17,19 @@ import scala.tools.jline.console.ConsoleReader
import scala.collection.JavaConverters._
import Properties.userHome
import Completion._
+import io.Streamable.slurp
/** Reads from the console using JLine */
class JLineReader(val completion: Completion) extends InteractiveReader {
val interactive = true
lazy val history = JLineHistory()
+ lazy val keyBindings =
+ try KeyBinding parse slurp(term.getDefaultBindings)
+ catch { case _: Exception => Nil }
- def reset() = consoleReader.getTerminal().reset()
- def init() = consoleReader.getTerminal().init()
+ private def term = consoleReader.getTerminal()
+ def reset() = term.reset()
+ def init() = term.init()
def scalaToJline(tc: ScalaCompleter): Completer = new Completer {
def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/KeyBinding.scala b/src/compiler/scala/tools/nsc/interpreter/KeyBinding.scala
new file mode 100644
index 0000000000..a7ca3a77f3
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interpreter/KeyBinding.scala
@@ -0,0 +1,39 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+case class KeyBinding(name: String, code: Int, aliases: List[String], description: String) {
+ def nameString = if (aliases.nonEmpty) aliases mkString ", " else name
+ override def toString = "%3d %s: %s".format(code, nameString, description)
+}
+
+object KeyBinding {
+ def parse(bindings: String): List[KeyBinding] = {
+ def loop(xs: List[String]): List[KeyBinding] = {
+ val (comment, lines) = xs span (_ startsWith "#")
+ val description = comment map (_ drop 1 trim) mkString " "
+ val (aliases, desc) = description span (_ != ':') match {
+ case (x, y) => (
+ x split ',' map (_.trim) toList,
+ if (y == "") "" else y.tail.trim
+ )
+ }
+ lines match {
+ case Nil => Nil
+ case hd :: tl =>
+ val kb = (hd indexOf '=') match {
+ case -1 => KeyBinding(hd, -1, aliases, desc)
+ case idx => KeyBinding(hd drop idx + 1, hd take idx toInt, aliases, desc)
+ }
+ kb :: loop(tl)
+ }
+ }
+ // This is verrrrrrrry specific to the current contents
+ // of the keybindings.properties in jline.
+ loop(bindings split "\\n" map (_.trim) dropWhile (_ != "") filterNot (_ == "") toList) sortBy (_.code)
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
index 079fa4b9fb..0e3b7412c8 100644
--- a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
@@ -17,6 +17,7 @@ extends InteractiveReader
{
val history = NoHistory
val completion = NoCompletion
+ val keyBindings: List[KeyBinding] = Nil
def init() = ()
def reset() = ()