Created
May 23, 2013 17:38
-
-
Save iamatypeofwalrus/5637895 to your computer and use it in GitHub Desktop.
A simple Python Tab Completer for either system paths OR lists.
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
import os | |
import sys | |
import readline | |
import glob | |
class tabCompleter(object): | |
""" | |
A tab completer that can either complete from | |
the filesystem or from a list. | |
Partially taken from: | |
http://stackoverflow.com/questions/5637124/tab-completion-in-pythons-raw-input | |
""" | |
def pathCompleter(self,text,state): | |
""" | |
This is the tab completer for systems paths. | |
Only tested on *nix systems | |
""" | |
line = readline.get_line_buffer().split() | |
return [x for x in glob.glob(text+'*')][state] | |
def createListCompleter(self,ll): | |
""" | |
This is a closure that creates a method that autocompletes from | |
the given list. | |
Since the autocomplete function can't be given a list to complete from | |
a closure is used to create the listCompleter function with a list to complete | |
from. | |
""" | |
def listCompleter(text,state): | |
line = readline.get_line_buffer() | |
if not line: | |
return [c + " " for c in ll][state] | |
else: | |
return [c + " " for c in ll if c.startswith(line)][state] | |
self.listCompleter = listCompleter | |
if __name__=="__main__": | |
t = tabCompleter() | |
t.createListCompleter(["ab","aa","bcd","bdf"]) | |
readline.set_completer_delims('\t') | |
readline.parse_and_bind("tab: complete") | |
readline.set_completer(t.listCompleter) | |
ans = raw_input("Complete from list ") | |
print ans | |
readline.set_completer(t.pathCompleter) | |
ans = raw_input("What file do you want? ") | |
print ans |
you probably meant
if '~' in text:
text = os.path.expanduser(text)
If you have many items you can easily truncate the results like so:
def set_readline_completion(list_):
def create_completer(list_):
def list_completer(_text, state):
line = readline.get_line_buffer()
if not line:
return [c + " " for c in list_][:25][state]
else:
return [c + " " for c in list_ if c.startswith(line)][:15][state]
return list_completer
listCompleter = create_completer(list_)
readline.set_completer_delims('\t')
readline.parse_and_bind("tab: complete")
readline.set_completer(listCompleter)
although this will lead to some premature path diving... maybe something like this is better if your list is a bunch of pathlike strings (of course if your paths are fs paths you are better off with os.walk or os.scandir):
def set_readline_completion(list_):
def create_completer(list_):
def list_completer(_text, state):
line = readline.get_line_buffer()
if not line:
min_depth = min([s.count(os.sep) for s in list_]) + 1
result_list = [c + " " for c in list_ if c.count(os.sep) <= min_depth]
shuffle(result_list)
return result_list[:25][state]
else:
match_list = [s for s in list_ if s.startswith(line)]
min_depth = min([s.count(os.sep) for s in match_list]) + 1
result_list = [c + " " for c in match_list if c.count(os.sep) <= min_depth]
shuffle(result_list)
return result_list[:15][state]
return list_completer
readline.set_completer(create_completer(list_))
readline.set_completer_delims('\t')
readline.parse_and_bind("tab: complete")
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add tilde
~
support by doing the following: