def Matches(self, comp): # type: (Api) -> Iterator[Union[Iterator, Iterator[str]]] to_complete = comp.to_complete # Problem: .. and ../.. don't complete /. # TODO: Set display_pos before fixing this. #import os #to_complete = os.path.normpath(to_complete) dirname, basename = os_path.split(to_complete) if dirname == '': # We're completing in this directory to_list = '.' else: # We're completing in some other directory to_list = dirname if 0: log('basename %r', basename) log('to_list %r', to_list) log('dirname %r', dirname) try: names = posix.listdir(to_list) except OSError as e: return # nothing for name in names: path = os_path.join(dirname, name) if path.startswith(to_complete): if self.dirs_only: # add_slash not used here # NOTE: There is a duplicate isdir() check later to add a trailing # slash. Consolidate the checks for fewer stat() ops. This is hard # because all the completion actions must obey the same interface. # We could have another type like candidate = File | Dir | # OtherString ? if path_stat.isdir(path): yield path continue if self.exec_only: # TODO: Handle exception if file gets deleted in between listing and # check? if not posix.access(path, posix.X_OK_): continue if self.add_slash and path_stat.isdir(path): yield path + '/' else: yield path
def Matches(self, comp): # type: (Api) -> Iterator[Union[Iterator, Iterator[str]]] """ TODO: Cache is never cleared. - When we get a newer timestamp, we should clear the old one. - When PATH is changed, we can remove old entries. """ val = self.mem.GetVar('PATH') if val.tag_() != value_e.Str: # No matches if not a string return assert isinstance(val, value__Str) # for MyPy path_dirs = val.s.split(':') #log('path: %s', path_dirs) executables = [] # type: List[str] for d in path_dirs: try: st = posix.stat(d) except OSError as e: # There could be a directory that doesn't exist in the $PATH. continue key = (d, st.st_mtime) dir_exes = self.cache.get(key) if dir_exes is None: entries = posix.listdir(d) dir_exes = [] for name in entries: path = os_path.join(d, name) # TODO: Handle exception if file gets deleted in between listing and # check? if not posix.access(path, posix.X_OK_): continue dir_exes.append(name) # append the name, not the path self.cache[key] = dir_exes executables.extend(dir_exes) # TODO: Shouldn't do the prefix / space thing ourselves. readline does # that at the END of the line. for word in executables: if word.startswith(comp.to_complete): yield word
def testFoo(self): print(posix_.getcwd()) # Testing this because I removed a lot of #ifdef entries = posix_.listdir('.') self.assert_('doc' in entries)