📄 readline.c
字号:
#if defined (TIOCGWINSZ) if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) { screenwidth = (int) window_size.ws_col; screenheight = (int) window_size.ws_row; }#endif if (screenwidth <= 0 || screenheight <= 0) { screenwidth = tgetnum ("co"); screenheight = tgetnum ("li"); } screenwidth--; if (screenwidth <= 0) screenwidth = 79; if (screenheight <= 0) screenheight = 24; term_im = tgetstr ("im", &buffer); term_ei = tgetstr ("ei", &buffer); term_IC = tgetstr ("IC", &buffer); term_ic = tgetstr ("ic", &buffer); /* "An application program can assume that the terminal can do character insertion if *any one of* the capabilities `IC', `im', `ic' or `ip' is provided." But we can't do anything if only `ip' is provided, so... */ terminal_can_insert = (term_IC || term_im || term_ic); term_up = tgetstr ("up", &buffer); term_dc = tgetstr ("dc", &buffer); term_DC = tgetstr ("DC", &buffer); visible_bell = tgetstr ("vb", &buffer);#endif /* !__GO32__ */}/* A function for the use of tputs () */static voidoutput_character_function (c) int c;{ putc (c, out_stream);}/* Write COUNT characters from STRING to the output stream. */static voidoutput_some_chars (string, count) char *string; int count;{ fwrite (string, 1, count, out_stream);}/* Delete COUNT characters from the display line. */staticdelete_chars (count) int count;{#ifdef __GO32__ int r, c, w; ScreenGetCursor(&r, &c); w = ScreenCols(); memcpy(ScreenPrimary+r*w+c, ScreenPrimary+r*w+c+count, w-c-count); memset(ScreenPrimary+r*w+w-count, 0, count*2);#else /* __GO32__ */ if (count > screenwidth) return; if (term_DC && *term_DC) { char *tgoto (), *buffer; buffer = tgoto (term_DC, 0, count); tputs (buffer, 1, output_character_function); } else { if (term_dc && *term_dc) while (count--) tputs (term_dc, 1, output_character_function); }#endif /* __GO32__ */}/* Insert COUNT characters from STRING to the output stream. */static voidinsert_some_chars (string, count) char *string; int count;{#ifdef __GO32__ int r, c, w; ScreenGetCursor(&r, &c); w = ScreenCols(); memcpy(ScreenPrimary+r*w+c+count, ScreenPrimary+r*w+c, w-c-count); /* Print the text. */ output_some_chars (string, count);#else /* __GO32__ */ /* If IC is defined, then we do not have to "enter" insert mode. */ if (term_IC) { char *tgoto (), *buffer; buffer = tgoto (term_IC, 0, count); tputs (buffer, 1, output_character_function); output_some_chars (string, count); } else { register int i; /* If we have to turn on insert-mode, then do so. */ if (term_im && *term_im) tputs (term_im, 1, output_character_function); /* If there is a special command for inserting characters, then use that first to open up the space. */ if (term_ic && *term_ic) { for (i = count; i--; ) tputs (term_ic, 1, output_character_function); } /* Print the text. */ output_some_chars (string, count); /* If there is a string to turn off insert mode, we had best use it now. */ if (term_ei && *term_ei) tputs (term_ei, 1, output_character_function); }#endif /* __GO32__ */}/* Move the cursor back. */backspace (count) int count;{ register int i;#ifndef __GO32__ if (term_backspace) for (i = 0; i < count; i++) tputs (term_backspace, 1, output_character_function); else#endif /* !__GO32__ */ for (i = 0; i < count; i++) putc ('\b', out_stream);}/* Move to the start of the next line. */crlf (){#if defined (NEW_TTY_DRIVER) tputs (term_cr, 1, output_character_function);#endif /* NEW_TTY_DRIVER */ putc ('\n', out_stream);}/* Clear to the end of the line. COUNT is the minimum number of character spaces to clear, */static voidclear_to_eol (count) int count;{#ifndef __GO32__ if (term_clreol) { tputs (term_clreol, 1, output_character_function); } else#endif /* !__GO32__ */ { register int i; /* Do one more character space. */ count++; for (i = 0; i < count; i++) putc (' ', out_stream); backspace (count); }}/* **************************************************************** *//* *//* Saving and Restoring the TTY *//* *//* **************************************************************** *//* Non-zero means that the terminal is in a prepped state. */static int terminal_prepped = 0;#if defined (NEW_TTY_DRIVER)/* Standard flags, including ECHO. */static int original_tty_flags = 0;/* Local mode flags, like LPASS8. */static int local_mode_flags = 0;/* Terminal characters. This has C-s and C-q in it. */static struct tchars original_tchars;/* Local special characters. This has the interrupt characters in it. */#if defined (TIOCGLTC)static struct ltchars original_ltchars;#endif/* We use this to get and set the tty_flags. */static struct sgttyb the_ttybuff;/* Put the terminal in CBREAK mode so that we can detect key presses. */static voidrl_prep_terminal (){#ifndef __GO32__ int tty = fileno (rl_instream); SIGNALS_DECLARE_SAVED (saved_signals); if (terminal_prepped) return; SIGNALS_BLOCK (SIGINT, saved_signals); /* We always get the latest tty values. Maybe stty changed them. */ ioctl (tty, TIOCGETP, &the_ttybuff); original_tty_flags = the_ttybuff.sg_flags; readline_echoing_p = (original_tty_flags & ECHO);#if defined (TIOCLGET) ioctl (tty, TIOCLGET, &local_mode_flags);#endif#if !defined (ANYP)# define ANYP (EVENP | ODDP)#endif /* If this terminal doesn't care how the 8th bit is used, then we can use it for the meta-key. We check by seeing if BOTH odd and even parity are allowed. */ if (the_ttybuff.sg_flags & ANYP) {#if defined (PASS8) the_ttybuff.sg_flags |= PASS8;#endif /* Hack on local mode flags if we can. */#if defined (TIOCLGET) && defined (LPASS8) { int flags; flags = local_mode_flags | LPASS8; ioctl (tty, TIOCLSET, &flags); }#endif /* TIOCLGET && LPASS8 */ }#if defined (TIOCGETC) { struct tchars temp; ioctl (tty, TIOCGETC, &original_tchars); temp = original_tchars;#if defined (USE_XON_XOFF) /* Get rid of C-s and C-q. We remember the value of startc (C-q) so that if the terminal is in xoff state, the user can xon it by pressing that character. */ xon_char = temp.t_startc; temp.t_stopc = -1; temp.t_startc = -1; /* If there is an XON character, bind it to restart the output. */ if (xon_char != -1) rl_bind_key (xon_char, rl_restart_output);#endif /* USE_XON_XOFF */ /* If there is an EOF char, bind eof_char to it. */ if (temp.t_eofc != -1) eof_char = temp.t_eofc;#if defined (NO_KILL_INTR) /* Get rid of C-\ and C-c. */ temp.t_intrc = temp.t_quitc = -1;#endif /* NO_KILL_INTR */ ioctl (tty, TIOCSETC, &temp); }#endif /* TIOCGETC */#if defined (TIOCGLTC) { struct ltchars temp; ioctl (tty, TIOCGLTC, &original_ltchars); temp = original_ltchars; /* Make the interrupt keys go away. Just enough to make people happy. */ temp.t_dsuspc = -1; /* C-y */ temp.t_lnextc = -1; /* C-v */ ioctl (tty, TIOCSLTC, &temp); }#endif /* TIOCGLTC */ the_ttybuff.sg_flags &= ~(ECHO | CRMOD); the_ttybuff.sg_flags |= CBREAK; ioctl (tty, TIOCSETN, &the_ttybuff); terminal_prepped = 1; SIGNALS_RESTORE (saved_signals);#endif /* !__GO32__ */}/* Restore the terminal to its original state. */static voidrl_deprep_terminal (){#ifndef __GO32__ int tty = fileno (rl_instream); SIGNALS_DECLARE_SAVED (saved_signals); if (!terminal_prepped) return; SIGNALS_BLOCK (SIGINT, saved_signals); the_ttybuff.sg_flags = original_tty_flags; ioctl (tty, TIOCSETN, &the_ttybuff); readline_echoing_p = 1;#if defined (TIOCLGET) ioctl (tty, TIOCLSET, &local_mode_flags);#endif#if defined (TIOCSLTC) ioctl (tty, TIOCSLTC, &original_ltchars);#endif#if defined (TIOCSETC) ioctl (tty, TIOCSETC, &original_tchars);#endif terminal_prepped = 0; SIGNALS_RESTORE (saved_signals);#endif /* !__GO32 */}#else /* !defined (NEW_TTY_DRIVER) */#if !defined (VMIN)#define VMIN VEOF#endif#if !defined (VTIME)#define VTIME VEOL#endif#ifndef __GO32__#if defined (TERMIOS_TTY_DRIVER)static struct termios otio;#elsestatic struct termio otio;#endif /* !TERMIOS_TTY_DRIVER */#endif /* __GO32__ */static voidrl_prep_terminal (){#ifndef __GO32__ int tty = fileno (rl_instream);#if defined (TERMIOS_TTY_DRIVER) struct termios tio;#else struct termio tio;#endif /* !TERMIOS_TTY_DRIVER */ SIGNALS_DECLARE_SAVED (saved_signals); if (terminal_prepped) return; /* Try to keep this function from being INTerrupted. We can do it on POSIX and systems with BSD-like signal handling. */ SIGNALS_BLOCK (SIGINT, saved_signals);#if defined (TERMIOS_TTY_DRIVER) tcgetattr (tty, &tio);#else ioctl (tty, TCGETA, &tio);#endif /* !TERMIOS_TTY_DRIVER */ otio = tio; readline_echoing_p = (tio.c_lflag & ECHO); tio.c_lflag &= ~(ICANON|ECHO); if (otio.c_cc[VEOF] != _POSIX_VDISABLE) eof_char = otio.c_cc[VEOF];#if defined (USE_XON_XOFF)#if defined (IXANY) tio.c_iflag &= ~(IXON|IXOFF|IXANY);#else /* `strict' Posix systems do not define IXANY. */ tio.c_iflag &= ~(IXON|IXOFF);#endif /* IXANY */#endif /* USE_XON_XOFF */ /* Only turn this off if we are using all 8 bits. */ /* |ISTRIP|INPCK */ tio.c_iflag &= ~(ISTRIP | INPCK); /* Make sure we differentiate between CR and NL on input. */ tio.c_iflag &= ~(ICRNL | INLCR);#if !defined (HANDLE_SIGNALS) tio.c_lflag &= ~ISIG;#else tio.c_lflag |= ISIG;#endif tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; /* Turn off characters that we need on Posix systems with job control, just to be sure. This includes ^Y and ^V. This should not really be necessary. */#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_JOB_CONTROL)#if defined (VLNEXT) tio.c_cc[VLNEXT] = _POSIX_VDISABLE;#endif#if defined (VDSUSP) tio.c_cc[VDSUSP] = _POSIX_VDISABLE;#endif#endif /* POSIX && JOB_CONTROL */#if defined (TERMIOS_TTY_DRIVER) tcsetattr (tty, TCSADRAIN, &tio); tcflow (tty, TCOON); /* Simulate a ^Q. */#else ioctl (tty, TCSETAW, &tio); ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */#endif /* !TERMIOS_TTY_DRIVER */ terminal_prepped = 1; SIGNALS_RESTORE (saved_signals);#endif /* !__GO32__ */}static voidrl_deprep_terminal (){#ifndef __GO32__ int tty = fileno (rl_instream); /* Try to keep this function from being INTerrupted. We can do it on POSIX and systems with BSD-like signal handling. */ SIGNALS_DECLARE_SAVED (saved_signals); if (!terminal_prepped) return; SIGNALS_BLOCK (SIGINT, saved_signals);#if defined (TERMIOS_TTY_DRIVER) tcsetattr (tty, TCSADRAIN, &otio); tcflow (tty, TCOON); /* Simulate a ^Q. */#else /* TERMIOS_TTY_DRIVER */ ioctl (tty, TCSETAW, &otio); ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */#endif /* !TERMIOS_TTY_DRIVER */ terminal_prepped = 0; SIGNALS_RESTORE (saved_signals);#endif /* !__GO32__ */}#endif /* NEW_TTY_DRIVER *//* **************************************************************** *//* *//* Utility Functions *//* *//* **************************************************************** *//* Return 0 if C is not a member of the class of characters that belong in words, or 1 if it is. */int allow_pathname_alphabetic_chars = 0;char *pathname_alphabetic_chars = "/-_=~.#$";intalphabetic (c) int c;{ if (pure_alphabetic (c) || (numeric (c))) return (1); if (allow_pathname_alphabetic_chars) return ((int)rindex (pathname_alphabetic_chars, c)); else return (0);}/* Return non-zero if C is a numeric character. */intnumeric (c) int c;{ return (c >= '0' && c <= '9');}/* Ring the terminal bell. */intding (){ if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -