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

📄 readline.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Begin defining a keyboard macro.   Keystrokes are recorded as they are executed.   End the definition with rl_end_kbd_macro ().   If a numeric argument was explicitly typed, then append this   definition to the end of the existing macro, and start by   re-executing the existing macro. */rl_start_kbd_macro (ignore1, ignore2)     int ignore1, ignore2;{  if (defining_kbd_macro)    rl_abort ();  if (rl_explicit_arg)    {      if (current_macro)	with_macro_input (savestring (current_macro));    }  else    current_macro_index = 0;  defining_kbd_macro = 1;}/* Stop defining a keyboard macro.   A numeric argument says to execute the macro right now,   that many times, counting the definition as the first time. */rl_end_kbd_macro (count, ignore)     int count, ignore;{  if (!defining_kbd_macro)    rl_abort ();  current_macro_index -= (rl_key_sequence_length - 1);  current_macro[current_macro_index] = '\0';  defining_kbd_macro = 0;  rl_call_last_kbd_macro (--count, 0);}/* Execute the most recently defined keyboard macro.   COUNT says how many times to execute it. */rl_call_last_kbd_macro (count, ignore)     int count, ignore;{  if (!current_macro)    rl_abort ();  while (count--)    with_macro_input (savestring (current_macro));}/* **************************************************************** *//*								    *//*			Initializations 			    *//*								    *//* **************************************************************** *//* Initliaze readline (and terminal if not already). */rl_initialize (){  extern char *rl_display_prompt;  /* 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_point = rl_end = 0;  the_line = rl_line_buffer;  the_line[0] = 0;  /* 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. */  {    extern char *rl_display_prompt;    extern int forced_display;    rl_on_new_line ();    rl_display_prompt = rl_prompt ? rl_prompt : "";    forced_display = 1;  }  /* No such function typed yet. */  rl_last_func = (Function *)NULL;  /* Parsing of key-bindings begins in an enabled state. */  parsing_conditionalized_out = 0;}/* Initialize the entire state of the world. */readline_initialize_everything (){  /* Find out if we are running in Emacs. */  running_in_emacs = getenv ("EMACS");  /* Set up input and output if they aren't already.  */  if (!rl_instream)    rl_instream = stdin;  if (!rl_outstream)    rl_outstream = stdout;  /* Allocate data structures. */  if (!rl_line_buffer)    rl_line_buffer =      (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);  /* Initialize the terminal interface. */  init_terminal_io ((char *)NULL);  /* Bind tty characters to readline functions. */  readline_default_bindings ();  /* Initialize the function names. */  rl_initialize_funmap ();  /* Read in the init file. */  rl_read_init_file ((char *)NULL);  /* If the completion parser's default word break characters haven't     been set yet, then do so now. */  {    extern char *rl_completer_word_break_characters;    extern char *rl_basic_word_break_characters;    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. */readline_default_bindings (){#ifndef __GO32__#if defined (NEW_TTY_DRIVER)  struct sgttyb ttybuff;  int tty = fileno (rl_instream);  if (ioctl (tty, TIOCGETP, &ttybuff) != -1)    {      int erase, kill;      erase = ttybuff.sg_erase;      kill  = ttybuff.sg_kill;      if (erase != -1 && keymap[erase].type == ISFUNC)	keymap[erase].function = rl_rubout;      if (kill != -1 && keymap[kill].type == ISFUNC)	keymap[kill].function = rl_unix_line_discard;    }#if defined (TIOCGLTC)  {    struct ltchars lt;    if (ioctl (tty, TIOCGLTC, &lt) != -1)      {	int erase, nextc;	erase = lt.t_werasc;	nextc = lt.t_lnextc;	if (erase != -1 && keymap[erase].type == ISFUNC)	  keymap[erase].function = rl_unix_word_rubout;	if (nextc != -1 && keymap[nextc].type == ISFUNC)	  keymap[nextc].function = rl_quoted_insert;      }  }#endif /* TIOCGLTC */#else /* not NEW_TTY_DRIVER */#if defined (TERMIOS_TTY_DRIVER)  struct termios ttybuff;#else  struct termio ttybuff;#endif /* TERMIOS_TTY_DRIVER */  int tty = fileno (rl_instream);#if defined (TERMIOS_TTY_DRIVER)  if (tcgetattr (tty, &ttybuff) != -1)#else  if (ioctl (tty, TCGETA, &ttybuff) != -1)#endif /* !TERMIOS_TTY_DRIVER */    {      int erase, kill;      erase = ttybuff.c_cc[VERASE];      kill = ttybuff.c_cc[VKILL];      if (erase != _POSIX_VDISABLE &&	  keymap[(unsigned char)erase].type == ISFUNC)	keymap[(unsigned char)erase].function = rl_rubout;      if (kill != _POSIX_VDISABLE &&	  keymap[(unsigned char)kill].type == ISFUNC)	keymap[(unsigned char)kill].function = rl_unix_line_discard;#if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)      {	int nextc;	nextc = ttybuff.c_cc[VLNEXT];	if (nextc != _POSIX_VDISABLE &&	    keymap[(unsigned char)nextc].type == ISFUNC)	  keymap[(unsigned char)nextc].function = rl_quoted_insert;      }#endif /* VLNEXT && TERMIOS_TTY_DRIVER */#if defined (VWERASE)      {	int werase;	werase = ttybuff.c_cc[VWERASE];	if (werase != _POSIX_VDISABLE &&	    keymap[(unsigned char)werase].type == ISFUNC)	  keymap[(unsigned char)werase].function = rl_unix_word_rubout;      }#endif /* VWERASE */    }#endif /* !NEW_TTY_DRIVER */#endif /* def __GO32__ */}/* **************************************************************** *//*								    *//*			Numeric Arguments			    *//*								    *//* **************************************************************** *//* Handle C-u style numeric args, as well as M--, and M-digits. *//* Add the current digit to the argument in progress. */rl_digit_argument (ignore, key)     int ignore, key;{  rl_pending_input = key;  rl_digit_loop ();}/* What to do when you abort reading an argument. */rl_discard_argument (){  ding ();  rl_clear_message ();  rl_init_argument ();}/* Create a default argument. */rl_init_argument (){  rl_numeric_arg = rl_arg_sign = 1;  rl_explicit_arg = 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. */rl_universal_argument (){  rl_numeric_arg *= 4;  rl_digit_loop ();}rl_digit_loop (){  int key, c;  while (1)    {      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);      key = c = rl_read_key ();      if (keymap[c].type == ISFUNC &&	  keymap[c].function == rl_universal_argument)	{	  rl_numeric_arg *= 4;	  continue;	}      c = UNMETA (c);      if (numeric (c))	{	  if (rl_explicit_arg)	    rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');	  else	    rl_numeric_arg = (c - '0');	  rl_explicit_arg = 1;	}      else	{	  if (c == '-' && !rl_explicit_arg)	    {	      rl_numeric_arg = 1;	      rl_arg_sign = -1;	    }	  else	    {	      rl_clear_message ();	      rl_dispatch (key, keymap);	      return;	    }	}    }}/* **************************************************************** *//*								    *//*			Display stuff				    *//*								    *//* **************************************************************** *//* This is the stuff that is hard for me.  I never seem to write good   display routines in C.  Let's see how I do this time. *//* (PWP) Well... Good for a simple line updater, but totally ignores   the problems of input lines longer than the screen width.   update_line and the code that calls it makes a multiple line,   automatically wrapping line update.  Carefull attention needs   to be paid to the vertical position variables.   handling of terminals with autowrap on (incl. DEC braindamage)   could be improved a bit.  Right now I just cheat and decrement   screenwidth by one. *//* Keep two buffers; one which reflects the current contents of the   screen, and the other to draw what we think the new contents should   be.  Then compare the buffers, and make whatever changes to the   screen itself that we should.  Finally, make the buffer that we   just drew into be the one which reflects the current contents of the   screen, and place the cursor where it belongs.   Commands that want to can fix the display themselves, and then let   this function know that the display has been fixed by setting the   RL_DISPLAY_FIXED variable.  This is good for efficiency. *//* Termcap variables: */extern char *term_up, *term_dc, *term_cr;extern int screenheight, screenwidth, terminal_can_insert;/* What YOU turn on when you have handled all redisplay yourself. */int rl_display_fixed = 0;/* The visible cursor position.  If you print some text, adjust this. */int last_c_pos = 0;int last_v_pos = 0;/* The last left edge of text that was displayed.  This is used when   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */static int last_lmargin = 0;/* The line display buffers.  One is the line currently displayed on   the screen.  The other is the line about to be displayed. */static char *visible_line = (char *)NULL;static char *invisible_line = (char *)NULL;/* Number of lines currently on screen minus 1. */int vis_botlin = 0;/* A buffer for `modeline' messages. */char msg_buf[128];/* Non-zero forces the redisplay even if we thought it was unnecessary. */int forced_display = 0;/* The stuff that gets printed out before the actual text of the line.   This is usually pointing to rl_prompt. */char *rl_display_prompt = (char *)NULL;/* Default and initial buffer size.  Can grow. */static int line_size = 1024;/* Non-zero means to always use horizontal scrolling in line display. */static int horizontal_scroll_mode = 0;/* Non-zero means to display an asterisk at the starts of history lines   which have been modified. */static int mark_modified_lines = 0;/* Non-zero means to use a visible bell if one is available rather than   simply ringing the terminal bell. */static int prefer_visible_bell = 0;/* I really disagree with this, but my boss (among others) insists that we   support compilers that don't work.  I don't think we are gaining by doing   so; what is the advantage in producing better code if we can't use it? *//* The following two declarations belong inside the   function block, not here. */static void move_cursor_relative ();static void output_some_chars ();static void output_character_function ();static int compare_strings ();/* Basic redisplay algorithm. */rl_redisplay (){  register int in, out, c, linenum;  register char *line = invisible_line;  char *prompt_this_line;  int c_pos = 0;  int inv_botlin = 0;		/* Number of lines in newly drawn buffer. */  extern int readline_echoing_p;  if (!readline_echoing_p)    return;  if (!rl_display_prompt)    rl_display_prompt = "";  if (!invisible_line)    {      visible_line = (char *)xmalloc (line_size);      invisible_line = (char *)xmalloc (line_size);      line = invisible_line;      for (in = 0; in < line_size; in++)	{	  visible_line[in] = 0;	  invisible_line[in] = 1;	}      rl_on_new_line ();    }  /* Draw the line into the buffer. */  c_pos = -1;  /* Mark the line as modified or not.  We only do this for history     lines. */  out = 0;  if (mark_modified_lines && current_history () && rl_undo_list)    {      line[out++] = '*';      line[out] = '\0';    }  /* If someone thought that the redisplay was handled, but the currently     visible line has a different modification state than the one about     to become visible, then correct the callers misconception. */  if (visible_line[0] != invisible_line[0])    rl_display_fixed = 0;  prompt_this_line = rindex (rl_display_prompt, '\n');  if (!prompt_this_line)    prompt_this_line = rl_display_prompt;  else    {      prompt_this_line++;      if (forced_display)	output_some_chars (rl_display_prompt,			   prompt_this_line - rl_display_prompt);    }  strncpy (line + out,  prompt_this_line, strlen (prompt_this_line));  out += strlen (prompt_this_line);  line[out] = '\0';  for (in = 0; in < rl_end; in++)    {      c = (unsigned char)the_line[in];      if (out + 1 >= line_size)	{	  line_size *= 2;	  visible_line = (char *)xrealloc (visible_line, line_size);	  invisible_line = (char *)xrealloc (invisible_line, line_size);	  line = invisible_line;	}      if (in == rl_point)	c_pos = out;      if (c > 127)	{	  line[out++] = 'M';	  line[out++] = '-';	  line[out++] = c - 128;	}#define DISPLAY_TABS#if defined (DISPLAY_TABS)      else if (c == '\t')	{	  register int newout = (out | (int)7) + 1;	  while (out < newout)	    line[out++] = ' ';	}#endif      else if (c < 32)	{	  line[out++] = 'C';	  line[out++] = '-';	  line[out++] = c + 64;	}      else if (c == 127)	{	  line[out++] = 'C';	  line[out++] = '-';	  line[out++] = '?';	}      else	line[out++] = c;    }  line[out] = '\0';  if (c_pos < 0)    c_pos = out;  /* PWP: now is when things get a bit hairy.  The visible and invisible     line buffers are really multiple lines, which would wrap every     (screenwidth - 1) characters.  Go through each in turn, finding     the changed region and updating it.  The line order is top to bottom. */  /* If we can move the cursor up and down, then use multiple lines,     otherwise, let long lines display in a single terminal line, and     horizontally scroll it. */  if (!horizontal_scroll_mode && term_up && *term_up)    {

⌨️ 快捷键说明

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