aboutsummaryrefslogtreecommitdiff
path: root/readline/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'readline/search.c')
-rw-r--r--readline/search.c146
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);