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

📄 xdisp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	     and therefore having to be redrawn.  */	  tem = scroll_screen_lines (bp.vpos + top - scroll_amount,				     top + height - max (0, scroll_amount),				     scroll_amount);	  if (!tem) stop_vpos = height;	}      else if (scroll_amount)	{	  /* If reprinting everything is nearly as fast as scrolling,	     don't bother scrolling.  Can happen if lines are short.  */	  /* Note that if scroll_amount > 0, xp.bufpos - bp.bufpos is an	     overestimate of cost of reprinting, since xp.bufpos	     would end up below the bottom of the window.  */	  if (scroll_cost (ep.vpos + top - scroll_amount,			   top + height - max (0, scroll_amount),			   scroll_amount)	      > xp.bufpos - ep.bufpos - 20)	    /* Return "try normal display with same window-start."	       Too bad we can't prevent further scroll-thinking.  */	    return -2;	  tem = scroll_screen_lines (ep.vpos + top - scroll_amount,				     top + height - max (0, scroll_amount),				     scroll_amount);	  if (!tem) stop_vpos = height;	}    }  debug_scroll_amount = scroll_amount;  debug_bp = bp;  debug_ep = ep;  debug_xp = xp;  debug_pp = pp;  /* In any case, do not display past bottom of window */  if (stop_vpos >= height)    {      stop_vpos = height;      scroll_amount = 0;    }  debug_stop_vpos = stop_vpos;  debug_start_vpos = vpos;  /* Handle case where pos is before w->start --     can happen if part of line had been clipped and is not clipped now */  if (vpos == 0 && pos < marker_position (w->start))    Fset_marker (w->start, make_number (pos), Qnil);  /* Redisplay the lines where the text was changed */  last_text_vpos = vpos;  tab_offset = pos_tab_offset (w, pos);  if (val.hpos + hscroll - (hscroll > 0) < 0)    tab_offset += XFASTINT (w->width) - 1;  while (vpos < stop_vpos)    {      val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset);      tab_offset += XFASTINT (w->width) - 1;      if (val.vpos) tab_offset = 0;      if (pos != val.bufpos)	last_text_vpos	  /* Next line, unless prev line ended in end of buffer with no cr */	    = vpos - (val.vpos && FETCH_CHAR (val.bufpos - 1) != '\n');      pos = val.bufpos;    }  /* There are two cases:     1) we have displayed down to the bottom of the window     2) we have scrolled lines below stop_vpos by scroll_amount  */  if (vpos == height)    {      /* If last line is continued in middle of character,	 include the split character in the text considered on the screen */      if (val.hpos < lmargin)	val.bufpos++;      XFASTINT (w->window_end_vpos) = last_text_vpos;      XFASTINT (w->window_end_pos) = Z - val.bufpos;    }  /* If scrolling made blank lines at window bottom,     redisplay to fill those lines */  if (scroll_amount < 0)    {      vpos = xp.vpos;      pos = xp.bufpos;      val.hpos = lmargin;      if (pos == ZV)	vpos = height + scroll_amount;      else if (xp.contin && xp.hpos != lmargin)	{	  val.hpos = xp.prevhpos - width + lmargin;	  pos--;	}      blank_end_of_window = 1;      tab_offset = pos_tab_offset (w, pos);      if (val.hpos < 0)	tab_offset += XFASTINT (w->width) - 1;      while (vpos < height)	{	  val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset);	  tab_offset += XFASTINT (w->width) - 1;	  if (val.vpos) tab_offset = 0;	  pos = val.bufpos;	}      /* Here is a case where display_text_line sets point_vpos wrong.	 Make it be fixed up, below.  */      if (xp.bufpos == ZV	  && xp.bufpos == point)	point_vpos = -1;    }  /* Attempt to adjust end-of-text positions to new bottom line */  if (scroll_amount)    {      delta = height - xp.vpos;      if (delta < 0	  || (delta > 0 && xp.bufpos < ZV)	  || (delta == 0 && xp.hpos))	{	  val = *vmotion (Z - XFASTINT (w->window_end_pos),			  delta, width, hscroll, window);	  XFASTINT (w->window_end_pos) = Z - val.bufpos;	  XFASTINT (w->window_end_vpos) += val.vpos;	}    }  w->window_end_valid = Qnil;  /* If point was not in a line that was displayed, find it */  if (point_vpos < 0)    {      val = *compute_motion (start, 0, lmargin, point, 10000, 10000,			     width, hscroll, pos_tab_offset (w, start));      /* Admit failure if point is off screen now */      if (val.vpos >= height)	{	  for (vpos = 0; vpos < height; vpos++)	    cancel_line (vpos + top);	  return 0;	}      point_vpos = val.vpos + top;      point_hpos = val.hpos + XFASTINT (w->left);    }  cursor_hpos = max (0, point_hpos);  cursor_vpos = point_vpos;  if (debug_end_pos)    {      val = *compute_motion (start, 0, lmargin, ZV,			     height, - (1 << (SHORTBITS - 1)),			     width, hscroll, pos_tab_offset (w, start));      if (val.vpos != XFASTINT (w->window_end_vpos))	abort ();      if (XFASTINT (w->window_end_pos) != Z - val.bufpos)	abort ();    }  return 1;}/* Display one line of window w, starting at position `start' in w's buffer. Display starting at horizontal position `hpos',  which is normally zero or negative.  A negative value causes output up to hpos = 0 to be discarded.  This is done for negative hscroll, or when this is a continuation line  and the continuation occurred in the middle of a multi-column character. `taboffset' is an offset for ostensible hpos, used in tab stop calculations. Display on position `vpos' on the screen.  (origin 0). Returns a `struct position' giving character to start next line with and where to display it, including a zero or negative hpos. The vpos field is not really a vpos; it is 1 unless the line is continued */struct position val_display_text_line;struct position *display_text_line (w, start, vpos, hpos, taboffset)     struct window *w;     int start;     int vpos;     int hpos;     int taboffset;{  register int pos = start;  register int c;  register unsigned char *p1;  int end;  register int pause;  register unsigned char *p;  unsigned char *endp;  register unsigned char *startp;  register unsigned char *p1prev;  int tab_width = XINT (current_buffer->tab_width);  int ctl_arrow = !NULL (current_buffer->ctl_arrow);  int width = XFASTINT (w->width) - 1    - (XFASTINT (w->width) + XFASTINT (w->left) != screen_width);  struct position val;  int lastpos;  int invis;  int hscroll = XINT (w->hscroll);  int truncate = hscroll    || (truncate_partial_width_windows	&& XFASTINT (w->width) < screen_width)    || !NULL (current_buffer->truncate_lines);  int selective    = XTYPE (current_buffer->selective_display) == Lisp_Int      ? XINT (current_buffer->selective_display)	: !NULL (current_buffer->selective_display) ? -1 : 0;  int selective_e = selective && !NULL (current_buffer->selective_display_ellipses);  hpos += XFASTINT (w->left);  get_display_line (vpos, XFASTINT (w->left));  if (tab_width <= 0 || tab_width > 20) tab_width = 8;  if (w == XWINDOW (minibuf_window) && start == 1      && vpos == XFASTINT (w->top))    {      if (minibuf_prompt)	hpos = display_string (w, vpos, minibuf_prompt, hpos,			       !truncate ? '\\' : '$', -1, -1);      minibuf_prompt_width = hpos;    }  p1 = new_screen->contents[vpos] + hpos;  end = ZV;  startp = new_screen->contents[vpos] + XFASTINT (w->left);  endp = startp + width;  /* Loop generating characters.   Stop at end of buffer, before newline,   or if reach or pass continuation column.  */  pause = pos;  while (p1 < endp)    {      p1prev = p1;      if (pos == pause)	{	  if (pos == end)	    break;	  if (pos == point && point_vpos < 0)	    {	      point_vpos = vpos;	      point_hpos = p1 - startp;	    }	  pause = end;	  if (pos < point && point < pause)	    pause = point;	  if (pos < GPT && GPT < pause)	    pause = GPT;	  p = &FETCH_CHAR (pos);	}      c = *p++;      if (c >= 040 && c < 0177)	{	  if (p1 >= startp)	    *p1 = c;	  p1++;	}      else if (c == '\n')	{	  invis = 0;	  while (pos < end		 && selective > 0		 && position_indentation (pos + 1) >= selective)	    {	      invis = 1;	      pos = find_next_newline (pos + 1, 1);	      if (FETCH_CHAR (pos - 1) == '\n')		pos--;	    }	  if (invis && selective_e)	    {	      p1 += 4;	      if (p1 - startp > width)		p1 = endp;	      if (p1prev >= startp)		strncpy (p1prev, " ...", p1 - p1prev);	    }	  break;	}      else if (c == '\t')	{	  do	    {	      if (p1 >= startp)		*p1 = ' ';	      p1++;	    }	  while ((p1 - startp + taboffset + hscroll - (hscroll > 0))		 % tab_width);	}      else if (c == Ctl('M') && selective == -1)	{	  pos = find_next_newline (pos, 1);	  if (FETCH_CHAR (pos - 1) == '\n')	    pos--;	  if (selective_e)	    {	      p1 += 4;	      if (p1 - startp > width)		p1 = endp;	      if (p1prev >= startp)		strncpy (p1prev, " ...", p1 - p1prev);	    }	  break;	}      else if (c < 0200 && ctl_arrow)	{	  if (p1 >= startp)	    *p1 = '^';	  p1++;	  if (p1 >= startp)	    *p1 = c ^ 0100;	  p1++;	}      else	{	  if (p1 >= startp)	    *p1 = '\\';	  p1++;	  if (p1 >= startp)	    *p1 = (c >> 6) + '0';	  p1++;	  if (p1 >= startp)	    *p1 = (7 & (c >> 3)) + '0';	  p1++;	  if (p1 >= startp)	    *p1 = (7 & c) + '0';	  p1++;	}      pos++;    }  val.hpos = - XINT (w->hscroll);  if (val.hpos)    val.hpos++;  val.vpos = 1;  lastpos = pos;  /* Handle continuation in middle of a character */  /* by backing up over it */  if (p1 > endp)    {      /* Start the next line with that same character */      pos--;      /* but at a negative hpos, to skip the columns output on this line.  */      val.hpos += p1prev - endp;      /* Keep in this line everything up to the continuation column.  */      p1 = endp;    }  /* Finish deciding which character to start the next line on,     and what hpos to start it at.     Also set `lastpos' to the last position which counts as "on this line"     for cursor-positioning.  */  if (pos < ZV)    {      if (FETCH_CHAR (pos) == '\n')	/* If stopped due to a newline, start next line after it */	pos++;      else	/* Stopped due to right margin of window */	{	  if (truncate)	    {	      *p1++ = '$';	      /* Truncating => start next line after next newline,		 and point is on this line if it is before the newline,		 and skip none of first char of next line */	      pos = find_next_newline (pos, 1);	      val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;	      lastpos = pos - (FETCH_CHAR (pos - 1) == '\n');	    }	  else	    {	      *p1++ = '\\';	      val.vpos = 0;	      lastpos--;	    }	}    }  /* If point is at eol or in invisible text at eol,     record its screen location now.  */  if (start <= point && point <= lastpos && point_vpos < 0)    {      point_vpos = vpos;      point_hpos = p1 - startp;    }  if (point_vpos == vpos)    {      if (point_hpos < 0) point_hpos = 0;      if (point_hpos > width) point_hpos = width;      point_hpos += XFASTINT (w->left);      if (w == XWINDOW (selected_window))	{	  cursor_vpos = point_vpos;	  cursor_hpos = point_hpos;	  /* Line is not continued and did not start in middle of character */	  if (hpos == (XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0)	      && val.vpos)	    {	      this_line_bufpos = start;	      this_line_buffer = current_buffer;	      this_line_vpos = point_vpos;	      this_line_start_hpos = hpos;	      this_line_endpos = Z - lastpos;	    }	  else	    this_line_bufpos = 0;	}    }  /* If hscroll and line not empty, insert truncation-at-left marker */  if (hscroll && lastpos != start)    {      *startp = '$';      if (p1 <= startp)	p1 = startp + 1;    }  if (XFASTINT (w->width) + XFASTINT (w->left) != screen_width)    {      endp++;      if (p1 < startp) p1 = startp;      while (p1 < endp) *p1++ = ' ';      *p1++ = '|';    }  new_screen->used[vpos] = max (new_screen->used[vpos],				p1 - new_screen->contents[vpos]);  new_screen->contents[vpos][new_screen->used[vpos]] = 0;  /* If the start of this line is the overlay arrow-position,     then put the arrow string into the display-line.  */  if (XTYPE (Voverlay_arrow_position) == Lisp_Marker      && current_buffer == XMARKER (Voverlay_arrow_position)->buffer      && start == marker_position (Voverlay_arrow_position)      && XTYPE (Voverlay_arrow_string) == Lisp_String)    {      unsigned char *p = XSTRING (Voverlay_arrow_string)->data;      int len = XSTRING (Voverlay_arrow_string)->size;      if (len > XFASTINT (w->width) - 1)	len = XFASTINT (w->width) - 1;      bcopy (p, startp, len);      if (new_screen->used[vpos] < len + startp - new_screen->contents[vpos])	new_screen->used[vpos] = len + startp - new_screen->contents[vpos];    }  val.bufpos = pos;  val_display_text_line = val;  return &val_display_text_line;}/* Display the mode line for window w */display_mode_line (w)     struct window *w;{  register int vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;  register int left = XFASTINT (w->left);  register int right = XFASTINT (w->width) + left;  get_display_line (vpos, left);  display_mode_element (w, vpos, left, 0, right, right,			current_buffer->mode_line_format);  /* Make the mode line inverse video if the entire line     is made of mode lines.     I.e. if this window is full width,     or if it is the child of a full width window     (which implies that that window is split side-by-side     and the rest of this line is mode lines of the sibling windows).  */  if (XFASTINT (w->width) == screen_width ||      XFASTINT (XWINDOW (w->parent)->width) == screen_width)    new_screen->highlight[vpos] = mode_line_inverse_video;}/* Contribute ELT to the mode line for window W.   How it translates into text depends on its data type.   LINE is the display-line that the mode line is being displayed in.   HPOS is the position (absolute on screen) where this element's text   should start.  The output is truncated automatically at the right   edge of window W.   DEPTH is the depth in recursion.  It is used to prevent   infinite recursion here.   MINENDCOL is the hpos before which the element may not end.   The element is padded at the right with spaces if nec   to reach this column.   MAXENDCOL is the hpos past which this element may not extend.   If MINENDCOL is > MAXENDCOL, MINENDCOL takes priority.   (This is necessary to make nested padding and truncation work.)

⌨️ 快捷键说明

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