📄 cplmatch.c
字号:
*/const char *cpl_last_error(WordCompletion *cpl){ return cpl ? cpl->errmsg : "NULL WordCompletion argument";}/*....................................................................... * When an error occurs while performing a completion, you registerf a * terse description of the error by calling cpl_record_error(). This * message will then be returned on the next call to cpl_last_error(). * * Input: * cpl WordCompletion * The string-completion resource object that was * originally passed to the callback. * errmsg const char * The description of the error. */void cpl_record_error(WordCompletion *cpl, const char *errmsg){ if(cpl && errmsg) { strncpy(cpl->errmsg, errmsg, ERRLEN); cpl->errmsg[ERRLEN] = '\0'; };}/*....................................................................... * This is the builtin completion callback function which performs file * completion. * * Input: * cpl WordCompletion * An opaque pointer to the object that will * contain the matches. This should be filled * via zero or more calls to cpl_add_completion(). * data void * Either NULL to request the default * file-completion behavior, or a pointer to a * CplFileConf structure, whose members specify * a different behavior. * line char * The current input line. * word_end int The index of the character in line[] which * follows the end of the token that is being * completed. * Output * return int 0 - OK. * 1 - Error. */CPL_MATCH_FN(cpl_file_completions){ const char *start_path; /* The pointer to the start of the pathname */ /* in line[]. */ CplFileConf *conf; /* The new-style configuration object. *//* * The following configuration object will be used if the caller didn't * provide one. */ CplFileConf default_conf;/* * This function can be called externally, so check its arguments. */ if(!cpl) return 1; if(!line || word_end < 0) { strcpy(cpl->errmsg, "cpl_file_completions: Invalid arguments."); return 1; };/* * The 'data' argument is either a CplFileConf pointer, identifiable * by having an integer id code as its first member, or the deprecated * CplFileArgs pointer, or can be NULL to request the default * configuration. */ if(data && *(int *)data == CFC_ID_CODE) { conf = (CplFileConf *) data; } else {/* * Select the defaults. */ conf = &default_conf; cpl_init_FileConf(&default_conf);/* * If we have been passed an instance of the deprecated CplFileArgs * structure, copy its configuration parameters over the defaults. */ if(data) { CplFileArgs *args = (CplFileArgs *) data; conf->escaped = args->escaped; conf->file_start = args->file_start; }; };/* * Get the start of the filename. If not specified by the caller * identify it by searching backwards in the input line for an * unescaped space or the start of the line. */ if(conf->file_start < 0) { start_path = _pu_start_of_path(line, word_end); if(!start_path) { strcpy(cpl->errmsg, "Unable to find the start of the filename."); return 1; }; } else { start_path = line + conf->file_start; };/* * Perform the completion. */ if(_cf_complete_file(cpl, cpl->cf, line, start_path - line, word_end, conf->escaped, conf->chk_fn, conf->chk_data)) { cpl_record_error(cpl, _cf_last_error(cpl->cf)); return 1; }; return 0;}/*....................................................................... * Initialize a CplFileArgs structure with default configuration * parameters. Note that the CplFileArgs configuration type is * deprecated. The opaque CplFileConf object should be used in future * applications. * * Input: * cfa CplFileArgs * The configuration object of the * cpl_file_completions() callback. */void cpl_init_FileArgs(CplFileArgs *cfa){ if(cfa) { cfa->escaped = 1; cfa->file_start = -1; };}/*....................................................................... * Initialize a CplFileConf structure with default configuration * parameters. * * Input: * cfc CplFileConf * The configuration object of the * cpl_file_completions() callback. */static void cpl_init_FileConf(CplFileConf *cfc){ if(cfc) { cfc->id = CFC_ID_CODE; cfc->escaped = 1; cfc->file_start = -1; cfc->chk_fn = 0; cfc->chk_data = NULL; };}/*....................................................................... * Create a new CplFileConf object and initialize it with defaults. * * Output: * return CplFileConf * The new object, or NULL on error. */CplFileConf *new_CplFileConf(void){ CplFileConf *cfc; /* The object to be returned *//* * Allocate the container. */ cfc = (CplFileConf *)malloc(sizeof(CplFileConf)); if(!cfc) return NULL;/* * Before attempting any operation that might fail, initialize the * container at least up to the point at which it can safely be passed * to del_CplFileConf(). */ cpl_init_FileConf(cfc); return cfc;}/*....................................................................... * Delete a CplFileConf object. * * Input: * cfc CplFileConf * The object to be deleted. * Output: * return CplFileConf * The deleted object (always NULL). */CplFileConf *del_CplFileConf(CplFileConf *cfc){ if(cfc) {/* * Delete the container. */ free(cfc); }; return NULL;}/*....................................................................... * If backslashes in the filename should be treated as literal * characters, call the following function with literal=1. Otherwise * the default is to treat them as escape characters, used for escaping * spaces etc.. * * Input: * cfc CplFileConf * The cpl_file_completions() configuration object * to be configured. * literal int Pass non-zero here to enable literal interpretation * of backslashes. Pass 0 to turn off literal * interpretation. */void cfc_literal_escapes(CplFileConf *cfc, int literal){ if(cfc) cfc->escaped = !literal;}/*....................................................................... * Call this function if you know where the index at which the * filename prefix starts in the input line. Otherwise by default, * or if you specify start_index to be -1, the filename is taken * to start after the first unescaped space preceding the cursor, * or the start of the line, which ever comes first. * * Input: * cfc CplFileConf * The cpl_file_completions() configuration object * to be configured. * start_index int The index of the start of the filename in * the input line, or -1 to select the default. */void cfc_file_start(CplFileConf *cfc, int start_index){ if(cfc) cfc->file_start = start_index;}/*....................................................................... * If you only want certain types of files to be included in the * list of completions, you use the following function to specify a * callback function which will be called to ask whether a given file * should be included. * * Input: * cfc CplFileConf * The cpl_file_completions() configuration object * to be configured. * chk_fn CplCheckFn * Zero to disable filtering, or a pointer to a * function that returns 1 if a given file should * be included in the list of completions. * chk_data void * Anonymous data to be passed to chk_fn() * every time that it is called. */void cfc_set_check_fn(CplFileConf *cfc, CplCheckFn *chk_fn, void *chk_data){ if(cfc) { cfc->chk_fn = chk_fn; cfc->chk_data = chk_data; };}/*....................................................................... * The following CplCheckFn callback returns non-zero if the specified * filename is that of an executable. */CPL_CHECK_FN(cpl_check_exe){ return _pu_path_is_exe(pathname);}/*....................................................................... * Remove duplicates from a sorted array of matches. * * Input: * cpl WordCompletion * The completion resource object. */static void cpl_zap_duplicates(WordCompletion *cpl){ CplMatch *matches; /* The array of matches */ int nmatch; /* The number of elements in matches[] */ const char *completion; /* The completion string of the last unique match */ const char *type_suffix; /* The type of the last unique match */ int src; /* The index of the match being considered */ int dst; /* The index at which to record the next */ /* unique match. *//* * Get the array of matches and the number of matches that it * contains. */ matches = cpl->result.matches; nmatch = cpl->result.nmatch;/* * No matches? */ if(nmatch < 1) return;/* * Initialize the comparison strings with the first match. */ completion = matches[0].completion; type_suffix = matches[0].type_suffix;/* * Go through the array of matches, copying each new unrecorded * match at the head of the array, while discarding duplicates. */ for(src=dst=1; src<nmatch; src++) { CplMatch *match = matches + src; if(strcmp(completion, match->completion) != 0 || strcmp(type_suffix, match->type_suffix) != 0) { if(src != dst) matches[dst] = *match; dst++; completion = match->completion; type_suffix = match->type_suffix; }; };/* * Record the number of unique matches that remain. */ cpl->result.nmatch = dst; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -