📄 readline.c
字号:
int eof; readline_internal_setup (); eof = readline_internal_charloop (); return (readline_internal_teardown (eof));}void_rl_init_line_state (){ rl_point = rl_end = rl_mark = 0; the_line = rl_line_buffer; the_line[0] = 0;}void_rl_set_the_line (){ the_line = rl_line_buffer;}/* Do the command associated with KEY in MAP. If the associated command is really a keymap, then read another key, and dispatch into that map. */int_rl_dispatch (key, map) register int key; Keymap map;{ return _rl_dispatch_subseq (key, map, 0);}int_rl_dispatch_subseq (key, map, got_subseq) register int key; Keymap map; int got_subseq;{ int r, newkey; char *macro; rl_command_func_t *func; if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) { if (RL_ISSTATE (RL_STATE_MACRODEF)) _rl_add_macro_char (ESC); map = FUNCTION_TO_KEYMAP (map, ESC); key = UNMETA (key); rl_key_sequence_length += 2; return (_rl_dispatch (key, map)); } else rl_ding (); return 0; } if (RL_ISSTATE (RL_STATE_MACRODEF)) _rl_add_macro_char (key); r = 0; switch (map[key].type) { case ISFUNC: func = map[key].function; if (func) { /* Special case rl_do_lowercase_version (). */ if (func == rl_do_lowercase_version) return (_rl_dispatch (_rl_to_lower (key), map)); rl_executing_keymap = map;#if 0 _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();#endif rl_dispatching = 1; RL_SETSTATE(RL_STATE_DISPATCHING); r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); RL_UNSETSTATE(RL_STATE_DISPATCHING); rl_dispatching = 0; /* If we have input pending, then the last command was a prefix command. Don't change the state of rl_last_func. Otherwise, remember the last command executed in this variable. */ if (rl_pending_input == 0 && map[key].function != rl_digit_argument) rl_last_func = map[key].function; } else if (map[ANYOTHERKEY].function) { /* OK, there's no function bound in this map, but there is a shadow function that was overridden when the current keymap was created. Return -2 to note that. */ _rl_unget_char (key); return -2; } else if (got_subseq) { /* Return -1 to note that we're in a subsequence, but we don't have a matching key, nor was one overridden. This means we need to back up the recursion chain and find the last subsequence that is bound to a function. */ _rl_unget_char (key); return -1; } else { _rl_abort_internal (); return -1; } break; case ISKMAP: if (map[key].function != 0) {#if defined (VI_MODE) /* The only way this test will be true is if a subsequence has been bound starting with ESC, generally the arrow keys. What we do is check whether there's input in the queue, which there generally will be if an arrow key has been pressed, and, if there's not, just dispatch to (what we assume is) rl_vi_movement_mode right away. This is essentially an input test with a zero timeout. */ if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap && _rl_input_queued (0) == 0) return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));#endif rl_key_sequence_length++; if (key == ESC) RL_SETSTATE(RL_STATE_METANEXT); RL_SETSTATE(RL_STATE_MOREINPUT); newkey = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); if (key == ESC) RL_UNSETSTATE(RL_STATE_METANEXT); if (newkey < 0) { _rl_abort_internal (); return -1; } r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function); if (r == -2) /* We didn't match anything, and the keymap we're indexed into shadowed a function previously bound to that prefix. Call the function. The recursive call to _rl_dispatch_subseq has already taken care of pushing any necessary input back onto the input queue with _rl_unget_char. */ {#if 0 r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));#else /* XXX - experimental code -- might never be executed. Save for later. */ Keymap m = FUNCTION_TO_KEYMAP (map, key); int type = m[ANYOTHERKEY].type; func = m[ANYOTHERKEY].function; if (type == ISFUNC && func == rl_do_lowercase_version) r = _rl_dispatch (_rl_to_lower (key), map); else r = _rl_dispatch (ANYOTHERKEY, m);#endif } else if (r && map[ANYOTHERKEY].function) { /* We didn't match (r is probably -1), so return something to tell the caller that it should try ANYOTHERKEY for an overridden function. */ _rl_unget_char (key); return -2; } else if (r && got_subseq) { /* OK, back up the chain. */ _rl_unget_char (key); return -1; } } else { _rl_abort_internal (); return -1; } break; case ISMACR: if (map[key].function != 0) { macro = savestring ((char *)map[key].function); _rl_with_macro_input (macro); return 0; } break; }#if defined (VI_MODE) if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && key != ANYOTHERKEY && _rl_vi_textmod_command (key)) _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);#endif return (r);}/* **************************************************************** *//* *//* Initializations *//* *//* **************************************************************** *//* Initialize readline (and terminal if not already). */intrl_initialize (){ /* If we have never been called before, initialize the terminal and data structures. */ if (!rl_initialized) { RL_SETSTATE(RL_STATE_INITIALIZING); readline_initialize_everything (); RL_UNSETSTATE(RL_STATE_INITIALIZING); rl_initialized++; RL_SETSTATE(RL_STATE_INITIALIZED); } /* Initalize the current line information. */ _rl_init_line_state (); /* We aren't done yet. We haven't even gotten started yet! */ rl_done = 0; RL_UNSETSTATE(RL_STATE_DONE); /* Tell the history routines what is going on. */ _rl_start_using_history (); /* Make the display buffer match the state of the line. */ rl_reset_line_state (); /* No such function typed yet. */ rl_last_func = (rl_command_func_t *)NULL; /* Parsing of key-bindings begins in an enabled state. */ _rl_parsing_conditionalized_out = 0;#if defined (VI_MODE) if (rl_editing_mode == vi_mode) _rl_vi_initialize_line ();#endif /* Each line starts in insert mode (the default). */ _rl_set_insert_mode (RL_IM_DEFAULT, 1); return 0;}#if 0#if defined (__EMX__)static void_emx_build_environ (){ TIB *tibp; PIB *pibp; char *t, **tp; int c; DosGetInfoBlocks (&tibp, &pibp); t = pibp->pib_pchenv; for (c = 1; *t; c++) t += strlen (t) + 1; tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *)); t = pibp->pib_pchenv; while (*t) { *tp++ = t; t += strlen (t) + 1; } *tp = 0;}#endif /* __EMX__ */#endif/* Initialize the entire state of the world. */static voidreadline_initialize_everything (){#if 0#if defined (__EMX__) if (environ == 0) _emx_build_environ ();#endif#endif#if 0 /* Find out if we are running in Emacs -- UNUSED. */ running_in_emacs = sh_get_env_value ("EMACS") != (char *)0;#endif /* Set up input and output if they are not already set up. */ if (!rl_instream) rl_instream = stdin; if (!rl_outstream) rl_outstream = stdout; /* Bind _rl_in_stream and _rl_out_stream immediately. These values may change, but they may also be used before readline_internal () is called. */ _rl_in_stream = rl_instream; _rl_out_stream = rl_outstream; /* Allocate data structures. */ if (rl_line_buffer == 0) rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); /* Initialize the terminal interface. */ if (rl_terminal_name == 0) rl_terminal_name = sh_get_env_value ("TERM"); _rl_init_terminal_io (rl_terminal_name); /* Bind tty characters to readline functions. */ readline_default_bindings (); /* Initialize the function names. */ rl_initialize_funmap (); /* Decide whether we should automatically go into eight-bit mode. */ _rl_init_eightbit (); /* Read in the init file. */ rl_read_init_file ((char *)NULL); /* XXX */ if (_rl_horizontal_scroll_mode && _rl_term_autowrap) { _rl_screenwidth--; _rl_screenchars -= _rl_screenheight; } /* Override the effect of any `set keymap' assignments in the inputrc file. */ rl_set_keymap_from_edit_mode (); /* Try to bind a common arrow key prefix, if not already bound. */ bind_arrow_keys (); /* Enable the meta key, if this terminal has one. */ if (_rl_enable_meta) _rl_enable_meta_key (); /* If the completion parser's default word break characters haven't been set yet, then do so now. */ if (rl_completer_word_break_characters == (char *)NULL) rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;}/* If this system allows us to look at the values of the regular input editing characters, then bind them to their readline equivalents, iff the characters are not bound to keymaps. */static voidreadline_default_bindings (){ rl_tty_set_default_bindings (_rl_keymap);}/* Reset the default bindings for the terminal special characters we're interested in back to rl_insert and read the new ones. */static voidreset_default_bindings (){ rl_tty_unset_default_bindings (_rl_keymap); rl_tty_set_default_bindings (_rl_keymap);}/* Bind some common arrow key sequences in MAP. */static voidbind_arrow_keys_internal (map) Keymap map;{ Keymap xkeymap; xkeymap = _rl_keymap; _rl_keymap = map;#if defined (__MSDOS__) rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char); rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char); rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);#endif rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history); rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char); rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char); rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line); rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line); rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history); rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char); rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char); rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line); rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line); _rl_keymap = xkeymap;}/* Try and bind the common arrow key prefixes after giving termcap and the inputrc file a chance to bind them and create `real' keymaps for the arrow key prefix. */static voidbind_arrow_keys (){ bind_arrow_keys_internal (emacs_standard_keymap);#if defined (VI_MODE) bind_arrow_keys_internal (vi_movement_keymap); bind_arrow_keys_internal (vi_insertion_keymap);#endif}/* **************************************************************** *//* *//* Saving and Restoring Readline's state *//* *//* **************************************************************** */intrl_save_state (sp) struct readline_state *sp;{ if (sp == 0) return -1; sp->point = rl_point; sp->end = rl_end; sp->mark = rl_mark; sp->buffer = rl_line_buffer; sp->buflen = rl_line_buffer_len; sp->ul = rl_undo_list; sp->prompt = rl_prompt; sp->rlstate = rl_readline_state; sp->done = rl_done; sp->kmap = _rl_keymap; sp->lastfunc = rl_last_func; sp->insmode = rl_insert_mode; sp->edmode = rl_editing_mode; sp->kseqlen = rl_key_sequence_length; sp->inf = rl_instream; sp->outf = rl_outstream; sp->pendingin = rl_pending_input; sp->macro = rl_executing_macro; sp->catchsigs = rl_catch_signals; sp->catchsigwinch = rl_catch_sigwinch; return (0);}intrl_restore_state (sp) struct readline_state *sp;{ if (sp == 0) return -1; rl_point = sp->point; rl_end = sp->end; rl_mark = sp->mark; the_line = rl_line_buffer = sp->buffer; rl_line_buffer_len = sp->buflen; rl_undo_list = sp->ul; rl_prompt = sp->prompt; rl_readline_state = sp->rlstate; rl_done = sp->done; _rl_keymap = sp->kmap; rl_last_func = sp->lastfunc; rl_insert_mode = sp->insmode; rl_editing_mode = sp->edmode; rl_key_sequence_length = sp->kseqlen; rl_instream = sp->inf; rl_outstream = sp->outf; rl_pending_input = sp->pendingin; rl_executing_macro = sp->macro; rl_catch_signals = sp->catchsigs; rl_catch_sigwinch = sp->catchsigwinch; return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -