version 1.1.1.1, 2014/07/30 08:16:45
|
version 1.1.1.2, 2021/03/17 01:01:01
|
Line 6
|
Line 6
|
/* */ |
/* */ |
/* **************************************************************** */ |
/* **************************************************************** */ |
|
|
/* Copyright (C) 1987-2012 Free Software Foundation, Inc. | /* Copyright (C) 1987-2020 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 66 static int rl_search_history PARAMS((int, int));
|
Line 66 static int rl_search_history PARAMS((int, int));
|
|
|
static _rl_search_cxt *_rl_isearch_init PARAMS((int)); |
static _rl_search_cxt *_rl_isearch_init PARAMS((int)); |
static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); |
static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); |
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); |
|
|
|
/* Last line found by the current incremental search, so we don't `find' |
/* Last line found by the current incremental search, so we don't `find' |
identical lines many times in a row. Now part of isearch context. */ |
identical lines many times in a row. Now part of isearch context. */ |
Line 79 static int last_isearch_string_len;
|
Line 78 static int last_isearch_string_len;
|
static char * const default_isearch_terminators = "\033\012"; |
static char * const default_isearch_terminators = "\033\012"; |
|
|
_rl_search_cxt * |
_rl_search_cxt * |
_rl_scxt_alloc (type, flags) | _rl_scxt_alloc (int type, int flags) |
int type, flags; | |
{ |
{ |
_rl_search_cxt *cxt; |
_rl_search_cxt *cxt; |
|
|
Line 121 _rl_scxt_alloc (type, flags)
|
Line 119 _rl_scxt_alloc (type, flags)
|
} |
} |
|
|
void |
void |
_rl_scxt_dispose (cxt, flags) | _rl_scxt_dispose (_rl_search_cxt *cxt, int flags) |
_rl_search_cxt *cxt; | |
int flags; | |
{ |
{ |
FREE (cxt->search_string); |
FREE (cxt->search_string); |
FREE (cxt->allocated_line); |
FREE (cxt->allocated_line); |
Line 135 _rl_scxt_dispose (cxt, flags)
|
Line 131 _rl_scxt_dispose (cxt, flags)
|
/* Search backwards through the history looking for a string which is typed |
/* Search backwards through the history looking for a string which is typed |
interactively. Start with the current line. */ |
interactively. Start with the current line. */ |
int |
int |
rl_reverse_search_history (sign, key) | rl_reverse_search_history (int sign, int key) |
int sign, key; | |
{ |
{ |
return (rl_search_history (-sign, key)); |
return (rl_search_history (-sign, key)); |
} |
} |
Line 144 rl_reverse_search_history (sign, key)
|
Line 139 rl_reverse_search_history (sign, key)
|
/* Search forwards through the history looking for a string which is typed |
/* Search forwards through the history looking for a string which is typed |
interactively. Start with the current line. */ |
interactively. Start with the current line. */ |
int |
int |
rl_forward_search_history (sign, key) | rl_forward_search_history (int sign, int key) |
int sign, key; | |
{ |
{ |
return (rl_search_history (sign, key)); |
return (rl_search_history (sign, key)); |
} |
} |
Line 156 rl_forward_search_history (sign, key)
|
Line 150 rl_forward_search_history (sign, key)
|
WHERE is the history list number of the current line. If it is |
WHERE is the history list number of the current line. If it is |
-1, then this line is the starting one. */ |
-1, then this line is the starting one. */ |
static void |
static void |
rl_display_search (search_string, flags, where) | rl_display_search (char *search_string, int flags, int where) |
char *search_string; | |
int flags, where; | |
{ |
{ |
char *message; |
char *message; |
int msglen, searchlen; |
int msglen, searchlen; |
Line 193 rl_display_search (search_string, flags, where)
|
Line 185 rl_display_search (search_string, flags, where)
|
strcpy (message + msglen, "i-search)`"); |
strcpy (message + msglen, "i-search)`"); |
msglen += 10; |
msglen += 10; |
|
|
if (search_string) | if (search_string && *search_string) |
{ |
{ |
strcpy (message + msglen, search_string); |
strcpy (message + msglen, search_string); |
msglen += searchlen; |
msglen += searchlen; |
} |
} |
|
else |
|
_rl_optimize_redisplay (); |
|
|
strcpy (message + msglen, "': "); |
strcpy (message + msglen, "': "); |
|
|
Line 207 rl_display_search (search_string, flags, where)
|
Line 201 rl_display_search (search_string, flags, where)
|
} |
} |
|
|
static _rl_search_cxt * |
static _rl_search_cxt * |
_rl_isearch_init (direction) | _rl_isearch_init (int direction) |
int direction; | |
{ |
{ |
_rl_search_cxt *cxt; |
_rl_search_cxt *cxt; |
register int i; |
register int i; |
Line 264 _rl_isearch_init (direction)
|
Line 257 _rl_isearch_init (direction)
|
|
|
_rl_iscxt = cxt; /* save globally */ |
_rl_iscxt = cxt; /* save globally */ |
|
|
|
/* experimental right now */ |
|
_rl_init_executing_keyseq (); |
|
|
return cxt; |
return cxt; |
} |
} |
|
|
static void |
static void |
_rl_isearch_fini (cxt) | _rl_isearch_fini (_rl_search_cxt *cxt) |
_rl_search_cxt *cxt; | |
{ |
{ |
/* First put back the original state. */ |
/* First put back the original state. */ |
strcpy (rl_line_buffer, cxt->lines[cxt->save_line]); | rl_replace_line (cxt->lines[cxt->save_line], 0); |
|
|
rl_restore_prompt (); |
rl_restore_prompt (); |
|
|
Line 297 _rl_isearch_fini (cxt)
|
Line 292 _rl_isearch_fini (cxt)
|
else |
else |
cxt->sline_index = strlen (rl_line_buffer); |
cxt->sline_index = strlen (rl_line_buffer); |
rl_mark = cxt->save_mark; |
rl_mark = cxt->save_mark; |
|
rl_deactivate_mark (); |
} |
} |
|
|
rl_point = cxt->sline_index; |
rl_point = cxt->sline_index; |
/* Don't worry about where to put the mark here; rl_get_previous_history |
/* Don't worry about where to put the mark here; rl_get_previous_history |
and rl_get_next_history take care of it. */ | and rl_get_next_history take care of it. |
| If we want to highlight the search string, this is where to set the |
| point and mark to do it. */ |
| _rl_fix_point (0); |
| rl_deactivate_mark (); |
|
|
|
/* _rl_optimize_redisplay (); */ |
rl_clear_message (); |
rl_clear_message (); |
} |
} |
|
|
|
/* XXX - we could use _rl_bracketed_read_mbstring () here. */ |
int |
int |
_rl_search_getchar (cxt) | _rl_search_getchar (_rl_search_cxt *cxt) |
_rl_search_cxt *cxt; | |
{ |
{ |
int c; |
int c; |
|
|
Line 335 _rl_search_getchar (cxt)
|
Line 336 _rl_search_getchar (cxt)
|
-1 if the caller should just free the context and return, 0 if we should |
-1 if the caller should just free the context and return, 0 if we should |
break out of the loop, and 1 if we should continue to read characters. */ |
break out of the loop, and 1 if we should continue to read characters. */ |
int |
int |
_rl_isearch_dispatch (cxt, c) | _rl_isearch_dispatch (_rl_search_cxt *cxt, int c) |
_rl_search_cxt *cxt; | |
int c; | |
{ |
{ |
int n, wstart, wlen, limit, cval; | int n, wstart, wlen, limit, cval, incr; |
| char *paste; |
| size_t pastelen; |
| int j; |
rl_command_func_t *f; |
rl_command_func_t *f; |
|
|
f = (rl_command_func_t *)NULL; |
f = (rl_command_func_t *)NULL; |
Line 351 _rl_isearch_dispatch (cxt, c)
|
Line 353 _rl_isearch_dispatch (cxt, c)
|
return -1; |
return -1; |
} |
} |
|
|
|
_rl_add_executing_keyseq (c); |
|
|
|
/* XXX - experimental code to allow users to bracketed-paste into the search |
|
string even when ESC is one of the isearch-terminators. Not perfect yet. */ |
|
if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (BRACK_PASTE_SLEN-1)) |
|
{ |
|
j = _rl_read_bracketed_paste_prefix (c); |
|
if (j == 1) |
|
{ |
|
cxt->lastc = -7; /* bracketed paste, see below */ |
|
goto opcode_dispatch; |
|
} |
|
else if (_rl_pushed_input_available ()) /* eat extra char we pushed back */ |
|
c = cxt->lastc = rl_read_key (); |
|
else |
|
c = cxt->lastc; /* last ditch */ |
|
} |
|
|
/* If we are moving into a new keymap, modify cxt->keymap and go on. |
/* If we are moving into a new keymap, modify cxt->keymap and go on. |
This can be a problem if c == ESC and we want to terminate the |
This can be a problem if c == ESC and we want to terminate the |
incremental search, so we check */ |
incremental search, so we check */ |
Line 396 add_character:
|
Line 416 add_character:
|
/* Translate the keys we do something with to opcodes. */ |
/* Translate the keys we do something with to opcodes. */ |
if (c >= 0 && cxt->keymap[c].type == ISFUNC) |
if (c >= 0 && cxt->keymap[c].type == ISFUNC) |
{ |
{ |
f = cxt->keymap[c].function; | /* If we have a multibyte character, see if it's bound to something that |
| affects the search. */ |
| #if defined (HANDLE_MULTIBYTE) |
| if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && cxt->mb[1]) |
| f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL); |
| else |
| #endif |
| { |
| f = cxt->keymap[c].function; |
| if (f == rl_do_lowercase_version) |
| f = cxt->keymap[_rl_to_lower (c)].function; |
| } |
|
|
if (f == rl_reverse_search_history) |
if (f == rl_reverse_search_history) |
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2; |
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2; |
Line 410 add_character:
|
Line 441 add_character:
|
cxt->lastc = -5; |
cxt->lastc = -5; |
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */ |
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */ |
cxt->lastc = -6; |
cxt->lastc = -6; |
|
else if (f == rl_bracketed_paste_begin) |
|
cxt->lastc = -7; |
} |
} |
|
|
/* If we changed the keymap earlier while translating a key sequence into |
/* If we changed the keymap earlier while translating a key sequence into |
Line 461 add_character:
|
Line 494 add_character:
|
} |
} |
else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert) |
else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert) |
{ |
{ |
rl_stuff_char (cxt->lastc); | _rl_term_executing_keyseq (); /* should this go in the caller? */ |
rl_execute_next (cxt->prevc); | |
/* XXX - do we insert everything in cxt->pmb? */ | _rl_pending_command.map = cxt->keymap; |
| _rl_pending_command.count = 1; /* XXX */ |
| _rl_pending_command.key = cxt->lastc; |
| _rl_pending_command.func = f; |
| _rl_command_to_execute = &_rl_pending_command; |
| |
return (0); |
return (0); |
} |
} |
} |
} |
Line 509 add_character:
|
Line 547 add_character:
|
return (0); |
return (0); |
} |
} |
|
|
|
_rl_init_executing_keyseq (); |
|
|
|
opcode_dispatch: |
/* Now dispatch on the character. `Opcodes' affect the search string or |
/* Now dispatch on the character. `Opcodes' affect the search string or |
state. Other characters are added to the string. */ |
state. Other characters are added to the string. */ |
switch (cxt->lastc) |
switch (cxt->lastc) |
Line 526 add_character:
|
Line 567 add_character:
|
rl_display_search (cxt->search_string, cxt->sflags, -1); |
rl_display_search (cxt->search_string, cxt->sflags, -1); |
break; |
break; |
} |
} |
|
/* XXX - restore keymap here? */ |
return (1); |
return (1); |
} |
} |
else if (cxt->sflags & SF_REVERSE) | else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0) |
cxt->sline_index--; |
cxt->sline_index--; |
else if (cxt->sline_index != cxt->sline_len) |
else if (cxt->sline_index != cxt->sline_len) |
cxt->sline_index++; |
cxt->sline_index++; |
Line 553 add_character:
|
Line 595 add_character:
|
do until we have a real isearch-undo. */ |
do until we have a real isearch-undo. */ |
if (cxt->search_string_index == 0) |
if (cxt->search_string_index == 0) |
rl_ding (); |
rl_ding (); |
else | else if (MB_CUR_MAX == 1 || rl_byte_oriented) |
cxt->search_string[--cxt->search_string_index] = '\0'; |
cxt->search_string[--cxt->search_string_index] = '\0'; |
|
else |
|
{ |
|
wstart = _rl_find_prev_mbchar (cxt->search_string, cxt->search_string_index, MB_FIND_NONZERO); |
|
if (wstart >= 0) |
|
cxt->search_string[cxt->search_string_index = wstart] = '\0'; |
|
else |
|
cxt->search_string[cxt->search_string_index = 0] = '\0'; |
|
} |
|
|
|
if (cxt->search_string_index == 0) |
|
rl_ding (); |
|
|
break; |
break; |
|
|
case -4: /* C-G, abort */ |
case -4: /* C-G, abort */ |
rl_replace_line (cxt->lines[cxt->save_line], 0); |
rl_replace_line (cxt->lines[cxt->save_line], 0); |
rl_point = cxt->save_point; |
rl_point = cxt->save_point; |
rl_mark = cxt->save_mark; |
rl_mark = cxt->save_mark; |
|
rl_deactivate_mark (); |
rl_restore_prompt(); |
rl_restore_prompt(); |
rl_clear_message (); |
rl_clear_message (); |
|
|
|
_rl_fix_point (1); /* in case save_line and save_point are out of sync */ |
return -1; |
return -1; |
|
|
case -5: /* C-W */ |
case -5: /* C-W */ |
Line 620 add_character:
|
Line 676 add_character:
|
cxt->search_string[cxt->search_string_index] = '\0'; |
cxt->search_string[cxt->search_string_index] = '\0'; |
break; |
break; |
|
|
|
case -7: /* bracketed paste */ |
|
paste = _rl_bracketed_text (&pastelen); |
|
if (paste == 0 || *paste == 0) |
|
{ |
|
free (paste); |
|
break; |
|
} |
|
if (_rl_enable_active_region) |
|
rl_activate_mark (); |
|
if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size) |
|
{ |
|
cxt->search_string_size += pastelen + 2; |
|
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); |
|
} |
|
strcpy (cxt->search_string + cxt->search_string_index, paste); |
|
cxt->search_string_index += pastelen; |
|
free (paste); |
|
break; |
|
|
/* Add character to search string and continue search. */ |
/* Add character to search string and continue search. */ |
default: |
default: |
if (cxt->search_string_index + 2 >= cxt->search_string_size) | #if defined (HANDLE_MULTIBYTE) |
| wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb); |
| #else |
| wlen = 1; |
| #endif |
| if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size) |
{ |
{ |
cxt->search_string_size += 128; | cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */ |
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); |
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); |
} |
} |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
{ |
{ |
int j, l; | int j; |
|
|
if (cxt->mb[0] == 0 || cxt->mb[1] == 0) |
if (cxt->mb[0] == 0 || cxt->mb[1] == 0) |
cxt->search_string[cxt->search_string_index++] = cxt->mb[0]; |
cxt->search_string[cxt->search_string_index++] = cxt->mb[0]; |
else |
else |
for (j = 0, l = RL_STRLEN (cxt->mb); j < l; ) | for (j = 0; j < wlen; ) |
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; |
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; |
} |
} |
else |
else |
Line 647 add_character:
|
Line 727 add_character:
|
|
|
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; ) |
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; ) |
{ |
{ |
|
if (cxt->search_string_index == 0) |
|
{ |
|
cxt->sflags |= SF_FAILED; |
|
break; |
|
} |
|
|
limit = cxt->sline_len - cxt->search_string_index + 1; |
limit = cxt->sline_len - cxt->search_string_index + 1; |
|
|
/* Search the current line. */ |
/* Search the current line. */ |
Line 659 add_character:
|
Line 745 add_character:
|
} |
} |
else |
else |
cxt->sline_index += cxt->direction; |
cxt->sline_index += cxt->direction; |
|
|
|
if (cxt->sline_index < 0) |
|
{ |
|
cxt->sline_index = 0; |
|
break; |
|
} |
} |
} |
if (cxt->sflags & SF_FOUND) |
if (cxt->sflags & SF_FOUND) |
break; |
break; |
Line 686 add_character:
|
Line 778 add_character:
|
(cxt->search_string_index > cxt->sline_len)); |
(cxt->search_string_index > cxt->sline_len)); |
|
|
if (cxt->sflags & SF_FAILED) |
if (cxt->sflags & SF_FAILED) |
break; | { |
| /* XXX - reset sline_index if < 0 */ |
| if (cxt->sline_index < 0) |
| cxt->sline_index = 0; |
| break; |
| } |
|
|
/* Now set up the line for searching... */ |
/* Now set up the line for searching... */ |
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0; |
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0; |
} |
} |
|
|
|
/* reset the keymaps for the next time through the loop */ |
|
cxt->keymap = cxt->okeymap = _rl_keymap; |
|
|
if (cxt->sflags & SF_FAILED) |
if (cxt->sflags & SF_FAILED) |
{ |
{ |
/* We cannot find the search string. Ding the bell. */ |
/* We cannot find the search string. Ding the bell. */ |
rl_ding (); |
rl_ding (); |
cxt->history_pos = cxt->last_found_line; |
cxt->history_pos = cxt->last_found_line; |
|
rl_deactivate_mark (); |
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); |
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); |
return 1; |
return 1; |
} |
} |
Line 708 add_character:
|
Line 809 add_character:
|
{ |
{ |
cxt->prev_line_found = cxt->lines[cxt->history_pos]; |
cxt->prev_line_found = cxt->lines[cxt->history_pos]; |
rl_replace_line (cxt->lines[cxt->history_pos], 0); |
rl_replace_line (cxt->lines[cxt->history_pos], 0); |
|
if (_rl_enable_active_region) |
|
rl_activate_mark (); |
rl_point = cxt->sline_index; |
rl_point = cxt->sline_index; |
|
if (rl_mark_active_p () && cxt->search_string_index > 0) |
|
rl_mark = rl_point + cxt->search_string_index; |
cxt->last_found_line = cxt->history_pos; |
cxt->last_found_line = cxt->history_pos; |
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); |
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); |
} |
} |
Line 716 add_character:
|
Line 821 add_character:
|
return 1; |
return 1; |
} |
} |
|
|
static int | int |
_rl_isearch_cleanup (cxt, r) | _rl_isearch_cleanup (_rl_search_cxt *cxt, int r) |
_rl_search_cxt *cxt; | |
int r; | |
{ |
{ |
if (r >= 0) |
if (r >= 0) |
_rl_isearch_fini (cxt); |
_rl_isearch_fini (cxt); |
Line 736 _rl_isearch_cleanup (cxt, r)
|
Line 839 _rl_isearch_cleanup (cxt, r)
|
DIRECTION is which direction to search; >= 0 means forward, < 0 means |
DIRECTION is which direction to search; >= 0 means forward, < 0 means |
backwards. */ |
backwards. */ |
static int |
static int |
rl_search_history (direction, invoking_key) | rl_search_history (int direction, int invoking_key) |
int direction, invoking_key; | |
{ |
{ |
_rl_search_cxt *cxt; /* local for now, but saved globally */ |
_rl_search_cxt *cxt; /* local for now, but saved globally */ |
int c, r; |
int c, r; |
Line 775 rl_search_history (direction, invoking_key)
|
Line 877 rl_search_history (direction, invoking_key)
|
If _rl_isearch_dispatch finishes searching, this function is responsible |
If _rl_isearch_dispatch finishes searching, this function is responsible |
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */ |
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */ |
int |
int |
_rl_isearch_callback (cxt) | _rl_isearch_callback (_rl_search_cxt *cxt) |
_rl_search_cxt *cxt; | |
{ |
{ |
int c, r; |
int c, r; |
|
|