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

📄 xdisp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
   Returns the hpos of the end of the text generated by ELT.   The next element will receive that value as its HPOS arg,   so as to concatenate the elements.  */intdisplay_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt)     struct window *w;     int vpos;     register int hpos;     int depth;     int minendcol;     register int maxendcol;     register Lisp_Object elt;{ tail_recurse:  if (depth > 10)    goto invalid;  depth++;#ifdef SWITCH_ENUM_BUG  switch ((int) XTYPE (elt))#else  switch (XTYPE (elt))#endif    {    case Lisp_String:      {	/* A string: output it and check for %-constructs within it.  */	register unsigned char c;	register unsigned char *this = XSTRING (elt)->data;	while (hpos < maxendcol && *this)	  {	    unsigned char *last = this;	    while ((c = *this++) != '\0' && c != '%')	      ;	    if (this - 1 != last)	      {		register int lim = --this - last + hpos;		hpos = display_string (w, vpos, last, hpos, 0, hpos,				       min (lim, maxendcol));	      }	    else /* c == '%' */	      {		register int spec_width = 0;		/* We can't allow -ve args due to the "%-" construct */		/* Argument specifies minwidth but not maxwidth		   (maxwidth can be specified by		     (<negative-number> . <stuff>) mode-line elements) */		while ((c = *this++) >= '0' && c <= '9')		  {		    spec_width = spec_width * 10 + (c - '0');		  }		spec_width += hpos;		if (spec_width > maxendcol)		  spec_width = maxendcol;		if (c == 'M')		  hpos = display_mode_element (w, vpos, hpos, depth,					       spec_width, maxendcol,					       Vglobal_mode_string);		else if (c != 0)		  hpos = display_string (w, vpos,					 decode_mode_spec (w, c,							   spec_width - hpos),					 hpos, 0, spec_width, maxendcol);	      }	  }      }      break;    case Lisp_Symbol:      /* A symbol: process the value of the symbol recursively	 as if it appeared here directly.  Avoid error if symbol void.	 Special case: if value of symbol is a string, output the string	 literally.  */      {	register Lisp_Object tem;	tem = Fboundp (elt);	if (!NULL (tem))	  {	    tem = Fsymbol_value (elt);	    /* If value is a string, output that string literally:	       don't check for % within it.  */	    if (XTYPE (tem) == Lisp_String)	      hpos = display_string (w, vpos, XSTRING (tem)->data,				     hpos, 0, minendcol, maxendcol);	    /* Give up right away for nil or t.  */	    else if (!EQ (tem, elt))	      { elt = tem; goto tail_recurse; }	  }      }      break;    case Lisp_Cons:      {	register Lisp_Object car, tem;	/* A cons cell: three distinct cases.	   If first element is a string or a cons, process all the elements	   and effectively concatenate them.	   If first element is a negative number, truncate displaying cdr to	   at most that many characters.  If positive, pad (with spaces)	   to at least that many characters.	   If first element is a symbol, process the cadr or caddr recursively	   according to whether the symbol's value is non-nil or nil.  */	car = XCONS (elt)->car;	if (XTYPE (car) == Lisp_Symbol)	  {	    tem = Fboundp (car);	    elt = XCONS (elt)->cdr;	    if (XTYPE (elt) != Lisp_Cons)	      goto invalid;	    /* elt is now the cdr, and we know it is a cons cell.	       Use its car if CAR has a non-nil value.  */	    if (!NULL (tem))	      {		tem = Fsymbol_value (car);		if (!NULL (tem))		  { elt = XCONS (elt)->car; goto tail_recurse; }	      }	    /* Symbol's value is nil (or symbol is unbound)	       Get the cddr of the original list	       and if possible find the caddr and use that.  */	    elt = XCONS (elt)->cdr;	    if (NULL (elt))	      break;	    else if (XTYPE (elt) != Lisp_Cons)	      goto invalid;	    elt = XCONS (elt)->car;	    goto tail_recurse;	  }	else if (XTYPE (car) == Lisp_Int)	  {	    register int lim = XINT (car);	    elt = XCONS (elt)->cdr;	    if (lim < 0)	      /* Negative int means reduce maximum width.		 DO NOT change MINENDCOL here!		 (20 -10 . foo) should truncate foo to 10 col		 and then pad to 20.  */	      maxendcol = min (maxendcol, hpos - lim);	    else if (lim > 0)	      {		/* Padding specified.  Don't let it be more than		   current maximum.  */		lim += hpos;		if (lim > maxendcol)		  lim = maxendcol;		/* If that's more padding than already wanted, queue it.		   But don't reduce padding already specified even if		   that is beyond the current truncation point.  */		if (lim > minendcol)		  minendcol = lim;	      }	    goto tail_recurse;	  }	else if (XTYPE (car) == Lisp_String || XTYPE (car) == Lisp_Cons)	  {	    register int limit = 50;	    /* LIMIT is to protect against circular lists.  */	    while (XTYPE (elt) == Lisp_Cons && --limit > 0		   && hpos < maxendcol)	      {		hpos = display_mode_element (w, vpos, hpos, depth,					     hpos, maxendcol,					     XCONS (elt)->car);		elt = XCONS (elt)->cdr;	      }	  }      }      break;    default:    invalid:      return (display_string (w, vpos, "*invalid*", hpos, 0,			      minendcol, maxendcol));    } end:  if (minendcol > hpos)    hpos = display_string (w, vpos, "", hpos, 0, minendcol, -1);  return hpos;}/* Return a string for the output of a mode line %-spec   for window W, generated by character C and width MAXWIDTH.  */char *decode_mode_spec (w, c, maxwidth)     struct window *w;     register char c;     register int maxwidth;{  Lisp_Object obj = Qnil;  char *decode_mode_spec_buf = (char *) temp_screen->total_contents;  switch (c)    {    case 'b':       obj = current_buffer->name;#if 0      if (maxwidth >= 3 && XSTRING (obj)->size > maxwidth)	{	  bcopy (XSTRING (obj)->data, decode_mode_spec_buf, maxwidth - 1);	  decode_mode_spec_buf[maxwidth - 1] = '\\';	  decode_mode_spec_buf[maxwidth] = '\0';	  return decode_mode_spec_buf;	}#endif      break;    case 'f':       obj = current_buffer->filename;#if 0      if (XTYPE (obj) == Lisp_String && XSTRING (obj)->size > maxwidth)	{	  bcopy ("...", decode_mode_spec_buf, 3);	  bcopy (XSTRING (obj)->data + XSTRING (obj)->size - maxwidth + 3,		 decode_mode_spec_buf + 3, maxwidth - 3);	  return decode_mode_spec_buf;	}#endif      break;    case 'm':       obj = current_buffer->mode_name;      break;    case 'n':      if (BEGV > BEG || ZV < Z)	return " Narrow";      break;    case '*':      if (!NULL (current_buffer->read_only))	return "%";      if (MODIFF > current_buffer->save_modified)	return "*";      return "-";    case 's':      /* status of process */#ifdef subprocesses      obj = Fget_buffer_process (Fcurrent_buffer ());      if (NULL (obj))	return "no process";      obj = Fsymbol_name (Fprocess_status (obj));      break;#else      return "no processes";#endif /* subprocesses */    case 'p':      {	int pos = marker_position (w->start);	int total = ZV - BEGV;	if (XFASTINT (w->window_end_pos) <= Z - ZV)	  {	    if (pos <= BEGV)	      return "All";	    else	      return "Bottom";	  }	else if (pos <= BEGV)	  return "Top";	else	  {	    total = ((pos - BEGV) * 100 + total - 1) / total;	    /* We can't normally display a 3-digit number,	       so get us a 2-digit number that is close.  */	    if (total == 100)	      total = 99;	    sprintf (decode_mode_spec_buf, "%2d%%", total);	    return decode_mode_spec_buf;	  }      }    case '[':       {	int i;	char *p;	if (command_loop_level > 5)	  return "[[[... ";	p = decode_mode_spec_buf;	for (i = 0; i < command_loop_level; i++)	  *p++ = '[';	*p = 0;	return decode_mode_spec_buf;      }    case '%':      return "%";    case ']':       {	int i;	char *p;	if (command_loop_level > 5)	  return " ...]]]";	p = decode_mode_spec_buf;	for (i = 0; i < command_loop_level; i++)	  *p++ = ']';	*p = 0;	return decode_mode_spec_buf;      }    case '-':      {	int i;	if (maxwidth < 140)	  return "--------------------------------------------------------------------------------------------------------------------------------------------";	for (i = 0; i < maxwidth; i++)	  decode_mode_spec_buf[i] = '-';	return decode_mode_spec_buf;      }    }  if (XTYPE (obj) == Lisp_String)    return (char *) XSTRING (obj)->data;  else    return "";}/* Display STRING on one line of window W, starting at HPOS.   Display at position VPOS.  Caller should do get_display_line first.  TRUNCATE is character to display at end if truncated.  Zero for none.  MINCOL is the first column ok to end at.  (Pad with spaces to this col.)  MAXCOL is the last column ok to end at.  Truncate here.    -1 for MINCOL or MAXCOL means no explicit minimum or maximum.  Both count from the left edge of the screen, as does HPOS.  The right edge of W is an implicit maximum.  If TRUNCATE is nonzero, the implicit maximum is one column before the edge.  Returns ending hpos */display_string (w, vpos, string, hpos, truncate, mincol, maxcol)     struct window *w;     int vpos;     unsigned char *string;     int hpos;     char truncate;     int mincol, maxcol;{  register int c;  register unsigned char *p1;  int hscroll = XINT (w->hscroll);  int tab_width = XINT (current_buffer->tab_width);  register unsigned char *start;  register unsigned char *end;  unsigned char *p1start = new_screen->contents[vpos] + hpos;  int window_width = XFASTINT (w->width);  if (tab_width <= 0 || tab_width > 20) tab_width = 8;  p1 = p1start;  start = new_screen->contents[vpos] + XFASTINT (w->left);  end = start + window_width - (truncate != 0);  if ((window_width + XFASTINT (w->left)) != screen_width)    *end-- = '|';  if (maxcol >= 0 && end - new_screen->contents[vpos] > maxcol)    end = new_screen->contents[vpos] + maxcol;  if (maxcol >= 0 && mincol > maxcol)    mincol = maxcol;  while (p1 < end)    {      c = *string++;      if (!c) break;      if (c >= 040 && c < 0177)	{	  if (p1 >= start)	    *p1 = c;	  p1++;	}      else if (c == '\t')	{	  do	    {	      if (p1 >= start)		*p1 = ' ';	      p1++;	    }	  while ((p1 - start + hscroll - (hscroll > 0)) % tab_width);	}      else if (c < 0200 && buffer_defaults.ctl_arrow)	{	  if (p1 >= start)	    *p1 = '^';	  p1++;	  if (p1 >= start)	    *p1 = c ^ 0100;	  p1++;	}      else	{	  if (p1 >= start)	    *p1 = '\\';	  p1++;	  if (p1 >= start)	    *p1 = (c >> 6) + '0';	  p1++;	  if (p1 >= start)	    *p1 = (7 & (c >> 3)) + '0';	  p1++;	  if (p1 >= start)	    *p1 = (7 & c) + '0';	  p1++;	}    }  if (c)    {      p1 = end;      if (truncate) *p1++ = truncate;    }  else if (mincol >= 0)    {      end = new_screen->contents[vpos] + mincol;      while (p1 < end)	*p1++ = ' ';    }  {    register int len = p1 - new_screen->contents[vpos];    if (len > new_screen->used[vpos])      new_screen->used[vpos] = len;    new_screen->contents[vpos][new_screen->used[vpos]] = 0;    return len;  }}syms_of_xdisp (){  staticpro (&last_arrow_position);  staticpro (&last_arrow_string);  last_arrow_position = Qnil;  last_arrow_string = Qnil;  DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,    "String displayed by mode-line-format's \"%m\" specifiation.");  Vglobal_mode_string = Qnil;  DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,    "Marker for where to display an arrow on top of the buffer text.\n\This must be the beginning of a line in order to work.\n\See also overlay-arrow-string.");  Voverlay_arrow_position = Qnil;  DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,    "String to display as an arrow.  See also overlay-arrow-position.");  Voverlay_arrow_string = Qnil;  DEFVAR_INT ("scroll-step", &scroll_step,    "*The number of lines to try scrolling a window by when point moves out.\n\If that fails to bring point back on screen, point is centered instead.\n\If this is zero, point is always centered after it moves off screen.");  DEFVAR_BOOL ("reset-terminal-on-clear", &reset_terminal_on_clear,    "Non-nil means re-init terminal modes for clear screen as on entry to Emacs.");  reset_terminal_on_clear = 1;  DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");  DEFVAR_BOOL ("truncate-partial-width-windows",	       &truncate_partial_width_windows,    "*Non-nil means truncate lines in all windows less than full screen wide.");  truncate_partial_width_windows = 1;  DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,    "*Non-nil means use inverse video, or other suitable display mode, for the mode line.");  mode_line_inverse_video = 1;  defsubr (&Sredraw_display);}/* initialize the window system */init_xdisp (){  Lisp_Object root_window;#ifndef COMPILER_REGISTER_BUG  register#endif COMPILER_REGISTER_BUG    struct window *mini_w;  this_line_bufpos = 0;  mini_w = XWINDOW (minibuf_window);  root_window = mini_w->prev;  echo_area_contents = 0;  prev_echo_area_contents = 0;  if (!noninteractive)    {      XFASTINT (XWINDOW (root_window)->top) = 0;      set_window_height (root_window, screen_height - 1, 0);      XFASTINT (mini_w->top) = screen_height - 1;      set_window_height (minibuf_window, 1, 0);      XFASTINT (XWINDOW (root_window)->width) = screen_width;      XFASTINT (mini_w->width) = screen_width;    }}

⌨️ 快捷键说明

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