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

📄 display.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* display.c -- readline redisplay facility. *//* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.   This file is part of the GNU Readline Library, a library for   reading lines of text with interactive input and history editing.   The GNU Readline Library is free software; you can redistribute it   and/or modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version 1, or   (at your option) any later version.   The GNU Readline Library is distributed in the hope that it will be   useful, but WITHOUT ANY WARRANTY; without even the implied warranty   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   The GNU General Public License is often shipped with GNU software, and   is generally kept in a file called COPYING or LICENSE.  If you do not   have a copy of the license, write to the Free Software Foundation,   675 Mass Ave, Cambridge, MA 02139, USA. */#define READLINE_LIBRARY#if defined (HAVE_CONFIG_H)#  include "config.h"#endif#include <stdio.h>#include <sys/types.h>#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif /* HAVE_UNISTD_H */#if defined (HAVE_STDLIB_H)#  include <stdlib.h>#else#  include "ansi_stdlib.h"#endif /* HAVE_STDLIB_H */#include "posixstat.h"/* System-specific feature definitions and include files. */#include "rldefs.h"/* Some standard library routines. */#include "readline.h"#include "history.h"#if !defined (strchr) && !defined (__STDC__)extern char *strchr (), *strrchr ();#endif /* !strchr && !__STDC__ *//* Global and pseudo-global variables and functions   imported from readline.c. */extern char *rl_prompt;extern int readline_echoing_p;extern char *term_clreol, *term_im, *term_ic,  *term_ei, *term_DC;/* Termcap variables. */extern char *term_up, *term_dc, *term_cr, *term_IC;extern int screenheight, screenwidth, screenchars;extern int terminal_can_insert, term_xn;extern void _rl_output_some_chars ();extern int _rl_output_character_function ();extern int _rl_output_meta_chars;extern int _rl_horizontal_scroll_mode;extern int _rl_mark_modified_lines;extern int _rl_prefer_visible_bell;/* Pseudo-global functions (local to the readline library) exported   by this file. */void _rl_move_cursor_relative (), _rl_output_some_chars ();void _rl_move_vert ();static void update_line (), clear_to_eol (), space_to_eol ();static void delete_chars (), insert_some_chars ();extern char *xmalloc (), *xrealloc ();/* Heuristic used to decide whether it is faster to move from CUR to NEW   by backing up or outputting a carriage return and moving forward. */#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))/* **************************************************************** *//*								    *//*			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.  Careful attention needs   to be paid to the vertical position variables. *//* 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. *//* Global variables declared here. *//* What YOU turn on when you have handled all redisplay yourself. */int rl_display_fixed = 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;/* Pseudo-global variables declared here. *//* The visible cursor position.  If you print some text, adjust this. */int _rl_last_c_pos = 0;int _rl_last_v_pos = 0;/* Number of lines currently on screen minus 1. */int _rl_vis_botlin = 0;/* Variables used only in this file. *//* 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;/* A buffer for `modeline' messages. */static char msg_buf[128];/* Non-zero forces the redisplay even if we thought it was unnecessary. */static int forced_display = 0;/* Default and initial buffer size.  Can grow. */static int line_size = 1024;static char *last_prompt_string = (char *)NULL;static char *local_prompt, *local_prompt_prefix;static int visible_length, prefix_length;/* The number of invisible characters in the line currently being   displayed on the screen. */static int visible_wrap_offset = 0;/* The length (buffer offset) of the first line of the last (possibly   multi-line) buffer displayed on the screen. */static int visible_first_line_len = 0;/* Expand the prompt string S and return the number of visible   characters in *LP, if LP is not null.  This is currently more-or-less   a placeholder for expansion. *//* Current implementation:	\001 (^A) start non-visible characters	\002 (^B) end non-visible characters   all characters except \001 and \002 (following a \001) are copied to   the returned string; all characters except those between \001 and   \002 are assumed to be `visible'. */	static char *expand_prompt (pmt, lp)     char *pmt;     int *lp;{  char *r, *ret, *p;  int l, rl, ignoring;  /* Short-circuit if we can. */  if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)    {      r = savestring (pmt);      if (lp)	*lp = strlen (r);      return r;    }  l = pmt ? strlen (pmt) : 0;  r = ret = xmalloc (l + 1);    for (rl = ignoring = 0, p = pmt; p && *p; p++)    {      /* This code strips the invisible character string markers	 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */      if (*p == RL_PROMPT_START_IGNORE)	{	  ignoring++;	  continue;	}      else if (ignoring && *p == RL_PROMPT_END_IGNORE)	{	  ignoring = 0;	  continue;	}      else	{	  *r++ = *p;	  if (!ignoring)	    rl++;	}    }  *r = '\0';  if (lp)    *lp = rl;  return ret;}/* * Expand the prompt string into the various display components, if * necessary. * * local_prompt = expanded last line of string in rl_display_prompt *		  (portion after the final newline) * local_prompt_prefix = portion before last newline of rl_display_prompt, *			 expanded via expand_prompt * visible_length = number of visible characters in local_prompt * prefix_length = number of visible characters in local_prompt_prefix * * This function is called once per call to readline().  It may also be * called arbitrarily to expand the primary prompt. * * The return value is the number of visible characters on the last line * of the (possibly multi-line) prompt. */intrl_expand_prompt (prompt)     char *prompt;{  char *p, *t;  int c;  /* Clear out any saved values. */  if (local_prompt)    free (local_prompt);  if (local_prompt_prefix)    free (local_prompt_prefix);  local_prompt = local_prompt_prefix = (char *)0;  if (prompt == 0 || *prompt == '\0')    return (0);  p = strrchr (prompt, '\n');  if (!p)    {      /* The prompt is only one line. */      local_prompt = expand_prompt (prompt, &visible_length);      local_prompt_prefix = (char *)0;      return (visible_length);    }  else    {      /* The prompt spans multiple lines. */      t = ++p;      local_prompt = expand_prompt (p, &visible_length);      c = *t; *t = '\0';      /* The portion of the prompt string up to and including the	 final newline is now null-terminated. */      local_prompt_prefix = expand_prompt (prompt, &prefix_length);      *t = c;      return (prefix_length);    }}/* Basic redisplay algorithm. */voidrl_redisplay (){  register int in, out, c, linenum;  register char *line = invisible_line;  int c_pos = 0, inv_botlin = 0, wrap_offset, wrap_column;  char *prompt_this_line;  if (!readline_echoing_p)    return;  if (!rl_display_prompt)    rl_display_prompt = "";  if (!invisible_line)    {      visible_line = xmalloc (line_size);      invisible_line = 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 (_rl_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 caller's misconception. */  if (visible_line[0] != invisible_line[0])    rl_display_fixed = 0;  /* If the prompt to be displayed is the `primary' readline prompt (the     one passed to readline()), use the values we have already expanded.     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the     number of non-visible characters in the prompt string. */  if (rl_display_prompt == rl_prompt)    {      int local_len = local_prompt ? strlen (local_prompt) : 0;      if (local_prompt_prefix && forced_display)	_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));      if (local_len > 0)	strncpy (line + out, local_prompt, local_len);      out += local_len;      line[out] = '\0';      wrap_offset = local_len - visible_length;    }  else    {      int pmtlen;      prompt_this_line = strrchr (rl_display_prompt, '\n');      if (!prompt_this_line)	prompt_this_line = rl_display_prompt;      else	{	  prompt_this_line++;	  if (forced_display)	    _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);	}      pmtlen = strlen (prompt_this_line);      strncpy (line + out,  prompt_this_line, pmtlen);      out += pmtlen;      line[out] = '\0';      wrap_offset = 0;    }  for (in = 0; in < rl_end; in++)    {      c = (unsigned char)rl_line_buffer[in];      if (out + 8 >= line_size)		/* XXX - 8 for \t */	{	  line_size *= 2;	  visible_line = xrealloc (visible_line, line_size);	  invisible_line = xrealloc (invisible_line, line_size);	  line = invisible_line;	}      if (in == rl_point)	c_pos = out;      if (META_CHAR (c))	{	  if (_rl_output_meta_chars == 0)	    {	      sprintf (line + out, "\\%o", c);	      out += 4;	    }	  else	    line[out++] = c;	  	}#if defined (DISPLAY_TABS)      else if (c == '\t')	{	  register int newout = (out | (int)7) + 1;	  while (out < newout)	    line[out++] = ' ';	}#endif      else if (c < ' ')	{	  line[out++] = '^';	  line[out++] = UNCTRL (c);	/* XXX was c ^ 0x40 */	}      else if (c == 127)	{	  line[out++] = '^';	  line[out++] = '?';	}      else	line[out++] = c;    }  line[out] = '\0';  if (c_pos < 0)    c_pos = out;  /* C_POS == position in buffer where cursor should be placed. */  /* 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 (!_rl_horizontal_scroll_mode && term_up && *term_up)    {      int total_screen_chars = screenchars;      int nleft, cursor_linenum, pos, changed_screen_line;      if (!rl_display_fixed || forced_display)	{	  forced_display = 0;

⌨️ 快捷键说明

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