⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 complete.c

📁 在非GUI环境下
💻 C
📖 第 1 页 / 共 5 页
字号:
	  temp = printable_part (matches[i]);	  printed_len = print_filename (temp, matches[i]);	  /* Have we reached the end of this line? */	  if (matches[i+1])	    {	      if (i && (limit > 1) && (i % limit) == 0)		{		  rl_crlf ();		  lines++;		  if (_rl_page_completions && lines >= _rl_screenheight - 1)		    {		      lines = _rl_internal_pager (lines);		      if (lines < 0)			return;		    }		}	      else		for (k = 0; k < max - printed_len; k++)		  putc (' ', rl_outstream);	    }	}      rl_crlf ();    }}/* Display MATCHES, a list of matching filenames in argv format.  This   handles the simple case -- a single match -- first.  If there is more   than one match, we compute the number of strings in the list and the   length of the longest string, which will be needed by the display   function.  If the application wants to handle displaying the list of   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the   address of a function, and we just call it.  If we're handling the   display ourselves, we just call rl_display_match_list.  We also check   that the list of matches doesn't exceed the user-settable threshold,   and ask the user if he wants to see the list if there are more matches   than RL_COMPLETION_QUERY_ITEMS. */static voiddisplay_matches (matches)     char **matches;{  int len, max, i;  char *temp;  /* Move to the last visible line of a possibly-multiple-line command. */  _rl_move_vert (_rl_vis_botlin);  /* Handle simple case first.  What if there is only one answer? */  if (matches[1] == 0)    {      temp = printable_part (matches[0]);      rl_crlf ();      print_filename (temp, matches[0]);      rl_crlf ();      rl_forced_update_display ();      rl_display_fixed = 1;      return;    }  /* There is more than one answer.  Find out how many there are,     and find the maximum printed length of a single entry. */  for (max = 0, i = 1; matches[i]; i++)    {      temp = printable_part (matches[i]);      len = fnwidth (temp);      if (len > max)	max = len;    }  len = i - 1;  /* If the caller has defined a display hook, then call that now. */  if (rl_completion_display_matches_hook)    {      (*rl_completion_display_matches_hook) (matches, len, max);      return;    }	  /* If there are many items, then ask the user if she really wants to     see them all. */  if (len >= rl_completion_query_items)    {      rl_crlf ();      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);      fflush (rl_outstream);      if (get_y_or_n (0) == 0)	{	  rl_crlf ();	  rl_forced_update_display ();	  rl_display_fixed = 1;	  return;	}    }  rl_display_match_list (matches, len, max);  rl_forced_update_display ();  rl_display_fixed = 1;}static char *make_quoted_replacement (match, mtype, qc)     char *match;     int mtype;     char *qc;	/* Pointer to quoting character, if any */{  int should_quote, do_replace;  char *replacement;  /* If we are doing completion on quoted substrings, and any matches     contain any of the completer_word_break_characters, then auto-     matically prepend the substring with a quote character (just pick     the first one from the list of such) if it does not already begin     with a quote string.  FIXME: Need to remove any such automatically     inserted quote character when it no longer is necessary, such as     if we change the string we are completing on and the new set of     matches don't require a quoted substring. */  replacement = match;  should_quote = match && rl_completer_quote_characters &&			rl_filename_completion_desired &&			rl_filename_quoting_desired;  if (should_quote)    should_quote = should_quote && (!qc || !*qc ||		     (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));  if (should_quote)    {      /* If there is a single match, see if we need to quote it.         This also checks whether the common prefix of several	 matches needs to be quoted. */      should_quote = rl_filename_quote_characters			? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)			: 0;      do_replace = should_quote ? mtype : NO_MATCH;      /* Quote the replacement, since we found an embedded	 word break character in a potential match. */      if (do_replace != NO_MATCH && rl_filename_quoting_function)	replacement = (*rl_filename_quoting_function) (match, do_replace, qc);    }  return (replacement);}static voidinsert_match (match, start, mtype, qc)     char *match;     int start, mtype;     char *qc;{  char *replacement;  char oqc;  oqc = qc ? *qc : '\0';  replacement = make_quoted_replacement (match, mtype, qc);  /* Now insert the match. */  if (replacement)    {      /* Don't double an opening quote character. */      if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&	    replacement[0] == *qc)	start--;      /* If make_quoted_replacement changed the quoting character, remove	 the opening quote and insert the (fully-quoted) replacement. */      else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&	    replacement[0] != oqc)	start--;      _rl_replace_text (replacement, start, rl_point - 1);      if (replacement != match)        free (replacement);    }}/* Append any necessary closing quote and a separator character to the   just-inserted match.  If the user has specified that directories   should be marked by a trailing `/', append one of those instead.  The   default trailing character is a space.  Returns the number of characters   appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS   has them) and don't add a suffix for a symlink to a directory.  A   nontrivial match is one that actually adds to the word being completed.   The variable rl_completion_mark_symlink_dirs controls this behavior   (it's initially set to the what the user has chosen, indicated by the   value of _rl_complete_mark_symlink_dirs, but may be modified by an   application's completion function). */static intappend_to_match (text, delimiter, quote_char, nontrivial_match)     char *text;     int delimiter, quote_char, nontrivial_match;{  char temp_string[4], *filename;  int temp_string_index, s;  struct stat finfo;  temp_string_index = 0;  if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&      rl_line_buffer[rl_point - 1] != quote_char)    temp_string[temp_string_index++] = quote_char;  if (delimiter)    temp_string[temp_string_index++] = delimiter;  else if (rl_completion_suppress_append == 0 && rl_completion_append_character)    temp_string[temp_string_index++] = rl_completion_append_character;  temp_string[temp_string_index++] = '\0';  if (rl_filename_completion_desired)    {      filename = tilde_expand (text);      s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)		? LSTAT (filename, &finfo)		: stat (filename, &finfo);      if (s == 0 && S_ISDIR (finfo.st_mode))	{	  if (_rl_complete_mark_directories)	    {	      /* This is clumsy.  Avoid putting in a double slash if point		 is at the end of the line and the previous character is a		 slash. */	      if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')		;	      else if (rl_line_buffer[rl_point] != '/')		rl_insert_text ("/");	    }	}#ifdef S_ISLNK      /* Don't add anything if the filename is a symlink and resolves to a	 directory. */      else if (s == 0 && S_ISLNK (finfo.st_mode) &&	       stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))	;#endif      else	{	  if (rl_point == rl_end && temp_string_index)	    rl_insert_text (temp_string);	}      free (filename);    }  else    {      if (rl_point == rl_end && temp_string_index)	rl_insert_text (temp_string);    }  return (temp_string_index);}static voidinsert_all_matches (matches, point, qc)     char **matches;     int point;     char *qc;{  int i;  char *rp;  rl_begin_undo_group ();  /* remove any opening quote character; make_quoted_replacement will add     it back. */  if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)    point--;  rl_delete_text (point, rl_point);  rl_point = point;  if (matches[1])    {      for (i = 1; matches[i]; i++)	{	  rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);	  rl_insert_text (rp);	  rl_insert_text (" ");	  if (rp != matches[i])	    free (rp);	}    }  else    {      rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);      rl_insert_text (rp);      rl_insert_text (" ");      if (rp != matches[0])	free (rp);    }  rl_end_undo_group ();}void_rl_free_match_list (matches)     char **matches;{  register int i;  if (matches == 0)    return;  for (i = 0; matches[i]; i++)    free (matches[i]);  free (matches);}/* Complete the word at or before point.   WHAT_TO_DO says what to do with the completion.   `?' means list the possible completions.   TAB means do standard completion.   `*' means insert all of the possible completions.   `!' means to do standard completion, and list all possible completions if   there is more than one.   `@' means to do standard completion, and list all possible completions if   there is more than one and partial completion is not possible. */intrl_complete_internal (what_to_do)     int what_to_do;{  char **matches;  rl_compentry_func_t *our_func;  int start, end, delimiter, found_quote, i, nontrivial_lcd;  char *text, *saved_line_buffer;  char quote_char;  RL_SETSTATE(RL_STATE_COMPLETING);  set_completion_defaults (what_to_do);  saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;  our_func = rl_completion_entry_function		? rl_completion_entry_function		: rl_filename_completion_function;  /* We now look backwards for the start of a filename/variable word. */  end = rl_point;  found_quote = delimiter = 0;  quote_char = '\0';  if (rl_point)    /* This (possibly) changes rl_point.  If it returns a non-zero char,       we know we have an open quote. */    quote_char = _rl_find_completion_word (&found_quote, &delimiter);  start = rl_point;  rl_point = end;  text = rl_copy_text (start, end);  matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);  /* nontrivial_lcd is set if the common prefix adds something to the word     being completed. */  nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;  free (text);  if (matches == 0)    {      rl_ding ();      FREE (saved_line_buffer);      completion_changed_buffer = 0;      RL_UNSETSTATE(RL_STATE_COMPLETING);      return (0);    }  /* If we are matching filenames, the attempted completion function will     have set rl_filename_completion_desired to a non-zero value.  The basic     rl_filename_completion_function does this. */  i = rl_filename_completion_desired;  if (postprocess_matches (&matches, i) == 0)    {      rl_ding ();      FREE (saved_line_buffer);      completion_changed_buffer = 0;      RL_UNSETSTATE(RL_STATE_COMPLETING);      return (0);    }  switch (what_to_do)    {    case TAB:    case '!':    case '@':      /* Insert the first match with proper quoting. */      if (*matches[0])	insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);      /* If there are more matches, ring the bell to indicate.	 If we are in vi mode, Posix.2 says to not ring the bell.	 If the `show-all-if-ambiguous' variable is set, display	 all the matches immediately.  Otherwise, if this was the	 only match, and we are hacking files, check the file to	 see if it was a directory.  If so, and the `mark-directories'	 variable is set, add a '/' to the name.  If not, and we	 are at the end of the line, then add a space.  */      if (matches[1])	{	  if (what_to_do == '!')	    {	      display_matches (matches);	      break;	    }	  else if (what_to_do == '@')	    {	      if (nontrivial_lcd == 0)		display_matches (matches);	      break;	    }	  else if (rl_editing_mode != vi_mode)	    rl_ding ();	/* There are other matches remaining. */	}      else	append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);      break;    case '*':      insert_all_matches (matches, start, &quote_char);      break;    case '?':      display_matches (matches);      break;    default:      fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);      rl_ding ();      FREE (saved_line_buffer);      RL_UNSETSTATE(RL_STATE_COMPLETING);      return 1;    }  _rl_free_match_list (matches);  /* Check to see if the line has changed through all of this manipulation. */  if (saved_line_buffer)    {      completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;      free (saved_line_buffer);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -