diff options
Diffstat (limited to 'readline/search.c')
-rw-r--r-- | readline/search.c | 146 |
1 files changed, 87 insertions, 59 deletions
diff --git a/readline/search.c b/readline/search.c index 45d95d2..c9c1f5d 100644 --- a/readline/search.c +++ b/readline/search.c @@ -1,6 +1,6 @@ /* search.c - code for non-incremental searching in emacs and vi modes. */ -/* Copyright (C) 1992-2015 Free Software Foundation, Inc. +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -73,8 +73,8 @@ static char *history_search_string; static int history_string_size; static void make_history_line_current PARAMS((HIST_ENTRY *)); -static int noninc_search_from_pos PARAMS((char *, int, int)); -static int noninc_dosearch PARAMS((char *, int)); +static int noninc_search_from_pos PARAMS((char *, int, int, int, int *)); +static int noninc_dosearch PARAMS((char *, int, int)); static int noninc_search PARAMS((int, int)); static int rl_history_search_internal PARAMS((int, int)); static void rl_history_search_reinit PARAMS((int)); @@ -87,8 +87,7 @@ static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int)); current line. This doesn't do anything with rl_point; the caller must set it. */ static void -make_history_line_current (entry) - HIST_ENTRY *entry; +make_history_line_current (HIST_ENTRY *entry) { _rl_replace_text (entry->line, 0, rl_end); _rl_fix_point (1); @@ -112,11 +111,10 @@ make_history_line_current (entry) for STRING. DIR < 0 means to search backwards through the history list, DIR >= 0 means to search forward. */ static int -noninc_search_from_pos (string, pos, dir) - char *string; - int pos, dir; +noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp) { - int ret, old; + int ret, old, sflags; + char *s; if (pos < 0) return -1; @@ -126,12 +124,28 @@ noninc_search_from_pos (string, pos, dir) return -1; RL_SETSTATE(RL_STATE_SEARCH); - if (*string == '^') + /* These functions return the match offset in the line; history_offset gives + the matching line in the history list */ + if (flags & SF_PATTERN) + { + s = string; + sflags = 0; /* Non-anchored search */ + if (*s == '^') + { + sflags |= ANCHORED_SEARCH; + s++; + } + ret = _hs_history_patsearch (s, dir, sflags); + } + else if (*string == '^') ret = history_search_prefix (string + 1, dir); else ret = history_search (string, dir); RL_UNSETSTATE(RL_STATE_SEARCH); + if (ncp) + *ncp = ret; /* caller will catch -1 to indicate no-op */ + if (ret != -1) ret = where_history (); @@ -143,9 +157,7 @@ noninc_search_from_pos (string, pos, dir) search is backwards through previous entries, else through subsequent entries. Returns 1 if the search was successful, 0 otherwise. */ static int -noninc_dosearch (string, dir) - char *string; - int dir; +noninc_dosearch (char *string, int dir, int flags) { int oldpos, pos; HIST_ENTRY *entry; @@ -156,7 +168,7 @@ noninc_dosearch (string, dir) return 0; } - pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); + pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0); if (pos == -1) { /* Search failed, current history position unchanged. */ @@ -188,8 +200,7 @@ noninc_dosearch (string, dir) } static _rl_search_cxt * -_rl_nsearch_init (dir, pchar) - int dir, pchar; +_rl_nsearch_init (int dir, int pchar) { _rl_search_cxt *cxt; char *p; @@ -197,6 +208,10 @@ _rl_nsearch_init (dir, pchar) cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0); if (dir < 0) cxt->sflags |= SF_REVERSE; /* not strictly needed */ +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/')) + cxt->sflags |= SF_PATTERN; +#endif cxt->direction = dir; cxt->history_pos = cxt->save_line; @@ -224,9 +239,7 @@ _rl_nsearch_init (dir, pchar) } int -_rl_nsearch_cleanup (cxt, r) - _rl_search_cxt *cxt; - int r; +_rl_nsearch_cleanup (_rl_search_cxt *cxt, int r) { _rl_scxt_dispose (cxt, 0); _rl_nscxt = 0; @@ -237,8 +250,7 @@ _rl_nsearch_cleanup (cxt, r) } static void -_rl_nsearch_abort (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_abort (_rl_search_cxt *cxt) { rl_maybe_unsave_line (); rl_clear_message (); @@ -253,10 +265,11 @@ _rl_nsearch_abort (cxt) if the caller should abort the search, 0 if we should break out of the loop, and 1 if we should continue to read characters. */ static int -_rl_nsearch_dispatch (cxt, c) - _rl_search_cxt *cxt; - int c; +_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c) { + if (c < 0) + c = CTRL ('C'); + switch (c) { case CTRL('W'): @@ -306,8 +319,7 @@ _rl_nsearch_dispatch (cxt, c) using _rl_nsearch_cleanup (). Returns 1 if the search was successful, 0 otherwise. */ static int -_rl_nsearch_dosearch (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_dosearch (_rl_search_cxt *cxt) { rl_mark = cxt->save_mark; @@ -340,7 +352,7 @@ _rl_nsearch_dosearch (cxt) } rl_restore_prompt (); - return (noninc_dosearch (noninc_search_string, cxt->direction)); + return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN)); } /* Search non-interactively through the history list. DIR < 0 means to @@ -349,9 +361,7 @@ _rl_nsearch_dosearch (cxt) history list. PCHAR is the character to use for prompting when reading the search string; if not specified (0), it defaults to `:'. */ static int -noninc_search (dir, pchar) - int dir; - int pchar; +noninc_search (int dir, int pchar) { _rl_search_cxt *cxt; int c, r; @@ -367,6 +377,12 @@ noninc_search (dir, pchar) { c = _rl_search_getchar (cxt); + if (c < 0) + { + _rl_nsearch_abort (cxt); + return 1; + } + if (c == 0) break; @@ -384,8 +400,7 @@ noninc_search (dir, pchar) /* Search forward through the history list for a string. If the vi-mode code calls this, KEY will be `?'. */ int -rl_noninc_forward_search (count, key) - int count, key; +rl_noninc_forward_search (int count, int key) { return noninc_search (1, (key == '?') ? '?' : 0); } @@ -393,17 +408,16 @@ rl_noninc_forward_search (count, key) /* Reverse search the history list for a string. If the vi-mode code calls this, KEY will be `/'. */ int -rl_noninc_reverse_search (count, key) - int count, key; +rl_noninc_reverse_search (int count, int key) { return noninc_search (-1, (key == '/') ? '/' : 0); } /* Search forward through the history list for the last string searched - for. If there is no saved search string, abort. */ + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `N'. */ int -rl_noninc_forward_search_again (count, key) - int count, key; +rl_noninc_forward_search_again (int count, int key) { int r; @@ -412,15 +426,20 @@ rl_noninc_forward_search_again (count, key) rl_ding (); return (1); } - r = noninc_dosearch (noninc_search_string, 1); +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'N') + r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, 1, 0); return (r != 1); } /* Reverse search in the history list for the last string searched - for. If there is no saved search string, abort. */ + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `n'. */ int -rl_noninc_reverse_search_again (count, key) - int count, key; +rl_noninc_reverse_search_again (int count, int key) { int r; @@ -429,18 +448,28 @@ rl_noninc_reverse_search_again (count, key) rl_ding (); return (1); } - r = noninc_dosearch (noninc_search_string, -1); +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'n') + r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, -1, 0); return (r != 1); } #if defined (READLINE_CALLBACKS) int -_rl_nsearch_callback (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_callback (_rl_search_cxt *cxt) { int c, r; c = _rl_search_getchar (cxt); + if (c <= 0) + { + if (c < 0) + _rl_nsearch_abort (cxt); + return 1; + } r = _rl_nsearch_dispatch (cxt, c); if (r != 0) return 1; @@ -451,11 +480,10 @@ _rl_nsearch_callback (cxt) #endif static int -rl_history_search_internal (count, dir) - int count, dir; +rl_history_search_internal (int count, int dir) { HIST_ENTRY *temp; - int ret, oldpos; + int ret, oldpos, newcol; char *t; rl_maybe_save_line (); @@ -469,7 +497,7 @@ rl_history_search_internal (count, dir) while (count) { RL_CHECK_SIGNALS (); - ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol); if (ret == -1) break; @@ -512,12 +540,17 @@ rl_history_search_internal (count, dir) /* Copy the line we found into the current line buffer. */ make_history_line_current (temp); + /* decide where to put rl_point -- need to change this for pattern search */ if (rl_history_search_flags & ANCHORED_SEARCH) rl_point = rl_history_search_len; /* easy case */ else { - t = strstr (rl_line_buffer, history_search_string); +#if 0 + t = strstr (rl_line_buffer, history_search_string); /* XXX */ rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end; +#else + rl_point = (newcol >= 0) ? newcol : rl_end; +#endif } rl_mark = rl_end; @@ -525,8 +558,7 @@ rl_history_search_internal (count, dir) } static void -rl_history_search_reinit (flags) - int flags; +rl_history_search_reinit (int flags) { int sind; @@ -556,8 +588,7 @@ rl_history_search_reinit (flags) from the start of the line to rl_point. This is a non-incremental search. The search is anchored to the beginning of the history line. */ int -rl_history_search_forward (count, ignore) - int count, ignore; +rl_history_search_forward (int count, int ignore) { if (count == 0) return (0); @@ -575,8 +606,7 @@ rl_history_search_forward (count, ignore) from the start of the line to rl_point. This is a non-incremental search. */ int -rl_history_search_backward (count, ignore) - int count, ignore; +rl_history_search_backward (int count, int ignore) { if (count == 0) return (0); @@ -595,8 +625,7 @@ rl_history_search_backward (count, ignore) search. The search succeeds if the search string is present anywhere in the history line. */ int -rl_history_substr_search_forward (count, ignore) - int count, ignore; +rl_history_substr_search_forward (int count, int ignore) { if (count == 0) return (0); @@ -614,8 +643,7 @@ rl_history_substr_search_forward (count, ignore) from the start of the line to rl_point. This is a non-incremental search. */ int -rl_history_substr_search_backward (count, ignore) - int count, ignore; +rl_history_substr_search_backward (int count, int ignore) { if (count == 0) return (0); |