def read(self, folder, base=None): """return all files in folder""" folder_cache = {} base = base if base is not None else folder # test ignore expressions on current path for test in self.exclude_folders: if re.search(test, folder) is not None: verbose(ID, "skip " + folder) return folder_cache # ressources = for ressource in os.listdir(folder): current_path = os.path.join(folder, ressource) if (os.path.isfile(current_path)): relative_path = os.path.relpath(current_path, base) filename, extension = os.path.splitext(relative_path) extension = extension[1:] # posix required for windows, else absolute paths are wrong: /asd\ads\ relative_path = re.sub("\$", config["ESCAPE_DOLLAR"], posix(relative_path)) if extension in self.extensions: # $ hack, reversed in post_commit_completion folder_cache[relative_path] = [re.sub("\$", config["ESCAPE_DOLLAR"], posix(filename)), extension, posix(filename) + "\t" + extension] elif (not ressource.startswith('.') and os.path.isdir(current_path)): folder_cache.update(self.read(current_path, base)) return folder_cache
def search_completions(self, needle, project_folder, valid_extensions, base_path=False): """ retrieves a list of valid completions, containing fuzzy searched needle Parameters ---------- needle : string -- to search in files project_folder : string -- folder to search in, cached via add valid_extensions : array -- list of valid file extensions base_path : string -- of current file, creates a relative path if not False with_extension : boolean -- insert extension return : List -- containing sublime completions """ project_files = self.get_files(project_folder) if (project_files is None): return False # basic: strip any dots needle = re.sub("\.\./", "", needle) needle = re.sub("\.\/", "", needle) # remove starting slash needle = re.sub("^\/", "", needle) # cleanup needle = re.sub('["\'\(\)$]', '', needle) # build search expression regex = ".*" for i in needle: regex += i + ".*" verbose(ID, "scan", len(project_files), "files for", needle, valid_extensions) # get matching files result = [] for filepath in project_files: properties = project_files.get(filepath) """ properties[0] = escaped filename without extension, like "test/mock/project/index" properties[1] = file extension, like "html" properties[2] = file displayed as suggestion, like 'test/mock/project/index html' """ if ((properties[1] in valid_extensions or "*" in valid_extensions) and re.match(regex, filepath, re.IGNORECASE)): completion = self.get_completion(filepath, properties[2], base_path) result.append(completion) return (result, sublime.INHIBIT_EXPLICIT_COMPLETIONS | sublime.INHIBIT_WORD_COMPLETIONS)
def update(self, folder, file_name=None): if file_name and self.file_is_cached(folder, file_name): return False if self.folder_is_cached(folder): # del self.cache[folder] return False verbose(ID_CACHE, "UPDATE", folder) self.cache[folder] = FileCache(self.exclude_folders, self.valid_extensions, folder) self.cache.get(folder).start(); return True
def update(self, folder, file_name=None): if file_name and self.file_is_cached(folder, file_name): return False if self.folder_is_cached(folder): # del self.cache[folder] return False verbose(ID_CACHE, "UPDATE", folder) self.cache[folder] = FileCache(self.exclude_folders, self.valid_extensions, folder) self.cache.get(folder).start() return True
def on_query_completions(self, view, prefix, locations): if config["DISABLE_AUTOCOMPLETION"] and not Query.by_command(): return False if self.is_project_file: completions = query_completions(view, self.project_folder, self.current_folder) if completions: # st2 - update current path self.post_remove = Context.get_context(view)["needle"] return completions else: verbose("disabled or not a project", self.is_project_file) return False
def search_completions(self, needle, project_folder, valid_extensions, base_path=False): """ retrieves a list of valid completions, containing fuzzy searched needle Parameters ---------- needle : string -- to search in files project_folder : string -- folder to search in, cached via add valid_extensions : array -- list of valid file extensions base_path : string -- of current file, creates a relative path if not False with_extension : boolean -- insert extension return : List -- containing sublime completions """ project_files = self.get_files(project_folder) if (project_files is None): return False # basic: strip any dots needle = re.sub("\.\./", "", needle) needle = re.sub("\.\/", "", needle) # remove starting slash needle = re.sub("^\/", "", needle) # cleanup needle = re.sub('["\'\(\)$]', '', needle) # build search expression regex = ".*" for i in needle: regex += i + ".*" verbose(ID, "scan", len(project_files), "files for", needle, valid_extensions); # get matching files result = [] for filepath in project_files: properties = project_files.get(filepath) """ properties[0] = escaped filename without extension, like "test/mock/project/index" properties[1] = file extension, like "html" properties[2] = file displayed as suggestion, like 'test/mock/project/index html' """ if ((properties[1] in valid_extensions or "*" in valid_extensions) and re.match(regex, filepath, re.IGNORECASE)): completion = self.get_completion(filepath, properties[2], base_path) result.append(completion) return (result, sublime.INHIBIT_EXPLICIT_COMPLETIONS | sublime.INHIBIT_WORD_COMPLETIONS)
def file_is_cached(self, folder, file_name=None): """ returns False if the given file is not within cache Parameters ---------- folder : string -- of project file_name : string -- optional, file to test """ if file_name is None: return self.folder_is_cached(folder) name, extension = os.path.splitext(file_name) extension = extension[1:] if not extension in self.valid_extensions: verbose(ID_CACHE, "file to cache has no valid extension", extension) return True if self.folder_is_cached(folder): file_name = file_name.replace(folder + '/', "") if (self.cache.get(folder).files.get(file_name)): return True return False
def read(self, folder, base=None): """return all files in folder""" folder_cache = {} base = base if base is not None else folder # test ignore expressions on current path for test in self.exclude_folders: if re.search(test, folder) is not None: verbose(ID, "skip " + folder) return folder_cache # ressources = for ressource in os.listdir(folder): current_path = os.path.join(folder, ressource) if (os.path.isfile(current_path)): relative_path = os.path.relpath(current_path, base) filename, extension = os.path.splitext(relative_path) extension = extension[1:] # posix required for windows, else absolute paths are wrong: /asd\ads\ relative_path = re.sub("\$", config["ESCAPE_DOLLAR"], posix(relative_path)) if extension in self.extensions: # $ hack, reversed in post_commit_completion folder_cache[relative_path] = [ re.sub("\$", config["ESCAPE_DOLLAR"], posix(filename)), extension, posix(filename) + "\t" + extension ] elif (not ressource.startswith('.') and os.path.isdir(current_path)): folder_cache.update(self.read(current_path, base)) return folder_cache
def run(self): verbose(ID, "START adding files in", self.folder) self.files = self.read(self.folder) verbose(ID, len(self.files), "files cached")
def on_activated(self, view): project_directory = "" self.is_project_file = False self.project_folder = None current_window = sublime.active_window() if not current_window: return False file_name = view.file_name() folders = current_window.folders() if folders is None or file_name is None: return False if config["PROJECT_DIRECTORY"]: # sanitize project directory project_directory = config["PROJECT_DIRECTORY"] verbose("project", "project folder found {0}".format(project_directory)) # find and build current project directory (modified by settings:project_directory) base_project_directory = False final_project_directory = False for folder in folders: final_project_directory = os.path.join(folder, project_directory) # does not require validation of folder since filename is always correct if final_project_directory in file_name: self.is_project_file = True base_project_directory = folder break # abort if file is not within a project if not self.is_project_file: sublime.status_message("FFP abort. File is not within a project {0}".format(project_directory)) return False elif config["LOG"]: sublime.status_message("FFP enabled for file being in project {0}".format(final_project_directory)) # save final project folder self.project_folder = final_project_directory # validate base directory path_to_base_directory = False if config["BASE_DIRECTORY"]: # # base_project_directory | /path/to/sublime/project # project_folder | /path/to/sublime/project/project_directory # # - path_to_base_directory | /path/to/sublime/project/base_directory # + path_to_base_directory | /path/to/sublime/project/project_directory/base_directory # path_to_base_directory = os.path.join(final_project_directory, config["BASE_DIRECTORY"]) if not os.path.isdir(path_to_base_directory): # BASE_DIRECTORY is NOT a valid folder releative to (possibly modified) project_directory path_to_base_directory = os.path.join(base_project_directory, config["BASE_DIRECTORY"]) if not os.path.isdir(path_to_base_directory): print("FFP", "Error: setting's base_directory is not a valid directory in project") print("FFP", "=> changing base_directory {0} to ''".format(config["BASE_DIRECTORY"])) config["BASE_DIRECTORY"] = "" elif path_to_base_directory in final_project_directory: # change BASE_DIRECTORY to be '' since its outside of project directory print("FFP", "Error: setting's base_directory is within project directory") print("FFP", "=> changing base_directory {0} to ''".format(config["BASE_DIRECTORY"])) config["BASE_DIRECTORY"] = "" else: # change BASE_DIRECTORY to be relative to modified project directory path_to_base_directory = path_to_base_directory.replace(final_project_directory, "") print("FFP", "Error: setting's base_directory is not relative to project directory") print("FFP", "=> changing base_directory '{0}' to '{1}'".format(config["BASE_DIRECTORY"], path_to_base_directory)) config["BASE_DIRECTORY"] = Path.sanitize_base_directory(path_to_base_directory) # get file's current folder self.current_folder = Path.get_relative_folder(file_name, self.project_folder) if project_files: project_files.add(self.project_folder)