import atexit
import code
import os
import readline
from subprocess import call, check_output
import sys
import traceback

HOME = os.environ["HOME"]


class Shell(object):
    BUILTINS = {'cd': os.chdir}

    def __init__(self, aliases=None, builtins=None,
                 histfile=os.path.expanduser("~/.console-history")):
        self.aliases = aliases or {}
        self.builtins = builtins or self.BUILTINS
        self.init_history(histfile)

    @property
    def prompt(self):
        pwd = check_output("pwd", shell=True)
        return (pwd.strip() + " ").replace(HOME, "~")

    def out(self, msg):
        sys.stdout.write(msg)

    def error(self, msg):
        sys.stderr.write(msg)

    def read(self):
        try:
            return self.rewrite(raw_input(self.prompt))
        except EOFError:
            raise SystemExit()

    def rewrite(self, line):
        tokens = line.split()
        new_tokens = []
        for token in tokens:
            try:
                v = self.aliases[token]
            except KeyError:
                if token.startswith("$"):
                    try:
                        v = os.environ[token[1:]]
                    except KeyError:
                        new_tokens.append(token)
                    else:
                        new_tokens.append(v)
                else:
                    new_tokens.append(token)
            else:
                new_tokens.append(v)
        return " ".join(new_tokens)

    def _raise_cursor(self, n=1):
        """Move the cursor up `n` lines."""
        self.out('\033[%sA' % n)
        sys.stdout.flush()

    def _clear_line(self):
        self.out('\033[K')
        sys.stdout.flush()

    def eval(self, line):
        call(line, shell=True)

    def interact(self):
        while True:
            try:
                line = self.read()
                if not line:
                    continue
                tokens = line.split()
                command, args = tokens[0], tokens[1:]
                # handle any shell builtin commands
                try:
                    self.builtins[command](args[0])
                except KeyError:
                    self.eval(line)
                self.after(line)
            except SystemExit:
                break
            except:
                self.error(traceback.format_exc())

    def complete(self, text, state):
        matches = []

        head, tail = os.path.split(text)

        ls = check_output("ls %s" % head, shell=True)
        filenames = ls.split()

        for filename in filenames:
            if filename.startswith(tail):
                matches.append(os.path.join(head, filename))
        try:
            return matches[state]
        except IndexError:
            return None

    def init_history(self, histfile):
        if sys.platform == 'darwin':
            readline.parse_and_bind("bind ^I rl_complete")
        else:
            readline.parse_and_bind("tab: complete")
        readline.set_completer(self.complete)
        if hasattr(readline, "read_history_file"):
            try:
                readline.read_history_file(histfile)
            except IOError:
                pass
            atexit.register(self.save_history, histfile)

    def save_history(self, histfile):
        readline.write_history_file(histfile)

@@ -1,175 +1,435 @@
-import atexit%0Aimport code%0Aimport os%0Aimport readline%0Afrom subprocess import call, check_output%0Aimport sys%0Aimport traceback%0A%0AHOME = os.environ%5B%22HOME%22%5D%0A%0A%0Aclass Shell(object):
+%22%22%22%0A%0A    twosheds.shell%0A    ~~~~~~~~~~~~~~%0A%0A    This module implements the central user interface for access to an%0A    operating system's kernel services.%0A%0A%22%22%22%0Aimport atexit%0Aimport code%0Aimport os%0Aimport readline%0Afrom subprocess import call, check_output%0Aimport sys%0Aimport traceback%0A%0A%0Aclass Shell(object):%0A    %22%22%22The shell is an sh-compatible command language interpreter that executes%0A    commands read from standard input.%0A    %22%22%22
 %0A   
@@ -751,99 +751,94 @@
     
-pwd = check_output(%22pwd%22, shell=True)%0A        return (pwd.strip() + %22 %22).replace(HOME, %22~%22)
+%22%22%22Indicate to the user that the shell is waiting for a command.%22%22%22%0A        return %22$%22
 %0A%0A  
@@ -846,16 +846,19 @@
  def out
+put
 (self, m
@@ -854,32 +854,64 @@
 put(self, msg):%0A
+        %22%22%22Output a message.%22%22%22%0A
         sys.stdo
@@ -943,32 +943,63 @@
 ror(self, msg):%0A
+        %22%22%22Output an error.%22%22%22%0A
         sys.stde
@@ -1025,32 +1025,78 @@
 def read(self):%0A
+        %22%22%22Accept a command from the user.%22%22%22%0A
         try:%0A   
@@ -1226,32 +1226,64 @@
 te(self, line):%0A
+        %22%22%22Transform a line.%22%22%22%0A
         tokens =
@@ -1958,24 +1958,27 @@
     self.out
+put
 ('%5C033%5B%25sA' 
@@ -2053,16 +2053,19 @@
 self.out
+put
 ('%5C033%5BK
@@ -2113,32 +2113,65 @@
 al(self, line):%0A
+        %22%22%22Evaluate an input.%22%22%22%0A
         call(lin
@@ -2202,32 +2202,47 @@
 interact(self):%0A
+        %22%22%22%22%22%22%0A
         while Tr
@@ -2567,15 +2567,13 @@
 nd%5D(
+*
 args
-%5B0%5D
 )%0A  
@@ -2830,24 +2830,248 @@
 xt, state):%0A
+        %22%22%22Return the next possible completion for 'text'.%0A%0A        This is called successively with state == 0, 1, 2, ... until it%0A        returns None.%0A        %0A        The completion should begin with 'text'.%0A        %22%22%22%0A
         matc

add documention