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

📄 readline.c

📁 UNIX下SH的实现源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    return (_rl_dispatch (_rl_to_lower (key), map));

	  rl_executing_keymap = map;

#if 0
	  _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
#endif

	  rl_dispatching = 1;
	  r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
	  rl_dispatching = 0;

	  /* If we have input pending, then the last command was a prefix
	     command.  Don't change the state of rl_last_func.  Otherwise,
	     remember the last command executed in this variable. */
	  if (!rl_pending_input && map[key].function != rl_digit_argument)
	    rl_last_func = map[key].function;
	}
      else
	{
	  _rl_abort_internal ();
	  return -1;
	}
      break;

    case ISKMAP:
      if (map[key].function != (Function *)NULL)
	{
	  rl_key_sequence_length++;
	  newkey = rl_read_key ();
	  r = _rl_dispatch (newkey, FUNCTION_TO_KEYMAP (map, key));
	}
      else
	{
	  _rl_abort_internal ();
	  return -1;
	}
      break;

    case ISMACR:
      if (map[key].function != (Function *)NULL)
	{
	  macro = savestring ((char *)map[key].function);
	  _rl_with_macro_input (macro);
	  return 0;
	}
      break;
    }
#if defined (VI_MODE)
  if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
      _rl_vi_textmod_command (key))
    _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
  return (r);
}

/* **************************************************************** */
/*								    */
/*			Initializations 			    */
/*								    */
/* **************************************************************** */

/* Initialize readline (and terminal if not already). */
int
rl_initialize ()
{
  /* If we have never been called before, initialize the
     terminal and data structures. */
  if (!rl_initialized)
    {
      readline_initialize_everything ();
      rl_initialized++;
    }

  /* Initalize the current line information. */
  _rl_init_line_state ();

  /* We aren't done yet.  We haven't even gotten started yet! */
  rl_done = 0;

  /* Tell the history routines what is going on. */
  start_using_history ();

  /* Make the display buffer match the state of the line. */
  rl_reset_line_state ();

  /* No such function typed yet. */
  rl_last_func = (Function *)NULL;

  /* Parsing of key-bindings begins in an enabled state. */
  _rl_parsing_conditionalized_out = 0;

#if defined (VI_MODE)
  if (rl_editing_mode == vi_mode)
    _rl_vi_initialize_line ();
#endif

  return 0;
}

#if 0
#if defined (__EMX__)
static void
_emx_build_environ ()
{
  TIB *tibp;
  PIB *pibp;
  char *t, **tp;
  int c;

  DosGetInfoBlocks (&tibp, &pibp);
  t = pibp->pib_pchenv;
  for (c = 1; *t; c++)
    t += strlen (t) + 1;
  tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *));
  t = pibp->pib_pchenv;
  while (*t)
    {
      *tp++ = t;
      t += strlen (t) + 1;
    }
  *tp = 0;
}
#endif /* __EMX__ */
#endif

/* Initialize the entire state of the world. */
static void
readline_initialize_everything ()
{
#if 0
#if defined (__EMX__)
  if (environ == 0)
    _emx_build_environ ();
#endif
#endif

  /* Find out if we are running in Emacs. */
  running_in_emacs = get_env_value ("EMACS") != (char *)0;

  /* Set up input and output if they are not already set up. */
  if (!rl_instream)
    rl_instream = stdin;

  if (!rl_outstream)
    rl_outstream = stdout;

  /* Bind _rl_in_stream and _rl_out_stream immediately.  These values
     may change, but they may also be used before readline_internal ()
     is called. */
  _rl_in_stream = rl_instream;
  _rl_out_stream = rl_outstream;

  /* Allocate data structures. */
  if (rl_line_buffer == 0)
    rl_line_buffer = xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);

  /* Initialize the terminal interface. */
  _rl_init_terminal_io ((char *)NULL);

  /* Bind tty characters to readline functions. */
  readline_default_bindings ();

  /* Initialize the function names. */
  rl_initialize_funmap ();

  /* Decide whether we should automatically go into eight-bit mode. */
  _rl_init_eightbit ();
      
  /* Read in the init file. */
  rl_read_init_file ((char *)NULL);

  /* XXX */
  if (_rl_horizontal_scroll_mode && _rl_term_autowrap)
    {
      screenwidth--;
      screenchars -= screenheight;
    }

  /* Override the effect of any `set keymap' assignments in the
     inputrc file. */
  rl_set_keymap_from_edit_mode ();

  /* Try to bind a common arrow key prefix, if not already bound. */
  bind_arrow_keys ();

  /* Enable the meta key, if this terminal has one. */
  if (_rl_enable_meta)
    _rl_enable_meta_key ();

  /* If the completion parser's default word break characters haven't
     been set yet, then do so now. */
  if (rl_completer_word_break_characters == (char *)NULL)
    rl_completer_word_break_characters = rl_basic_word_break_characters;
}

/* If this system allows us to look at the values of the regular
   input editing characters, then bind them to their readline
   equivalents, iff the characters are not bound to keymaps. */
static void
readline_default_bindings ()
{
  rltty_set_default_bindings (_rl_keymap);
}

static void
bind_arrow_keys_internal ()
{
  Function *f;

#if defined (__MSDOS__) && 0
  f = rl_function_of_keyseq ("\033[0A", _rl_keymap, (int *)NULL);
  if (!f || f == rl_do_lowercase_version)
    {
      _rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
      _rl_bind_if_unbound ("\033[0B", rl_get_next_history);
      _rl_bind_if_unbound ("\033[0C", rl_forward);
      _rl_bind_if_unbound ("\033[0D", rl_backward);
    }
#endif
	
  f = rl_function_of_keyseq ("\033[A", _rl_keymap, (int *)NULL);
  if (!f || f == rl_do_lowercase_version)
    {
      _rl_bind_if_unbound ("\033[A", rl_get_previous_history);
      _rl_bind_if_unbound ("\033[B", rl_get_next_history);
      _rl_bind_if_unbound ("\033[C", rl_forward);
      _rl_bind_if_unbound ("\033[D", rl_backward);
    }

  f = rl_function_of_keyseq ("\033OA", _rl_keymap, (int *)NULL);
  if (!f || f == rl_do_lowercase_version)
    {
      _rl_bind_if_unbound ("\033OA", rl_get_previous_history);
      _rl_bind_if_unbound ("\033OB", rl_get_next_history);
      _rl_bind_if_unbound ("\033OC", rl_forward);
      _rl_bind_if_unbound ("\033OD", rl_backward);
    }
}

/* Try and bind the common arrow key prefix after giving termcap and
   the inputrc file a chance to bind them and create `real' keymaps
   for the arrow key prefix. */
static void
bind_arrow_keys ()
{
  Keymap xkeymap;

  xkeymap = _rl_keymap;

  _rl_keymap = emacs_standard_keymap;
  bind_arrow_keys_internal ();

#if defined (VI_MODE)
  _rl_keymap = vi_movement_keymap;
  bind_arrow_keys_internal ();
#endif

  _rl_keymap = xkeymap;
}



/* **************************************************************** */
/*								    */
/*			Numeric Arguments			    */
/*								    */
/* **************************************************************** */

/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
  int key, c, sawminus, sawdigits;

  rl_save_prompt ();

  sawminus = sawdigits = 0;
  while (1)
    {
      if (rl_numeric_arg > 1000000)
	{
	  sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
	  ding ();
	  rl_restore_prompt ();
	  rl_clear_message ();
	  return 1;
	}
      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
      key = c = rl_read_key ();

      /* If we see a key bound to `universal-argument' after seeing digits,
	 it ends the argument but is otherwise ignored. */
      if (_rl_keymap[c].type == ISFUNC &&
	  _rl_keymap[c].function == rl_universal_argument)
	{
	  if (sawdigits == 0)
	    {
	      rl_numeric_arg *= 4;
	      continue;
	    }
	  else
	    {
	      key = rl_read_key ();
	      rl_restore_prompt ();
	      rl_clear_message ();
	      return (_rl_dispatch (key, _rl_keymap));
	    }
	}

      c = UNMETA (c);

      if (_rl_digit_p (c))
	{
	  rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
	  sawdigits = rl_explicit_arg = 1;
	}
      else if (c == '-' && rl_explicit_arg == 0)
	{
	  rl_numeric_arg = sawminus = 1;
	  rl_arg_sign = -1;
	}
      else
	{
	  /* Make M-- command equivalent to M--1 command. */
	  if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
	    rl_explicit_arg = 1;
	  rl_restore_prompt ();
	  rl_clear_message ();
	  return (_rl_dispatch (key, _rl_keymap));
	}
    }

  return 0;
}

/* Add the current digit to the argument in progress. */
int
rl_digit_argument (ignore, key)
     int ignore, key;
{
  rl_pending_input = key;
  return (rl_digit_loop ());
}

/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
  ding ();
  rl_clear_message ();
  _rl_init_argument ();
  return 0;
}

/* Create a default argument. */
int
_rl_init_argument ()
{
  rl_numeric_arg = rl_arg_sign = 1;
  rl_explicit_arg = 0;
  return 0;
}

/* C-u, universal argument.  Multiply the current argument by 4.
   Read a key.  If the key has nothing to do with arguments, then
   dispatch on it.  If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
     int count, key;
{
  rl_numeric_arg *= 4;
  return (rl_digit_loop ());
}

/* **************************************************************** */
/*								    */
/*			Insert and Delete			    */
/*								    */
/* **************************************************************** */

/* Insert a string of text into the line at point.  This is the only
   way that you should do insertion.  rl_insert () calls this
   function. */
int
rl_insert_text (string)
     char *string;
{
  register int i, l = strlen (string);

  if (rl_end + l >= rl_line_buffer_len)
    rl_extend_line_buffer (rl_end + l);

  for (i = rl_end; i >= rl_point; i--)
    the_line[i + l] = the_line[i];
  strncpy (the_line + rl_point, string, l);

  /* Remember how to undo this if we aren't undoing something. */
  if (!_rl_doing_an_undo)
    {
      /* If possible and desirable, concatenate the undos. */
      if ((l == 1) &&
	  rl_undo_list &&
	  (rl_undo_list->what == UNDO_INSERT) &&
	  (rl_undo_list->end == rl_point) &&
	  (rl_undo_list->end - rl_undo_list->start < 20))
	rl_undo_list->end++;
      else
	rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
    }
  rl_point += l;
  rl_end += l;
  the_line[rl_end] = '\0';
  return l;
}

/* Delete the string between FROM and TO.  FROM is
   inclusive, TO is not. */
int
rl_delete_text (from, to)
     int from, to;
{
  register char *text;
  register int diff, i;

  /* Fix it if the caller is confused. */
  if (from > to)
    SWAP (from, to);

  /* fix boundaries */
  if (to > rl_end)
    {
      to = rl_end;
      if (from > to)
        from = to;
    }

  text = rl_copy_text (from, to);

  /* Some versions of strncpy() can't handle overlapping arguments. */
  diff = to - from;
  for (i = from; i < rl_end - diff; i++)
    the_line[i] = the_line[i + diff];

  /* Remember how to undo this delete. */
  if (_rl_doing_an_undo == 0)
    rl_add_undo (UNDO_DELETE, from, to, text);
  else
    free (text);

  rl_end -= diff;
  the_line[rl_end] = '\0';
  return (diff);
}

/* Fix up point so that it is within the line boundaries after killing
   text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
   boundaries also. */

#define _RL_FIX_POINT(x) \
	do { \
	if (x > rl_end) \
	  x = rl_end; \
	else if (x < 0) \
	  x = 0; \
	} while (0)

void
_rl_fix_point (fix_mark_too)
     int fix_mark_too;
{
  _RL_FIX_POINT (rl_point);
  if (fix_mark_too)
    _RL_FIX_POINT (rl_mark);
}
#undef _RL_FIX_POINT

void
_rl_replace_text (text, start, end)
     char *text;
     int start, end;
{
  rl_begin_undo_group ();
  rl_delete_text (start, end + 1);
  rl_point = start;
  rl_insert_text (text);
  rl_end_undo_group ();
}

/* **************************************************************** */
/*								    */
/*			Readline character functions		    */
/*								    */
/* **************************************************************** */

/* This is not a gap editor, just a stupid line input routine.  No hair
   is involved in writing any of the functions, and none should be. */

/* Note that:

   rl_end is the place in the string that we would place '\0';
   i.e., it is always safe to place '\0' there.

   rl_point is the place in the string where the cursor is.  Sometimes
   this is the same as rl_end.

   Any command that is called interactively receives two arguments.
   The first is a count: the numeric arg pased to this command.
   The second is the key which invoked this command.
*/

/* **************************************************************** */
/*								    */
/*			Movement Commands			    */
/*								    */
/* **************************************************************** */

/* Note that if you `optimize' the display for these functions, you cannot
   use said functions in other functions which do not do optimizing display.
   I.e., you will have to update the data base for rl_redisplay, and you
   might as well let rl_redisplay do that job. */

/* Move forward COUNT characters. */

⌨️ 快捷键说明

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