diff --git a/.bashrc b/.bashrc
index 87b863d0052d00895abe45334745987372aa5b53..8af1def1a1ebdaca3c56866c6492b36ac5bb7bc0 100644
--- a/.bashrc
+++ b/.bashrc
@@ -16,7 +16,7 @@ export PATH="$HOME/Documents/Shore/ssl-ca:$PATH"
 export PATH="$HOME/.cargo/bin:$PATH"
 export PATH="$HOME/.cabal/bin:$PATH"
 export PATH="$HOME/Documents/bin:$PATH"
-export PYTHONSTARTUP=~/.config/python/startup.py
+export PYTHONSTARTUP=~/.config/pythonrc/pythonrc.py
 export AWS_DEFAULT_PROFILE='shore'
 export ANSIBLE_VERBOSITY=2
 export ANSIBLE_COMMAND_WARNINGS=True
diff --git a/.config/python/startup/10_pythonrc.py b/.config/python/startup/10_pythonrc.py
deleted file mode 100644
index 80407af81aee8bbae7140068b969c9c42b2c778a..0000000000000000000000000000000000000000
--- a/.config/python/startup/10_pythonrc.py
+++ /dev/null
@@ -1,561 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# The MIT License (MIT)
-#
-# Copyright (c) 2015-2017 Steven Fernandez
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-"""pymp - lonetwin's pimped-up pythonrc
-
-This file will be executed when the Python interactive shell is started, if
-$PYTHONSTARTUP is in your environment and points to this file. You could
-also make this file executable and call it directly.
-
-This file creates an InteractiveConsole instance, which provides:
-  * execution history
-  * colored prompts and pretty printing
-  * auto-indentation
-  * intelligent tab completion:¹
-  * source code listing for objects
-  * session history editing using your $EDITOR, as well as editing of
-    source files for objects or regular files
-  * temporary escape to $SHELL or ability to execute a shell command and
-    capturing the result into the '_' variable
-  * convenient printing of doc stings and search for entries in online docs
-  * auto-execution of a virtual env specific (`.venv_rc.py`) file at startup
-
-If you have any other good ideas please feel free to submit issues/pull requests.
-
-¹ Since python 3.4 the default interpreter also has tab completion
-enabled however it does not do pathname completion
-"""
-
-
-# Fix for Issue #5
-# - Exit if being called from within ipython
-try:
-    import sys
-    __IPYTHON__ and sys.exit(0)
-except NameError:
-    pass
-
-try:
-    import builtins
-except ImportError:
-    import __builtin__ as builtins
-import atexit
-import glob
-import inspect
-import keyword
-import os
-import pkgutil
-import pprint
-import re
-import readline
-import rlcompleter
-import shlex
-import signal
-import subprocess
-import webbrowser
-
-from code import InteractiveConsole
-from collections import namedtuple
-from functools import partial
-from tempfile import NamedTemporaryFile
-
-
-__version__ = "0.6.4"
-
-
-config = dict(
-    HISTFILE = os.path.expanduser("~/.python_history"),
-    HISTSIZE = -1,
-    EDITOR   = os.getenv('EDITOR', 'vi'),
-    SHELL    = os.getenv('SHELL', '/bin/bash'),
-    EDIT_CMD = '\e',
-    SH_EXEC  = '!',
-    DOC_CMD  = '?',
-    DOC_URL  = "https://docs.python.org/{sys.version_info.major}/search.html?q={term}",
-    HELP_CMD = '\h',
-    LIST_CMD = '\l',
-    VENV_RC  = ".venv_rc.py"
-)
-
-
-class ImprovedConsole(InteractiveConsole, object):
-    """
-    Welcome to lonetwin's pimped up python prompt
-
-    You've got color, tab completion, auto-indentation, pretty-printing
-    and more !
-
-    * A tab with preceding text will attempt auto-completion of
-      keywords, names in the current namespace, attributes and methods.
-      If the preceding text has a '/', filename completion will be
-      attempted. Without preceding text four spaces will be inserted.
-
-    * History will be saved in {HISTFILE} when you exit.
-
-    * If you create a file named {VENV_RC} in the current directory, the
-      contents will be executed in this session before the prompt is
-      shown.
-
-    * Typing out a defined name followed by a '{DOC_CMD}' will print out
-      the object's __doc__ attribute if one exists.
-      (eg: []? / str? / os.getcwd? )
-
-    * Typing '{DOC_CMD}{DOC_CMD}' after something will search for the
-      term at {DOC_URL}
-      (eg: try webbrowser.open??)
-
-    * Open the your editor with current session history, source code of
-      objects or arbitrary files, using the '{EDIT_CMD}' command.
-
-    * List source code for objects using the '{LIST_CMD}' command.
-
-    * Execute shell commands using the '{SH_EXEC}' command.
-
-    Try `<cmd> -h` for any of the commands to learn more.
-
-    The EDITOR, SHELL, command names and more can be changed in the
-    config dict at the top of this file. Make this your own !
-    """
-
-    def __init__(self, tab='    ', *args, **kwargs):
-        self.session_history = []  # This holds the last executed statements
-        self.buffer = []           # This holds the statement to be executed
-        self.tab = tab
-        self._indent = ''
-        super(ImprovedConsole, self).__init__(*args, **kwargs)
-        self.init_color_functions()
-        self.init_readline()
-        self.init_prompt()
-        self.init_pprint()
-
-    def init_color_functions(self):
-        """Populates globals dict with some helper functions for colorizing text
-        """
-        def colorize(color_code, text, bold=True, readline_workaround=False):
-            reset = '\033[0m'
-            color = '\033[{0}{1}m'.format('1;' if bold else '', color_code)
-            # - reason for readline_workaround: http://bugs.python.org/issue20359
-            if readline_workaround:
-                color = '\001{color}\002'.format(color=color)
-                reset = '\001{reset}\002'.format(reset=reset)
-            return "{color}{text}{reset}".format(**vars())
-
-        g = globals()
-        for code, color in enumerate(['red', 'green', 'yellow', 'blue', 'purple', 'cyan'], 31):
-            g[color] = partial(colorize, code)
-
-    def init_readline(self):
-        """Activates history and tab completion
-        """
-        # - mainly borrowed from site.enablerlcompleter() from py3.4+
-
-        # Reading the initialization (config) file may not be enough to set a
-        # completion key, so we set one first and then read the file.
-        readline_doc = getattr(readline, '__doc__', '')
-        if readline_doc is not None and 'libedit' in readline_doc:
-            readline.parse_and_bind('bind ^I rl_complete')
-        else:
-            readline.parse_and_bind('tab: complete')
-
-        try:
-            readline.read_init_file()
-        except OSError:
-            # An OSError here could have many causes, but the most likely one
-            # is that there's no .inputrc file (or .editrc file in the case of
-            # Mac OS X + libedit) in the expected location.  In that case, we
-            # want to ignore the exception.
-            pass
-
-        if readline.get_current_history_length() == 0:
-            # If no history was loaded, default to .python_history.
-            # The guard is necessary to avoid doubling history size at
-            # each interpreter exit when readline was already configured
-            # see: http://bugs.python.org/issue5845#msg198636
-            try:
-                readline.read_history_file(config['HISTFILE'])
-            except IOError:
-                pass
-            atexit.register(readline.write_history_file,
-                            config['HISTFILE'])
-        readline.set_history_length(config['HISTSIZE'])
-
-        # - replace default completer
-        readline.set_completer(self.improved_rlcompleter())
-
-        # - enable auto-indenting
-        readline.set_pre_input_hook(self.auto_indent_hook)
-
-    def init_prompt(self):
-        """Activates color on the prompt based on python version.
-
-        Also adds the hosts IP if running on a remote host over a
-        ssh connection.
-        """
-        prompt_color = green if sys.version_info.major == 2 else yellow
-        sys.ps1 = prompt_color('>>> ', readline_workaround=True)
-        sys.ps2 = red('... ', readline_workaround=True)
-        # - if we are over a remote connection, modify the ps1
-        if os.getenv('SSH_CONNECTION'):
-            _, _, this_host, _ = os.getenv('SSH_CONNECTION').split()
-            sys.ps1 = prompt_color('[{}]>>> '.format(this_host), readline_workaround=True)
-            sys.ps2 = red('[{}]... '.format(this_host), readline_workaround=True)
-
-    def init_pprint(self):
-        """Activates pretty-printing of output values.
-        """
-        keys_re = re.compile(r'([\'\("]+(.*?[\'\)"]: ))+?')
-        color_dict = partial(keys_re.sub, lambda m: purple(m.group()))
-        format_func = pprint.pformat
-        if sys.version_info.major > 3 and sys.version.minor > 3:
-            format_func = partial(pprint.pformat, compact=True)
-
-        def pprint_callback(value):
-            if value is not None:
-                try:
-                    rows, cols = os.get_teminal_size()
-                except AttributeError:
-                    try:
-                        rows, cols = map(int, subprocess.check_output(['stty', 'size']).split())
-                    except:
-                        cols = 80
-                builtins._ = value
-                formatted = format_func(value, width=cols)
-                print(color_dict(formatted) if issubclass(type(value), dict) else blue(formatted))
-
-        sys.displayhook = pprint_callback
-
-    def improved_rlcompleter(self):
-        """Enhances the default rlcompleter
-
-        The function enhances the default rlcompleter by also doing
-        pathname completion and module name completion for import
-        statements. Additionally, it inserts a tab instead of attempting
-        completion if there is no preceding text.
-        """
-        completer = rlcompleter.Completer(namespace=self.locals)
-        # - remove / from the delimiters to help identify possibility for path completion
-        readline.set_completer_delims(readline.get_completer_delims().replace('/', ''))
-        modlist = frozenset(name for _, name, _ in pkgutil.iter_modules())
-
-        def complete_wrapper(text, state):
-            line = readline.get_line_buffer().strip()
-            if line == '':
-                return None if state > 0 else self.tab
-            if state == 0:
-                if line.startswith('import') or line.startswith('from'):
-                    completer.matches = [name for name in modlist if name.startswith(text)]
-                else:
-                    match = completer.complete(text, state)
-                    if match is None and '/' in text:
-                        completer.matches = glob.glob(text+'*')
-            try:
-                match = completer.matches[state]
-                return '{}{}'.format(match, ' ' if keyword.iskeyword(match) else '')
-            except IndexError:
-                return None
-        return complete_wrapper
-
-    def auto_indent_hook(self):
-        """Hook called by readline between printing the prompt and
-        starting to read input.
-        """
-        readline.insert_text(self._indent)
-        readline.redisplay()
-
-    def raw_input(self, *args):
-        """Read the input and delegate if necessary.
-        """
-        line = InteractiveConsole.raw_input(self, *args)
-        if line == config['HELP_CMD']:
-            print(cyan(self.__doc__).format(**config))
-            line = ''
-        elif line.startswith(config['EDIT_CMD']):
-            offset = len(config['EDIT_CMD'])
-            line = self.process_edit_cmd(line[offset:].strip())
-        elif line.startswith(config['SH_EXEC']):
-            offset = len(config['SH_EXEC'])
-            line = self.process_sh_cmd(line[offset:].strip())
-        elif line.startswith(config['LIST_CMD']):
-            # - strip off the possible tab-completed '('
-            line = line.rstrip('(')
-            offset = len(config['LIST_CMD'])
-            line = self.process_list_cmd(line[offset:].strip())
-        elif line.endswith(config['DOC_CMD']):
-            if line.endswith(config['DOC_CMD']*2):
-                # search for line in online docs
-                # - strip off the '??' and the possible tab-completed
-                # '(' or '.' and replace inner '.' with '+' to create the
-                # query search string
-                line = line.rstrip(config['DOC_CMD'] + '.(').replace('.', '+')
-                webbrowser.open(config['DOC_URL'].format(sys=sys, term=line))
-                line = ''
-            else:
-                line = line.rstrip(config['DOC_CMD'] + '.(')
-                if not line:
-                    line = 'dir()'
-                elif keyword.iskeyword(line):
-                    line = 'help("{}")'.format(line)
-                else:
-                    line = 'print({}.__doc__)'.format(line)
-        elif line.startswith(self.tab) or self._indent:
-            if line.strip():
-                # if non empty line with an indent, check if the indent
-                # level has been changed
-                leading_space = line[:line.index(line.lstrip()[0])]
-                if self._indent != leading_space:
-                    # indent level changed, update self._indent
-                    self._indent = leading_space
-            else:
-                # - empty line, decrease indent
-                self._indent = self._indent[:-len(self.tab)]
-                line = self._indent
-        elif line.startswith('%'):
-            self.writeline('Y U NO LIKE ME?')
-            return line
-        return line or ''
-
-    def push(self, line):
-        """Wrapper around InteractiveConsole's push method for adding an
-        indent on start of a block.
-        """
-        more = super(ImprovedConsole, self).push(line)
-        if more:
-            if line[-1] in (":", '[', '{', '('):
-                self._indent += self.tab
-        else:
-            self._indent = ''
-        return more
-
-    def write(self, data):
-        """Write out data to stderr
-        """
-        sys.stderr.write(red(data))
-
-    def writeline(self, data):
-        """Same as write but adds a newline to the end
-        """
-        return self.write('{}\n'.format(data))
-
-    def resetbuffer(self):
-        self._indent = ''
-        previous = ''
-        for line in self.buffer:
-            # - replace multiple empty lines with one before writing to session history
-            stripped = line.strip()
-            if stripped or stripped != previous:
-                self.session_history.append(line)
-            previous = stripped
-        return super(ImprovedConsole, self).resetbuffer()
-
-    def _doc_to_usage(method):
-        def inner(self, arg):
-            arg = arg.strip()
-            if arg.startswith('-h') or arg.startswith('--help'):
-                return self.writeline(blue(method.__doc__.strip().format(**config)))
-            return method(self, arg)
-        return inner
-
-    def _mktemp_buffer(self, lines):
-        """Writes lines to a temp file and returns the filename.
-        """
-        with NamedTemporaryFile(mode='w+', suffix='.py', delete=False) as tempbuf:
-            tempbuf.write('\n'.join(lines))
-        return tempbuf.name
-
-    def _exec_from_file(self, filename, quiet=False):
-        previous = ''
-        for stmt in open(filename):
-            # - skip over multiple empty lines
-            stripped = stmt.strip()
-            if stripped == '' and stripped == previous:
-                continue
-            if not quiet:
-                self.write(cyan("... {}".format(stmt)))
-            if not stripped.startswith('#'):
-                line = stmt.strip('\n')
-                self.push(line)
-                readline.add_history(line)
-            previous = stripped
-
-    def lookup(self, name, namespace=None):
-        """Lookup the (dotted) object specified with the string `name`
-        in the specified namespace or in the current namespace if
-        unspecified.
-        """
-        components = name.split('.', 1)
-        name = components.pop(0)
-        obj = getattr(namespace, name, namespace) if namespace else self.locals.get(name)
-        return self.lookup(components[0], obj) if components else obj
-
-    @_doc_to_usage
-    def process_edit_cmd(self, arg=''):
-        """{EDIT_CMD} [object|filename]
-
-        Open {EDITOR} with session history, provided filename or
-        object's source file.
-
-        - without arguments, a temporary file containing session history is
-          created and opened in {EDITOR}. On quitting the editor, all
-          the non commented lines in the file are executed.
-
-        - with a filename argument, the file is opened in the editor. On
-          close, you are returned bay to the interpreter.
-
-        - with an object name argument, an attempt is made to lookup the
-          source file of the object and it is opened if found. Else the
-          argument is treated as a filename.
-        """
-        if arg:
-            obj = self.lookup(arg)
-            try:
-                filename = inspect.getsourcefile(obj) if obj else arg
-            except (IOError, TypeError, NameError) as e:
-                return self.writeline(e)
-        else:
-            # - make a list of all lines in session history, commenting
-            # any non-blank lines.
-            filename = self._mktemp_buffer("# {}".format(line) if line else ''
-                                           for line in (line.strip('\n') for line in self.session_history))
-
-        # - shell out to the editor
-        os.system('{} {}'.format(config['EDITOR'], filename))
-
-        # - if arg was not provided (we edited session history), execute
-        # it in the current namespace
-        if not arg:
-            self._exec_from_file(filename)
-            os.unlink(filename)
-
-    @_doc_to_usage
-    def process_sh_cmd(self, cmd):
-        """{SH_EXEC} [cmd [args ...] | {{fmt string}}]
-
-        Escape to {SHELL} or execute `cmd` in {SHELL}
-
-        - without arguments, the current interpreter will be suspended
-          and you will be dropped in a {SHELL} prompt. Use fg to return.
-
-        - with arguments, the text will be executed in {SHELL} and the
-          output/error will be displayed. Additionally '_' will contain
-          a named tuple with the (<stdout>, <stderror>, <return_code>)
-          for the execution of the command.
-
-          You may pass strings from the global namespace to the command
-          line using the `.format()` syntax. for example:
-
-        >>> filename = '/does/not/exist'
-        >>> !ls {{filename}}
-        ls: cannot access /does/not/exist: No such file or directory
-        >>> _
-        CmdExec(out='', err='ls: cannot access /does/not/exist: No such file or directory\n', rc=2)
-        """
-        if cmd:
-            try:
-                cmd = cmd.format(**self.locals)
-                cmd = shlex.split(cmd)
-                if cmd[0] == 'cd':
-                    os.chdir(os.path.expanduser(os.path.expandvars(' '.join(cmd[1:]) or '${HOME}')))
-                else:
-                    cmd_exec = namedtuple('CmdExec', ['out', 'err', 'rc'])
-                    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-                    out, err = process.communicate()
-                    rc = process.returncode
-                    print (red(err.decode('utf-8')) if err else green(out.decode('utf-8'), bold=False))
-                    builtins._ = cmd_exec(out, err, rc)
-                    del cmd_exec
-            except:
-                self.showtraceback()
-        else:
-            if os.getenv('SSH_CONNECTION'):
-                # I use the bash function similar to the one below in my
-                # .bashrc to directly open a python prompt on remote
-                # systems I log on to.
-                #   function rpython { ssh -t $1 -- "python" }
-                # Unfortunately, suspending this ssh session, does not place me
-                # in a shell, so I need to create one:
-                os.system(config['SHELL'])
-            else:
-                os.kill(os.getpid(), signal.SIGSTOP)
-
-    @_doc_to_usage
-    def process_list_cmd(self, arg):
-        """
-        {LIST_CMD} <object> - List source code for object, if possible.
-        """
-        try:
-            if not arg:
-                self.writeline('source list command requires an argument '
-                               '(eg: {} foo)\n'.format(config['LIST_CMD']))
-            src_lines, offset = inspect.getsourcelines(self.lookup(arg))
-        except (IOError, TypeError, NameError) as e:
-            self.writeline(e)
-        else:
-            for line_no, line in enumerate(src_lines, offset+1):
-                self.write(cyan("{0:03d}: {1}".format(line_no, line)))
-
-    def interact(self):
-        """A forgiving wrapper around InteractiveConsole.interact()
-        """
-        venv_rc_done = '(no venv rc found)'
-        try:
-            self._exec_from_file(config['VENV_RC'], quiet=True)
-            venv_rc_done = green('Successfully executed venv rc !')
-        except IOError:
-            pass
-
-        banner = ("Welcome to the ImprovedConsole (version {version})\n"
-                  "Type in {HELP_CMD} for list of features.\n"
-                  "{venv_rc_done}").format(
-                      version=__version__, venv_rc_done=venv_rc_done, **config)
-
-        retries = 2
-        while retries:
-            try:
-                super(ImprovedConsole, self).interact(banner=banner)
-            except SystemExit:
-                # Fixes #2: exit when 'quit()' invoked
-                break
-            except:
-                import traceback
-                retries -= 1
-                print(red("I'm sorry, ImprovedConsole could not handle that !\n"
-                          "Please report an error with this traceback, "
-                          "I would really appreciate that !"))
-                traceback.print_exc()
-
-                print(red("I shall try to restore the crashed session.\n"
-                          "If the crash occurs again, please exit the session"))
-                banner = blue("Your crashed session has been restored")
-            else:
-                # exit with a Ctrl-D
-                break
-
-        # Exit the Python shell on exiting the InteractiveConsole
-        sys.exit()
-
-
-if not os.getenv('SKIP_PYMP'):
-    # - create our pimped out console and fire it up !
-    pymp = ImprovedConsole()
-    pymp.interact()
diff --git a/.config/python/startup/50_pprint.py b/.config/python/startup/50_pprint.py
deleted file mode 100755
index 9f9a1997e2841f7209444abb3007575c05409d38..0000000000000000000000000000000000000000
--- a/.config/python/startup/50_pprint.py
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env python
-from pprint import PrettyPrinter
-pprint = PrettyPrinter().pprint
diff --git a/.config/pythonrc b/.config/pythonrc
new file mode 160000
index 0000000000000000000000000000000000000000..d9f2c7a9caf0076c011bbe0aa42fca641432ea57
--- /dev/null
+++ b/.config/pythonrc
@@ -0,0 +1 @@
+Subproject commit d9f2c7a9caf0076c011bbe0aa42fca641432ea57
diff --git a/.githooks/post-merge b/.githooks/post-merge
index 42ae6f97a5f7f781b61f4def2e2b6d82a30aaa34..3b0fd3c72aa5755c7c87d09f4a7180fd283d2d3c 100755
--- a/.githooks/post-merge
+++ b/.githooks/post-merge
@@ -9,8 +9,6 @@ echo Loading dconf config >> /dev/stderr
 Documents/bin/dconf-load
 echo Configuring Git repo >> /dev/stderr
 git config --local status.showUntrackedFiles no
-echo Creating Python startup file >> /dev/stderr
-Documents/bin/gen-python-startup
 echo Creating Bash completion scripts >> /dev/stderr
 Documents/bin/gen-bash-completion
 echo Adding Cron job >> /dev/stderr
diff --git a/.gitmodules b/.gitmodules
index 8479cf99a040d5c69dce5c0c06400fbca90b09a7..2f43042a0e50abb675312a69b942b44217a887f0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -21,3 +21,6 @@
 [submodule "Documents/Shore/poquita"]
     path = Documents/Shore/poquita
     url = https://www.shore.co.il/git/poquita
+[submodule ".config/pythonrc"]
+	path = .config/pythonrc
+	url = https://github.com/lonetwin/pythonrc.git
diff --git a/Documents/bin/gen-python-startup b/Documents/bin/gen-python-startup
deleted file mode 100755
index e25b6cc6e3779fd85fff136782d237b9ba3f16fb..0000000000000000000000000000000000000000
--- a/Documents/bin/gen-python-startup
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-set -eu
-find "$HOME/.config/python/startup" -type f \! -name '.*' -print0 | sort --zero | xargs -0 cat > "$HOME/.config/python/startup.py"