From 067b822d04a4f5d4fc0fbd19a5620721fd397df9 Mon Sep 17 00:00:00 2001 From: pgen Date: Sun, 19 Aug 2018 23:57:31 +0200 Subject: Change the behaviors of n,N and add s and S cmds n/N moves the cursor to the next/previous word, regardless of the match quality in fuzzy search mode. This is the old behaviour. s/S moves the cursor to the next/previous words whose matching part is a substring of them. When not possible, acts as n/N. --- smenu.1 | 57 +++++++++++++++++++----------- smenu.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 135 insertions(+), 45 deletions(-) diff --git a/smenu.1 b/smenu.1 index c584a75..26c0775 100644 --- a/smenu.1 +++ b/smenu.1 @@ -145,21 +145,26 @@ in a word must not necessarily be consecutive. The case is also ignored. +The cursor is placed, if possible, on the first matching word having the +minimum number of gaps between the first and last matching character, +see the difference between the actions of the \fBs\fP/\fBS\fP and +\fBn\fP/\fBN\fP keys below. + This method also tolerates intermediate symbols not appearing in the -words to be ignored. +words which will be ignored. If this is the case, the attributes of the approximatively matching -words are changed into error versions of them to warn the user to this -situation. +words are changed into an error versions of them to warn the user to +this situation. -The erroneous symbols will not be \fBput\fP in the search buffer. +The erroneous symbols will \fInot\fP be inserted in the search buffer. By example: if the word \fBabcdef\fP is present in the standard input, then entering \f(CBabxcdye\fP puts \fBabcdef\fP in the search buffer -and the word is added to the matching list and displayed with an error -attribute (in red by default). +and the word is added to the list of matching words and displayed with +an error attribute (in red by default). This special state will persist until all the symbols following the first -erroneous one are deleted (using backspace) or \fBESC\fP is pressed. +erroneous one are deleted (using backspace) or if \fBESC\fP is pressed. .PP During a search session, the cursor changes and each character entered is added in (or removed from) the search buffer. @@ -182,14 +187,26 @@ depending of the display attributes configured. .PP \fBESC\fP can be used anytime to abort the current search session. \fBENTER\fP and all cursor moves also terminate the search -session but do not clear the list of the matching words. +session but do not clear the list of the matchng words. .PP -The user can then use the \fBn\fP/\fBSPACE\fP keys (forward) and the -\fBN\fP key (backward) to navigate in the matching words list. +The user can then use the \fBn\fP/\fBs\fP/\fBSPACE\fP keys (forward) and +the \fBN\fP/\fBS\fP keys (backward) to navigate in the list of matching +words, + +In \fIfuzzy\fP search mode, the \fBs\fP/\fBS\fP keys attempt to move the +cursor to the next/previous word whose matching part forms a substring +of this word. +If no such matches exist, \fBs\fP/\fBS\fP and \fBn\fP/\fBN\fP do the +same things. +To move the cursor to the next/previous fuzzy match, use the +\fBn\fP/\fBN\fP/\fBSPACE\fP keys. +\fBs\fP means next \fPs\fPubstring match in this context while \fBn\fP +just means \fBn\fPext match. .PP If the user hits the \fBHome\fP or \fBEnd\fP key during a search session -then the matched word list is reduced to the words starting (respectively) -ending with the current search pattern and the window is refreshed. +then the list of matching words is reduced to the words starting +(respectively) ending with the current search pattern and the window +is refreshed. For those who consider \fBHome\fP and \fBEnd\fP as non-intuitive, the \fBCTRL-A\fP and \fBCtrl-Z\fP keys are also available in search mode as an alternative. @@ -205,7 +222,7 @@ Note that when a matching word is selected, its enhanced characters only show one of the multiple matching possibilities. When not in a search session \fBESC\fP can be also used to clear the -matched words list and to reset the search buffer. +list of matching words and to reset the search buffer. .PP In summary, here is the meaning of the special keys in search mode: .TS @@ -214,7 +231,7 @@ lb s s l l c ^ ^ l l lw(6c) c . -Keys which clear the matched words list. +Keys which clear the list of matching words. Key@Meaning@Closes @@the @@search @@ -228,7 +245,7 @@ lb s s l l l ^ ^ l l lw(6c) c . -Keys which keep or update the matched words list. +Keys which keep or update the list of matching words. Key@Meaning@Closes @@the @@search @@ -596,13 +613,13 @@ approximate search field with error. .IP \fIste\fP approximate search text with error. .IP \fImf\fP -matched words field. +matching words field. .IP \fImt\fP -matched words text. +matching words text. .IP \fImfe\fP -matched words field with error. +matching words field with error. .IP \fImte\fP -matched words text with error. +matching words text with error. .IP \fIda\fP direct access tag. .RE @@ -690,7 +707,7 @@ This sequence can be stopped if a \fBstop\fP flag is encountered. .RS \fBflags:\fP .IP * 2 -The optional trailing \fBg\fP (for \fIg\fPlobal) means that all matched +The optional trailing \fBg\fP (for \fIg\fPlobal) means that all matching occurrences shall be replaced and not only the first one. .IP * 2 The optional trailing \fBv\fP (for \fIv\fPisual) means that the altered diff --git a/smenu.c b/smenu.c index 4d6f3ba..da86669 100644 --- a/smenu.c +++ b/smenu.c @@ -838,7 +838,9 @@ ll_t * tst_search_list = NULL; long * matching_words_a; long matching_words_a_size; long matches_count; -long fuzzy_best_index; /* Index of the word with the smallest badness */ +long * best_matching_words_a; +long best_matching_words_a_size; +long best_matches_count; long * alt_matching_words_a = NULL; long alt_matches_count; @@ -2431,9 +2433,8 @@ update_bitmaps(search_mode_t mode, search_data_t * data, long last = data->mb_len - 1; long badness; - long best_badness = LONG_MAX; - fuzzy_best_index = matching_words_a[0]; + best_matches_count = 0; if (mode == FUZZY || mode == SUBSTRING) { @@ -2603,10 +2604,26 @@ update_bitmaps(search_mode_t mode, search_data_t * data, } free(str_orig); - if (badness < best_badness) + if (search_mode == FUZZY) { - best_badness = badness; - fuzzy_best_index = matching_words_a[i]; + /* When the badness is zero (best match), add the word position. */ + /* at the end of a special array which will be used to move the. */ + /* cursor among this category of words. */ + /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (badness == 0) + { + if (best_matches_count == best_matching_words_a_size) + { + best_matching_words_a = xrealloc(best_matching_words_a, + (best_matching_words_a_size + 16) + * sizeof(long)); + best_matching_words_a_size += 16; + } + + best_matching_words_a[best_matches_count] = n; + + best_matches_count++; + } } } if (mode == FUZZY) @@ -6443,9 +6460,6 @@ select_ending_matches(win_t * win, term_t * term, search_data_t * search_data, /* """"""""""""""""""""""""""""""""""""""" */ update_bitmaps(search_mode, search_data, END_AFFINITY); - if (search_mode == FUZZY) - current = fuzzy_best_index; - else current = matching_words_a[0]; if (current < win->start || current > win->end) @@ -6529,9 +6543,6 @@ select_starting_matches(win_t * win, term_t * term, search_data_t * search_data, /* """"""""""""""""""""""""""""""""""""""" */ update_bitmaps(search_mode, search_data, START_AFFINITY); - if (search_mode == FUZZY) - current = fuzzy_best_index; - else current = matching_words_a[0]; if (current < win->start || current > win->end) @@ -6957,6 +6968,10 @@ main(int argc, char * argv[]) matching_words_a = xmalloc(matching_words_a_size * sizeof(long)); matches_count = 0; + best_matching_words_a_size = 16; + best_matching_words_a = xmalloc(best_matching_words_a_size * sizeof(long)); + best_matches_count = 0; + /* Initialize the tag hit number which will permit to sort the */ /* pinned words when displayed. */ /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ @@ -10708,8 +10723,8 @@ main(int argc, char * argv[]) case 'n': case ' ': - /* n or has been pressed */ - /* """"""""""""""""""""""""""""""""" */ + /* n or the sspace bar has been pressed */ + /* """""""""""""""""""""""""""""""""""" */ if (search_mode != NONE) goto special_cmds_when_searching; @@ -10735,8 +10750,8 @@ main(int argc, char * argv[]) break; case 'N': - /* N or has been pressed */ - /* """"""""""""""""""""" */ + /* N has been pressed */ + /* """""""""""""""""" */ if (search_mode != NONE) goto special_cmds_when_searching; @@ -10760,6 +10775,73 @@ main(int argc, char * argv[]) &search_data, &term, last_line, tmp_word, &langinfo); break; + case 's': + /* s has been pressed */ + /* """""""""""""""""" */ + if (search_mode != NONE) + goto special_cmds_when_searching; + + if (matches_count > 0) + { + long pos; + + if (best_matches_count > 0) + pos = find_next_matching_word(best_matching_words_a, + best_matches_count, current, + &matching_word_cur_index); + else + pos = find_next_matching_word(matching_words_a, matches_count, + current, &matching_word_cur_index); + + if (pos >= 0) + current = pos; + + if (current < win.start || current > win.end) + last_line = build_metadata(&term, count, &win); + + /* Set new first column to display */ + /* """"""""""""""""""""""""""""""" */ + set_new_first_column(&win, &term); + + nl = disp_lines(&win, &toggle, current, count, search_mode, + &search_data, &term, last_line, tmp_word, + &langinfo); + } + break; + + case 'S': + /* S has been pressed */ + /* """""""""""""""""" */ + if (search_mode != NONE) + goto special_cmds_when_searching; + + if (matches_count > 0) + { + long pos; + + if (best_matches_count > 0) + pos = find_prev_matching_word(best_matching_words_a, + best_matches_count, current, + &matching_word_cur_index); + else + pos = find_prev_matching_word(matching_words_a, matches_count, + current, &matching_word_cur_index); + + if (pos >= 0) + current = pos; + } + + if (current < win.start || current > win.end) + last_line = build_metadata(&term, count, &win); + + /* Set new first column to display */ + /* """"""""""""""""""""""""""""""" */ + set_new_first_column(&win, &term); + + nl = disp_lines(&win, &toggle, current, count, search_mode, + &search_data, &term, last_line, tmp_word, &langinfo); + break; + enter: case 0x0d: /* CR */ { @@ -12077,9 +12159,6 @@ main(int argc, char * argv[]) /* """"""""""""""""""""""""""""""""""""""" */ update_bitmaps(search_mode, &search_data, NO_AFFINITY); - if (search_mode == FUZZY) - current = fuzzy_best_index; - else current = matching_words_a[0]; if (current < win.start || current > win.end) @@ -12248,9 +12327,6 @@ main(int argc, char * argv[]) /* """"""""""""""""""""""""""""""""""""""" */ update_bitmaps(search_mode, &search_data, NO_AFFINITY); - if (search_mode == FUZZY) - current = fuzzy_best_index; - else current = matching_words_a[0]; if (current < win.start || current > win.end) @@ -12330,9 +12406,6 @@ main(int argc, char * argv[]) else update_bitmaps(search_mode, &search_data, NO_AFFINITY); - if (search_mode == FUZZY) - current = fuzzy_best_index; - else current = matching_words_a[0]; if (current < win.start || current > win.end) -- cgit v1.2.3