📄 isearch.c
字号:
/* **************************************************************** *//* *//* I-Search and Searching *//* *//* **************************************************************** *//* Copyright (C) 1987-2002 Free Software Foundation, Inc. This file contains the Readline Library (the Library), a set of routines for providing Emacs style line input to programs that ask for it. The 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 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 <stdio.h>#if defined (HAVE_UNISTD_H)# include <unistd.h>#endif#if defined (HAVE_STDLIB_H)# include <stdlib.h>#else# include "ansi_stdlib.h"#endif#include "rldefs.h"#include "rlmbutil.h"#include "readline.h"#include "history.h"#include "rlprivate.h"#include "xmalloc.h"/* Variables exported to other files in the readline library. */char *_rl_isearch_terminators = (char *)NULL;/* Variables imported from other files in the readline library. */extern HIST_ENTRY *_rl_saved_line_for_history;/* Forward declarations */static int rl_search_history PARAMS((int, int));/* Last line found by the current incremental search, so we don't `find' identical lines many times in a row. */static char *prev_line_found;/* Last search string and its length. */static char *last_isearch_string;static int last_isearch_string_len;static char *default_isearch_terminators = "\033\012";/* Search backwards through the history looking for a string which is typed interactively. Start with the current line. */intrl_reverse_search_history (sign, key) int sign, key;{ return (rl_search_history (-sign, key));}/* Search forwards through the history looking for a string which is typed interactively. Start with the current line. */intrl_forward_search_history (sign, key) int sign, key;{ return (rl_search_history (sign, key));}/* Display the current state of the search in the echo-area. SEARCH_STRING contains the string that is being searched for, DIRECTION is zero for forward, or 1 for reverse, WHERE is the history list number of the current line. If it is -1, then this line is the starting one. */static voidrl_display_search (search_string, reverse_p, where) char *search_string; int reverse_p, where;{ char *message; int msglen, searchlen; searchlen = (search_string && *search_string) ? strlen (search_string) : 0; message = (char *)xmalloc (searchlen + 33); msglen = 0;#if defined (NOTDEF) if (where != -1) { sprintf (message, "[%d]", where + history_base); msglen = strlen (message); }#endif /* NOTDEF */ message[msglen++] = '('; if (reverse_p) { strcpy (message + msglen, "reverse-"); msglen += 8; } strcpy (message + msglen, "i-search)`"); msglen += 10; if (search_string) { strcpy (message + msglen, search_string); msglen += searchlen; } strcpy (message + msglen, "': "); rl_message ("%s", message); free (message); (*rl_redisplay_function) ();}/* Search through the history looking for an interactively typed string. This is analogous to i-search. We start the search in the current line. DIRECTION is which direction to search; >= 0 means forward, < 0 means backwards. */static intrl_search_history (direction, invoking_key) int direction, invoking_key;{ /* The string that the user types in to search for. */ char *search_string; /* The current length of SEARCH_STRING. */ int search_string_index; /* The amount of space that SEARCH_STRING has allocated to it. */ int search_string_size; /* The list of lines to search through. */ char **lines, *allocated_line; /* The length of LINES. */ int hlen; /* Where we get LINES from. */ HIST_ENTRY **hlist; register int i; int orig_point, orig_mark, orig_line, last_found_line; int c, found, failed, sline_len; int n, wstart, wlen;#if defined (HANDLE_MULTIBYTE) char mb[MB_LEN_MAX];#endif /* The line currently being searched. */ char *sline; /* Offset in that line. */ int line_index; /* Non-zero if we are doing a reverse search. */ int reverse; /* The list of characters which terminate the search, but are not subsequently executed. If the variable isearch-terminators has been set, we use that value, otherwise we use ESC and C-J. */ char *isearch_terminators; RL_SETSTATE(RL_STATE_ISEARCH); orig_point = rl_point; orig_mark = rl_mark; last_found_line = orig_line = where_history (); reverse = direction < 0; hlist = history_list (); allocated_line = (char *)NULL; isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators : default_isearch_terminators; /* Create an arrary of pointers to the lines that we want to search. */ rl_maybe_replace_line (); i = 0; if (hlist) for (i = 0; hlist[i]; i++); /* Allocate space for this many lines, +1 for the current input line, and remember those lines. */ lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *)); for (i = 0; i < hlen; i++) lines[i] = hlist[i]->line; if (_rl_saved_line_for_history) lines[i] = _rl_saved_line_for_history->line; else { /* Keep track of this so we can free it. */ allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer)); strcpy (allocated_line, &rl_line_buffer[0]); lines[i] = allocated_line; } hlen++; /* The line where we start the search. */ i = orig_line; rl_save_prompt (); /* Initialize search parameters. */ search_string = (char *)xmalloc (search_string_size = 128); *search_string = '\0'; search_string_index = 0; prev_line_found = (char *)0; /* XXX */ /* Normalize DIRECTION into 1 or -1. */ direction = (direction >= 0) ? 1 : -1; rl_display_search (search_string, reverse, -1); sline = rl_line_buffer; sline_len = strlen (sline); line_index = rl_point; found = failed = 0; for (;;) { rl_command_func_t *f = (rl_command_func_t *)NULL; /* Read a key and decide how to proceed. */ RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT);#if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) c = _rl_read_mbstring (c, mb, MB_LEN_MAX);#endif /* Translate the keys we do something with to opcodes. */ if (c >= 0 && _rl_keymap[c].type == ISFUNC) { f = _rl_keymap[c].function; if (f == rl_reverse_search_history) c = reverse ? -1 : -2; else if (f == rl_forward_search_history) c = !reverse ? -1 : -2; else if (f == rl_rubout) c = -3; else if (c == CTRL ('G')) c = -4; else if (c == CTRL ('W')) /* XXX */ c = -5; else if (c == CTRL ('Y')) /* XXX */ c = -6; } /* The characters in isearch_terminators (set from the user-settable variable isearch-terminators) are used to terminate the search but
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -