The usual (and some new modules).
diff --git a/Lib/dos-8x3/rlcomple.py b/Lib/dos-8x3/rlcomple.py
new file mode 100644
index 0000000..285faed
--- /dev/null
+++ b/Lib/dos-8x3/rlcomple.py
@@ -0,0 +1,108 @@
+"""Word completion for GNU readline 2.0.
+
+This requires the latest extension to the readline module (the
+set_completer() function).  When completing a simple identifier, it
+completes keywords, built-ins and globals in __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 string" type "string.", hit the
+completion key (twice), and see the list of names defined by the
+string module!
+
+Tip: to use the tab key as the completion key, call
+
+    readline.parse_and_bind("tab: complete")
+
+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.
+
+- GNU readline is also used by the built-in functions input() and
+raw_input(), and thus these also benefit/suffer from the completer
+features.  Clearly an interactive application can benefit by
+specifying its own completer function and using raw_input() for all
+its input.
+
+- When the original stdin is not a tty device, GNU readline is never
+used, and this module (and the readline module) are silently inactive.
+
+"""
+
+import readline
+import keyword
+import __builtin__
+import __main__
+import string
+import re
+import traceback
+
+class Completer:
+
+    def complete(self, text, state):
+	"""Return the next possible completion for 'text'.
+
+	This is called successively with state == 0, 1, 2, ... until it
+	returns None.  The completion should begin with 'text'.
+
+	"""
+	if state == 0:
+	    if "." in text:
+		self.matches = self.attr_matches(text)
+	    else:
+		self.matches = self.global_matches(text)
+	return self.matches[state]
+
+    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 defines in __main__ that match.
+
+	"""
+	matches = []
+	n = len(text)
+	for list in [keyword.kwlist,
+		     __builtin__.__dict__.keys(),
+		     __main__.__dict__.keys()]:
+	    for word in list:
+		if word[:n] == text:
+		    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
+	evaluabable in the globals of __main__, it will be evaluated
+	and its attributes (as revealed by dir()) are used as possible
+	completions.
+
+	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)
+	words = dir(eval(expr, __main__.__dict__))
+	matches = []
+	n = len(attr)
+	for word in words:
+	    if word[:n] == attr:
+		matches.append("%s.%s" % (expr, word))
+	return matches
+
+readline.set_completer(Completer().complete)