The current find/replace algorithm leads to a wasted search after
changing directions.

The current algorithm for find is as follows:
On forward search, start looking forwards and if the string is found,
place the cursor to the right of the found string.
On reverse search, start by looking backwards and if the string is
found, place the cursor to the left of the found string.

If we change directions in the search, the next find will be wasted.
This is because of the asymmetric cursor placement on finding a
string. To see the problem, open a .lyx file and search for a word.
Then change directions and search again.

Is this a problem worth fixing?

I have a two proposals to address this (if it is decided that it
deserves addressing).

Proposition 1
When the users toggles "Search backwards", the cursor moves to the
other side of the string (without clearing the selection).

I did not think of (1) until just now so I did not try to implement
it. I will share my Proposition (2), which is uglier in my opinion.

Proposition 2 is:
(a) Whether search forward or search backward, the cursor should
always be on the left side. This causes a problem because if you
search forward, the algorithm will infinitely find the string just in
front of the cursor so you are stuck. You cannot just say "don't find
the string if it is right in front of the cursor" because that string
should be found if it has not been found yet (i.e. if it's the first
time you're searching and your cursor happens to be in front).

(b) A hackish solution to the problem caused by (a) is
"if the highlighted string is equal to the search string, move one
character forward before searching forward (or move one character
backward before searching backward)".

I do not like (2) because it is not intuitive and it affects code that
is run every time that find is run. (1) is nonintrusive and leaves the
algorithm untouched. Nonetheless, attached is a patch for Proposition
2 in case someone likes it better. Regarding the patch, it only works
now for searching using word-find-forward and word-find-backward on
the mini-buffer. It breaks the GUI find. I think I could easily fix
this but I stopped here because I don't think this is the right
approach.

Any other ideas?

Thanks,

Scott
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 4342020..2506266 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -1528,6 +1528,10 @@ void BufferView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                bool const fw = act == LFUN_WORD_FIND_FORWARD;
                docstring const data =
                        find2string(searched_string, true, false, fw);
+               if (searched_string == d->cursor_.selectionAsString(true))
+                       act == LFUN_WORD_FIND_FORWARD ?
+                               d->cursor_.posForward():
+                               d->cursor_.posBackward();
                bool found = lyxfind(this, FuncRequest(LFUN_WORD_FIND, data));
                if (found)
                        dr.screenUpdate(Update::Force | Update::FitCursor);
@@ -2520,11 +2524,8 @@ void BufferView::putSelectionAt(DocIterator const & cur,
        setCursor(cur);
 
        if (length) {
-               if (backwards) {
-                       d->cursor_.pos() += length;
-                       d->cursor_.setSelection(d->cursor_, -length);
-               } else
-                       d->cursor_.setSelection(d->cursor_, length);
+               d->cursor_.pos() += length;
+               d->cursor_.setSelection(d->cursor_, -length);
        }
 }
 

Reply via email to