Created
November 12, 2012 18:28
-
-
Save ralphbean/4061003 to your computer and use it in GitHub Desktop.
Half-working filename tab-completer. Play with it--it mostly works, but you have to help it along more than you're used to at the command line.
This file contains hidden or 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
#!/usr/bin/env python | |
import readline | |
import os | |
import re | |
# This will tab-complete from the working directory, starting from /, and going | |
# through the sub-directories, but it doesn't behave quite the way you expect. | |
# For instance, it chooses for you if there are two partial matches. | |
# The readline call to def complete_path does not pass a leading "/" in the "text" | |
# variable, so I had to start using get_line_buffer and really don't find much | |
# use for the variables "text" and "state". | |
#RE_SPACE = re.compile(".*\s+$", re.M) # Not sure what this does. | |
possible_completions = os.listdir(".") | |
# This will be changed to a class, so that the list possible_completions can be saved | |
# between calls, rather than using a global definition. | |
def complete_path(text, state): | |
# NOTE THAT THE LEADING / WILL NOT COME THROUGH IN text. This is why only | |
# the line buffer is used below, not the "text" field passed from readline. | |
# Changed the type of "line" to a string. (It was a list in the last | |
# version.) | |
line = readline.get_line_buffer() | |
print "\n" + str(line) + "\n" | |
try: | |
if line == "": | |
# Nothing has been typed yet, so the default starting path is the | |
# working directory. | |
possible_completions = os.listdir(".") | |
elif not "/" in line: | |
# The line is not empty, but does not contain a "/". This must be | |
# a partial file name in the working directory. | |
temporary_completion_list = os.listdir(".") | |
# Keep only the entries where the last sub-string after | |
# the last "/" matches partial_file_name. | |
possible_completions = [] | |
for one_item in temporary_completion_list: | |
this_partial_file_name = one_item.rsplit("/",1)[1] | |
if this_partial_file_name == line: | |
possible_completions.append(one_item) | |
else: | |
# Need to treat a path that refers to a directory, as well as one | |
# that refers to a file or partial file name. | |
try: | |
# Assume that the line typed so far is a directory, and try to | |
# get a listing of its contents. This will handle either e.g. | |
# /home/jenny/mydir/ or /home/jenny/mydir | |
possible_completions = os.listdir(line) | |
except: | |
# In the final version, examine the exception--error 20 from os | |
# is "Not a directory" and will elucidate the problem. | |
# See if the path is a directory followed by a file name or | |
# partial file name. e.g. "/home/jenny/mydir/blah": if the | |
# path does not end in "/", strip off everything to the right | |
# of the last "/", and see if that is a valid directory. | |
if not line.endswith("/"): | |
# If it ends with "/", then it must be a directory name | |
# (valid or not). | |
try: | |
# Strip off the last word. | |
# Example: /home/jenny/mydir/blah --> /home/jenny/mydir/ | |
path, partial_file_name = line.rsplit("/",1) | |
temporary_completion_list = os.listdir(path) | |
# Keep only the entries where the last sub-string after | |
# the last "/" matches partial_file_name. | |
possible_completions = [] | |
for one_item in temporary_completion_list: | |
this_partial_file_name = one_item.rsplit("/",1)[1] | |
if this_partial_file_name == partial_file_name: | |
possible_completions.append(one_item) | |
### This is repeated code and can be moved to another | |
### method. | |
except: | |
# /home/jenny/mydir/ was not a valid directory. | |
try: | |
# See if the line refers to a directory followed by a | |
# If nothing works, don't try any more completion. The | |
# user will have to fix the path. | |
pass | |
except: | |
pass | |
for one_file in possible_completions: | |
if one_file.startswith(text) and state == 0: | |
return one_file | |
else: | |
state -= 1 | |
print os.listdir("/home/hayes/testing.py") | |
readline.parse_and_bind("tab: complete") | |
readline.set_completer(complete_path) | |
while True: | |
file_name = raw_input("Enter file name: ") | |
print file_name | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There's a new working version in good shape on gist https://gist.github.com/4040404/ with credits in the comments.