Skip to content

Instantly share code, notes, and snippets.

@ralphbean
Created November 12, 2012 18:28
Show Gist options
  • Save ralphbean/4061003 to your computer and use it in GitHub Desktop.
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.
#!/usr/bin/env python
import readline
import os
import re
import sys
# 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 = []
# 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.)
def db(line):
line = line + "\n"
with open("debugging.txt","a") as f:
f.write(line)
line = readline.get_line_buffer()
# print "\n" + str(line) + "\n"
# db(line)
# Expand the user name "~" if it is in line. It does not necessarily exist.
line = os.path.expanduser(line)
# REMEMBER TO EXPAND ALL PATHS.
if line == "":
# Use the working directory to start.
directory = os.path.abspath(".")
basename = ""
# Split the line into base name (blah.txt) and directory (/home/jenny
# without the end slash). "/home" has base name "home" and directory "/".
# "/home/" has base name "" and directory "/home".
else:
base_name = os.path.basename(line)
directory = os.path.dirname(line)
if directory == "":
directory = os.path.abspath(".")
db("dir " + directory + " base " + base_name + " line " + line)
if os.path.exists(directory):
if os.path.isdir(directory):
base_name = ""
if not line.endswith("/"):
directory = directory + "/"
if not os.path.exists(directory):
possible_completions = []
else:
# Find all files in this directory.
possible_completions = os.listdir(directory)
db(line + " " + str(possible_completions))
for one in possible_completions:
if state < len(possible_completions):
if line in one or line == "" or line == directory or basename in one:
return one
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
Copy link

ghost commented Nov 12, 2012

There's a new working version in good shape on gist https://gist.github.com/4040404/ with credits in the comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment