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

📄 display.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	  /* 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.  The first line wraps at	     (screenwidth + wrap_offset) chars, the rest of the lines have	     screenwidth chars. */	  nleft = out - wrap_offset + term_xn - 1;	  inv_botlin = (nleft > 0) ? nleft / screenwidth : 0;	  /* The first line is at character position 0 in the buffer.  The	     second and subsequent lines start at N * screenwidth, offset by	     OFFSET.  OFFSET is wrap_offset for the invisible line and	     visible_wrap_offset for the line currently displayed. */#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)#define L_OFFSET(n, offset) ((n) > 0 ? ((n) * screenwidth) + (offset) : 0)#define VIS_CHARS(line) &visible_line[L_OFFSET((line), visible_wrap_offset)]#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)#define INV_LINE(line) &invisible_line[L_OFFSET((line), wrap_offset)]	  /* For each line in the buffer, do the updating display. */	  for (linenum = 0; linenum <= inv_botlin; linenum++)	    {	      update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,			   screenwidth + W_OFFSET(linenum, visible_wrap_offset),			   screenwidth + W_OFFSET(linenum, wrap_offset),			   inv_botlin);	      /* If this is the line with the prompt, we might need to		 compensate for invisible characters in the new line. Do		 this only if there is not more than one new line (which		 implies that we completely overwrite the old visible line)		 and the new line is shorter than the old. */	      if (linenum == 0 &&		  inv_botlin == 0 &&		  (wrap_offset > visible_wrap_offset) &&		  (_rl_last_c_pos < visible_first_line_len))		{		  nleft = screenwidth + wrap_offset - _rl_last_c_pos;		  if (nleft)		    clear_to_eol (nleft);		}	      /* Since the new first line is now visible, save its length. */	      if (linenum == 0)		visible_first_line_len = (inv_botlin > 0) ? screenwidth : out - wrap_offset;	    }	  /* We may have deleted some lines.  If so, clear the left over	     blank ones at the bottom out. */	  if (_rl_vis_botlin > inv_botlin)	    {	      char *tt;	      for (; linenum <= _rl_vis_botlin; linenum++)		{		  tt = VIS_CHARS (linenum);		  _rl_move_vert (linenum);		  _rl_move_cursor_relative (0, tt);		  clear_to_eol		    ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);		}	    }	  _rl_vis_botlin = inv_botlin;	  /* Move the cursor where it should be. */	  /* Which line? */	  nleft = c_pos - wrap_offset + term_xn - 1;	  cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0;	  /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a	     different screen line during this redisplay. */	  changed_screen_line = _rl_last_v_pos != cursor_linenum;	  if (changed_screen_line)	    {	      _rl_move_vert (cursor_linenum);	      /* If we moved up to the line with the prompt using term_up,	         the physical cursor position on the screen stays the same,	         but the buffer position needs to be adjusted to account	         for invisible characters. */	      if (cursor_linenum == 0 && wrap_offset)	        _rl_last_c_pos += wrap_offset;	    }	  /* We have to reprint the prompt if it contains invisible	     characters, since it's not generally OK to just reprint	     the characters from the current cursor position. */	  nleft = visible_length + wrap_offset;	  if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&	      _rl_last_c_pos <= nleft && local_prompt)	    {	      if (term_cr)		tputs (term_cr, 1, _rl_output_character_function);	      _rl_output_some_chars (local_prompt, nleft);	      _rl_last_c_pos = nleft;	    }	  /* Where on that line?  And where does that line start	     in the buffer? */	  pos = L_OFFSET(cursor_linenum, wrap_offset);	  /* nleft == number of characters in the line buffer between the	     start of the line and the cursor position. */	  nleft = c_pos - pos;	  /* Since backspace() doesn't know about invisible characters in the	     prompt, and there's no good way to tell it, we compensate for	     those characters here and call backspace() directly. */	  if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)	    {	      backspace (_rl_last_c_pos - nleft);	      _rl_last_c_pos = nleft;	    }	  if (nleft != _rl_last_c_pos)	    _rl_move_cursor_relative (nleft, &invisible_line[pos]);	}    }  else				/* Do horizontal scrolling. */    {#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)      int lmargin, ndisp, nleft, phys_c_pos, t;      /* Always at top line. */      _rl_last_v_pos = 0;      /* Compute where in the buffer the displayed line should start.  This	 will be LMARGIN. */      /* The number of characters that will be displayed before the cursor. */      ndisp = c_pos - wrap_offset;      nleft  = visible_length + wrap_offset;      /* Where the new cursor position will be on the screen.  This can be         longer than SCREENWIDTH; if it is, lmargin will be adjusted. */      phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);      t = screenwidth / 3;      /* If the number of characters had already exceeded the screenwidth,         last_lmargin will be > 0. */      /* If the number of characters to be displayed is more than the screen         width, compute the starting offset so that the cursor is about         two-thirds of the way across the screen. */      if (phys_c_pos > screenwidth - 2)	{	  lmargin = c_pos - (2 * t);	  if (lmargin < 0)	    lmargin = 0;	  /* If the left margin would be in the middle of a prompt with	     invisible characters, don't display the prompt at all. */	  if (wrap_offset && lmargin > 0 && lmargin < nleft)	    lmargin = nleft;	}      else if (ndisp < screenwidth - 2)		/* XXX - was -1 */        lmargin = 0;      else if (phys_c_pos < 1)	{	  /* If we are moving back towards the beginning of the line and	     the last margin is no longer correct, compute a new one. */	  lmargin = ((c_pos - 1) / t) * t;	/* XXX */	  if (wrap_offset && lmargin > 0 && lmargin < nleft)	    lmargin = nleft;	}      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 SCREENWIDTH characters starting at LMARGIN do not encompass         the whole line, indicate that with a special characters at the         right edge of the screen.  If LMARGIN is 0, we need to take the         wrap offset into account. */      t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;      if (t < out)        line[t - 1] = '>';      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)	{	  forced_display = 0;	  update_line (&visible_line[last_lmargin],		       &invisible_line[lmargin],		       0,		       screenwidth + visible_wrap_offset,		       screenwidth + (lmargin ? 0 : wrap_offset),		       0);	  /* If the visible new line is shorter than the old, but the number	     of invisible characters is greater, and we are at the end of	     the new line, we need to clear to eol. */	  t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);	  if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&	      (_rl_last_c_pos == out) &&	      t < visible_first_line_len)	    {	      nleft = screenwidth - t;	      clear_to_eol (nleft);	    }	  visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);	  if (visible_first_line_len > screenwidth)	    visible_first_line_len = screenwidth;	  _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);	  last_lmargin = lmargin;	}    }  fflush (rl_outstream);  /* Swap visible and non-visible lines. */  {    char *temp = visible_line;    visible_line = invisible_line;    invisible_line = temp;    rl_display_fixed = 0;    /* If we are displaying on a single line, and last_lmargin is > 0, we       are not displaying any invisible characters, so set visible_wrap_offset       to 0. */    if (_rl_horizontal_scroll_mode && last_lmargin)      visible_wrap_offset = 0;    else      visible_wrap_offset = wrap_offset;  }}/* 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 */static voidupdate_line (old, new, current_line, omax, nmax, inv_botlin)     register char *old, *new;     int current_line, omax, nmax;{  register char *ofd, *ols, *oe, *nfd, *nls, *ne;  int temp, lendiff, wsatend, od, nd;  /* If we're at the right edge of a terminal that supports xn, we're     ready to wrap around, so do so.  This fixes problems with knowing     the exact cursor position and cut-and-paste with certain terminal     emulators.  In this calculation, TEMP is the physical screen     position of the cursor. */  temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);  if (temp == screenwidth && term_xn && !_rl_horizontal_scroll_mode      && _rl_last_v_pos == current_line - 1)    {      if (new[0])	putc (new[0], rl_outstream);      else	putc (' ', rl_outstream);      _rl_last_c_pos = 1;		/* XXX */      _rl_last_v_pos++;      if (old[0] && new[0])        old[0] = new[0];    }        /* Find first difference. */  for (ofd = old, nfd = new;       (ofd - old < omax) && *ofd && (*ofd == *nfd);       ofd++, nfd++)    ;  /* Move to the end of the screen line.  ND and OD are used to keep track     of the distance between ne and new and oe and old, respectively, to     move a subtraction out of each loop. */  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);  /* 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 > ofd) && (nls > nfd) && (*ols == *nls))    {      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++;    }  _rl_move_vert (current_line);  /* If this is the first line and there are invisible characters in the     prompt string, and the prompt string has not changed, then redraw     the entire prompt string.  We can only do this reliably if the     terminal supports a `cr' capability.     This is more than just an efficiency hack -- there is a problem with     redrawing portions of the prompt string if they contain terminal     escape sequences (like drawing the `unbold' sequence without a     corresponding `bold') that manifests itself on certain terminals. */  lendiff = local_prompt ? strlen (local_prompt) : 0;  if (current_line == 0 && !_rl_horizontal_scroll_mode &&      lendiff > visible_length &&      _rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr)    {      tputs (term_cr, 1, _rl_output_character_function);      _rl_output_some_chars (local_prompt, lendiff);      _rl_last_c_pos = lendiff;    }  _rl_move_cursor_relative (ofd - old, old);  /* if (len (new) > len (old)) */  lendiff = (nls - nfd) - (ols - ofd);  /* Insert (diff (len (old), len (new)) ch. */  temp = ne - nfd;  if (lendiff > 0)    {      /* Non-zero if we're increasing the number of lines. */      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;      /* Sometimes it is cheaper to print the characters rather than	 use the terminal's capabilities.  If we're growing the number	 of lines, make sure we actually cause the new line to wrap	 around on auto-wrapping terminals. */      if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl))	{	  /* If lendiff > visible_length and _rl_last_c_pos == 0 and	     _rl_horizontal_scroll_mode == 1, inserting the characters with	     term_IC or term_ic will screw up the screen because of the	     invisible characters.  We need to just draw them. */	  if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||			lendiff <= visible_length))	    {	      insert_some_chars (nfd, lendiff);	      _rl_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. */	      _rl_output_some_chars (nfd, lendiff);	      _rl_last_c_pos += lendiff;	    }	  /* Copy (new) chars to screen from first diff to last match. */	  temp = nls - nfd;	  if ((temp - lendiff) > 0)	    {	      _rl_output_some_chars (nfd + lendiff, temp - lendiff);	      _rl_last_c_pos += temp - lendiff;	    }	}      else	{	  /* cannot insert chars, write to EOL */	  _rl_output_some_chars (nfd, temp);	  _rl_last_c_pos += temp;	}    }  else				/* Delete characters from line. */    {      /* If possible and inexpensive to use terminal deletion, then do so. */      if (term_dc && (2 * temp) >= -lendiff)	{	  /* If all we're doing is erasing the invisible characters in the	     prompt string, don't bother.  It screws up the assumptions	     about what's on the screen. */	  if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&	      -lendiff == visible_wrap_offset)	    lendiff = 0;	  if (lendiff)	    delete_chars (-lendiff); /* delete (diff) characters */	  /* Copy (new) chars to screen from first diff to last match */	  temp = nls - nfd;	  if (temp > 0)	    {	      _rl_output_some_chars (nfd, temp);	      _rl_last_c_pos += temp;	    }	}      /* Otherwise, print over the existing material. */      else	{	  if (temp > 0)	    {	      _rl_output_some_chars (nfd, temp);	      _rl_last_c_pos += temp;	    }	  lendiff = (oe - old) - (ne - new);	  if (term_xn && current_line < inv_botlin)	    space_to_eol (lendiff);	  else	    clear_to_eol (lendiff);	}    }}/* Tell the update routines that we have moved onto a new (empty) line. */rl_on_new_line (){  if (visible_line)    visible_line[0] = '\0';

⌨️ 快捷键说明

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