aboutsummaryrefslogtreecommitdiff
path: root/devel/jline/files
diff options
context:
space:
mode:
Diffstat (limited to 'devel/jline/files')
-rw-r--r--devel/jline/files/JLineCompleter.py211
-rw-r--r--devel/jline/files/jython.sh48
-rw-r--r--devel/jline/files/patch-src-src-main-java-jline-ConsoleRunner.java22
3 files changed, 281 insertions, 0 deletions
diff --git a/devel/jline/files/JLineCompleter.py b/devel/jline/files/JLineCompleter.py
new file mode 100644
index 000000000000..548f5ff6d5ba
--- /dev/null
+++ b/devel/jline/files/JLineCompleter.py
@@ -0,0 +1,211 @@
+# (X)Emacs: -*- mode: python; coding: latin-1; -*-
+# TAB-Completion for Jython with JLine console.
+# JLineCompleter.py,v 1.5 2007/09/28 09:13:10 martin Exp
+
+# Jython + JLine + Tab-Completion Micro-Howto:
+#
+# JLine is a 99% pure Java console library similar to GNU Readline but
+# with an incompatible API. Jython 2.2 already contains some support
+# for JLine. For basic line editing and a command history it suffices
+# to set python.console=org.python.util.JLineConsole either in the
+# Jython registry or in the ~/.jython file. Obviously the JLine
+# jarfile must be in your classpath.
+#
+# Unfortunately Jython does not support tab-completion for JLine yet.
+# It can be enabled by importing this file - however this needs
+# patches. To summarize prerequisites:
+#
+# 1. You need a patch to JLine that adds the
+# ConsoleRunner.getReader() method. On FreeBSD build jline with
+# option WITH_JLINEPATCH enabled.
+#
+# 2. You must wrap the entry point to Jython with a
+# jline.ConsoleRunner instance. You do this by editing
+# /usr/local/bin/jython and inserting an extra argument
+# "jline.ConsoleRunner" right before the "org.python.util.jython"
+# argument.
+#
+# 3. While there don't forget to add
+# /usr/local/share/java/classes/jline.jar to the classpath.
+#
+# 4. You must set python.console="" in the ~/.jython file. You
+# don't want Jython to create another console instance running
+# behind the wrapper console.
+#
+# 5. Finally you have to import this module. You may want to do a
+# "import user" instead and code the "import JLineCompleter"
+# inside ~/.pythonrc.py instead.
+#
+# If that is too much hassle - just wait for my upcoming
+# devel/libreadline-java port!
+
+
+"""Word completion for JLine
+
+The completer completes keywords, built-ins and globals in a
+selectable namespace (which defaults to __main__); when completing
+NAME.NAME..., it evaluates (!) the expression up to the last dot and
+completes its attributes.
+
+It's very cool to do "import sys" type "sys.", hit the
+completion key (twice), and see the list of names defined by the
+sys module!
+
+Notes:
+
+- Exceptions raised by the completer function are *ignored* (and
+generally cause the completion to fail). This is a feature -- since
+readline sets the tty device in raw (or cbreak) mode, printing a
+traceback wouldn't work well without some complicated hoopla to save,
+reset and restore the tty state.
+
+- The evaluation of the NAME.NAME... form may cause arbitrary
+application defined code to be executed if an object with a
+__getattr__ hook is found. Since it is the responsibility of the
+application (or the user) to enable this feature, I consider this an
+acceptable risk. More complicated expressions (e.g. function calls or
+indexing operations) are *not* evaluated.
+
+This module is a slightly hacked version of the CPython 2.5 module
+rlcompleter. It is therefore under the PSF (Python Software
+Foundation) license.
+"""
+
+__all__ = ["JLineCompleter"]
+__license__ = "PSF"
+
+try:
+ import jline
+except ImportError:
+ raise ImportError("Make sure you have the jline.jar in classpath!")
+if not jline.__file__:
+ jline.__file__ = "jline.jar" # Keep the site module from throwing.
+import __builtin__
+import keyword
+import re
+
+
+# @sig public class JythonCompleter extends java.lang.Object implements
+# jline.Completor, org.python.core.PyProxy, org.python.core.ClassDictInit
+class JLineCompleter(jline.Completor):
+ def __init__(self, namespace = None):
+ """Create a new completer for the command line.
+
+ Completer([namespace]) -> completer instance.
+
+ If unspecified, the default namespace where completions are performed
+ is __main__ (technically, __main__.__dict__). Namespaces should be
+ given as dictionaries.
+
+ Completer instances should be used as the completion mechanism of
+ JLine via the jline.ConsoleRunner.completors system property.
+ """
+
+ if namespace and not isinstance(namespace, dict):
+ raise TypeError,'namespace must be a dictionary'
+
+ # Don't bind to namespace quite yet, but flag whether the user wants a
+ # specific namespace or to use __main__.__dict__. This will allow us
+ # to bind to __main__.__dict__ at completion time, not now.
+ if namespace is None:
+ self.use_main_ns = 1
+ else:
+ self.use_main_ns = 0
+ self.namespace = namespace
+
+ # @sig int complete(String buffer, int cursor, List candidates)
+ def complete(self, buffer, cursor, candidates):
+ """Return the list of possible completions for 'buffer'."""
+ if self.use_main_ns:
+ import __main__
+ self.namespace = __main__.__dict__
+
+ # Determine the text to be expanded:
+ text = buffer[:cursor]
+ start = 0
+ for i in xrange(cursor - 1, -1, -1):
+ ch = text[i]
+ if not (ch.isalnum() or ch == '.' or ch == '_'):
+ start = i + 1
+ break
+ text = text[start:]
+ try:
+ if "." in text:
+ self.matches = self.attr_matches(text)
+ else:
+ self.matches = self.global_matches(text)
+ for m in self.matches:
+ candidates.add(m)
+ if self.matches:
+ return start
+ else:
+ return -1
+ except (AttributeError, IndexError, NameError):
+ return -1
+
+ def global_matches(self, text):
+ """Compute matches when text is a simple name.
+
+ Return a list of all keywords, built-in functions and names currently
+ defined in self.namespace that match.
+
+ """
+ matches = []
+ n = len(text)
+ for list in [keyword.kwlist,
+ __builtin__.__dict__,
+ self.namespace]:
+ for word in list:
+ if word[:n] == text and word != "__builtins__":
+ matches.append(word)
+ return matches
+
+ def attr_matches(self, text):
+ """Compute matches when text contains a dot.
+
+ Assuming the text is of the form NAME.NAME....[NAME], and is
+ evaluatable in self.namespace, it will be evaluated and its attributes
+ (as revealed by dir()) are used as possible completions. (For class
+ instances, class members are also considered.)
+
+ WARNING: this can still invoke arbitrary C code, if an object
+ with a __getattr__ hook is evaluated.
+
+ """
+ m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
+ if not m:
+ return
+ expr, attr = m.group(1, 3)
+ object = eval(expr, self.namespace)
+ words = dir(object)
+ if hasattr(object,'__class__'):
+ words.append('__class__')
+ words = words + get_class_members(object.__class__)
+ matches = []
+ n = len(attr)
+ for word in words:
+ if word[:n] == attr and word != "__builtins__":
+ matches.append("%s.%s" % (expr, word))
+ return matches
+
+def get_class_members(klass):
+ ret = dir(klass)
+ if hasattr(klass,'__bases__'):
+ for base in klass.__bases__:
+ ret = ret + get_class_members(base)
+ return ret
+
+try:
+ reader = jline.ConsoleRunner.getReader()
+ if reader:
+ reader.addCompletor(JLineCompleter())
+ else:
+ raise RuntimeError("jline.ConsoleRunner not active")
+except AttributeError:
+ # XXX This message is FreeBSD specific!
+ raise NotImplementedError("Incompatible JLine version! Set WITH_JLINEPATCH=1 and rebuild the devel/jline port!")
+
+if __name__ == '__main__':
+ print "Sorry, no unittests yet!"
+
+#EOF#
diff --git a/devel/jline/files/jython.sh b/devel/jline/files/jython.sh
new file mode 100644
index 000000000000..5e008d3a2d79
--- /dev/null
+++ b/devel/jline/files/jython.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# Invoke Jython.
+# jython.sh,v 1.5 2007/09/28 09:13:55 martin Exp
+#
+# The path names below are for Jython 2.2 on FreeBSD.
+#
+
+CP="/usr/local/lib/jython22/jython.jar"
+defs=
+wrapper=
+
+case "${JYTHON_CONSOLE:-JLine}" in
+ *[Ee]dit[Ll]ine)
+ CP="$CP:/usr/local/share/java/classes/libreadline-java.jar"
+ defs="-Dpython.console=org.python.util.ReadlineConsole"
+ defs="$defs -Dpython.console.readlinelib=Editline"
+ ;;
+ *[Gg]et[Ll]ine)
+ CP="$CP:/usr/local/share/java/classes/libreadline-java.jar"
+ defs="-Dpython.console=org.python.util.ReadlineConsole"
+ defs="$defs -Dpython.console.readlinelib=Getline"
+ ;;
+ *[Jj][Ll]ine)
+ CP="$CP:/usr/local/share/java/classes/jline.jar"
+ defs="-Dpython.console="
+ wrapper=jline.ConsoleRunner
+ ;;
+ *[Rr]ead[Ll]ine)
+ CP="$CP:/usr/local/share/java/classes/libreadline-java.jar"
+ defs="-Dpython.console=org.python.util.ReadlineConsole"
+ defs="$defs -Dpython.console.readlinelib=GnuReadline"
+ ;;
+ *)
+ echo >&2 "$0: illegal value of JYTHON_CONSOLE: $JYTHON_CONSOLE"
+ exit 64
+ ;;
+esac
+
+
+if [ -n "$CLASSPATH" ]; then
+ CP="$CP:$CLASSPATH"
+fi
+
+exec java -Dpython.home="/usr/local/lib/jython22" \
+ -Dpython.cachedir="${HOME}/.jython-cachedir" \
+ -classpath "$CP" $wrapper org.python.util.jython $defs "$@"
+
+#EOF#
diff --git a/devel/jline/files/patch-src-src-main-java-jline-ConsoleRunner.java b/devel/jline/files/patch-src-src-main-java-jline-ConsoleRunner.java
new file mode 100644
index 000000000000..63d2ae26cd37
--- /dev/null
+++ b/devel/jline/files/patch-src-src-main-java-jline-ConsoleRunner.java
@@ -0,0 +1,22 @@
+--- src/src/main/java/jline/ConsoleRunner.java.orig 2007-03-09 16:32:28.000000000 +0100
++++ src/src/main/java/jline/ConsoleRunner.java 2007-09-24 19:22:42.000000000 +0200
+@@ -17,6 +17,10 @@
+ * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
+ */
+ public class ConsoleRunner {
++ private static ConsoleReader reader;
++
++ public static ConsoleReader getReader() { return reader; }
++
+ public static final String property = "jline.history";
+
+ public static void main(final String[] args) throws Exception {
+@@ -36,7 +40,7 @@
+ String mainClass = (String) argList.remove(0);
+
+ // setup the inpout stream
+- ConsoleReader reader = new ConsoleReader();
++ reader = new ConsoleReader();
+
+ if (historyFileName != null) {
+ reader.setHistory(new History (new File