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

📄 readline.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      int total_screen_chars = (screenwidth * screenheight);      if (!rl_display_fixed || forced_display)	{	  forced_display = 0;	  /* If we have more than a screenful of material to display, then	     only display a screenful.  We should display the last screen,	     not the first.  I'll fix this in a minute. */	  if (out >= total_screen_chars)	    out = total_screen_chars - 1;	  /* Number of screen lines to display. */	  inv_botlin = out / screenwidth;	  /* For each line in the buffer, do the updating display. */	  for (linenum = 0; linenum <= inv_botlin; linenum++)	    update_line (linenum > vis_botlin ? ""			 : &visible_line[linenum * screenwidth],			 &invisible_line[linenum * screenwidth],			 linenum);	  /* We may have deleted some lines.  If so, clear the left over	     blank ones at the bottom out. */	  if (vis_botlin > inv_botlin)	    {	      char *tt;	      for (; linenum <= vis_botlin; linenum++)		{		  tt = &visible_line[linenum * screenwidth];		  move_vert (linenum);		  move_cursor_relative (0, tt);		  clear_to_eol ((linenum == vis_botlin)?				strlen (tt) : screenwidth);		}	    }	  vis_botlin = inv_botlin;	  /* Move the cursor where it should be. */	  move_vert (c_pos / screenwidth);	  move_cursor_relative (c_pos % screenwidth,				&invisible_line[(c_pos / screenwidth) * screenwidth]);	}    }  else				/* Do horizontal scrolling. */    {      int lmargin;      /* Always at top line. */      last_v_pos = 0;      /* If the display position of the cursor would be off the edge	 of the screen, start the display of this line at an offset that	 leaves the cursor on the screen. */      if (c_pos - last_lmargin > screenwidth - 2)	lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);      else if (c_pos - last_lmargin < 1)	lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);      else	lmargin = last_lmargin;      /* If the first character on the screen isn't the first character	 in the display line, indicate this with a special character. */      if (lmargin > 0)	line[lmargin] = '<';      if (lmargin + screenwidth < out)	line[lmargin + screenwidth - 1] = '>';      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)	{	  forced_display = 0;	  update_line (&visible_line[last_lmargin],		       &invisible_line[lmargin], 0);	  move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);	  last_lmargin = lmargin;	}    }  fflush (out_stream);  /* Swap visible and non-visible lines. */  {    char *temp = visible_line;    visible_line = invisible_line;    invisible_line = temp;    rl_display_fixed = 0;  }}/* PWP: update_line() is based on finding the middle difference of each   line on the screen; vis:			     /old first difference	/beginning of line   |              /old last same       /old EOL	v		     v              v                    vold:	eddie> Oh, my little gruntle-buggy is to me, as lurgid asnew:	eddie> Oh, my little buggy says to me, as lurgid as	^		     ^        ^			   ^	\beginning of line   |        \new last same	   \new end of line			     \new first difference   All are character pointers for the sake of speed.  Special cases for   no differences, as well as for end of line additions must be handeled.   Could be made even smarter, but this works well enough */staticupdate_line (old, new, current_line)     register char *old, *new;     int current_line;{  register char *ofd, *ols, *oe, *nfd, *nls, *ne;  int lendiff, wsatend;  /* Find first difference. */  for (ofd = old, nfd = new;       (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);       ofd++, nfd++)    ;  /* Move to the end of the screen line. */  for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);  for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);  /* If no difference, continue to next line. */  if (ofd == oe && nfd == ne)    return;  wsatend = 1;			/* flag for trailing whitespace */  ols = oe - 1;			/* find last same */  nls = ne - 1;  while ((*ols == *nls) && (ols > ofd) && (nls > nfd))    {      if (*ols != ' ')	wsatend = 0;      ols--;      nls--;    }  if (wsatend)    {      ols = oe;      nls = ne;    }  else if (*ols != *nls)    {      if (*ols)			/* don't step past the NUL */	ols++;      if (*nls)	nls++;    }  move_vert (current_line);  move_cursor_relative (ofd - old, old);  /* if (len (new) > len (old)) */  lendiff = (nls - nfd) - (ols - ofd);  /* Insert (diff(len(old),len(new)) ch */  if (lendiff > 0)    {      if (terminal_can_insert)	{	  extern char *term_IC;	  /* Sometimes it is cheaper to print the characters rather than	     use the terminal's capabilities. */	  if ((2 * (ne - nfd)) < lendiff && !term_IC)	    {	      output_some_chars (nfd, (ne - nfd));	      last_c_pos += (ne - nfd);	    }	  else	    {	      if (*ols)		{		  insert_some_chars (nfd, lendiff);		  last_c_pos += lendiff;		}	      else		{		  /* At the end of a line the characters do not have to		     be "inserted".  They can just be placed on the screen. */		  output_some_chars (nfd, lendiff);		  last_c_pos += lendiff;		}	      /* Copy (new) chars to screen from first diff to last match. */	      if (((nls - nfd) - lendiff) > 0)		{		  output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));		  last_c_pos += ((nls - nfd) - lendiff);		}	    }	}      else	{		/* cannot insert chars, write to EOL */	  output_some_chars (nfd, (ne - nfd));	  last_c_pos += (ne - nfd);	}    }  else				/* Delete characters from line. */    {      /* If possible and inexpensive to use terminal deletion, then do so. */      if (term_dc && (2 * (ne - nfd)) >= (-lendiff))	{	  if (lendiff)	    delete_chars (-lendiff); /* delete (diff) characters */	  /* Copy (new) chars to screen from first diff to last match */	  if ((nls - nfd) > 0)	    {	      output_some_chars (nfd, (nls - nfd));	      last_c_pos += (nls - nfd);	    }	}      /* Otherwise, print over the existing material. */      else	{	  output_some_chars (nfd, (ne - nfd));	  last_c_pos += (ne - nfd);	  clear_to_eol ((oe - old) - (ne - new));	}    }}/* (PWP) tell the update routines that we have moved onto a   new (empty) line. */rl_on_new_line (){  if (visible_line)    visible_line[0] = '\0';  last_c_pos = last_v_pos = 0;  vis_botlin = last_lmargin = 0;}/* Actually update the display, period. */rl_forced_update_display (){  if (visible_line)    {      register char *temp = visible_line;      while (*temp) *temp++ = '\0';    }  rl_on_new_line ();  forced_display++;  rl_redisplay ();}/* Move the cursor from last_c_pos to NEW, which are buffer indices.   DATA is the contents of the screen line of interest; i.e., where   the movement is being done. */static voidmove_cursor_relative (new, data)     int new;     char *data;{  register int i;  /* It may be faster to output a CR, and then move forwards instead     of moving backwards. */  if (new + 1 < last_c_pos - new)    {#ifdef __MSDOS__      putc('\r', out_stream);#else      tputs (term_cr, 1, output_character_function);#endif      last_c_pos = 0;    }  if (last_c_pos == new) return;  if (last_c_pos < new)    {      /* Move the cursor forward.  We do it by printing the command	 to move the cursor forward if there is one, else print that	 portion of the output buffer again.  Which is cheaper? */      /* The above comment is left here for posterity.  It is faster	 to print one character (non-control) than to print a control	 sequence telling the terminal to move forward one character.	 That kind of control is for people who don't know what the	 data is underneath the cursor. */#if defined (HACK_TERMCAP_MOTION)      extern char *term_forward_char;      if (term_forward_char)	for (i = last_c_pos; i < new; i++)	  tputs (term_forward_char, 1, output_character_function);      else	for (i = last_c_pos; i < new; i++)	  putc (data[i], out_stream);#else      for (i = last_c_pos; i < new; i++)	putc (data[i], out_stream);#endif				/* HACK_TERMCAP_MOTION */    }  else    backspace (last_c_pos - new);  last_c_pos = new;}/* PWP: move the cursor up or down. */move_vert (to)     int to;{  void output_character_function ();  register int delta, i;  if (last_v_pos == to) return;  if (to > screenheight)    return;#ifdef __GO32__  {    int cur_r, cur_c;    ScreenGetCursor(&cur_r, &cur_c);    ScreenSetCursor(cur_r+to-last_v_pos, cur_c);  }#else /* __GO32__ */  if ((delta = to - last_v_pos) > 0)    {      for (i = 0; i < delta; i++)	putc ('\n', out_stream);      tputs (term_cr, 1, output_character_function);      last_c_pos = 0;    }  else    {			/* delta < 0 */      if (term_up && *term_up)	for (i = 0; i < -delta; i++)	  tputs (term_up, 1, output_character_function);    }#endif /* __GO32__ */  last_v_pos = to;		/* now to is here */}/* Physically print C on out_stream.  This is for functions which know   how to optimize the display. */rl_show_char (c)     int c;{  if (c > 127)    {      fprintf (out_stream, "M-");      c -= 128;    }#if defined (DISPLAY_TABS)  if (c < 32 && c != '\t')#else  if (c < 32)#endif    {      c += 64;    }  putc (c, out_stream);  fflush (out_stream);}#if defined (DISPLAY_TABS)intrl_character_len (c, pos)     register int c, pos;{  if (c < ' ' || c > 126)    {      if (c == '\t')	return (((pos | (int)7) + 1) - pos);      else	return (3);    }  else    return (1);}#elseintrl_character_len (c)     int c;{  if (c < ' ' || c > 126)    return (3);  else    return (1);}#endif  /* DISPLAY_TAB *//* How to print things in the "echo-area".  The prompt is treated as a   mini-modeline. */rl_message (string, arg1, arg2)     char *string;{  sprintf (msg_buf, string, arg1, arg2);  rl_display_prompt = msg_buf;  rl_redisplay ();}/* How to clear things from the "echo-area". */rl_clear_message (){  rl_display_prompt = rl_prompt;  rl_redisplay ();}/* **************************************************************** *//*								    *//*			Terminal and Termcap			    *//*								    *//* **************************************************************** */static char *term_buffer = (char *)NULL;static char *term_string_buffer = (char *)NULL;/* Non-zero means this terminal can't really do anything. */int dumb_term = 0;/* On Solaris2, sys/types.h brings in sys/reg.h,   which screws up the Termcap variable PC, used below.  */#undef	PC	char PC;char *BC, *UP;/* Some strings to control terminal actions.  These are output by tputs (). */char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;int screenwidth, screenheight;/* Non-zero if we determine that the terminal can do character insertion. */int terminal_can_insert = 0;/* How to insert characters. */char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;/* How to delete characters. */char *term_dc, *term_DC;#if defined (HACK_TERMCAP_MOTION)char *term_forward_char;#endif  /* HACK_TERMCAP_MOTION *//* How to go up a line. */char *term_up;/* A visible bell, if the terminal can be made to flash the screen. */char *visible_bell;/* Re-initialize the terminal considering that the TERM/TERMCAP variable   has changed. */rl_reset_terminal (terminal_name)     char *terminal_name;{  init_terminal_io (terminal_name);}init_terminal_io (terminal_name)     char *terminal_name;{#ifdef __GO32__  screenwidth = ScreenCols();  screenheight = ScreenRows();  term_cr = "\r";  term_im = term_ei = term_ic = term_IC = (char *)NULL;  term_up = term_dc = term_DC = visible_bell = (char *)NULL;#if defined (HACK_TERMCAP_MOTION)      term_forward_char = (char *)NULL;#endif  terminal_can_insert = 0;  return;#else  extern char *tgetstr ();  char *term, *buffer;#if defined (TIOCGWINSZ)  struct winsize window_size;#endif  int tty;  term = terminal_name ? terminal_name : getenv ("TERM");  if (!term_string_buffer)    term_string_buffer = (char *)xmalloc (2048);  if (!term_buffer)    term_buffer = (char *)xmalloc (2048);  buffer = term_string_buffer;  term_clrpag = term_cr = term_clreol = (char *)NULL;  if (!term)    term = "dumb";  if (tgetent (term_buffer, term) <= 0)    {      dumb_term = 1;      screenwidth = 79;      screenheight = 24;      term_cr = "\r";      term_im = term_ei = term_ic = term_IC = (char *)NULL;      term_up = term_dc = term_DC = visible_bell = (char *)NULL;#if defined (HACK_TERMCAP_MOTION)      term_forward_char = (char *)NULL;#endif      terminal_can_insert = 0;      return;    }  BC = tgetstr ("pc", &buffer);  PC = buffer ? *buffer : 0;  term_backspace = tgetstr ("le", &buffer);  term_cr = tgetstr ("cr", &buffer);  term_clreol = tgetstr ("ce", &buffer);  term_clrpag = tgetstr ("cl", &buffer);  if (!term_cr)    term_cr =  "\r";#if defined (HACK_TERMCAP_MOTION)  term_forward_char = tgetstr ("nd", &buffer);#endif  /* HACK_TERMCAP_MOTION */  if (rl_instream)    tty = fileno (rl_instream);  else    tty = 0;  screenwidth = screenheight = 0;

⌨️ 快捷键说明

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