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