Bug 130252

Summary: Repeatedly search doesn't work backwards in kwrite and kate
Product: [Applications] kate Reporter: Tim <lecit>
Component: kwriteAssignee: Andreas Kling <info>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:

Description Tim 2006-07-04 16:42:22 UTC
Version:            (using KDE KDE 3.5.3)
Installed from:    Compiled From Sources
Compiler:          gcc-4.1.1 
OS:                Linux

If "Find backwards" option is checked before searching, "Find next F3" doesn't work as expected while "Find Previous Shift+F3" does its job. If it's unchecked, the opposite happens. Put it another way, repeatedly search can only be done forwards. This is very inconvenient when repeatedly backwards search is wanted especially in a large file.


Steps to Reproduce:
1. Create a test file
for i in `seq 10`; do echo "line$i" >> test; done
2. Open "test" using kwrite or kate
3. Go to bottom and search(Ctrl+F) "line" with "Find backwards" option 
checked. Then press F3 to find next.
  
Actual results:
Nothing happens

Expected results:
"line" in line9 should be highlighted

Additional info:
Other editors like kedit and vi support repeatedly backwards search pretty well.
Comment 1 Andreas Kling 2006-07-05 23:52:10 UTC
SVN commit 558717 by kling:

"Find previous" should reverse the original direction, and nothing else.

BUG: 130252


 M  +4 -2      katesearch.cpp  
 M  +1 -1      katesearch.h  


--- branches/KDE/3.5/kdelibs/kate/part/katesearch.cpp #558716:558717
@@ -216,7 +216,7 @@
   search( searchFlags );
 }
 
-void KateSearch::findAgain( bool back )
+void KateSearch::findAgain( bool reverseDirection )
 {
   SearchFlags searchFlags;
   searchFlags.caseSensitive = KateViewConfig::global()->searchFlags() & KFindDialog::CaseSensitive;
@@ -231,7 +231,9 @@
   searchFlags.regExp = KateViewConfig::global()->searchFlags() & KFindDialog::RegularExpression;
   searchFlags.useBackRefs = KateViewConfig::global()->searchFlags() & KReplaceDialog::BackReference;
 
-  searchFlags.backward = searchFlags.backward != back;
+  if (reverseDirection)
+    searchFlags.backward = !searchFlags.backward;
+
   searchFlags.fromBeginning = false;
   searchFlags.prompt = true; // ### why is the above assignment there?
   s.cursor = getCursor();
--- branches/KDE/3.5/kdelibs/kate/part/katesearch.h #558716:558717
@@ -113,7 +113,7 @@
      * @param flags OR'd combination of KFindDialog::Options
      */
     void replace( const QString &pattern, const QString &replacement, long flags );
-    void findAgain( bool back );
+    void findAgain( bool reverseDirection );
 
   private slots:
     void replaceSlot();
Comment 2 Tim 2006-07-06 16:04:05 UTC
Andreas, i built kdelibs with above patch but this problem still appears!
Comment 3 Andreas Kling 2006-07-06 17:21:32 UTC
Yes, I forgot to mention that #123307, which is a part of your problem, is still unresolved. :]
Comment 4 Andreas Kling 2006-07-07 16:12:25 UTC
SVN commit 559493 by kling:

Made backward searches work a lot better.

BUG: 123307
BUG: 130252


 M  +26 -4     katesearch.cpp  
 M  +1 -1      katesearch.h  


--- branches/KDE/3.5/kdelibs/kate/part/katesearch.cpp #559492:559493
@@ -141,7 +141,7 @@
     s.selEnd   = KateTextCursor( m_view->selEndLine(),   m_view->selEndCol()   );
     s.cursor   = s.flags.backward ? s.selEnd : s.selBegin;
   } else {
-    s.cursor = getCursor();
+    s.cursor = getCursor( searchFlags );
   }
 
   s.wrappedEnd = s.cursor;
@@ -207,7 +207,7 @@
     s.selEnd   = KateTextCursor( m_view->selEndLine(), m_view->selEndCol()   );
     s.cursor   = s.flags.backward ? s.selEnd : s.selBegin;
   } else {
-    s.cursor = getCursor();
+    s.cursor = getCursor( searchFlags );
   }
 
   s.wrappedEnd = s.cursor;
@@ -236,8 +236,8 @@
 
   searchFlags.fromBeginning = false;
   searchFlags.prompt = true; // ### why is the above assignment there?
-  s.cursor = getCursor();
 
+  s.cursor = getCursor( searchFlags );
   search( searchFlags );
 }
 
@@ -547,8 +547,15 @@
   return str;
 }
 
-KateTextCursor KateSearch::getCursor()
+KateTextCursor KateSearch::getCursor( SearchFlags flags )
 {
+  if (flags.backward && !flags.selected && view()->hasSelection())
+  {
+    // We're heading backwards (and not within a selection),
+    // the selection might start before the cursor.
+    return KMIN( KateTextCursor(view()->selStartLine(), view()->selStartCol()),
+                 KateTextCursor(view()->cursorLine(), view()->cursorColumnReal()));
+  }
   return KateTextCursor(view()->cursorLine(), view()->cursorColumnReal());
 }
 
@@ -586,6 +593,21 @@
   //kdDebug() << "Searching at " << line << ", " << col << endl;
 //   kdDebug()<<"KateSearch::doSearch: "<<line<<", "<<col<<", "<<backward<<endl;
 
+  if (backward)
+  {
+    KateDocCursor docCursor(line, col, doc());
+
+    // If we're at the top of the document, we're not gonna find anything, so bail.
+    if (docCursor.line() == 0 && docCursor.col() == 0)
+      return false;
+
+    // Move one step backward before searching, if this is a "find again", we don't
+    // want to find the same match.
+    docCursor.moveBackward(1);
+    line = docCursor.line();
+    col = docCursor.col();
+  }
+
   do {
       if( regExp ) {
         m_re = QRegExp( text, caseSensitive );
--- branches/KDE/3.5/kdelibs/kate/part/katesearch.h #559492:559493
@@ -139,7 +139,7 @@
     void skipOne();
 
     QString getSearchText();
-    KateTextCursor getCursor();
+    KateTextCursor getCursor( SearchFlags flags );
     bool doSearch( const QString& text );
     void exposeFound( KateTextCursor &cursor, int slen );
 
Comment 5 Tim 2006-07-10 11:07:47 UTC
great, it works fine with above patch now. Thank you very much!