Adding File Completion to the Entry Widget
May 19, 1998 | Fredrik Lundh
from Tkinter import * import os # # completion entry baseclass. class CompletionEntry(Entry): def __init__(self, master, **kw): apply(Entry.__init__, (self, master), kw) self.bind("<Tab>", self.__tab) self.__state = None, None, None def __tab(self, event): index = self.index(INSERT) value = self.get() prefix, suffix = value[:index], value[index:] # check state state, old_index, old_prefix = self.__state if index != old_index or prefix != old_prefix: state = 0 try: # get next completion match = self.complete(state, prefix, suffix) if match: # insert completion if self.select_present(): self.delete(SEL_FIRST, SEL_LAST) self.insert(index, match) self.select_range(index, index+len(match)) self.icursor(index) self.__state = state+1, index, prefix else: self.__state = 0, index, prefix except IndexError: pass return "break" def complete(self, state, prefix, suffix): return None # override # # file completion class FileEntry(CompletionEntry): def complete(self, state, prefix, suffix): # workaround os.path.isdir buglet path = prefix if path[-1:] in ("/", os.sep): path = path[:-1] # get directory and file prefix if os.path.isdir(path): path, prefix = prefix, "" else: path, prefix = os.path.split(prefix) if state == 0: try: # look for matching files in directory prefix = os.path.normcase(prefix) length = len(prefix) self.__files = [] for file in os.listdir(path): file = os.path.normcase(file) if file[:length] == prefix: if os.path.isdir(os.path.join(path, file)): file = file + os.sep self.__files.append(file) except os.error: self.__files = [] # return next match return self.__files[state][len(prefix):]