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); } }