Last active
August 29, 2015 14:01
-
-
Save Roguelazer/a3cfd3d193072cb688be to your computer and use it in GitHub Desktop.
pythonrc with tab completion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
try: | |
import readline | |
except ImportError: | |
pass | |
else: | |
import itertools | |
import rlcompleter | |
import re | |
import os | |
import atexit | |
import sys | |
import socket | |
def get_all_modules(): | |
import os.path, sys | |
yield 'sys' | |
for p in sys.path: | |
if p and os.path.isdir(p): | |
for root, dirs, files in os.walk(p): | |
base = '' | |
if '.egg-info' in root: | |
continue | |
if '.egg' in root: | |
egg_offset = 0 | |
for i, component in enumerate(root.split(os.sep)): | |
if '.egg' in component: | |
egg_offset = i | |
base = os.sep.join(root.split(os.sep)[egg_offset+1:]).replace(os.sep, '.') | |
else: | |
base = root.replace(p, '').replace(os.sep, '.') | |
if base.startswith('.'): | |
base = base[1:] | |
if base: | |
base += '.' | |
for d in dirs: | |
full_path = os.path.join(root, d) | |
if os.path.exists(os.path.join(full_path, '__init__.py')): | |
yield base + d | |
for item in files: | |
if item == '__init__.py': | |
yield base[:-1] | |
elif item.startswith('__'): | |
continue | |
elif '.py' in item: | |
yield base + re.sub(r'.py[co]?$', '', item) | |
elif item.endswith('.so'): | |
yield base + item[:-3] | |
# custom completer. knows how to complete python keywords (from rlcompleter.Completer) and also | |
# any modules in sys.path | |
class irlcompleter(rlcompleter.Completer): | |
def complete_module(self, text, state, strip_prefix=None): | |
if getattr(self, 'mods', None) is None: | |
mods = set() | |
mods_by_dot = {} | |
for m in get_all_modules(): | |
dot = m.count('.') | |
mods_by_dot.setdefault(dot, set()) | |
mods_by_dot[dot].add(m) | |
mods.add(m) | |
self.mods = mods | |
self.mods_by_dot = mods_by_dot | |
if state == 0: | |
self.mod_matches = {} | |
for k, ms in sorted(self.mods_by_dot.items(), reverse=True): | |
self.mod_matches[k] = list(sorted(m for m in ms if m.lower().startswith(text.lower()))) | |
try: | |
rv = self.mod_matches.get(text.count('.'), list)[state] | |
if strip_prefix: | |
rv = rv[len(strip_prefix):] | |
return rv | |
except IndexError: | |
return None | |
def complete(self, text, state, buf=None): | |
if buf is None: | |
buf = readline.get_line_buffer() | |
if re.match(r'^\s*import ', buf): | |
return self.complete_module(text, state) | |
else: | |
if re.match(r'^\s*from\s+', buf): | |
# trim leading empty fields | |
fields = re.split(r'\s+', buf) | |
#fields = list(itertools.dropwhile(lambda x: not x, | |
if len(fields) <= 2: | |
return self.complete_module(text, state) | |
elif len(fields) == 3: | |
if state == 0: | |
return 'import' | |
else: | |
return None | |
else: | |
search = fields[1] | |
if len(fields) >= 4: | |
search += '.' + fields[3] | |
return self.complete_module(search, state, strip_prefix=(fields[1]+'.')) | |
return rlcompleter.Completer.complete(self,text,state) | |
# Restore our command-line history, and save it when Python exits. | |
history_file = os.path.expanduser("~/.pyhistory") | |
if os.path.exists(history_file): | |
try: | |
readline.read_history_file(history_file) | |
except Exception as e: | |
pass | |
def save_hist(): | |
import readline | |
readline.write_history_file(history_file) | |
atexit.register(save_hist) | |
if 'libedit' in readline.__doc__: | |
readline.parse_and_bind("bind ^I rl_complete") | |
else: | |
readline.parse_and_bind("tab: complete") | |
readline.set_completer(irlcompleter().complete) | |
# make the promt more informative | |
sys.ps1 = 'python %s @ %s >>> ' % ('.'.join(map(str, sys.version_info)), socket.gethostname()) | |
# Clean up the namespace. | |
del sys | |
del socket | |
del os | |
del atexit | |
# vim: set syntax=python expandtab ts=4 sw=4: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment