add DB's refactored search code and a few of his minor display code

changes, plus a few minor search and display fixes of mine


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1660 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
David Lawrence Ramsey 2004-02-24 20:41:39 +00:00
parent 656dd9c7eb
commit 1044d74fd3
6 changed files with 538 additions and 503 deletions

View File

@ -36,10 +36,17 @@ CVS code -
- Remove the now-unneeded code to disable XON, XOFF, and
suspend, since we now go into raw mode in
get_verbatim_kbinput() and bypass them. (DLR)
do_spell(), do_int_speller(), do_alt_speller()
do_int_speller(), do_alt_speller(), do_spell()
- Modify to write only the current selection from a file to the
temporary file used for spell checking when the mark is on,
and add a few miscellaneous cosmetic cleanups. (DLR)
do_int_spell_fix()
- Store the value of current_x in a size_t instead of an int,
and add a few minor efficiency tweaks. (David Benbennick)
- Remove comment explaining why findnextstr() is called with
bracket_mode set to TRUE even though we aren't doing a bracket
search, since after the above efficiency tweaks, it's now more
accurately called can_display_wrap. (DLR)
signal_init()
- Trap SIGQUIT in addition to turning it off via termios in
main(). This is consistent with SIGINT, which we trap here
@ -59,10 +66,76 @@ CVS code -
curses setup routines, and turn the keypad on before setting
the input mode. (DLR)
- search.c:
regexp_cleanup()
- Only do anything if REGEXP_COMPILED is set. (David Benbennick)
search_abort()
- Only test if the mark is set when NANO_SMALL isn't defined.
(David Benbennick)
search_init()
- Add some more comments and comment tweaks, don't indicate that
the search has been canceled when we enter a blank string in
replace mode, only call regexp_init() when USE_REGEXP is set,
and return -1 instead of -3 since a canceled search and a
canceled replace should be mostly equivalent. (David
Benbennick) DLR: Tweak to use the old behavior if we try to
search for invalid regexes.
findnextstr()
- Refactor to use a loop invariant, and tweak for greater
efficiency and simplicity. Also modify so that all searches
start one character after (or before, if we're doing a
backwards search) the current one, as opposed to all searches
except for regex searches for "^" and the like, for
consistency with other searches. (David Benbennick)
do_search()
- Handle search_init()'s no longer returning -3 above. (David
Benbennick)
- Port the code from do_replace_loop() to skip the current line
if we're searching for a regex with "^" and/or "$" in it and
end up on the same line to this function. This fixes a
problem where doing a forward search for "^" on a file with
more than one line would erroneously stop at the magicline and
indicate that that was the only occurrence. (DLR)
do_research()
- Port David Benbennick's efficiency tweaks and the
aforementioned code ported from do_replace_loop() to this
function. (DLR)
replace_regexp()
- Completely refactor for increased efficiency. (David
Benbennick)
replace_line()
- Use a char* parameter for the replacement string instead of
last_search, and add minor efficiency tweaks. (David
Benbennick)
do_replace_loop()
- Fix segfault when doing a regex replace of a string that
matches inside a line (e.g. replace the "b" in "abc" with
anything). (David Benbennick)
- If the mark is on at the beginning of the functio, turn it off
and turn it back on just before returning. Also overhaul to
rely on the return value of findnextstr() instead of a loop
invariant, to not need to take an int* parameter, and store
the beginning x-coordinate in a size_t instead of an int.
(David Benbennick)
do_replace()
- Handle search_init()'s no longer returning -3 above, and add
efficiency tweaks. (David Benbennick) DLR: Tweak to follow
the old behavior of adding non-blank strings entered at the
"Replace: " prompt to the search history. (DLR)
do_bracket()
- Add efficiency tweaks. (David Benbennick) DLR: Remove
reliance on the hardcoded bracket string length; instead, only
require that the bracket string length be even.
- utils.c:
regexec_safe()
- Wrap in HAVE_REGEX_H #ifdefs. (DLR)
regexp_bol_or_eol()
- New function used to check if a regex contains "^" and/or "$",
assuming that the regex would be found if the REG_NOT(BOL|EOL)
flags aren't used in the regexec() call; it replaces the
direct regexec()s used before. (DLR)
strstrwrapper()
- Refactor for increased efficiency, and eliminate the need for
the line_pos parameter. (David Benbennick)
- winio.c:
get_verbatim_kbinput()
- Set keypad() to FALSE and switch to raw mode while reading
@ -96,6 +169,16 @@ CVS code -
(a) when we move onto the "$" at the end of the line on the
first page and (b) when we move onto the character just before
the "$" on subsequent pages. (DLR)
reset_cursor()
- Tweak for efficiency. (David Benbennick)
update_line()
- Move leaveok() calls here from edit_refresh(), since the
places where they were used in edit_refresh() mainly affected
the update_line()s. (DLR)
edit_refresh()
- Tweak for efficiency. (David Benbennick)
- Remove the aforementioned leaveok() calls from this function.
(DLR)
do_credits()
- Use nanosleep() instead of usleep(). The latter is only
standard under BSD, whereas the former is POSIX compliant.

View File

@ -1510,13 +1510,13 @@ int do_wrap(filestruct *inptr)
#ifndef DISABLE_SPELLER
/* A word is misspelled in the file. Let the user replace it. We
* return False if the user cancels. */
* return zero if the user cancels. */
int do_int_spell_fix(const char *word)
{
char *save_search;
char *save_replace;
filestruct *current_save = current;
int current_x_save = current_x;
size_t current_x_save = current_x;
filestruct *edittop_save = edittop;
/* Save where we are. */
int i = 0;
@ -1527,37 +1527,35 @@ int do_int_spell_fix(const char *word)
int mark_set = ISSET(MARK_ISSET);
SET(CASE_SENSITIVE);
/* Make sure the marking highlight is off during Spell Check */
/* Make sure the marking highlight is off during spell-check. */
UNSET(MARK_ISSET);
#endif
/* Make sure Spell Check goes forward only */
/* Make sure spell-check goes forward only. */
UNSET(REVERSE_SEARCH);
/* save the current search/replace strings */
/* Save the current search/replace strings. */
search_init_globals();
save_search = last_search;
save_replace = last_replace;
/* set search/replace strings to mis-spelt word */
/* Set search/replace strings to misspelled word. */
last_search = mallocstrcpy(NULL, word);
last_replace = mallocstrcpy(NULL, word);
/* start from the top of file */
/* Start from the top of the file. */
current = fileage;
current_x = -1;
search_last_line = FALSE;
/* We find the first whole-word occurrence of word. We call
findnextstr() with bracket_mode set to TRUE in order to disable
search wrapping. */
while (findnextstr(TRUE, TRUE, fileage, -1, word, 0))
/* Find the first whole-word occurrence of word. */
while (findnextstr(TRUE, TRUE, fileage, 0, word, FALSE) != 0)
if (is_whole_word(current_x, current->data, word)) {
edit_refresh();
do_replace_highlight(TRUE, word);
/* allow replace word to be corrected */
/* Allow the replace word to be corrected. */
i = statusq(0, spell_list, word,
#ifndef NANO_SMALL
NULL,
@ -1567,26 +1565,26 @@ int do_int_spell_fix(const char *word)
do_replace_highlight(FALSE, word);
if (i != -1 && strcmp(word, answer)) {
int j = 0;
search_last_line = FALSE;
current_x--;
do_replace_loop(word, current_save, &current_x_save, TRUE, &j);
do_replace_loop(word, current_save, &current_x_save, TRUE);
}
break;
}
/* restore the search/replace strings */
free(last_search); last_search=save_search;
free(last_replace); last_replace=save_replace;
/* Restore the search/replace strings. */
free(last_search);
last_search = save_search;
free(last_replace);
last_replace = save_replace;
/* restore where we were */
/* Restore where we were. */
current = current_save;
current_x = current_x_save;
edittop = edittop_save;
/* restore Search/Replace direction */
/* Restore search/replace direction. */
if (reverse_search_set)
SET(REVERSE_SEARCH);
@ -1594,7 +1592,7 @@ int do_int_spell_fix(const char *word)
if (!case_sens_set)
UNSET(CASE_SENSITIVE);
/* restore marking highlight */
/* Restore marking highlight. */
if (mark_set)
SET(MARK_ISSET);
#endif

View File

@ -364,19 +364,19 @@ void not_found_msg(const char *str);
void search_abort(void);
void search_init_globals(void);
int search_init(int replacing);
int is_whole_word(int curr_pos, const char *datastr, const char *searchword);
filestruct *findnextstr(int quiet, int bracket_mode,
const filestruct *begin, int beginx,
const char *needle, int no_sameline);
int is_whole_word(int curr_pos, const char *datastr, const char
*searchword);
int findnextstr(int can_display_wrap, int wholeword, const filestruct
*begin, size_t beginx, const char *needle, int no_sameline);
int do_search(void);
int do_research(void);
void replace_abort(void);
#ifdef HAVE_REGEX_H
int replace_regexp(char *string, int create_flag);
#endif
char *replace_line(void);
int do_replace_loop(const char *prevanswer, const filestruct *begin,
int *beginx, int wholewords, int *i);
char *replace_line(const char *needle);
int do_replace_loop(const char *needle, const filestruct *real_current,
size_t *real_current_x, int wholewords);
int do_replace(void);
int do_gotoline(int line, int save_pos);
int do_gotoline_void(void);
@ -401,10 +401,13 @@ void save_history(void);
#endif
/* Public functions in utils.c */
#ifdef HAVE_REGEX_H
#ifdef BROKEN_REGEXEC
int regexec_safe(const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
#endif
int regexp_bol_or_eol(const regex_t *preg, const char *string);
#endif
int is_cntrl_char(int c);
int num_of_digits(int n);
void align(char **strp);
@ -425,7 +428,7 @@ const char *revstristr(const char *haystack, const char *needle,
#endif
const char *stristr(const char *haystack, const char *needle);
const char *strstrwrapper(const char *haystack, const char *needle,
const char *rev_start, int line_pos);
const char *start);
void nperror(const char *s);
void *nmalloc(size_t howmuch);
void *nrealloc(void *ptr, size_t howmuch);

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@
#include "proto.h"
#include "nano.h"
#ifdef HAVE_REGEX_H
#ifdef BROKEN_REGEXEC
#undef regexec
int regexec_safe(const regex_t *preg, const char *string, size_t nmatch,
@ -40,7 +41,16 @@ int regexec_safe(const regex_t *preg, const char *string, size_t nmatch,
return REG_NOMATCH;
}
#define regexec(preg, string, nmatch, pmatch, eflags) regexec_safe(preg, string, nmatch, pmatch, eflags)
#endif
#endif /* BROKEN_REGEXEC */
/* Assume that string will be found by regexec() if the REG_NOTBOL and
* REG_NOTEOL glags are not set. */
int regexp_bol_or_eol(const regex_t *preg, const char *string)
{
return (regexec(preg, string, 0, NULL, REG_NOTBOL | REG_NOTEOL) ==
REG_NOMATCH);
}
#endif /* HAVE_REGEX_H */
int is_cntrl_char(int c)
{
@ -182,29 +192,32 @@ const char *stristr(const char *haystack, const char *needle)
return NULL;
}
/* If we are searching backwards, we will find the last match
* that starts no later than rev_start. If we are doing a regexp search,
* then line_pos should be 0 if haystack starts at the beginning of a
* line, and positive otherwise. In the regexp case, we fill in the
* global variable regmatches with at most 9 subexpression matches. Also,
* all .rm_so elements are relative to the start of the whole match, so
* regmatches[0].rm_so == 0. */
/* If we are searching backwards, we will find the last match that
* starts no later than start. Otherwise we find the first match
* starting no earlier than start. If we are doing a regexp search, we
* fill in the global variable regmatches with at most 9 subexpression
* matches. Also, all .rm_so elements are relative to the start of the
* whole match, so regmatches[0].rm_so == 0. */
const char *strstrwrapper(const char *haystack, const char *needle,
const char *rev_start, int line_pos)
const char *start)
{
/* start can be 1 character before the start or after the end of the
* line. In either case, we just say there is no match found. */
if ((start > haystack && *(start - 1) == '\0') || start < haystack)
return NULL;
assert(haystack != NULL && needle != NULL && start != NULL);
#ifdef HAVE_REGEX_H
if (ISSET(USE_REGEXP)) {
#ifndef NANO_SMALL
if (ISSET(REVERSE_SEARCH)) {
/* When doing a backwards search, haystack is a whole line. */
if (regexec(&search_regexp, haystack, 1, regmatches, 0) == 0 &&
haystack + regmatches[0].rm_so <= rev_start) {
if (regexec(&search_regexp, haystack, 1, regmatches, 0) == 0
&& haystack + regmatches[0].rm_so <= start) {
const char *retval = haystack + regmatches[0].rm_so;
/* Search forward until there is no more match. */
while (regexec(&search_regexp, retval + 1, 1, regmatches,
REG_NOTBOL) == 0 &&
retval + 1 + regmatches[0].rm_so <= rev_start)
REG_NOTBOL) == 0 && retval + 1 +
regmatches[0].rm_so <= start)
retval += 1 + regmatches[0].rm_so;
/* Finally, put the subexpression matches in global
* variable regmatches. The REG_NOTBOL flag doesn't
@ -214,9 +227,9 @@ const char *strstrwrapper(const char *haystack, const char *needle,
}
} else
#endif /* !NANO_SMALL */
if (regexec(&search_regexp, haystack, 10, regmatches,
line_pos > 0 ? REG_NOTBOL : 0) == 0) {
const char *retval = haystack + regmatches[0].rm_so;
if (regexec(&search_regexp, start, 10, regmatches,
start > haystack ? REG_NOTBOL : 0) == 0) {
const char *retval = start + regmatches[0].rm_so;
regexec(&search_regexp, retval, 10, regmatches, 0);
return retval;
@ -224,16 +237,21 @@ const char *strstrwrapper(const char *haystack, const char *needle,
return NULL;
}
#endif /* HAVE_REGEX_H */
#ifndef NANO_SMALL
#if !defined(DISABLE_SPELLER) || !defined(NANO_SMALL)
if (ISSET(CASE_SENSITIVE)) {
#ifndef NANO_SMALL
if (ISSET(REVERSE_SEARCH))
return revstrstr(haystack, needle, rev_start);
return revstrstr(haystack, needle, start);
else
return strstr(haystack, needle);
} else if (ISSET(REVERSE_SEARCH))
return revstristr(haystack, needle, rev_start);
#endif
return stristr(haystack, needle);
return strstr(haystack, needle);
}
#endif /* !DISABLE_SPELLER || !NANO_SMALL */
#ifndef NANO_SMALL
else if (ISSET(REVERSE_SEARCH))
return revstristr(haystack, needle, start);
#endif
return stristr(start, needle);
}
/* This is a wrapper for the perror function. The wrapper takes care of

View File

@ -1523,23 +1523,17 @@ size_t get_page_start(size_t column)
* cursor at (current_y, current_x). */
void reset_cursor(void)
{
const filestruct *ptr = edittop;
size_t x;
/* Yuck. This condition can be true after open_file() when opening
* the first file. */
if (edittop == NULL)
return;
current_y = 0;
current_y = current->lineno - edittop->lineno;
if (current_y < editwinrows) {
size_t x = xplustabs();
while (ptr != current && ptr != editbot && ptr->next != NULL) {
ptr = ptr->next;
current_y++;
}
x = xplustabs();
wmove(edit, current_y, x - get_page_start(x));
wmove(edit, current_y, x - get_page_start(x));
}
}
/* edit_add() takes care of the job of actually painting a line into the
@ -1878,6 +1872,9 @@ void update_line(const filestruct *fileptr, size_t index)
if (line < 0 || line >= editwinrows)
return;
/* Don't make the cursor jump around the screen while updating. */
leaveok(edit, TRUE);
/* First, blank out the line (at a minimum) */
mvwaddstr(edit, line, 0, hblank);
@ -1898,6 +1895,9 @@ void update_line(const filestruct *fileptr, size_t index)
mvwaddch(edit, line, 0, '$');
if (strlenpt(fileptr->data) > page_start + COLS)
mvwaddch(edit, line, COLS - 1, '$');
/* Let the cursor jump around the screen again. */
leaveok(edit, FALSE);
}
/* This function updates current, based on where current_y is;
@ -1948,27 +1948,27 @@ void edit_refresh(void)
edit_update(current, CENTER);
else {
int nlines = 0;
const filestruct *foo = edittop;
/* Don't make the cursor jump around the screen whilst
* updating. */
leaveok(edit, TRUE);
#ifdef DEBUG
fprintf(stderr, "edit_refresh(): edittop->lineno = %ld\n", edittop->lineno);
#endif
editbot = edittop;
while (nlines < editwinrows) {
update_line(editbot, current_x);
update_line(foo, current_x);
nlines++;
if (editbot->next == NULL)
if (foo->next == NULL)
break;
editbot = editbot->next;
foo = foo->next;
}
while (nlines < editwinrows) {
mvwaddstr(edit, nlines, 0, hblank);
nlines++;
}
reset_cursor();
/* What the hell are we expecting to update the screen if this
* isn't here? Luck? */
wrefresh(edit);
leaveok(edit, FALSE);
}
}