📄 readline.c
字号:
/* readline.c -- a general facility for reading lines of input with emacs style editing and completion. *//* Copyright (C) 1987-2002 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 2, 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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */#define READLINE_LIBRARY#if defined (HAVE_CONFIG_H)# include <config.h>#endif#include <sys/types.h>#include "posixstat.h"#include <fcntl.h>#if defined (HAVE_SYS_FILE_H)# include <sys/file.h>#endif /* HAVE_SYS_FILE_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 */#if defined (HAVE_LOCALE_H)# include <locale.h>#endif#include <stdio.h>#include "posixjmp.h"/* System-specific feature definitions and include files. */#include "rldefs.h"#include "rlmbutil.h"#if defined (__EMX__)# define INCL_DOSPROCESS# include <os2.h>#endif /* __EMX__ *//* Some standard library routines. */#include "readline.h"#include "history.h"#include "rlprivate.h"#include "rlshell.h"#include "xmalloc.h"#ifndef RL_LIBRARY_VERSION# define RL_LIBRARY_VERSION "5.0"#endif#ifndef RL_READLINE_VERSION# define RL_READLINE_VERSION 0x0500#endifextern void _rl_free_history_entry PARAMS((HIST_ENTRY *));/* Forward declarations used in this file. */static char *readline_internal PARAMS((void));static void readline_initialize_everything PARAMS((void));static void bind_arrow_keys_internal PARAMS((Keymap));static void bind_arrow_keys PARAMS((void));static void readline_default_bindings PARAMS((void));static void reset_default_bindings PARAMS((void));/* **************************************************************** *//* *//* Line editing input utility *//* *//* **************************************************************** */const char *rl_library_version = RL_LIBRARY_VERSION;int rl_readline_version = RL_READLINE_VERSION;/* True if this is `real' readline as opposed to some stub substitute. */int rl_gnu_readline_p = 1;/* A pointer to the keymap that is currently in use. By default, it is the standard emacs keymap. */Keymap _rl_keymap = emacs_standard_keymap;/* The current style of editing. */int rl_editing_mode = emacs_mode;/* The current insert mode: input (the default) or overwrite */int rl_insert_mode = RL_IM_DEFAULT;/* Non-zero if we called this function from _rl_dispatch(). It's present so functions can find out whether they were called from a key binding or directly from an application. */int rl_dispatching;/* Non-zero if the previous command was a kill command. */int _rl_last_command_was_kill = 0;/* The current value of the numeric argument specified by the user. */int rl_numeric_arg = 1;/* Non-zero if an argument was typed. */int rl_explicit_arg = 0;/* Temporary value used while generating the argument. */int rl_arg_sign = 1;/* Non-zero means we have been called at least once before. */static int rl_initialized;#if 0/* If non-zero, this program is running in an EMACS buffer. */static int running_in_emacs;#endif/* Flags word encapsulating the current readline state. */int rl_readline_state = RL_STATE_NONE;/* The current offset in the current input line. */int rl_point;/* Mark in the current input line. */int rl_mark;/* Length of the current input line. */int rl_end;/* Make this non-zero to return the current input_line. */int rl_done;/* The last function executed by readline. */rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL;/* Top level environment for readline_internal (). */procenv_t readline_top_level;/* The streams we interact with. */FILE *_rl_in_stream, *_rl_out_stream;/* The names of the streams that we do input and output to. */FILE *rl_instream = (FILE *)NULL;FILE *rl_outstream = (FILE *)NULL;/* Non-zero means echo characters as they are read. Defaults to no echo; set to 1 if there is a controlling terminal, we can get its attributes, and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings for the code that sets it. */int readline_echoing_p = 0;/* Current prompt. */char *rl_prompt = (char *)NULL;int rl_visible_prompt_length = 0;/* Set to non-zero by calling application if it has already printed rl_prompt and does not want readline to do it the first time. */int rl_already_prompted = 0;/* The number of characters read in order to type this complete command. */int rl_key_sequence_length = 0;/* If non-zero, then this is the address of a function to call just before readline_internal_setup () prints the first prompt. */rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL;/* If non-zero, this is the address of a function to call just before readline_internal_setup () returns and readline_internal starts reading input characters. */rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL;/* What we use internally. You should always refer to RL_LINE_BUFFER. */static char *the_line;/* The character that can generate an EOF. Really read from the terminal driver... just defaulted here. */int _rl_eof_char = CTRL ('D');/* Non-zero makes this the next keystroke to read. */int rl_pending_input = 0;/* Pointer to a useful terminal name. */const char *rl_terminal_name = (const char *)NULL;/* Non-zero means to always use horizontal scrolling in line display. */int _rl_horizontal_scroll_mode = 0;/* Non-zero means to display an asterisk at the starts of history lines which have been modified. */int _rl_mark_modified_lines = 0; /* The style of `bell' notification preferred. This can be set to NO_BELL, AUDIBLE_BELL, or VISIBLE_BELL. */int _rl_bell_preference = AUDIBLE_BELL; /* String inserted into the line by rl_insert_comment (). */char *_rl_comment_begin;/* Keymap holding the function currently being executed. */Keymap rl_executing_keymap;/* Non-zero means to erase entire line, including prompt, on empty input lines. */int rl_erase_empty_line = 0;/* Non-zero means to read only this many characters rather than up to a character bound to accept-line. */int rl_num_chars_to_read;/* Line buffer and maintenence. */char *rl_line_buffer = (char *)NULL;int rl_line_buffer_len = 0;/* Forward declarations used by the display, termcap, and history code. *//* **************************************************************** *//* *//* `Forward' declarations *//* *//* **************************************************************** *//* Non-zero means do not parse any lines other than comments and parser directives. */unsigned char _rl_parsing_conditionalized_out = 0;/* Non-zero means to convert characters with the meta bit set to escape-prefixed characters so we can indirect through emacs_meta_keymap or vi_escape_keymap. */int _rl_convert_meta_chars_to_ascii = 1;/* Non-zero means to output characters with the meta bit set directly rather than as a meta-prefixed escape sequence. */int _rl_output_meta_chars = 0;/* **************************************************************** *//* *//* Top Level Functions *//* *//* **************************************************************** *//* Non-zero means treat 0200 bit in terminal input as Meta bit. */int _rl_meta_flag = 0; /* Forward declaration *//* Set up the prompt and expand it. Called from readline() and rl_callback_handler_install (). */intrl_set_prompt (prompt) const char *prompt;{ FREE (rl_prompt); rl_prompt = prompt ? savestring (prompt) : (char *)NULL; rl_visible_prompt_length = rl_expand_prompt (rl_prompt); return 0;} /* Read a line of input. Prompt with PROMPT. An empty PROMPT means none. A return value of NULL means that EOF was encountered. */char *readline (prompt) const char *prompt;{ char *value; /* If we are at EOF return a NULL string. */ if (rl_pending_input == EOF) { rl_clear_pending_input (); return ((char *)NULL); } rl_set_prompt (prompt); rl_initialize (); (*rl_prep_term_function) (_rl_meta_flag);#if defined (HANDLE_SIGNALS) rl_set_signals ();#endif value = readline_internal (); (*rl_deprep_term_function) ();#if defined (HANDLE_SIGNALS) rl_clear_signals ();#endif return (value);}#if defined (READLINE_CALLBACKS)# define STATIC_CALLBACK#else# define STATIC_CALLBACK static#endifSTATIC_CALLBACK voidreadline_internal_setup (){ char *nprompt; _rl_in_stream = rl_instream; _rl_out_stream = rl_outstream; if (rl_startup_hook) (*rl_startup_hook) (); /* If we're not echoing, we still want to at least print a prompt, because rl_redisplay will not do it for us. If the calling application has a custom redisplay function, though, let that function handle it. */ if (readline_echoing_p == 0 && rl_redisplay_function == rl_redisplay) { if (rl_prompt && rl_already_prompted == 0) { nprompt = _rl_strip_prompt (rl_prompt); fprintf (_rl_out_stream, "%s", nprompt); fflush (_rl_out_stream); free (nprompt); } } else { if (rl_prompt && rl_already_prompted) rl_on_new_line_with_prompt (); else rl_on_new_line (); (*rl_redisplay_function) (); }#if defined (VI_MODE) if (rl_editing_mode == vi_mode) rl_vi_insertion_mode (1, 'i');#endif /* VI_MODE */ if (rl_pre_input_hook) (*rl_pre_input_hook) ();}STATIC_CALLBACK char *readline_internal_teardown (eof) int eof;{ char *temp; HIST_ENTRY *entry; /* Restore the original of this history line, iff the line that we are editing was originally in the history, AND the line has changed. */ entry = current_history (); if (entry && rl_undo_list) { temp = savestring (the_line); rl_revert_line (1, 0); entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL); _rl_free_history_entry (entry); strcpy (the_line, temp); free (temp); } /* At any rate, it is highly likely that this line has an undo list. Get rid of it now. */ if (rl_undo_list) rl_free_undo_list (); /* Restore normal cursor, if available. */ _rl_set_insert_mode (RL_IM_INSERT, 0); return (eof ? (char *)NULL : savestring (the_line));}STATIC_CALLBACK int#if defined (READLINE_CALLBACKS)readline_internal_char ()#elsereadline_internal_charloop ()#endif{ static int lastc, eof_found; int c, code, lk; lastc = -1; eof_found = 0;#if !defined (READLINE_CALLBACKS) while (rl_done == 0) {#endif lk = _rl_last_command_was_kill; code = setjmp (readline_top_level); if (code) (*rl_redisplay_function) (); if (rl_pending_input == 0) { /* Then initialize the argument and number of keys read. */ _rl_init_argument (); rl_key_sequence_length = 0; } RL_SETSTATE(RL_STATE_READCMD); c = rl_read_key (); RL_UNSETSTATE(RL_STATE_READCMD); /* EOF typed to a non-blank line is a <NL>. */ if (c == EOF && rl_end) c = NEWLINE; /* The character _rl_eof_char typed to blank line, and not as the previous character is interpreted as EOF. */ if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end) {#if defined (READLINE_CALLBACKS) RL_SETSTATE(RL_STATE_DONE); return (rl_done = 1);#else eof_found = 1; break;#endif } lastc = c; _rl_dispatch ((unsigned char)c, _rl_keymap); /* If there was no change in _rl_last_command_was_kill, then no kill has taken place. Note that if input is pending we are reading a prefix command, so nothing has changed yet. */ if (rl_pending_input == 0 && lk == _rl_last_command_was_kill) _rl_last_command_was_kill = 0;#if defined (VI_MODE) /* In vi mode, when you exit insert mode, the cursor moves back over the previous character. We explicitly check for that here. */ if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) rl_vi_check ();#endif /* VI_MODE */ if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read) { (*rl_redisplay_function) (); rl_newline (1, '\n'); } if (rl_done == 0) (*rl_redisplay_function) (); /* If the application writer has told us to erase the entire line if the only character typed was something bound to rl_newline, do so. */ if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline && rl_point == 0 && rl_end == 0) _rl_erase_entire_line ();#if defined (READLINE_CALLBACKS) return 0;#else } return (eof_found);#endif}#if defined (READLINE_CALLBACKS)static intreadline_internal_charloop (){ int eof = 1; while (rl_done == 0) eof = readline_internal_char (); return (eof);}#endif /* READLINE_CALLBACKS *//* Read a line of input from the global rl_instream, doing output on the global rl_outstream. If rl_prompt is non-null, then that is our prompt. */static char *readline_internal (){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -