]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfind.cpp
Revert previous commit, which committed too much.
[lyx.git] / src / lyxfind.cpp
index 409a2e2cf7f2a1bf8d24fbf5725d111dd2311a0a..86d8b9818189f11ded597a7e93c991317e18d07c 100644 (file)
@@ -40,6 +40,7 @@
 #include "mathed/InsetMathGrid.h"
 #include "mathed/InsetMathHull.h"
 #include "mathed/MathStream.h"
+#include "mathed/MathSupport.h"
 
 #include "support/convert.h"
 #include "support/debug.h"
@@ -229,7 +230,7 @@ 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 whole, bool forward, bool findnext)
 {
        Cursor & cur = bv->cursor();
        if (!cur.selection()) {
@@ -278,7 +279,8 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
                cur.pos() -= replacestr.length();
                LASSERT(cur.pos() >= 0, /* */);
        }
-       findOne(bv, searchstr, case_sens, whole, forward, false);
+       if (findnext)
+               findOne(bv, searchstr, case_sens, whole, forward, false);
 
        return pair<bool, int>(true, 1);
 }
@@ -300,7 +302,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 all, bool forward, bool findnext)
 {
        odocstringstream ss;
        ss << replace << '\n'
@@ -308,7 +310,8 @@ docstring const replace2string(docstring const & replace,
           << int(casesensitive) << ' '
           << int(matchword) << ' '
           << int(all) << ' '
-          << int(forward);
+          << int(forward) << ' '
+          << int(findnext);
        return ss.str();
 }
 
@@ -343,7 +346,7 @@ bool lyxreplace(BufferView * bv,
        // data is of the form
        // "<search>
        //  <replace>
-       //  <casesensitive> <matchword> <all> <forward>"
+       //  <casesensitive> <matchword> <all> <forward> <findnext>"
        docstring search;
        docstring rplc;
        docstring howto = split(ev.argument(), rplc, '\n');
@@ -353,6 +356,7 @@ bool lyxreplace(BufferView * bv,
        bool matchword     = parse_bool(howto);
        bool all           = parse_bool(howto);
        bool forward       = parse_bool(howto);
+       bool findnext      = howto.empty() ? true : parse_bool(howto);
 
        int replace_count = 0;
        bool update = false;
@@ -363,7 +367,7 @@ bool lyxreplace(BufferView * bv,
                        update = replace_count > 0;
                } else {
                        pair<bool, int> rv = 
-                               replaceOne(bv, search, rplc, casesensitive, matchword, forward);
+                               replaceOne(bv, search, rplc, casesensitive, matchword, forward, findnext);
                        update = rv.first;
                        replace_count = rv.second;
                }
@@ -383,7 +387,7 @@ bool lyxreplace(BufferView * bv,
                                buf.message(str);
                        }
                }
-       } else {
+       } else if (findnext) {
                // if we have deleted characters, we do not replace at all, but
                // rather search for the next occurence
                if (findOne(bv, search, casesensitive, matchword, forward))
@@ -740,21 +744,19 @@ static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions co
        if (!opt.ignoreformat) {
                str = buffer_to_latex(buffer);
        } else {
-               ParIterator it = buffer.par_iterator_begin();
-               ParIterator end = buffer.par_iterator_end();
                OutputParams runparams(&buffer.params().encoding());
-               odocstringstream os;
                runparams.nice = true;
                runparams.flavor = OutputParams::LATEX;
                runparams.linelen = 100000; //lyxrc.plaintext_linelen;
                runparams.dryrun = true;
-               for (; it != end; ++it) {
+               for (pos_type pit = pos_type(0); pit < (pos_type)buffer.paragraphs().size(); ++pit) {
+                       Paragraph const & par = buffer.paragraphs().at(pit);
                        LYXERR(Debug::FIND, "Adding to search string: '"
-                               << it->asString(false)
+                               << par.stringify(pos_type(0), par.size(),
+                                                AS_STR_INSETS, runparams)
                                << "'");
-                       str +=
-                               it->stringify(pos_type(0), it->size(),
-                                             AS_STR_INSETS, runparams);
+                       str += par.stringify(pos_type(0), par.size(),
+                                            AS_STR_INSETS, runparams);
                }
        }
        return str;
@@ -765,11 +767,12 @@ static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions co
 static size_t identifyLeading(string const & s)  {
        string t = s;
        // @TODO Support \item[text]
-       while (regex_replace(t, t, "\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph|part)\\{", "")
+       while (regex_replace(t, t, "\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph|part)\\*?\\{", "")
               || regex_replace(t, t, "^\\$", "")
               || regex_replace(t, t, "^\\\\\\[ ", "")
-              || regex_replace(t, t, "^\\\\item ", ""))
-               LYXERR(Debug::FIND, "  after removing leading $, \\[ , \\emph{, \\textbf{, etc.: " << t);
+              || regex_replace(t, t, "^\\\\item ", "")
+              || regex_replace(t, t, "^\\\\begin\\{[a-zA-Z_]*\\*?\\} ", ""))
+               LYXERR(Debug::FIND, "  after removing leading $, \\[ , \\emph{, \\textbf{, etc.: '" << t << "'");
        return s.find(t);
 }
 
@@ -788,16 +791,14 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const &
                // Remove trailing closure of math, macros and environments, so to catch parts of them.
                do {
                        LYXERR(Debug::FIND, "par_as_string now is '" << par_as_string << "'");
-                       if (regex_replace(par_as_string, par_as_string, "(.*)[[:blank:]]\\'", "$1"))
-                                       continue;
-                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) ?\\$\\'", "$1"))
+                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\])\\$\\'", "$1"))
                                        continue;
                        // @todo need to account for open square braces as well ?
-                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) ?\\\\\\]\\'", "$1"))
+                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) \\\\\\]\\'", "$1"))
                                        continue;
-                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) ?\\\\end\\{[a-zA-Z_]*\\}\\'", "$1"))
+                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) \\\\end\\{[a-zA-Z_]*\\*?\\}\\'", "$1"))
                                        continue;
-                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\]) ?\\}\\'", "$1")) {
+                       if (regex_replace(par_as_string, par_as_string, "(.*[^\\\\])\\}\\'", "$1")) {
                                ++open_braces;
                                continue;
                        }
@@ -821,10 +822,10 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const &
                        // Insert .* before trailing '\$' ('$' has been escaped by escape_for_regex)
                        regex_replace(par_as_string, par_as_string, "(.*[^\\\\])(\\\\\\$)\\'", "$1(.*?)$2")
                                // Insert .* before trailing '\\\]' ('\]' has been escaped by escape_for_regex)
-                               || regex_replace(par_as_string, par_as_string, "(.*[^\\\\])(\\\\\\\\\\\\\\])\\'", "$1(.*?)$2")
+                               || regex_replace(par_as_string, par_as_string, "(.*[^\\\\])( \\\\\\\\\\\\\\])\\'", "$1(.*?)$2")
                                // Insert .* before trailing '\\end\{...}' ('\end{...}' has been escaped by escape_for_regex)
                                || regex_replace(par_as_string, par_as_string, 
-                                       "(.*[^\\\\])(\\\\\\\\end\\\\\\{[a-zA-Z_]*\\\\\\})\\'", "$1(.*?)$2")
+                                       "(.*[^\\\\])( \\\\\\\\end\\\\\\{[a-zA-Z_]*)(\\\\\\*)?(\\\\\\})\\'", "$1(.*?)$2$3$4")
                                // Insert .* before trailing '\}' ('}' has been escaped by escape_for_regex)
                                || regex_replace(par_as_string, par_as_string, "(.*[^\\\\])(\\\\\\})\\'", "$1(.*?)$2")
                ) {
@@ -882,8 +883,9 @@ int MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_begin) con
                        // plus the last subexpression, if a (.*?) was inserted in the constructor.
                        if (!braces_match(m[0].first, m[0].second, open_braces))
                                return 0;
-                       // Check braces on segments that matched all (.*?) subexpressions.
-                       for (size_t i = 1; i < m.size(); ++i)
+                       // Check braces on segments that matched all (.*?) subexpressions,
+                       // except the last "padding" one inserted by lyx.
+                       for (size_t i = 1; i < m.size() - 1; ++i)
                                if (!braces_match(m[i].first, m[i].second))
                                        return false;
                        // Exclude from the returned match length any length 
@@ -965,15 +967,16 @@ docstring stringifyFromCursor(DocIterator const & cur, int len)
                                << cur << ", from pos: " << cur.pos() << ", end: " << end);
                        return par.stringify(cur.pos(), end, AS_STR_INSETS, runparams);
        } else if (cur.inMathed()) {
-                       odocstringstream os;
+                       docstring s;
                        CursorSlice cs = cur.top();
                        MathData md = cs.cell();
                        MathData::const_iterator it_end = 
                                ( ( len == -1 || cs.pos() + len > int(md.size()) )
                                        ? md.end() : md.begin() + cs.pos() + len );
                        for (MathData::const_iterator it = md.begin() + cs.pos(); it != it_end; ++it)
-                                       os << *it;
-                       return os.str();
+                               s = s + asString(*it);
+                       LYXERR(Debug::FIND, "Stringified math: '" << s << "'");
+                       return s;
        }
        LYXERR(Debug::FIND, "Don't know how to stringify from here: " << cur);
        return docstring();
@@ -990,7 +993,7 @@ docstring latexifyFromCursor(DocIterator const & cur, int len)
        LYXERR(Debug::FIND, "  with cur.lastpost=" << cur.lastpos() << ", cur.lastrow="
                << cur.lastrow() << ", cur.lastcol=" << cur.lastcol());
        Buffer const & buf = *cur.buffer();
-       LASSERT(buf.isLatex(), /* */);
+       LASSERT(buf.params().isLatex(), /* */);
 
        TexRow texrow;
        odocstringstream ods;
@@ -1026,7 +1029,7 @@ docstring latexifyFromCursor(DocIterator const & cur, int len)
                MathData::const_iterator it_end = ( ( len == -1 || cs.pos() + len > int(md.size()) )
                        ? md.end() : md.begin() + cs.pos() + len );
                for (MathData::const_iterator it = md.begin() + cs.pos(); it != it_end; ++it)
-                               ods << *it;
+                       ods << asString(*it);
 
                // Retrieve the math environment type, and add '$' or '$]'
                // or others (\end{equation}) accordingly
@@ -1096,10 +1099,14 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match)
                return 0;
        while (cur) {
                LYXERR(Debug::FIND, "findForwardAdv() cur: " << cur);
-               if (match(cur, -1, false)) {
+               int match_len = match(cur, -1, false);
+               LYXERR(Debug::FIND, "match_len: " << match_len);
+               if (match_len) {
                        for (; cur; cur.forwardPos()) {
                                LYXERR(Debug::FIND, "Advancing cur: " << cur);
-                               if (match(cur)) {
+                               int match_len = match(cur);
+                               LYXERR(Debug::FIND, "match_len: " << match_len);
+                               if (match_len) {
                                        // Sometimes in finalize we understand it wasn't a match
                                        // and we need to continue the outest loop
                                        int len = findAdvFinalize(cur, match);
@@ -1336,12 +1343,14 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M
                LYXERR(Debug::FIND, "Replacing by niceInsert()ing latex: '" << repl_latex << "'");
                sel_len = cur.niceInsert(repl_latex);
        }
-       cur.pos() -= sel_len;
-       if (cur.pos() < 0)
+       if (cur.pos() >= sel_len)
+               cur.pos() -= sel_len;
+       else
                cur.pos() = 0;
        LYXERR(Debug::FIND, "Putting selection at cur=" << cur << " with len: " << sel_len);
        bv->putSelectionAt(DocIterator(cur), sel_len, !opt.forward);
        bv->processUpdateFlags(Update::Force);
+       bv->buffer().updatePreviews();
 }