mirror of
git://git.sv.gnu.org/nano.git
synced 2024-11-22 12:51:23 +03:00
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:
parent
656dd9c7eb
commit
1044d74fd3
85
ChangeLog
85
ChangeLog
@ -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.
|
||||
|
40
src/nano.c
40
src/nano.c
@ -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, ¤t_x_save, TRUE, &j);
|
||||
do_replace_loop(word, current_save, ¤t_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
|
||||
|
19
src/proto.h
19
src/proto.h
@ -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);
|
||||
|
795
src/search.c
795
src/search.c
File diff suppressed because it is too large
Load Diff
64
src/utils.c
64
src/utils.c
@ -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
|
||||
|
38
src/winio.c
38
src/winio.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user