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

📄 readline.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      int orig_point = rl_point;      if (count <= 0)	count = 1;      while (count--)	{	  while (rl_point && whitespace (the_line[rl_point - 1]))	    rl_point--;	  while (rl_point && !whitespace (the_line[rl_point - 1]))	    rl_point--;	}      rl_kill_text (orig_point, rl_point);    }  return 0;}/* Here is C-u doing what Unix does.  You don't *have* to use these   key-bindings.  We have a choice of killing the entire line, or   killing from where we are to the start of the line.  We choose the   latter, because if you are a Unix weenie, then you haven't backspaced   into the line at all, and if you aren't, then you know what you are   doing. */rl_unix_line_discard (count, key)     int count, key;{  if (!rl_point)    ding ();  else    {      rl_kill_text (rl_point, 0);      rl_point = 0;    }  return 0;}/* **************************************************************** *//*								    *//*			Commands For Typos			    *//*								    *//* **************************************************************** *//* Random and interesting things in here.  *//* **************************************************************** *//*								    *//*			Changing Case				    *//*								    *//* **************************************************************** *//* The three kinds of things that we know how to do. */#define UpCase 1#define DownCase 2#define CapCase 3static int rl_change_case ();/* Uppercase the word at point. */rl_upcase_word (count, key)     int count, key;{  return (rl_change_case (count, UpCase));}/* Lowercase the word at point. */rl_downcase_word (count, key)     int count, key;{  return (rl_change_case (count, DownCase));}/* Upcase the first letter, downcase the rest. */rl_capitalize_word (count, key)     int count, key;{ return (rl_change_case (count, CapCase));}/* The meaty function.   Change the case of COUNT words, performing OP on them.   OP is one of UpCase, DownCase, or CapCase.   If a negative argument is given, leave point where it started,   otherwise, leave it where it moves to. */static intrl_change_case (count, op)     int count, op;{  register int start = rl_point, end;  int state = 0;  rl_forward_word (count);  end = rl_point;  if (count < 0)    {      int temp = start;      start = end;      end = temp;    }  /* We are going to modify some text, so let's prepare to undo it. */  rl_modifying (start, end);  for (; start < end; start++)    {      switch (op)	{	case UpCase:	  the_line[start] = to_upper (the_line[start]);	  break;	case DownCase:	  the_line[start] = to_lower (the_line[start]);	  break;	case CapCase:	  if (state == 0)	    {	      the_line[start] = to_upper (the_line[start]);	      state = 1;	    }	  else	    {	      the_line[start] = to_lower (the_line[start]);	    }	  if (!pure_alphabetic (the_line[start]))	    state = 0;	  break;	default:	  ding ();	  return -1;	}    }  rl_point = end;  return 0;}/* **************************************************************** *//*								    *//*			Transposition				    *//*								    *//* **************************************************************** *//* Transpose the words at point. */rl_transpose_words (count, key)     int count, key;{  char *word1, *word2;  int w1_beg, w1_end, w2_beg, w2_end;  int orig_point = rl_point;  if (!count)    return 0;  /* Find the two words. */  rl_forward_word (count);  w2_end = rl_point;  rl_backward_word (1);  w2_beg = rl_point;  rl_backward_word (count);  w1_beg = rl_point;  rl_forward_word (1);  w1_end = rl_point;  /* Do some check to make sure that there really are two words. */  if ((w1_beg == w2_beg) || (w2_beg < w1_end))    {      ding ();      rl_point = orig_point;      return -1;    }  /* Get the text of the words. */  word1 = rl_copy_text (w1_beg, w1_end);  word2 = rl_copy_text (w2_beg, w2_end);  /* We are about to do many insertions and deletions.  Remember them     as one operation. */  rl_begin_undo_group ();  /* Do the stuff at word2 first, so that we don't have to worry     about word1 moving. */  rl_point = w2_beg;  rl_delete_text (w2_beg, w2_end);  rl_insert_text (word1);  rl_point = w1_beg;  rl_delete_text (w1_beg, w1_end);  rl_insert_text (word2);  /* This is exactly correct since the text before this point has not     changed in length. */  rl_point = w2_end;  /* I think that does it. */  rl_end_undo_group ();  free (word1);  free (word2);  return 0;}/* Transpose the characters at point.  If point is at the end of the line,   then transpose the characters before point. */rl_transpose_chars (count, key)     int count, key;{  char dummy[2];  if (!count)    return 0;  if (!rl_point || rl_end < 2)    {      ding ();      return -1;    }  rl_begin_undo_group ();  if (rl_point == rl_end)    {      --rl_point;      count = 1;    }  rl_point--;  dummy[0] = the_line[rl_point];  dummy[1] = '\0';  rl_delete_text (rl_point, rl_point + 1);  rl_point += count;  if (rl_point > rl_end)    rl_point = rl_end;  else if (rl_point < 0)    rl_point = 0;  rl_insert_text (dummy);  rl_end_undo_group ();  return 0;}/* **************************************************************** *//*								    *//*			Undo, and Undoing			    *//*								    *//* **************************************************************** *//* The current undo list for THE_LINE. */UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;/* Remember how to undo something.  Concatenate some undos if that   seems right. */voidrl_add_undo (what, start, end, text)     enum undo_code what;     int start, end;     char *text;{  UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));  temp->what = what;  temp->start = start;  temp->end = end;  temp->text = text;  temp->next = rl_undo_list;  rl_undo_list = temp;}/* Free the existing undo list. */voidfree_undo_list (){  while (rl_undo_list)    {      UNDO_LIST *release = rl_undo_list;      rl_undo_list = rl_undo_list->next;      if (release->what == UNDO_DELETE)	free (release->text);      free (release);    }  rl_undo_list = (UNDO_LIST *)NULL;}/* Undo the next thing in the list.  Return 0 if there   is nothing to undo, or non-zero if there was. */intrl_do_undo (){  UNDO_LIST *release;  int waiting_for_begin = 0;undo_thing:  if (!rl_undo_list)    return (0);  doing_an_undo = 1;  switch (rl_undo_list->what) {    /* Undoing deletes means inserting some text. */  case UNDO_DELETE:    rl_point = rl_undo_list->start;    rl_insert_text (rl_undo_list->text);    free (rl_undo_list->text);    break;    /* Undoing inserts means deleting some text. */  case UNDO_INSERT:    rl_delete_text (rl_undo_list->start, rl_undo_list->end);    rl_point = rl_undo_list->start;    break;    /* Undoing an END means undoing everything 'til we get to       a BEGIN. */  case UNDO_END:    waiting_for_begin++;    break;    /* Undoing a BEGIN means that we are done with this group. */  case UNDO_BEGIN:    if (waiting_for_begin)      waiting_for_begin--;    else      ding ();    break;  }  doing_an_undo = 0;  release = rl_undo_list;  rl_undo_list = rl_undo_list->next;  free (release);  if (waiting_for_begin)    goto undo_thing;  return (1);}/* Begin a group.  Subsequent undos are undone as an atomic operation. */intrl_begin_undo_group (){  rl_add_undo (UNDO_BEGIN, 0, 0, 0);  return 0;}/* End an undo group started with rl_begin_undo_group (). */intrl_end_undo_group (){  rl_add_undo (UNDO_END, 0, 0, 0);  return 0;}/* Save an undo entry for the text from START to END. */rl_modifying (start, end)     int start, end;{  if (start > end)    {      int t = start;      start = end;      end = t;    }  if (start != end)    {      char *temp = rl_copy_text (start, end);      rl_begin_undo_group ();      rl_add_undo (UNDO_DELETE, start, end, temp);      rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);      rl_end_undo_group ();    }  return 0;}/* Revert the current line to its previous state. */intrl_revert_line (count, key)     int count, key;{  if (!rl_undo_list)    ding ();  else    {      while (rl_undo_list)	rl_do_undo ();    }  return 0;}/* Do some undoing of things that were done. */intrl_undo_command (count, key)     int count, key;{  if (count < 0)    return 0;	/* Nothing to do. */  while (count)    {      if (rl_do_undo ())	count--;      else	{	  ding ();	  break;	}    }  return 0;}/* **************************************************************** *//*								    *//*			History Utilities			    *//*								    *//* **************************************************************** *//* We already have a history library, and that is what we use to control   the history features of readline.  However, this is our local interface   to the history mechanism. *//* While we are editing the history, this is the saved   version of the original line. */HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;/* Set the history pointer back to the last entry in the history. */static voidstart_using_history (){  using_history ();  if (saved_line_for_history)    _rl_free_history_entry (saved_line_for_history);  saved_line_for_history = (HIST_ENTRY *)NULL;}/* Free the contents (and containing structure) of a HIST_ENTRY. */void_rl_free_history_entry (entry)     HIST_ENTRY *entry;{  if (!entry)    return;  if (entry->line)    free (entry->line);  free (entry);}/* Perhaps put back the current line if it has changed. */maybe_replace_line (){  HIST_ENTRY *temp = current_history ();  /* If the current line has changed, save the changes. */  if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))    {      temp = replace_history_entry (where_history (), the_line, rl_undo_list);      free (temp->line);      free (temp);    }  return 0;}/* Put back the saved_line_for_history if there is one. */maybe_unsave_line (){  if (saved_line_for_history)    {      int line_len;      line_len = strlen (saved_line_for_history->line);      if (line_len >= rl_line_buffer_len)	rl_extend_line_buffer (line_len);      strcpy (the_line, saved_line_for_history->line);      rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;      _rl_free_history_entry (saved_line_for_history);      saved_line_for_history = (HIST_ENTRY *)NULL;      rl_end = rl_point = strlen (the_line);    }  else    ding ();  return 0;}/* Save the current line in saved_line_for_history. */maybe_save_line (){  if (!saved_line_for_history)    {      saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));      saved_line_for_history->line = savestring (the_line);      saved_line_for_history->data = (char *)rl_undo_list;    }  return 0;}/* **************************************************************** *//*								    *//*			History Commands			    *//*								    *//* **************************************************************** *//* Meta-< goes to the start of the history. */rl_beginning_of_history (count, key)     int count, key;{  return (rl_get_previous_history (1 + where_history ()));}/* Meta-> goes to the end of the history.  (The current line). */rl_end_of_history (count, key)     int count, key;{  maybe_replace_line ();  using_history ();  maybe_unsave_line ();  return 0;}/* Move down to the next history line. */rl_get_next_history (count, key)     int count, key;{  HIST_ENTRY *temp = (HIST_ENTRY *)NULL;  if (count < 0)    return (rl_get_previous_history (-count));  if (!count)    return 0;  maybe_replace_line ();  while (count)    {      temp = next_history ();      if (!temp)	break;      --count;    }  if (!temp)    maybe_unsave_line ();  else    {      int line_len;      line_len = strlen (temp->line);      if (line_len >= rl_line_buffer_len)	rl_extend_line_buffer (line_len);      strcpy (the_line, temp->line);      rl_undo_list = (UNDO_LIST *)temp->data;      rl_end = rl_point = strlen (the_line);#

⌨️ 快捷键说明

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