fix findnextstr() so wholewords works properly with regular expressions
and in conjunction with no_sameline, and add a few other minor cosmetic fixes git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2002 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
b802e70208
Коммит
53752e8f9a
13
ChangeLog
13
ChangeLog
@ -183,16 +183,19 @@ CVS code -
|
|||||||
edit_refresh() if the mark was originally on, and make
|
edit_refresh() if the mark was originally on, and make
|
||||||
length_change a ssize_t. (DLR)
|
length_change a ssize_t. (DLR)
|
||||||
- If the mark is on when we start, skip over all matches not
|
- If the mark is on when we start, skip over all matches not
|
||||||
found inside the marked text. This makes marked spell
|
found inside the marked text. This allows replacing
|
||||||
checking when using the internal spell checker work as
|
only marked text when the mark is on. (DLR, suggested by
|
||||||
expected (found by Rocco Corsi), and also allows replacing
|
Joseph Birthisel)
|
||||||
only marked text when the mark is on (suggested by Joseph
|
- Return ssize_t instead of int. (DLR)
|
||||||
Birthisel). (DLR)
|
|
||||||
findnextstr()
|
findnextstr()
|
||||||
- Take the no_sameline parameter after can_display_wrap and
|
- Take the no_sameline parameter after can_display_wrap and
|
||||||
wholewords, not after all other parameters. (DLR)
|
wholewords, not after all other parameters. (DLR)
|
||||||
- Maintain current_y's value when moving up or down lines so
|
- Maintain current_y's value when moving up or down lines so
|
||||||
that smooth scrolling works correctly. (DLR)
|
that smooth scrolling works correctly. (DLR)
|
||||||
|
- Fix handling of the wholewords flag so that it works with
|
||||||
|
regular expressions and in conjunction with the no_sameline
|
||||||
|
flag, and add a new parameter needle_len to return the length
|
||||||
|
of the match in. (DLR)
|
||||||
- utils.c:
|
- utils.c:
|
||||||
regexp_bol_or_eol()
|
regexp_bol_or_eol()
|
||||||
- Don't assume any longer that string will be found if
|
- Don't assume any longer that string will be found if
|
||||||
|
@ -1471,7 +1471,7 @@ bool do_int_spell_fix(const char *word)
|
|||||||
search_last_line = FALSE;
|
search_last_line = FALSE;
|
||||||
|
|
||||||
/* Find the first whole-word occurrence of word. */
|
/* Find the first whole-word occurrence of word. */
|
||||||
while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word))
|
while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word, NULL)) {
|
||||||
if (is_whole_word(current_x, current->data, word)) {
|
if (is_whole_word(current_x, current->data, word)) {
|
||||||
edit_refresh();
|
edit_refresh();
|
||||||
|
|
||||||
@ -1494,6 +1494,7 @@ bool do_int_spell_fix(const char *word)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Restore the search/replace strings. */
|
/* Restore the search/replace strings. */
|
||||||
free(last_search);
|
free(last_search);
|
||||||
|
@ -406,7 +406,7 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
|
|||||||
*searchword);
|
*searchword);
|
||||||
bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
||||||
no_sameline, const filestruct *begin, size_t beginx, const char
|
no_sameline, const filestruct *begin, size_t beginx, const char
|
||||||
*needle);
|
*needle, size_t *needle_len);
|
||||||
void do_search(void);
|
void do_search(void);
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
void do_research(void);
|
void do_research(void);
|
||||||
@ -416,8 +416,8 @@ void replace_abort(void);
|
|||||||
int replace_regexp(char *string, bool create_flag);
|
int replace_regexp(char *string, bool create_flag);
|
||||||
#endif
|
#endif
|
||||||
char *replace_line(const char *needle);
|
char *replace_line(const char *needle);
|
||||||
int do_replace_loop(const char *needle, filestruct *real_current, size_t
|
ssize_t do_replace_loop(const char *needle, filestruct *real_current,
|
||||||
*real_current_x, bool wholewords);
|
size_t *real_current_x, bool wholewords);
|
||||||
void do_replace(void);
|
void do_replace(void);
|
||||||
void do_gotoline(int line, bool save_pos);
|
void do_gotoline(int line, bool save_pos);
|
||||||
void do_gotoline_void(void);
|
void do_gotoline_void(void);
|
||||||
|
78
src/search.c
78
src/search.c
@ -267,15 +267,18 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
|
|||||||
* is the line where we first started searching, at column beginx. If
|
* is the line where we first started searching, at column beginx. If
|
||||||
* can_display_wrap is TRUE, we put messages on the statusbar, and wrap
|
* can_display_wrap is TRUE, we put messages on the statusbar, and wrap
|
||||||
* around the file boundaries. The return value specifies whether we
|
* around the file boundaries. The return value specifies whether we
|
||||||
* found anything. */
|
* found anything. If we did, and needle_len isn't NULL, set it to the
|
||||||
|
* length of the string we found. */
|
||||||
bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
||||||
no_sameline, const filestruct *begin, size_t beginx, const char
|
no_sameline, const filestruct *begin, size_t beginx, const char
|
||||||
*needle)
|
*needle, size_t *needle_len)
|
||||||
{
|
{
|
||||||
filestruct *fileptr = current;
|
filestruct *fileptr = current;
|
||||||
const char *rev_start = NULL, *found = NULL;
|
const char *rev_start = NULL, *found = NULL;
|
||||||
|
size_t found_len;
|
||||||
|
/* The length of the match we found. */
|
||||||
size_t current_x_find = 0;
|
size_t current_x_find = 0;
|
||||||
/* Where needle was found. */
|
/* The location of the match we found. */
|
||||||
int current_y_find = current_y;
|
int current_y_find = current_y;
|
||||||
|
|
||||||
/* rev_start might end up 1 character before the start or after the
|
/* rev_start might end up 1 character before the start or after the
|
||||||
@ -293,9 +296,37 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
|||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
found = strstrwrapper(fileptr->data, needle, rev_start);
|
found = strstrwrapper(fileptr->data, needle, rev_start);
|
||||||
|
|
||||||
if (found != NULL && (!wholeword || is_whole_word(found -
|
/* We've found a potential match. */
|
||||||
fileptr->data, fileptr->data, needle))) {
|
if (found != NULL) {
|
||||||
if (!no_sameline || fileptr != current)
|
bool found_whole = FALSE;
|
||||||
|
/* Is this potential match a whole word? */
|
||||||
|
|
||||||
|
/* Set found_len to the length of the potential match. */
|
||||||
|
found_len =
|
||||||
|
#ifdef HAVE_REGEX_H
|
||||||
|
ISSET(USE_REGEXP) ?
|
||||||
|
regmatches[0].rm_eo - regmatches[0].rm_so :
|
||||||
|
#endif
|
||||||
|
strlen(needle);
|
||||||
|
|
||||||
|
/* If we're searching for whole words, see if this potential
|
||||||
|
* match is a whole word. */
|
||||||
|
if (wholeword) {
|
||||||
|
char *word = charalloc(found_len + 1);
|
||||||
|
strncpy(word, found, found_len);
|
||||||
|
word[found_len] = '\0';
|
||||||
|
|
||||||
|
found_whole = is_whole_word(found - fileptr->data,
|
||||||
|
fileptr->data, word);
|
||||||
|
free(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're searching for whole words and this potential
|
||||||
|
* match isn't a whole word, or if we're not allowed to find
|
||||||
|
* a match on the same line we started on and this potential
|
||||||
|
* match is on that line, continue searching. */
|
||||||
|
if ((!wholeword || found_whole) && (!no_sameline ||
|
||||||
|
fileptr != current))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,6 +402,8 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
|
|||||||
current = fileptr;
|
current = fileptr;
|
||||||
current_x = current_x_find;
|
current_x = current_x_find;
|
||||||
current_y = current_y_find;
|
current_y = current_y_find;
|
||||||
|
if (needle_len != NULL)
|
||||||
|
*needle_len = found_len;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -416,7 +449,8 @@ void do_search(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
search_last_line = FALSE;
|
search_last_line = FALSE;
|
||||||
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x, answer);
|
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
|
||||||
|
answer, NULL);
|
||||||
|
|
||||||
/* Check to see if there's only one occurrence of the string and
|
/* Check to see if there's only one occurrence of the string and
|
||||||
* we're on it now. */
|
* we're on it now. */
|
||||||
@ -430,7 +464,7 @@ void do_search(void)
|
|||||||
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
|
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
|
||||||
last_search)) {
|
last_search)) {
|
||||||
didfind = findnextstr(TRUE, FALSE, TRUE, current, current_x,
|
didfind = findnextstr(TRUE, FALSE, TRUE, current, current_x,
|
||||||
answer);
|
answer, NULL);
|
||||||
if (fileptr == current && fileptr_x == current_x && !didfind)
|
if (fileptr == current && fileptr_x == current_x && !didfind)
|
||||||
statusbar(_("This is the only occurrence"));
|
statusbar(_("This is the only occurrence"));
|
||||||
} else {
|
} else {
|
||||||
@ -470,7 +504,7 @@ void do_research(void)
|
|||||||
|
|
||||||
search_last_line = FALSE;
|
search_last_line = FALSE;
|
||||||
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
|
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
|
||||||
last_search);
|
last_search, NULL);
|
||||||
|
|
||||||
/* Check to see if there's only one occurrence of the string and
|
/* Check to see if there's only one occurrence of the string and
|
||||||
* we're on it now. */
|
* we're on it now. */
|
||||||
@ -484,7 +518,7 @@ void do_research(void)
|
|||||||
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
|
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
|
||||||
last_search)) {
|
last_search)) {
|
||||||
didfind = findnextstr(TRUE, FALSE, TRUE, current,
|
didfind = findnextstr(TRUE, FALSE, TRUE, current,
|
||||||
current_x, answer);
|
current_x, answer, NULL);
|
||||||
if (fileptr == current && fileptr_x == current_x && !didfind)
|
if (fileptr == current && fileptr_x == current_x && !didfind)
|
||||||
statusbar(_("This is the only occurrence"));
|
statusbar(_("This is the only occurrence"));
|
||||||
} else {
|
} else {
|
||||||
@ -608,10 +642,11 @@ char *replace_line(const char *needle)
|
|||||||
*
|
*
|
||||||
* needle is the string to seek. We replace it with answer. Return -1
|
* needle is the string to seek. We replace it with answer. Return -1
|
||||||
* if needle isn't found, else the number of replacements performed. */
|
* if needle isn't found, else the number of replacements performed. */
|
||||||
int do_replace_loop(const char *needle, filestruct *real_current, size_t
|
ssize_t do_replace_loop(const char *needle, filestruct *real_current,
|
||||||
*real_current_x, bool wholewords)
|
size_t *real_current_x, bool wholewords)
|
||||||
{
|
{
|
||||||
int numreplaced = -1;
|
ssize_t numreplaced = -1;
|
||||||
|
size_t match_len;
|
||||||
size_t old_pww = placewewant, current_x_save = *real_current_x;
|
size_t old_pww = placewewant, current_x_save = *real_current_x;
|
||||||
const filestruct *current_save = real_current;
|
const filestruct *current_save = real_current;
|
||||||
bool replaceall = FALSE;
|
bool replaceall = FALSE;
|
||||||
@ -650,15 +685,9 @@ int do_replace_loop(const char *needle, filestruct *real_current, size_t
|
|||||||
#else
|
#else
|
||||||
FALSE
|
FALSE
|
||||||
#endif
|
#endif
|
||||||
, current_save, current_x_save, needle)) {
|
, current_save, current_x_save, needle, &match_len)) {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
size_t match_len =
|
|
||||||
#ifdef HAVE_REGEX_H
|
|
||||||
ISSET(USE_REGEXP) ?
|
|
||||||
regmatches[0].rm_eo - regmatches[0].rm_so :
|
|
||||||
#endif
|
|
||||||
strlen(needle);
|
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
/* If we've found a match outside the marked text, skip over it
|
/* If we've found a match outside the marked text, skip over it
|
||||||
@ -809,9 +838,10 @@ int do_replace_loop(const char *needle, filestruct *real_current, size_t
|
|||||||
/* Replace a string. */
|
/* Replace a string. */
|
||||||
void do_replace(void)
|
void do_replace(void)
|
||||||
{
|
{
|
||||||
int i, numreplaced;
|
int i;
|
||||||
filestruct *edittop_save, *begin;
|
filestruct *edittop_save, *begin;
|
||||||
size_t beginx;
|
size_t beginx;
|
||||||
|
ssize_t numreplaced;
|
||||||
|
|
||||||
if (ISSET(VIEW_MODE)) {
|
if (ISSET(VIEW_MODE)) {
|
||||||
print_view_warning();
|
print_view_warning();
|
||||||
@ -889,8 +919,8 @@ void do_replace(void)
|
|||||||
edit_refresh();
|
edit_refresh();
|
||||||
|
|
||||||
if (numreplaced >= 0)
|
if (numreplaced >= 0)
|
||||||
statusbar(P_("Replaced %d occurrence", "Replaced %d occurrences",
|
statusbar(P_("Replaced %ld occurrence", "Replaced %ld occurrences",
|
||||||
numreplaced), numreplaced);
|
(long)numreplaced), (long)numreplaced);
|
||||||
|
|
||||||
replace_abort();
|
replace_abort();
|
||||||
}
|
}
|
||||||
@ -1026,7 +1056,7 @@ void do_find_bracket(void)
|
|||||||
search_last_line = FALSE;
|
search_last_line = FALSE;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (findnextstr(FALSE, FALSE, FALSE, current, current_x,
|
if (findnextstr(FALSE, FALSE, FALSE, current, current_x,
|
||||||
regexp_pat)) {
|
regexp_pat, NULL)) {
|
||||||
/* Found identical bracket. */
|
/* Found identical bracket. */
|
||||||
if (current->data[current_x] == ch_under_cursor)
|
if (current->data[current_x] == ch_under_cursor)
|
||||||
count++;
|
count++;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user