diff options
author | pgen <p.gen.progs@gmail.com> | 2018-07-23 00:52:35 +0200 |
---|---|---|
committer | pgen <p.gen.progs@gmail.com> | 2018-07-23 00:52:35 +0200 |
commit | df78ba74b015feff3a45ebd3a6152c546ad7769e (patch) | |
tree | 83ca29ed73de4f011a738373fb450f1d58073aaf | |
parent | 509559334df9c418024f2a05719b310cbfe99c65 (diff) |
Fix a logic bug using End/Home while searching
Make sure to pre-select all matching word even if the enhanced characters
in the word does not reflect this matching possibility.
Improve the manual to detail this point.
-rw-r--r-- | smenu.1 | 18 | ||||
-rw-r--r-- | smenu.c | 299 |
2 files changed, 201 insertions, 116 deletions
@@ -189,14 +189,24 @@ The user can then use the \fBn\fP/\fBSPACE\fP keys (forward) and the .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 curent search pattern and the window is actialized. +ending with the current search pattern and the window is refreshed. -by example, if the search pattern is \f(CBsh\fP and the user hits +By example, if the search pattern is \f(CBsh\fP and the user hits \fBEnd\fP, then only the words \fIending\fP with \f(CBsh\fP will be added in the searched word list and enhanced. -When not in a search session \fBESC\fP can be used to clear this list -and reset the search buffer. +Note that all the words matching the pattern will be selected, the +enhanced characters in the selected word only show one of the multiple +possible matches. + +By example, the ending pattern \f(CBab\fP will add the word \f(CBcabcb\fP +in the matching list when fuzzy searching, while the word \f(CBabcab\fP +will also be considered when substring searching even if only the first +\f(CBab\fP is enhanced because of the second (non enhanced) \f(CBab\fP +ending the word. + +When not in a search session \fBESC\fP can be also used to clear this +list and reset the search buffer. .PP In summary, here is the meaning of the special keys in search mode: .TS @@ -6205,6 +6205,190 @@ set_new_first_column(win_t * win, term_t * term) } } +/* =================================================== */ +/* Resting the matches to word ending with the pattern */ +/* =================================================== */ +void +select_ending_matches(win_t * win, term_t * term, search_data_t * search_data, + long * last_line) +{ + long i; + long j = 0; + long index; + long nb; + long * tmp; + char * ptr; + char * last_mb; + int mb_len; + + /* Creation of an alternate array which will */ + /* contain only the candidate having potentially */ + /* an ending pattern, if this array become non */ + /* empty then it will replace the original array. */ + /* """""""""""""""""""""""""""""""""""""""""""""" */ + alt_matching_words_a = xrealloc(alt_matching_words_a, + matches_count * (sizeof(long))); + + for (i = 0; i < matches_count; i++) + { + index = matching_words_a[i]; + + /* count the trailing blanks non counted in the bitmap */ + /* """"""""""""""""""""""""""""""""""""""""""""""""""" */ + ptr = word_a[index].str + strlen(word_a[index].str); + + nb = 0; + while ((ptr = mb_prev(word_a[index].str, ptr)) != NULL && isblank(*ptr)) + nb++; + + /* Check the bit corresponding to the last non blank glyph */ + /* If set we add the index to an alternate array, if not we */ + /* clear the bitmap of the corresponding word */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (BIT_ISSET(word_a[index].bitmap, + word_a[index].mb - nb - 1 - daccess.flength - 1)) + alt_matching_words_a[j++] = index; + else + { + /* Look if the end of the word potentially contain an */ + /* ending pattern. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""" */ + if (search_mode == FUZZY) + { + mb_len = mblen(ptr, 4); + last_mb = search_data->buf + search_data->len - mb_len; + + /* in fuzzy search mode we only look the last glyph */ + /* """""""""""""""""""""""""""""""""""""""""""""""" */ + if (memcmp(ptr, last_mb, mb_len) == 0) + alt_matching_words_a[j++] = index; + else + memset(word_a[index].bitmap, '\0', + (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT + 1); + } + else + { + /* in not fuzzy search mode use all the pattern */ + /* """""""""""""""""""""""""""""""""""""""""""" */ + for (nb = 0; nb < search_data->mb_len - 1; nb++) + ptr = mb_prev(word_a[index].str, ptr); + if (memcmp(ptr, search_data->buf, search_data->len) == 0) + alt_matching_words_a[j++] = index; + else + memset(word_a[index].bitmap, '\0', + (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT + 1); + } + } + } + + if (j > 0) + { + /* We have some candidates */ + /* swap the normal and alt array */ + /* """"""""""""""""""""""""""""" */ + matches_count = j; + matching_words_a_size = j; + + tmp = matching_words_a; + matching_words_a = alt_matching_words_a; + alt_matching_words_a = tmp; + + current = matching_words_a[0]; + + 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); + } + else + /* we restore the old bitmaps in this case */ + /* """"""""""""""""""""""""""""""""""""""" */ + update_bitmaps(search_mode, search_data); +} + +/* ===================================================== */ +/* Resting the matches to word starting with the pattern */ +/* ===================================================== */ +void +select_starting_mathes(win_t * win, term_t * term, search_data_t * search_data, + long * last_line) +{ + if (matches_count > 0) + { + long i; + long j = 0; + long index; + long * tmp; + long pos; + char * first_mb; + int mb_len; + + alt_matching_words_a = xrealloc(alt_matching_words_a, + matches_count * (sizeof(long))); + + first_mb = xmalloc(5); + + for (i = 0; i < matches_count; i++) + { + index = matching_words_a[i]; + if (BIT_ISSET(word_a[index].bitmap, 0)) + alt_matching_words_a[j++] = index; + else + { + if (search_mode == FUZZY) + { + first_mb = mb_strprefix(first_mb, word_a[index].str, 1, &pos); + mb_len = pos; + + /* in fuzzy search mode we only look the first glyph */ + /* """"""""""""""""""""""""""""""""""""""""""""""""" */ + if (memcmp(search_data->buf, first_mb, mb_len) == 0) + alt_matching_words_a[j++] = index; + else + memset(word_a[index].bitmap, '\0', + (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT + 1); + } + else + { + /* in not fuzzy search mode use all the pattern */ + /* """""""""""""""""""""""""""""""""""""""""""" */ + if (memcmp(search_data->buf, word_a[index].str, search_data->len) + == 0) + alt_matching_words_a[j++] = index; + else + memset(word_a[index].bitmap, '\0', + (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT + 1); + } + } + } + + free(first_mb); + + if (j > 0) + { + matches_count = j; + matching_words_a_size = j; + + tmp = matching_words_a; + matching_words_a = alt_matching_words_a; + alt_matching_words_a = tmp; + + current = matching_words_a[0]; + + 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); + } + else + update_bitmaps(search_mode, search_data); + } +} + /* ================ */ /* Main entry point */ /* ================ */ @@ -10020,52 +10204,7 @@ main(int argc, char * argv[]) /* HOME key has been pressed */ /* """"""""""""""""""""""""" */ if (search_mode != NONE) - { - if (matches_count > 0) - { - long i; - long j = 0; - long index; - long * tmp; - - alt_matching_words_a = xrealloc(alt_matching_words_a, - matches_count * (sizeof(long))); - - for (i = 0; i < matches_count; i++) - { - index = matching_words_a[i]; - if (BIT_ISSET(word_a[index].bitmap, 0)) - alt_matching_words_a[j++] = index; - else - { - memset(word_a[index].bitmap, '\0', - (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT - + 1); - } - } - - if (j > 0) - { - matches_count = j; - matching_words_a_size = j; - - tmp = matching_words_a; - matching_words_a = alt_matching_words_a; - alt_matching_words_a = tmp; - - current = matching_words_a[0]; - - 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); - } - else - update_bitmaps(search_mode, &search_data); - } - } + select_starting_mathes(&win, &term, &search_data, &last_line); else { /* Find the first selectable word */ @@ -10106,72 +10245,8 @@ main(int argc, char * argv[]) /* """""""""""""""""""""""" */ if (search_mode != NONE) { - if (matches_count > 0) - { - long i; - long j = 0; - long index; - long nb; - long * tmp; - char * ptr; - - alt_matching_words_a = xrealloc(alt_matching_words_a, - matches_count * (sizeof(long))); - - for (i = 0; i < matches_count; i++) - { - index = matching_words_a[i]; - - /* count the trailing blanks non counted in the bitmap */ - /* """"""""""""""""""""""""""""""""""""""""""""""""""" */ - ptr = word_a[index].str + strlen(word_a[index].str); - - nb = 0; - while ((ptr = mb_prev(word_a[index].str, ptr)) != NULL - && isblank(*ptr)) - nb++; - - /* Check the bit corresponding to the last non blank glyph */ - /* If set we add the index to an alternate array, if not we */ - /* clear the bitmap of the corresponding word */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (BIT_ISSET(word_a[index].bitmap, word_a[index].mb - nb - 1 - - daccess.flength - 1)) - alt_matching_words_a[j++] = index; - else - { - memset(word_a[index].bitmap, '\0', - (word_a[index].mb - 1 - daccess.flength) / CHAR_BIT - + 1); - } - } - - if (j > 0) - { - /* We have some candidates */ - /* swap the normal and alt array */ - /* """"""""""""""""""""""""""""" */ - matches_count = j; - matching_words_a_size = j; - - tmp = matching_words_a; - matching_words_a = alt_matching_words_a; - alt_matching_words_a = tmp; - - current = matching_words_a[0]; - - 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); - } - else - /* we restore the old bitmaps in this case */ - /* """"""""""""""""""""""""""""""""""""""" */ - update_bitmaps(search_mode, &search_data); - } + if (matches_count > 0 && search_mode != PREFIX) + select_ending_matches(&win, &term, &search_data, &last_line); } else { |