From c9ef4c7627401a2cd460f5f99a4af729924a1a46 2011-06-20 23:39:15
From: MinRK <benjaminrk@gmail.com>
Date: 2011-06-20 23:39:15
Subject: [PATCH] Terminal IPython working with newapp

---

diff --git a/IPython/core/history.py b/IPython/core/history.py
index 62720e4..723b150 100644
--- a/IPython/core/history.py
+++ b/IPython/core/history.py
@@ -101,18 +101,15 @@ class HistoryManager(Configurable):
 
         if self.hist_file == u'':
             # No one has set the hist_file, yet.
-            if shell.profile:
-                histfname = 'history-%s' % shell.profile
-            else:
-                histfname = 'history'
-            self.hist_file = os.path.join(shell.ipython_dir, histfname + '.sqlite')
+            histfname = 'history'
+            self.hist_file = os.path.join(shell.profile_dir.location, histfname + '.sqlite')
 
         try:
             self.init_db()
         except sqlite3.DatabaseError:
             if os.path.isfile(self.hist_file):
                 # Try to move the file out of the way.
-                newpath = os.path.join(self.shell.ipython_dir, "hist-corrupt.sqlite")
+                newpath = os.path.join(self.shell.profile_dir.location, "hist-corrupt.sqlite")
                 os.rename(self.hist_file, newpath)
                 print("ERROR! History file wasn't a valid SQLite database.",
                 "It was moved to %s" % newpath, "and a new file created.")
diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
index e32d32c..93ca390 100644
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -54,6 +54,7 @@ from IPython.core.inputsplitter import IPythonInputSplitter
 from IPython.core.logger import Logger
 from IPython.core.macro import Macro
 from IPython.core.magic import Magic
+from IPython.core.newapplication import ProfileDir
 from IPython.core.payload import PayloadManager
 from IPython.core.plugin import PluginManager
 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
@@ -238,7 +239,9 @@ class InteractiveShell(SingletonConfigurable, Magic):
         """
     )
     colors = CaselessStrEnum(('NoColor','LightBG','Linux'), 
-                             default_value=get_default_colors(), config=True)
+                             default_value=get_default_colors(), config=True,
+        help="Set the color scheme (NoColor, Linux, and LightBG)."
+    )
     debug = CBool(False, config=True)
     deep_reload = CBool(False, config=True, help=
         """
@@ -291,7 +294,6 @@ class InteractiveShell(SingletonConfigurable, Magic):
         """
     )
 
-    profile = Unicode('', config=True)
     prompt_in1 = Str('In [\\#]: ', config=True)
     prompt_in2 = Str('   .\\D.: ', config=True)
     prompt_out = Str('Out[\\#]: ', config=True)
@@ -342,10 +344,18 @@ class InteractiveShell(SingletonConfigurable, Magic):
     payload_manager = Instance('IPython.core.payload.PayloadManager')
     history_manager = Instance('IPython.core.history.HistoryManager')
 
+    profile_dir = Instance('IPython.core.newapplication.ProfileDir')
+    @property
+    def profile(self):
+        if self.profile_dir is not None:
+            name = os.path.basename(self.profile_dir.location)
+            return name.replace('profile_','')
+
+
     # Private interface
     _post_execute = Instance(dict)
 
-    def __init__(self, config=None, ipython_dir=None,
+    def __init__(self, config=None, ipython_dir=None, profile_dir=None,
                  user_ns=None, user_global_ns=None,
                  custom_exceptions=((), None)):
 
@@ -355,6 +365,7 @@ class InteractiveShell(SingletonConfigurable, Magic):
 
         # These are relatively independent and stateless
         self.init_ipython_dir(ipython_dir)
+        self.init_profile_dir(profile_dir)
         self.init_instance_attrs()
         self.init_environment()
 
@@ -372,7 +383,7 @@ class InteractiveShell(SingletonConfigurable, Magic):
         # While we're trying to have each part of the code directly access what
         # it needs without keeping redundant references to objects, we have too
         # much legacy code that expects ip.db to exist.
-        self.db = PickleShareDB(os.path.join(self.ipython_dir, 'db'))
+        self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
 
         self.init_history()
         self.init_encoding()
@@ -457,16 +468,16 @@ class InteractiveShell(SingletonConfigurable, Magic):
     def init_ipython_dir(self, ipython_dir):
         if ipython_dir is not None:
             self.ipython_dir = ipython_dir
-            self.config.Global.ipython_dir = self.ipython_dir
             return
 
-        if hasattr(self.config.Global, 'ipython_dir'):
-            self.ipython_dir = self.config.Global.ipython_dir
-        else:
-            self.ipython_dir = get_ipython_dir()
+        self.ipython_dir = get_ipython_dir()
 
-        # All children can just read this
-        self.config.Global.ipython_dir = self.ipython_dir
+    def init_profile_dir(self, profile_dir):
+        if profile_dir is not None:
+            self.profile_dir = profile_dir
+            return
+        self.profile_dir =\
+            ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
 
     def init_instance_attrs(self):
         self.more = False
diff --git a/IPython/core/magic.py b/IPython/core/magic.py
index d904d28..5399aa2 100644
--- a/IPython/core/magic.py
+++ b/IPython/core/magic.py
@@ -46,6 +46,7 @@ from IPython.core import debugger, oinspect
 from IPython.core.error import TryNext
 from IPython.core.error import UsageError
 from IPython.core.fakemodule import FakeModule
+from IPython.core.newapplication import ProfileDir
 from IPython.core.macro import Macro
 from IPython.core import page
 from IPython.core.prefilter import ESC_MAGIC
@@ -533,10 +534,7 @@ Currently the magic system has the following functions:\n"""
 
     def magic_profile(self, parameter_s=''):
         """Print your currently active IPython profile."""
-        if self.shell.profile:
-            printpl('Current IPython profile: $self.shell.profile.')
-        else:
-            print 'No profile active.'
+        print self.shell.profile
 
     def magic_pinfo(self, parameter_s='', namespaces=None):
         """Provide detailed information about an object.
@@ -3373,22 +3371,16 @@ Defaulting color scheme to 'NoColor'"""
         else:
             overwrite = False
         from IPython.config import profile
-        profile_dir = os.path.split(profile.__file__)[0]
+        profile_dir = os.path.dirname(profile.__file__)
         ipython_dir = self.ipython_dir
-        files = os.listdir(profile_dir)
-
-        to_install = []
-        for f in files:
-            if f.startswith('ipython_config'):
-                src = os.path.join(profile_dir, f)
-                dst = os.path.join(ipython_dir, f)
-                if (not os.path.isfile(dst)) or overwrite:
-                    to_install.append((f, src, dst))
-        if len(to_install)>0:
-            print "Installing profiles to: ", ipython_dir
-            for (f, src, dst) in to_install:
-                shutil.copy(src, dst)
-                print "    %s" % f
+        print "Installing profiles to: %s [overwrite=%s]"(ipython_dir,overwrite)
+        for src in os.listdir(profile_dir):
+            if src.startswith('profile_'):
+                name = src.replace('profile_', '')
+                print "    %s"%name
+                pd = ProfileDir.create_profile_dir_by_name(ipython_dir, name)
+                pd.copy_config_file('ipython_config.py', path=src, 
+                                overwrite=overwrite)
 
     @skip_doctest
     def magic_install_default_config(self, s):
@@ -3404,15 +3396,9 @@ Defaulting color scheme to 'NoColor'"""
             overwrite = True
         else:
             overwrite = False
-        from IPython.config import default
-        config_dir = os.path.split(default.__file__)[0]
-        ipython_dir = self.ipython_dir
-        default_config_file_name = 'ipython_config.py'
-        src = os.path.join(config_dir, default_config_file_name)
-        dst = os.path.join(ipython_dir, default_config_file_name)
-        if (not os.path.isfile(dst)) or overwrite:
-            shutil.copy(src, dst)
-            print "Installing default config file: %s" % dst
+        pd = self.shell.profile_dir
+        print "Installing default config file in: %s" % pd.location
+        pd.copy_config_file('ipython_config.py', overwrite=overwrite)
 
     # Pylab support: simple wrappers that activate pylab, load gui input
     # handling and modify slightly %run
diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py
index ede323c..d27ea2e 100644
--- a/IPython/frontend/terminal/interactiveshell.py
+++ b/IPython/frontend/terminal/interactiveshell.py
@@ -58,11 +58,21 @@ raw_input_original = raw_input
 
 class TerminalInteractiveShell(InteractiveShell):
 
-    autoedit_syntax = CBool(False, config=True)
+    autoedit_syntax = CBool(False, config=True,
+        help="auto editing of files with syntax errors.")
     banner = Unicode('')
-    banner1 = Unicode(default_banner, config=True)
-    banner2 = Unicode('', config=True)
-    confirm_exit = CBool(True, config=True)
+    banner1 = Unicode(default_banner, config=True,
+        help="""The part of the banner to be printed before the profile"""
+    )
+    banner2 = Unicode('', config=True,
+        help="""The part of the banner to be printed after the profile"""
+    )
+    confirm_exit = CBool(True, config=True,
+        help="""
+        Set to confirm when you try to exit IPython with an EOF (Control-D
+        in Unix, Control-Z/Enter in Windows). By typing 'exit', 'quit' or
+        '%%Exit', you can force a direct exit without any confirmation.""",
+    )
     # This display_banner only controls whether or not self.show_banner()
     # is called when mainloop/interact are called.  The default is False
     # because for the terminal based application, the banner behavior
@@ -71,19 +81,35 @@ class TerminalInteractiveShell(InteractiveShell):
     display_banner = CBool(False) # This isn't configurable!
     embedded = CBool(False)
     embedded_active = CBool(False)
-    editor = Unicode(get_default_editor(), config=True)
-    pager = Unicode('less', config=True)
-
-    screen_length = Int(0, config=True)
-    term_title = CBool(False, config=True)
-
-    def __init__(self, config=None, ipython_dir=None, user_ns=None,
+    editor = Unicode(get_default_editor(), config=True,
+        help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
+    )
+    pager = Unicode('less', config=True,
+        help="The shell program to be used for paging.")
+
+    screen_length = Int(0, config=True,
+        help=
+        """Number of lines of your screen, used to control printing of very
+        long strings.  Strings longer than this number of lines will be sent
+        through a pager instead of directly printed.  The default value for
+        this is 0, which means IPython will auto-detect your screen size every
+        time it needs to print certain potentially long strings (this doesn't
+        change the behavior of the 'print' keyword, it's only triggered
+        internally). If for some reason this isn't working well (it needs
+        curses support), specify it yourself. Otherwise don't change the
+        default.""",
+    )
+    term_title = CBool(False, config=True,
+        help="Enable auto setting the terminal title."
+    )
+
+    def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
                  user_global_ns=None, custom_exceptions=((),None),
                  usage=None, banner1=None, banner2=None,
                  display_banner=None):
 
         super(TerminalInteractiveShell, self).__init__(
-            config=config, ipython_dir=ipython_dir, user_ns=user_ns,
+            config=config, profile_dir=profile_dir, user_ns=user_ns,
             user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
         )
         # use os.system instead of utils.process.system by default, except on Windows
diff --git a/IPython/frontend/terminal/ipapp.py b/IPython/frontend/terminal/ipapp.py
index c667181..99fa337 100755
--- a/IPython/frontend/terminal/ipapp.py
+++ b/IPython/frontend/terminal/ipapp.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # encoding: utf-8
 """
-The :class:`~IPython.core.application.Application` object for the command
+The :class:`~IPython.core.newapplication.Application` object for the command
 line :command:`ipython` program.
 
 Authors
@@ -9,6 +9,7 @@ Authors
 
 * Brian Granger
 * Fernando Perez
+* Min Ragan-Kelley
 """
 
 #-----------------------------------------------------------------------------
@@ -28,17 +29,23 @@ import logging
 import os
 import sys
 
+from IPython.config.loader import (
+    Config, PyFileConfigLoader
+)
+from IPython.config.application import boolean_flag
 from IPython.core import release
+from IPython.core import usage
 from IPython.core.crashhandler import CrashHandler
-from IPython.core.application import Application, BaseAppConfigLoader
-from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
-from IPython.config.loader import (
-    Config,
-    PyFileConfigLoader
+from IPython.core.formatters import PlainTextFormatter
+from IPython.core.newapplication import (
+    ProfileDir, BaseIPythonApplication, base_flags, base_aliases
 )
+from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
 from IPython.lib import inputhook
 from IPython.utils.path import filefind, get_ipython_dir, check_for_old_config
-from IPython.core import usage
+from IPython.utils.traitlets import (
+    Bool, Unicode, Dict, Instance, List,CaselessStrEnum
+)
 
 #-----------------------------------------------------------------------------
 # Globals, utilities and helpers
@@ -48,275 +55,6 @@ from IPython.core import usage
 default_config_file_name = u'ipython_config.py'
 
 
-class IPAppConfigLoader(BaseAppConfigLoader):
-
-    def _add_arguments(self):
-        super(IPAppConfigLoader, self)._add_arguments()
-        paa = self.parser.add_argument
-        paa('-p', 
-            '--profile', dest='Global.profile', type=unicode,
-            help=
-            """The string name of the ipython profile to be used.  Assume that your
-            config file is ipython_config-<name>.py (looks in current dir first,
-            then in IPYTHON_DIR). This is a quick way to keep and load multiple
-            config files for different tasks, especially if include your basic one
-            in your more specialized ones.  You can keep a basic
-            IPYTHON_DIR/ipython_config.py file and then have other 'profiles' which
-            include this one and load extra things for particular tasks.""",
-            metavar='Global.profile')
-        paa('--config-file', 
-            dest='Global.config_file', type=unicode,
-            help=
-            """Set the config file name to override default.  Normally IPython
-            loads ipython_config.py (from current directory) or
-            IPYTHON_DIR/ipython_config.py.  If the loading of your config file
-            fails, IPython starts with a bare bones configuration (no modules
-            loaded at all).""",
-            metavar='Global.config_file')
-        paa('--autocall', 
-            dest='InteractiveShell.autocall', type=int, 
-            help=
-            """Make IPython automatically call any callable object even if you
-            didn't type explicit parentheses. For example, 'str 43' becomes
-            'str(43)' automatically.  The value can be '0' to disable the feature,
-            '1' for 'smart' autocall, where it is not applied if there are no more
-            arguments on the line, and '2' for 'full' autocall, where all callable
-            objects are automatically called (even if no arguments are present).
-            The default is '1'.""",
-            metavar='InteractiveShell.autocall')
-        paa('--autoindent',
-            action='store_true', dest='InteractiveShell.autoindent',
-            help='Turn on autoindenting.')
-        paa('--no-autoindent',
-            action='store_false', dest='InteractiveShell.autoindent',
-            help='Turn off autoindenting.')
-        paa('--automagic',
-            action='store_true', dest='InteractiveShell.automagic',
-            help=
-            """Turn on the auto calling of magic commands. Type %%magic at the
-            IPython  prompt  for  more information.""")
-        paa('--no-automagic',
-            action='store_false', dest='InteractiveShell.automagic',
-            help='Turn off the auto calling of magic commands.')
-        paa('--autoedit-syntax',
-            action='store_true', dest='TerminalInteractiveShell.autoedit_syntax',
-            help='Turn on auto editing of files with syntax errors.')
-        paa('--no-autoedit-syntax',
-            action='store_false', dest='TerminalInteractiveShell.autoedit_syntax',
-            help='Turn off auto editing of files with syntax errors.')
-        paa('--banner',
-            action='store_true', dest='Global.display_banner',
-            help='Display a banner upon starting IPython.')
-        paa('--no-banner',
-            action='store_false', dest='Global.display_banner',
-            help="Don't display a banner upon starting IPython.")
-        paa('--cache-size',
-            type=int, dest='InteractiveShell.cache_size',
-            help=
-            """Set the size of the output cache.  The default is 1000, you can
-            change it permanently in your config file.  Setting it to 0 completely
-            disables the caching system, and the minimum value accepted is 20 (if
-            you provide a value less than 20, it is reset to 0 and a warning is
-            issued).  This limit is defined because otherwise you'll spend more
-            time re-flushing a too small cache than working""",
-            metavar='InteractiveShell.cache_size')
-        paa('--classic',
-            action='store_true', dest='Global.classic',
-            help="Gives IPython a similar feel to the classic Python prompt.")
-        paa('--colors',
-            type=str, dest='InteractiveShell.colors',
-            help="Set the color scheme (NoColor, Linux, and LightBG).",
-            metavar='InteractiveShell.colors')
-        paa('--color-info',
-            action='store_true', dest='InteractiveShell.color_info',
-            help=
-            """IPython can display information about objects via a set of func-
-            tions, and optionally can use colors for this, syntax highlighting
-            source code and various other elements.  However, because this
-            information is passed through a pager (like 'less') and many pagers get
-            confused with color codes, this option is off by default.  You can test
-            it and turn it on permanently in your ipython_config.py file if it
-            works for you.  Test it and turn it on permanently if it works with
-            your system.  The magic function %%color_info allows you to toggle this
-            inter- actively for testing.""")
-        paa('--no-color-info',
-            action='store_false', dest='InteractiveShell.color_info',
-            help="Disable using colors for info related things.")
-        paa('--confirm-exit',
-            action='store_true', dest='TerminalInteractiveShell.confirm_exit',
-            help=
-            """Set to confirm when you try to exit IPython with an EOF (Control-D
-            in Unix, Control-Z/Enter in Windows). By typing 'exit', 'quit' or
-            '%%Exit', you can force a direct exit without any confirmation.""")
-        paa('--no-confirm-exit',
-            action='store_false', dest='TerminalInteractiveShell.confirm_exit',
-            help="Don't prompt the user when exiting.")
-        paa('--deep-reload',
-            action='store_true', dest='InteractiveShell.deep_reload',
-            help=
-            """Enable deep (recursive) reloading by default. IPython can use the
-            deep_reload module which reloads changes in modules recursively (it
-            replaces the reload() function, so you don't need to change anything to
-            use it). deep_reload() forces a full reload of modules whose code may
-            have changed, which the default reload() function does not.  When
-            deep_reload is off, IPython will use the normal reload(), but
-            deep_reload will still be available as dreload(). This fea- ture is off
-            by default [which means that you have both normal reload() and
-            dreload()].""")
-        paa('--no-deep-reload',
-            action='store_false', dest='InteractiveShell.deep_reload',
-            help="Disable deep (recursive) reloading by default.")
-        paa('--editor',
-            type=str, dest='TerminalInteractiveShell.editor',
-            help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
-            metavar='TerminalInteractiveShell.editor')
-        paa('--log','-l', 
-            action='store_true', dest='InteractiveShell.logstart',
-            help="Start logging to the default log file (./ipython_log.py).")
-        paa('--logfile','-lf',
-            type=unicode, dest='InteractiveShell.logfile',
-            help="Start logging to logfile with this name.",
-            metavar='InteractiveShell.logfile')
-        paa('--log-append','-la',
-            type=unicode, dest='InteractiveShell.logappend',
-            help="Start logging to the given file in append mode.",
-            metavar='InteractiveShell.logfile')
-        paa('--pdb',
-            action='store_true', dest='InteractiveShell.pdb',
-            help="Enable auto calling the pdb debugger after every exception.")
-        paa('--no-pdb',
-            action='store_false', dest='InteractiveShell.pdb',
-            help="Disable auto calling the pdb debugger after every exception.")
-        paa('--pprint',
-            action='store_true', dest='PlainTextFormatter.pprint',
-            help="Enable auto pretty printing of results.")
-        paa('--no-pprint',
-            action='store_false', dest='PlainTextFormatter.pprint',
-            help="Disable auto auto pretty printing of results.")
-        paa('--prompt-in1','-pi1',
-            type=str, dest='InteractiveShell.prompt_in1',
-            help=
-            """Set the main input prompt ('In [\#]: ').  Note that if you are using
-            numbered prompts, the number is represented with a '\#' in the string.
-            Don't forget to quote strings with spaces embedded in them. Most
-            bash-like escapes can be used to customize IPython's prompts, as well
-            as a few additional ones which are IPython-spe- cific.  All valid
-            prompt escapes are described in detail in the Customization section of
-            the IPython manual.""",
-            metavar='InteractiveShell.prompt_in1')
-        paa('--prompt-in2','-pi2',
-            type=str, dest='InteractiveShell.prompt_in2',
-            help=
-            """Set the secondary input prompt (' .\D.: ').  Similar to the previous
-            option, but used for the continuation prompts. The special sequence
-            '\D' is similar to '\#', but with all digits replaced by dots (so you
-            can have your continuation prompt aligned with your input prompt).
-            Default: ' .\D.: ' (note three spaces at the start for alignment with
-            'In [\#]')""",
-            metavar='InteractiveShell.prompt_in2')
-        paa('--prompt-out','-po',
-            type=str, dest='InteractiveShell.prompt_out',
-            help="Set the output prompt ('Out[\#]:')",
-            metavar='InteractiveShell.prompt_out')
-        paa('--quick',
-            action='store_true', dest='Global.quick',
-            help="Enable quick startup with no config files.")
-        paa('--readline',
-            action='store_true', dest='InteractiveShell.readline_use',
-            help="Enable readline for command line usage.")
-        paa('--no-readline',
-            action='store_false', dest='InteractiveShell.readline_use',
-            help="Disable readline for command line usage.")
-        paa('--screen-length','-sl',
-            type=int, dest='TerminalInteractiveShell.screen_length',
-            help=
-            """Number of lines of your screen, used to control printing of very
-            long strings.  Strings longer than this number of lines will be sent
-            through a pager instead of directly printed.  The default value for
-            this is 0, which means IPython will auto-detect your screen size every
-            time it needs to print certain potentially long strings (this doesn't
-            change the behavior of the 'print' keyword, it's only triggered
-            internally). If for some reason this isn't working well (it needs
-            curses support), specify it yourself. Otherwise don't change the
-            default.""",
-            metavar='TerminalInteractiveShell.screen_length')
-        paa('--separate-in','-si',
-            type=str, dest='InteractiveShell.separate_in',
-            help="Separator before input prompts.  Default '\\n'.",
-            metavar='InteractiveShell.separate_in')
-        paa('--separate-out','-so',
-            type=str, dest='InteractiveShell.separate_out',
-            help="Separator before output prompts.  Default 0 (nothing).",
-            metavar='InteractiveShell.separate_out')
-        paa('--separate-out2','-so2', 
-            type=str, dest='InteractiveShell.separate_out2',
-            help="Separator after output prompts.  Default 0 (nonight).",
-            metavar='InteractiveShell.separate_out2')
-        paa('--no-sep',
-            action='store_true', dest='Global.nosep',
-            help="Eliminate all spacing between prompts.")
-        paa('--term-title',
-            action='store_true', dest='TerminalInteractiveShell.term_title',
-            help="Enable auto setting the terminal title.")
-        paa('--no-term-title',
-            action='store_false', dest='TerminalInteractiveShell.term_title',
-            help="Disable auto setting the terminal title.")
-        paa('--xmode',
-            type=str, dest='InteractiveShell.xmode',
-            help=
-            """Exception reporting mode ('Plain','Context','Verbose').  Plain:
-            similar to python's normal traceback printing.  Context: prints 5 lines
-            of context source code around each line in the traceback.  Verbose:
-            similar to Context, but additionally prints the variables currently
-            visible where the exception happened (shortening their strings if too
-            long).  This can potentially be very slow, if you happen to have a huge
-            data structure whose string representation is complex to compute.
-            Your computer may appear to freeze for a while with cpu usage at 100%%.
-            If this occurs, you can cancel the traceback with Ctrl-C (maybe hitting
-            it more than once).
-            """,
-            metavar='InteractiveShell.xmode')
-        paa('--ext',
-            type=str, dest='Global.extra_extension',
-            help="The dotted module name of an IPython extension to load.",
-            metavar='Global.extra_extension')
-        paa('-c',
-            type=str, dest='Global.code_to_run',
-            help="Execute the given command string.",
-            metavar='Global.code_to_run')
-        paa('-i',
-            action='store_true', dest='Global.force_interact',
-            help=
-            "If running code from the command line, become interactive afterwards.")
-
-        # Options to start with GUI control enabled from the beginning
-        paa('--gui',
-            type=str, dest='Global.gui',
-            help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
-            metavar='gui-mode')
-        paa('--pylab','-pylab',
-            type=str, dest='Global.pylab',
-            nargs='?', const='auto', metavar='gui-mode',
-            help="Pre-load matplotlib and numpy for interactive use. "+
-            "If no value is given, the gui backend is matplotlib's, else use "+
-            "one of:  ['tk', 'qt', 'wx', 'gtk', 'osx'].")
-
-        # Legacy GUI options.  Leave them in for backwards compatibility, but the
-        # 'thread' names are really a misnomer now.
-        paa('--wthread', '-wthread',
-            action='store_true', dest='Global.wthread',
-            help=
-            """Enable wxPython event loop integration. (DEPRECATED, use --gui wx)""")
-        paa('--q4thread', '--qthread', '-q4thread', '-qthread',
-            action='store_true', dest='Global.q4thread',
-            help=
-            """Enable Qt4 event loop integration. Qt3 is no longer supported.
-            (DEPRECATED, use --gui qt)""")
-        paa('--gthread', '-gthread',
-            action='store_true', dest='Global.gthread',
-            help=
-            """Enable GTK event loop integration. (DEPRECATED, use --gui gtk)""")
-
 
 #-----------------------------------------------------------------------------
 # Crash handler for this application
@@ -377,206 +115,337 @@ class IPAppCrashHandler(CrashHandler):
 
         return ''.join(report)
 
+#-----------------------------------------------------------------------------
+# Aliases and Flags
+#-----------------------------------------------------------------------------
+flags = dict(base_flags)
+flags.update({
+
+
+})
+addflag = lambda *args: flags.update(boolean_flag(*args))
+addflag('autoindent', 'InteractiveShell.autoindent',
+        'Turn on autoindenting.', 'Turn off autoindenting.'
+)
+addflag('automagic', 'InteractiveShell.automagic',
+        """Turn on the auto calling of magic commands. Type %%magic at the
+        IPython  prompt  for  more information.""",
+        'Turn off the auto calling of magic commands.'
+)
+addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
+        'Turn on auto editing of files with syntax errors.',
+        'Turn off auto editing of files with syntax errors.'
+)
+addflag('banner', 'IPythonApp.display_banner',
+        "Display a banner upon starting IPython.",
+        "Don't display a banner upon starting IPython."
+)
+addflag('pdb', 'InteractiveShell.pdb',
+    "Enable auto calling the pdb debugger after every exception.",
+    "Disable auto calling the pdb debugger after every exception."
+)
+addflag('pprint', 'PlainTextFormatter.pprint',
+    "Enable auto pretty printing of results.",
+    "Disable auto auto pretty printing of results."
+)
+addflag('color-info', 'InteractiveShell.color_info',
+    """IPython can display information about objects via a set of func-
+    tions, and optionally can use colors for this, syntax highlighting
+    source code and various other elements.  However, because this
+    information is passed through a pager (like 'less') and many pagers get
+    confused with color codes, this option is off by default.  You can test
+    it and turn it on permanently in your ipython_config.py file if it
+    works for you.  Test it and turn it on permanently if it works with
+    your system.  The magic function %%color_info allows you to toggle this
+    inter- actively for testing.""",
+    "Disable using colors for info related things."
+)
+addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
+    """Set to confirm when you try to exit IPython with an EOF (Control-D
+    in Unix, Control-Z/Enter in Windows). By typing 'exit', 'quit' or
+    '%%Exit', you can force a direct exit without any confirmation.""",
+    "Don't prompt the user when exiting."
+)
+addflag('deep-reload', 'InteractiveShell.deep_reload',
+    """Enable deep (recursive) reloading by default. IPython can use the
+    deep_reload module which reloads changes in modules recursively (it
+    replaces the reload() function, so you don't need to change anything to
+    use it). deep_reload() forces a full reload of modules whose code may
+    have changed, which the default reload() function does not.  When
+    deep_reload is off, IPython will use the normal reload(), but
+    deep_reload will still be available as dreload(). This fea- ture is off
+    by default [which means that you have both normal reload() and
+    dreload()].""",
+    "Disable deep (recursive) reloading by default."
+)
+addflag('readline', 'InteractiveShell.readline_use',
+    "Enable readline for command line usage.",
+    "Disable readline for command line usage."
+)
+addflag('term-title', 'TerminalInteractiveShell.term_title',
+    "Enable auto setting the terminal title.",
+    "Disable auto setting the terminal title."
+)
+classic_config = Config()
+classic_config.InteractiveShell.cache_size = 0
+classic_config.PlainTextFormatter.pprint = False
+classic_config.InteractiveShell.prompt_in1 = '>>> '
+classic_config.InteractiveShell.prompt_in2 = '... '
+classic_config.InteractiveShell.prompt_out = ''
+classic_config.InteractiveShell.separate_in = ''
+classic_config.InteractiveShell.separate_out = ''
+classic_config.InteractiveShell.separate_out2 = ''
+classic_config.InteractiveShell.colors = 'NoColor'
+classic_config.InteractiveShell.xmode = 'Plain'
+
+flags['classic']=(
+    classic_config,
+    "Gives IPython a similar feel to the classic Python prompt."
+)
+# # log doesn't make so much sense this way anymore
+# paa('--log','-l',
+#     action='store_true', dest='InteractiveShell.logstart',
+#     help="Start logging to the default log file (./ipython_log.py).")
+#
+# # quick is harder to implement
+flags['quick']=(
+    {'IPythonApp' : {'quick' : True}},
+    "Enable quick startup with no config files."
+)
+
+nosep_config = Config()
+nosep_config.InteractiveShell.separate_in = ''
+nosep_config.InteractiveShell.separate_out = ''
+nosep_config.InteractiveShell.separate_out2 = ''
+
+flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
+
+flags['i'] = (
+    {'IPythonApp' : {'force_interact' : True}},
+    "If running code from the command line, become interactive afterwards."
+)
+flags['pylab'] = (
+    {'IPythonApp' : {'pylab' : 'auto'}},
+    """Pre-load matplotlib and numpy for interactive use with
+    the default matplotlib backend."""
+)
+
+aliases = dict(base_aliases)
+
+# it's possible we don't want short aliases for *all* of these:
+aliases.update(dict(
+    autocall='InteractiveShell.autocall',
+    cache_size='InteractiveShell.cache_size',
+    colors='InteractiveShell.colors',
+    editor='TerminalInteractiveShell.editor',
+    logfile='InteractiveShell.logfile',
+    log_append='InteractiveShell.logappend',
+    pi1='InteractiveShell.prompt_in1',
+    pi2='InteractiveShell.prompt_in1',
+    po='InteractiveShell.prompt_out',
+    sl='TerminalInteractiveShell.screen_length',
+    si='InteractiveShell.separate_in',
+    so='InteractiveShell.separate_out',
+    so2='InteractiveShell.separate_out2',
+    xmode='InteractiveShell.xmode',
+    c='IPythonApp.code_to_run',
+    ext='IPythonApp.extra_extension',
+    gui='IPythonApp.gui',
+    pylab='IPythonApp.pylab',
+))
 
 #-----------------------------------------------------------------------------
 # Main classes and functions
 #-----------------------------------------------------------------------------
 
-class IPythonApp(Application):
+class IPythonApp(BaseIPythonApplication):
     name = u'ipython'
-    #: argparse formats better the 'usage' than the 'description' field
-    description = None
-    usage = usage.cl_usage
-    command_line_loader = IPAppConfigLoader
+    description = usage.cl_usage
+    # command_line_loader = IPAppConfigLoader
     default_config_file_name = default_config_file_name
     crash_handler_class = IPAppCrashHandler
-
-    def create_default_config(self):
-        super(IPythonApp, self).create_default_config()
-        # Eliminate multiple lookups
-        Global = self.default_config.Global
-
-        # Set all default values
-        Global.display_banner = True
+    flags = Dict(flags)
+    aliases = Dict(aliases)
+    classes = [TerminalInteractiveShell, ProfileDir, PlainTextFormatter]
+    # *do* autocreate requested profile
+    auto_create=Bool(True)
+    copy_config_files=Bool(True)
+    # configurables
+    ignore_old_config=Bool(False, config=True,
+        help="Suppress warning messages about legacy config files"
+    )
+    quick = Bool(False, config=True,
+        help="""Start IPython quickly by skipping the loading of config files."""
+    )
+    def _quick_changed(self, name, old, new):
+        if new:
+            self.load_config_file = lambda *a, **kw: None
+            self.ignore_old_config=True
+
+    gui = CaselessStrEnum(('qt','wx','gtk'), config=True,
+        help="Enable GUI event loop integration ('qt', 'wx', 'gtk')."
+    )
+    pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
+        config=True,
+        help="""Pre-load matplotlib and numpy for interactive use,
+        selecting a particular matplotlib backend and loop integration.
+        """
+    )
+    display_banner = Bool(True, config=True,
+        help="Whether to display a banner upon starting IPython."
+    )
+    extensions = List(Unicode, config=True,
+        help="A list of dotted module names of IPython extensions to load."
+    )
+    extra_extension = Unicode('', config=True,
+        help="dotted module name of an IPython extension to load."
+    )
+    def _extra_extension_changed(self, name, old, new):
+        if new:
+            # add to self.extensions
+            self.extensions.append(new)
+
+    # if there is code of files to run from the cmd line, don't interact
+    # unless the --i flag (App.force_interact) is true.
+    force_interact = Bool(False, config=True,
+        help="""If a command or file is given via the command-line,
+        e.g. 'ipython foo.py"""
+    )
+    def _force_interact_changed(self, name, old, new):
+        if new:
+            self.interact = True
+
+    exec_files = List(Unicode, config=True,
+        help="""List of files to run at IPython startup."""
+    )
+    file_to_run = Unicode('', config=True,
+        help="""A file to be run""")
+    def _file_to_run_changed(self, name, old, new):
+        if new and not self.force_interact:
+                self.interact = False
+
+    exec_lines = List(Unicode, config=True,
+        help="""lines of code to run at IPython startup."""
+    )
+    code_to_run = Unicode('', config=True,
+        help="Execute the given command string."
+    )
+    _code_to_run_changed = _file_to_run_changed
+
+    # internal, not-configurable
+    interact=Bool(True)
+
+
+    def initialize(self, argv=None):
+        """Do actions after construct, but before starting the app."""
+        super(IPythonApp, self).initialize(argv)
+        if not self.ignore_old_config:
+            check_for_old_config(self.ipython_dir)
         
-        # If the -c flag is given or a file is given to run at the cmd line
-        # like "ipython foo.py", normally we exit without starting the main
-        # loop.  The force_interact config variable allows a user to override
-        # this and interact.  It is also set by the -i cmd line flag, just
-        # like Python.
-        Global.force_interact = False
-
-        # By default always interact by starting the IPython mainloop.
-        Global.interact = True
-
-        # No GUI integration by default
-        Global.gui = False
-        # Pylab off by default
-        Global.pylab = False
-
-        # Deprecated versions of gui support that used threading, we support
-        # them just for bacwards compatibility as an alternate spelling for
-        # '--gui X'
-        Global.qthread = False
-        Global.q4thread = False
-        Global.wthread = False
-        Global.gthread = False
-
-    def load_file_config(self):
-        if hasattr(self.command_line_config.Global, 'quick'):
-            if self.command_line_config.Global.quick:
-                self.file_config = Config()
-                return
-        super(IPythonApp, self).load_file_config()
-
-    def post_load_file_config(self):
-        if hasattr(self.command_line_config.Global, 'extra_extension'):
-            if not hasattr(self.file_config.Global, 'extensions'):
-                self.file_config.Global.extensions = []
-            self.file_config.Global.extensions.append(
-                self.command_line_config.Global.extra_extension)
-            del self.command_line_config.Global.extra_extension
-
-    def pre_construct(self):
-        config = self.master_config
-
-        if hasattr(config.Global, 'classic'):
-            if config.Global.classic:
-                config.InteractiveShell.cache_size = 0
-                config.PlainTextFormatter.pprint = False
-                config.InteractiveShell.prompt_in1 = '>>> '
-                config.InteractiveShell.prompt_in2 = '... '
-                config.InteractiveShell.prompt_out = ''
-                config.InteractiveShell.separate_in = \
-                    config.InteractiveShell.separate_out = \
-                    config.InteractiveShell.separate_out2 = ''
-                config.InteractiveShell.colors = 'NoColor'
-                config.InteractiveShell.xmode = 'Plain'
-
-        if hasattr(config.Global, 'nosep'):
-            if config.Global.nosep:
-                config.InteractiveShell.separate_in = \
-                config.InteractiveShell.separate_out = \
-                config.InteractiveShell.separate_out2 = ''
-
-        # if there is code of files to run from the cmd line, don't interact
-        # unless the -i flag (Global.force_interact) is true.
-        code_to_run = config.Global.get('code_to_run','')
-        file_to_run = False
-        if self.extra_args and self.extra_args[0]:
-                file_to_run = True
-        if file_to_run or code_to_run:
-            if not config.Global.force_interact:
-                config.Global.interact = False
-
-    def construct(self):
+        # print self.extra_args
+        if self.extra_args:
+            self.file_to_run = self.extra_args[0]
+        # create the shell
+        self.init_shell()
+        # and draw the banner
+        self.init_banner()
+        # Now a variety of things that happen after the banner is printed.
+        self.init_gui_pylab()
+        self.init_extensions()
+        self.init_code()
+
+    def init_shell(self):
+        """initialize the InteractiveShell instance"""
         # I am a little hesitant to put these into InteractiveShell itself.
         # But that might be the place for them
         sys.path.insert(0, '')
 
         # Create an InteractiveShell instance.
-        self.shell = TerminalInteractiveShell.instance(config=self.master_config)
-
-    def post_construct(self):
-        """Do actions after construct, but before starting the app."""
-        config = self.master_config
-        
         # shell.display_banner should always be False for the terminal 
         # based app, because we call shell.show_banner() by hand below
         # so the banner shows *before* all extension loading stuff.
-        self.shell.display_banner = False
-        if config.Global.display_banner and \
-            config.Global.interact:
-            self.shell.show_banner()
+        self.shell = TerminalInteractiveShell.instance(config=self.config,
+                        display_banner=False, profile_dir=self.profile_dir,
+                        ipython_dir=self.ipython_dir)
 
+    def init_banner(self):
+        """optionally display the banner"""
+        if self.display_banner and self.interact:
+            self.shell.show_banner()
         # Make sure there is a space below the banner.
         if self.log_level <= logging.INFO: print
 
-        # Now a variety of things that happen after the banner is printed.
-        self._enable_gui_pylab()
-        self._load_extensions()
-        self._run_exec_lines()
-        self._run_exec_files()
-        self._run_cmd_line_code()
 
-    def _enable_gui_pylab(self):
+    def init_gui_pylab(self):
         """Enable GUI event loop integration, taking pylab into account."""
-        Global = self.master_config.Global
-
-        # Select which gui to use
-        if Global.gui:
-            gui = Global.gui
-        # The following are deprecated, but there's likely to be a lot of use
-        # of this form out there, so we might as well support it for now.  But
-        # the --gui option above takes precedence.
-        elif Global.wthread:
-            gui = inputhook.GUI_WX
-        elif Global.qthread:
-            gui = inputhook.GUI_QT
-        elif Global.gthread:
-            gui = inputhook.GUI_GTK
-        else:
-            gui = None
+        gui = self.gui
 
-        # Using --pylab will also require gui activation, though which toolkit
+        # Using `pylab` will also require gui activation, though which toolkit
         # to use may be chosen automatically based on mpl configuration.
-        if Global.pylab:
+        if self.pylab:
             activate = self.shell.enable_pylab
-            if Global.pylab == 'auto':
+            if self.pylab == 'auto':
                 gui = None
             else:
-                gui = Global.pylab
+                gui = self.pylab
         else:
             # Enable only GUI integration, no pylab
             activate = inputhook.enable_gui
 
-        if gui or Global.pylab:
+        if gui or self.pylab:
             try:
                 self.log.info("Enabling GUI event loop integration, "
-                              "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
+                              "toolkit=%s, pylab=%s" % (gui, self.pylab) )
                 activate(gui)
             except:
                 self.log.warn("Error in enabling GUI event loop integration:")
                 self.shell.showtraceback()
 
-    def _load_extensions(self):
-        """Load all IPython extensions in Global.extensions.
+    def init_extensions(self):
+        """Load all IPython extensions in IPythonApp.extensions.
 
         This uses the :meth:`ExtensionManager.load_extensions` to load all
-        the extensions listed in ``self.master_config.Global.extensions``.
+        the extensions listed in ``self.extensions``.
         """
+        if not self.extensions:
+            return
         try:
-            if hasattr(self.master_config.Global, 'extensions'):
-                self.log.debug("Loading IPython extensions...")
-                extensions = self.master_config.Global.extensions
-                for ext in extensions:
-                    try:
-                        self.log.info("Loading IPython extension: %s" % ext)                        
-                        self.shell.extension_manager.load_extension(ext)
-                    except:
-                        self.log.warn("Error in loading extension: %s" % ext)
-                        self.shell.showtraceback()
+            self.log.debug("Loading IPython extensions...")
+            extensions = self.extensions
+            for ext in extensions:
+                try:
+                    self.log.info("Loading IPython extension: %s" % ext)
+                    self.shell.extension_manager.load_extension(ext)
+                except:
+                    self.log.warn("Error in loading extension: %s" % ext)
+                    self.shell.showtraceback()
         except:
             self.log.warn("Unknown error in loading extensions:")
             self.shell.showtraceback()
 
+    def init_code(self):
+        """run the pre-flight code, specified via exec_lines"""
+        self._run_exec_lines()
+        self._run_exec_files()
+        self._run_cmd_line_code()
+
     def _run_exec_lines(self):
-        """Run lines of code in Global.exec_lines in the user's namespace."""
+        """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
+        if not self.exec_lines:
+            return
         try:
-            if hasattr(self.master_config.Global, 'exec_lines'):
-                self.log.debug("Running code from Global.exec_lines...")
-                exec_lines = self.master_config.Global.exec_lines
-                for line in exec_lines:
-                    try:
-                        self.log.info("Running code in user namespace: %s" %
-                                      line)
-                        self.shell.run_cell(line, store_history=False)
-                    except:
-                        self.log.warn("Error in executing line in user "
-                                      "namespace: %s" % line)
-                        self.shell.showtraceback()
+            self.log.debug("Running code from IPythonApp.exec_lines...")
+            for line in self.exec_lines:
+                try:
+                    self.log.info("Running code in user namespace: %s" %
+                                  line)
+                    self.shell.run_cell(line, store_history=False)
+                except:
+                    self.log.warn("Error in executing line in user "
+                                  "namespace: %s" % line)
+                    self.shell.showtraceback()
         except:
-            self.log.warn("Unknown error in handling Global.exec_lines:")
+            self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
             self.shell.showtraceback()
 
     def _exec_file(self, fname):
@@ -598,35 +467,36 @@ class IPythonApp(Application):
             else:
                 self.log.warn("File does not have a .py or .ipy extension: <%s>"
                                % full_filename)
+
     def _run_exec_files(self):
+        """Run files from IPythonApp.exec_files"""
+        if not self.exec_files:
+            return
+
+        self.log.debug("Running files in IPythonApp.exec_files...")
         try:
-            if hasattr(self.master_config.Global, 'exec_files'):
-                self.log.debug("Running files in Global.exec_files...")
-                exec_files = self.master_config.Global.exec_files
-                for fname in exec_files:
-                    self._exec_file(fname)
+            for fname in self.exec_files:
+                self._exec_file(fname)
         except:
-            self.log.warn("Unknown error in handling Global.exec_files:")
+            self.log.warn("Unknown error in handling IPythonApp.exec_files:")
             self.shell.showtraceback()
 
     def _run_cmd_line_code(self):
-        if hasattr(self.master_config.Global, 'code_to_run'):
-            line = self.master_config.Global.code_to_run
+        """Run code or file specified at the command-line"""
+        if self.code_to_run:
+            line = self.code_to_run
             try:
-                self.log.info("Running code given at command line (-c): %s" %
+                self.log.info("Running code given at command line (c=): %s" %
                               line)
                 self.shell.run_cell(line, store_history=False)
             except:
                 self.log.warn("Error in executing line in user namespace: %s" %
                               line)
                 self.shell.showtraceback()
-            return
+
         # Like Python itself, ignore the second if the first of these is present
-        try:
-            fname = self.extra_args[0]
-        except:
-            pass
-        else:
+        elif self.file_to_run:
+            fname = self.file_to_run
             try:
                 self._exec_file(fname)
             except:
@@ -634,14 +504,14 @@ class IPythonApp(Application):
                               fname)
                 self.shell.showtraceback()
 
-    def start_app(self):
-        if not getattr(self.master_config.Global, 'ignore_old_config', False):
-            check_for_old_config(self.ipython_dir)
-        if self.master_config.Global.interact:
+
+    def start(self):
+        # perform any prexec steps:
+        if self.interact:
             self.log.debug("Starting IPython's mainloop...")
             self.shell.mainloop()
         else:
-            self.log.debug("IPython not interactive, start_app is no-op...")
+            self.log.debug("IPython not interactive...")
 
 
 def load_default_config(ipython_dir=None):
@@ -651,7 +521,8 @@ def load_default_config(ipython_dir=None):
     """
     if ipython_dir is None:
         ipython_dir = get_ipython_dir()
-    cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
+    profile_dir = os.path.join(ipython_dir, 'profile_default')
+    cl = PyFileConfigLoader(default_config_file_name, profile_dir)
     config = cl.load_config()
     return config
 
@@ -659,6 +530,9 @@ def load_default_config(ipython_dir=None):
 def launch_new_instance():
     """Create and run a full blown IPython instance"""
     app = IPythonApp()
+    app.initialize()
+    # print app.config
+    # print app.profile_dir.location
     app.start()
 
 
diff --git a/IPython/lib/irunner.py b/IPython/lib/irunner.py
index c132f58..ac652e5 100755
--- a/IPython/lib/irunner.py
+++ b/IPython/lib/irunner.py
@@ -304,9 +304,7 @@ class IPythonRunner(InteractiveRunner):
     def __init__(self,program = 'ipython',args=None,out=sys.stdout,echo=True):
         """New runner, optionally passing the ipython command to use."""
         
-        args0 = ['--colors','NoColor',
-                 '-pi1','In [\\#]: ',
-                 '-pi2','   .\\D.: ',
+        args0 = ['colors=NoColor',
                  '--no-term-title',
                  '--no-autoindent']
         if args is None: args = args0
diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py
index c829c8e..52130ee 100644
--- a/IPython/testing/tools.py
+++ b/IPython/testing/tools.py
@@ -158,8 +158,8 @@ def default_argv():
 
     return ['--quick', # so no config file is loaded
             # Other defaults to minimize side effects on stdout
-            '--colors=NoColor', '--no-term-title','--no-banner',
-            '--autocall=0']
+            'colors=NoColor', '--no-term-title','--no-banner',
+            'autocall=0']
 
 
 def default_config():
@@ -197,7 +197,7 @@ def ipexec(fname, options=None):
     
     # For these subprocess calls, eliminate all prompt printing so we only see
     # output from script execution
-    prompt_opts = ['--prompt-in1=""', '--prompt-in2=""', '--prompt-out=""']
+    prompt_opts = ['pi1=""', 'pi2=""', 'po=""']
     cmdargs = ' '.join(default_argv() + prompt_opts + options)
     
     _ip = get_ipython()