]> git.lyx.org Git - features.git/blobdiff - src/lyxfind.cpp
Improve instant search
[features.git] / src / lyxfind.cpp
index 4c629b309cc779d0c6e9aaf52bc2204a01c0b0f4..8487c013265cea16c5601b93ad748d03fc0f79f5 100644 (file)
@@ -106,7 +106,7 @@ class IgnoreFormats {
        ///
        void setIgnoreDeleted(bool value);
        ///
-       void setIgnoreFormat(string const & type, bool value);
+       void setIgnoreFormat(string const & type, bool value, bool fromUser = true);
 
 private:
        ///
@@ -129,17 +129,23 @@ private:
        bool ignoreColor_ = false;
        ///
        bool ignoreLanguage_ = false;
+       bool userSelectedIgnoreLanguage_ = false;
        ///
        bool ignoreDeleted_ = true;
 };
 
-void IgnoreFormats::setIgnoreFormat(string const & type, bool value)
+void IgnoreFormats::setIgnoreFormat(string const & type, bool value, bool fromUser)
 {
        if (type == "color") {
                ignoreColor_ = value;
        }
        else if (type == "language") {
-               ignoreLanguage_ = value;
+               if (fromUser) {
+                       userSelectedIgnoreLanguage_ = value;
+                       ignoreLanguage_ = value;
+               }
+               else
+                       ignoreLanguage_ = (value || userSelectedIgnoreLanguage_);
        }
        else if (type == "sectioning") {
                ignoreSectioning_ = value;
@@ -177,18 +183,18 @@ void IgnoreFormats::setIgnoreFormat(string const & type, bool value)
 IgnoreFormats ignoreFormats;
 
 
-void setIgnoreFormat(string const & type, bool value)
+void setIgnoreFormat(string const & type, bool value, bool fromUser)
 {
-  ignoreFormats.setIgnoreFormat(type, value);
+  ignoreFormats.setIgnoreFormat(type, value, fromUser);
 }
 
 
 namespace {
 
-bool parse_bool(docstring & howto)
+bool parse_bool(docstring & howto, bool const defvalue = false)
 {
        if (howto.empty())
-               return false;
+               return defvalue;
        docstring var;
        howto = split(howto, var, ' ');
        return var == "1";
@@ -256,17 +262,20 @@ bool searchAllowed(docstring const & str)
        return true;
 }
 
+} // namespace
+
 
 bool findOne(BufferView * bv, docstring const & searchstr,
             bool case_sens, bool whole, bool forward,
-            bool find_del = true, bool check_wrap = false)
+            bool find_del, bool check_wrap, bool auto_wrap,
+            bool instant)
 {
        if (!searchAllowed(searchstr))
                return false;
 
        DocIterator cur = forward
-               ? bv->cursor().selectionEnd()
-               : bv->cursor().selectionBegin();
+               ? (instant ? bv->cursor().selectionBegin() : bv->cursor().selectionEnd())
+               : (instant ? bv->cursor().selectionEnd() : bv->cursor().selectionBegin());
 
        MatchString const match(searchstr, case_sens, whole);
 
@@ -278,16 +287,19 @@ bool findOne(BufferView * bv, docstring const & searchstr,
                bv->putSelectionAt(cur, match_len, !forward);
        else if (check_wrap) {
                DocIterator cur_orig(bv->cursor());
-               docstring q;
-               if (forward)
-                       q = _("End of file reached while searching forward.\n"
-                         "Continue searching from the beginning?");
-               else
-                       q = _("Beginning of file reached while searching backward.\n"
-                         "Continue searching from the end?");
-               int wrap_answer = frontend::Alert::prompt(_("Wrap search?"),
-                       q, 0, 1, _("&Yes"), _("&No"));
-               if (wrap_answer == 0) {
+               if (!auto_wrap) {
+                       docstring q;
+                       if (forward)
+                               q = _("End of file reached while searching forward.\n"
+                                 "Continue searching from the beginning?");
+                       else
+                               q = _("Beginning of file reached while searching backward.\n"
+                                 "Continue searching from the end?");
+                       int wrap_answer = frontend::Alert::prompt(_("Wrap search?"),
+                               q, 0, 1, _("&Yes"), _("&No"));
+                       auto_wrap = wrap_answer == 0;
+               }
+               if (auto_wrap) {
                        if (forward) {
                                bv->cursor().clear();
                                bv->cursor().push_back(CursorSlice(bv->buffer().inset()));
@@ -296,7 +308,8 @@ bool findOne(BufferView * bv, docstring const & searchstr,
                                bv->cursor().backwardPos();
                        }
                        bv->clearSelection();
-                       if (findOne(bv, searchstr, case_sens, whole, forward, find_del, false))
+                       if (findOne(bv, searchstr, case_sens, whole, forward,
+                                   find_del, false, false, false))
                                return true;
                }
                bv->cursor().setCursor(cur_orig);
@@ -307,6 +320,8 @@ bool findOne(BufferView * bv, docstring const & searchstr,
 }
 
 
+namespace {
+
 int replaceAll(BufferView * bv,
               docstring const & searchstr, docstring const & replacestr,
               bool case_sens, bool whole)
@@ -371,13 +386,14 @@ int replaceAll(BufferView * bv,
 // whether anything at all was done.
 pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
                           docstring const & replacestr, bool case_sens,
-                          bool whole, bool forward, bool findnext)
+                          bool whole, bool forward, bool findnext, bool wrap)
 {
        Cursor & cur = bv->cursor();
        if (!cur.selection()) {
                // no selection, non-empty search string: find it
                if (!searchstr.empty()) {
-                       bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext);
+                       bool const found = findOne(bv, searchstr, case_sens, whole,
+                                                  forward, true, findnext, wrap, false);
                        return make_pair(found, 0);
                }
                // empty search string
@@ -406,7 +422,8 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
        // no selection or current selection is not search word:
        // just find the search word
        if (!have_selection || !match) {
-               bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext);
+               bool const found = findOne(bv, searchstr, case_sens, whole, forward,
+                                          true, findnext, wrap, false);
                return make_pair(found, 0);
        }
 
@@ -422,7 +439,8 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
                        cur.pos() = cur.lastpos());
        }
        if (findnext)
-               findOne(bv, searchstr, case_sens, whole, forward, false, findnext);
+               findOne(bv, searchstr, case_sens, whole,
+                       forward, false, findnext, wrap, false);
 
        return make_pair(true, 1);
 }
@@ -431,13 +449,16 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
 
 
 docstring const find2string(docstring const & search,
-                           bool casesensitive, bool matchword, bool forward)
+                           bool casesensitive, bool matchword,
+                           bool forward, bool wrap, bool instant)
 {
        odocstringstream ss;
        ss << search << '\n'
           << int(casesensitive) << ' '
           << int(matchword) << ' '
-          << int(forward);
+          << int(forward) << ' '
+          << int(wrap) << ' '
+          << int(instant);
        return ss.str();
 }
 
@@ -445,7 +466,7 @@ docstring const find2string(docstring const & search,
 docstring const replace2string(docstring const & replace,
                               docstring const & search,
                               bool casesensitive, bool matchword,
-                              bool all, bool forward, bool findnext)
+                              bool all, bool forward, bool findnext, bool wrap)
 {
        odocstringstream ss;
        ss << replace << '\n'
@@ -454,7 +475,8 @@ docstring const replace2string(docstring const & replace,
           << int(matchword) << ' '
           << int(all) << ' '
           << int(forward) << ' '
-          << int(findnext);
+          << int(findnext) << ' '
+          << int(wrap);
        return ss.str();
 }
 
@@ -462,17 +484,21 @@ docstring const replace2string(docstring const & replace,
 docstring const string2find(docstring const & argument,
                              bool &casesensitive,
                              bool &matchword,
-                             bool &forward)
+                             bool &forward,
+                             bool &wrap,
+                             bool &instant)
 {
        // data is of the form
        // "<search>
-       //  <casesensitive> <matchword> <forward>"
+       //  <casesensitive> <matchword> <forward> <wrap>"
        docstring search;
        docstring howto = split(argument, search, '\n');
 
        casesensitive = parse_bool(howto);
        matchword     = parse_bool(howto);
-       forward       = parse_bool(howto);
+       forward       = parse_bool(howto, true);
+       wrap          = parse_bool(howto);
+       instant       = parse_bool(howto);
 
        return search;
 }
@@ -487,9 +513,14 @@ bool lyxfind(BufferView * bv, FuncRequest const & ev)
        bool casesensitive;
        bool matchword;
        bool forward;
-       docstring search = string2find(ev.argument(), casesensitive, matchword, forward);
-
-       return findOne(bv, search, casesensitive, matchword, forward, false, true);
+       bool wrap;
+       bool instant;
+       
+       docstring search = string2find(ev.argument(), casesensitive,
+                                      matchword, forward, wrap, instant);
+
+       return findOne(bv, search, casesensitive, matchword, forward,
+                      false, true, wrap, instant);
 }
 
 
@@ -501,7 +532,7 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
        // data is of the form
        // "<search>
        //  <replace>
-       //  <casesensitive> <matchword> <all> <forward> <findnext>"
+       //  <casesensitive> <matchword> <all> <forward> <findnext> <wrap>"
        docstring search;
        docstring rplc;
        docstring howto = split(ev.argument(), rplc, '\n');
@@ -510,8 +541,9 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
        bool casesensitive = parse_bool(howto);
        bool matchword     = parse_bool(howto);
        bool all           = parse_bool(howto);
-       bool forward       = parse_bool(howto);
-       bool findnext      = howto.empty() ? true : parse_bool(howto);
+       bool forward       = parse_bool(howto, true);
+       bool findnext      = parse_bool(howto, true);
+       bool wrap          = parse_bool(howto);
 
        bool update = false;
 
@@ -521,7 +553,7 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
                update = replace_count > 0;
        } else {
                pair<bool, int> rv =
-                       replaceOne(bv, search, rplc, casesensitive, matchword, forward, findnext);
+                       replaceOne(bv, search, rplc, casesensitive, matchword, forward, findnext, wrap);
                update = rv.first;
                replace_count = rv.second;
        }
@@ -1677,9 +1709,9 @@ class MathInfo {
     m.wait = wait;
     m.mathStart = start;
     m.mathprefixsize = prefixsize;
-    m.mathEnd = end;
+    m.mathEnd = end + postfixsize;
     m.mathpostfixsize = postfixsize;
-    m.mathSize = end - start;
+    m.mathSize = m.mathEnd - m.mathStart;
     entries_.push_back(m);
   }
   bool empty() const { return entries_.empty(); };
@@ -1754,17 +1786,17 @@ void LatexInfo::buildEntries(bool isPatternString)
       size_t pos = submath.position(size_t(2));
       if ((math_end == "$") &&
           (submath.str(2) == "$")) {
-        mi.insert("$", math_pos, 1, pos + 1, 1);
+        mi.insert("$", math_pos, 1, pos, 1);
         math_end_waiting = false;
       }
       else if ((math_end == "\\]") &&
                (submath.str(2) == "\\]")) {
-        mi.insert("\\]", math_pos, 2, pos + 2, 2);
+        mi.insert("\\]", math_pos, 2, pos, 2);
         math_end_waiting = false;
       }
       else if ((submath.str(3).compare("end") == 0) &&
           (submath.str(4).compare(math_end) == 0)) {
-        mi.insert(math_end, math_pos, math_prefix_size, pos + submath.str(2).length(), submath.str(2).length());
+        mi.insert(math_end, math_pos, math_prefix_size, pos, submath.str(2).length());
         math_end_waiting = false;
       }
       else
@@ -2849,7 +2881,7 @@ static string correctlanguagesetting(string par, bool isPatternString, bool with
                                        break;
                                }
                        }
-                       setIgnoreFormat("language", toIgnoreLang);
+                       setIgnoreFormat("language", toIgnoreLang, false);
 
                }
                result = splitOnKnownMacros(par.substr(0,parlen), isPatternString);