X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=82c8728656f22a2fcbee4fd46687f0939ca5a54c;hb=35058f35a9864f8adf9ae225d0747cd19d84122c;hp=0610568a77e727c72198644c32c04fafdad5efe4;hpb=c0d42b97ee79a50a3a77f343098ea184466eb3e8;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index 0610568a77..82c8728656 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -25,7 +25,7 @@ #include "Cursor.h" #include "CutAndPaste.h" #include "FuncRequest.h" -#include "LyXFunc.h" +#include "LyX.h" #include "output_latex.h" #include "OutputParams.h" #include "Paragraph.h" @@ -171,6 +171,8 @@ int replaceAll(BufferView * bv, if (!searchAllowed(bv, searchstr) || buf.isReadonly()) return 0; + DocIterator cur_orig(bv->cursor()); + MatchString const match(searchstr, cs, mw); int num = 0; @@ -194,10 +196,14 @@ int replaceAll(BufferView * bv, ++num; } - buf.updateLabels(); + buf.updateBuffer(); bv->putSelectionAt(doc_iterator_begin(&buf), 0, false); if (num) buf.markDirty(); + + cur_orig.fixIfBroken(); + bv->setCursor(cur_orig); + return num; } @@ -206,8 +212,10 @@ bool stringSelected(BufferView * bv, docstring & searchstr, bool cs, bool mw, bool fw) { // if nothing selected and searched string is empty, this - // means that we want to search current word at cursor position. - if (!bv->cursor().selection() && searchstr.empty()) { + // means that we want to search current word at cursor position, + // but only if we are in texted() mode. + if (!bv->cursor().selection() && searchstr.empty() + && bv->cursor().inTexted()) { bv->cursor().innerText()->selectWord(bv->cursor(), WHOLE_WORD); searchstr = bv->cursor().selectionAsString(false); return true; @@ -277,7 +285,7 @@ docstring const replace2string(docstring const & replace, bool find(BufferView * bv, FuncRequest const & ev) { - if (!bv || ev.action != LFUN_WORD_FIND) + if (!bv || ev.action() != LFUN_WORD_FIND) return false; //lyxerr << "find called, cmd: " << ev << endl; @@ -298,7 +306,7 @@ bool find(BufferView * bv, FuncRequest const & ev) void replace(BufferView * bv, FuncRequest const & ev, bool has_deleted) { - if (!bv || ev.action != LFUN_WORD_REPLACE) + if (!bv || ev.action() != LFUN_WORD_REPLACE) return; // data is of the form @@ -363,7 +371,7 @@ bool findChange(BufferView * bv, bool next) if (bv->cursor().selection()) { // set the cursor at the beginning or at the end of the selection // before searching. Otherwise, the current change will be found. - if (next != (bv->cursor().top() > bv->cursor().anchor())) + if (next != (bv->cursor().top() > bv->cursor().normalAnchor())) bv->cursor().setCursorToAnchor(); } @@ -405,14 +413,14 @@ bool findChange(BufferView * bv, bool next) if (next) { for (; !tip.at_end(); tip.forwardPos()) { Change change = tip.paragraph().lookupChange(tip.pos()); - if (change != orig_change) + if (!change.isSimilarTo(orig_change)) break; } } else { for (; !tip.at_begin();) { tip.backwardPos(); Change change = tip.paragraph().lookupChange(tip.pos()); - if (change != orig_change) { + if (!change.isSimilarTo(orig_change)) { // take a step forward to correctly set the selection tip.forwardPos(); break; @@ -519,33 +527,34 @@ string escape_for_regex(string s) { size_t pos = 0; while (pos < s.size()) { - size_t new_pos = s.find("\\regexp{", pos); - if (new_pos == string::npos) - new_pos = s.size(); - LYXERR(Debug::FIND, "new_pos: " << new_pos); - string t = apply_escapes(s.substr(pos, new_pos - pos), get_lyx_unescapes()); - LYXERR(Debug::FIND, "t : " << t); - t = apply_escapes(t, get_regexp_escapes()); - s.replace(pos, new_pos - pos, t); - new_pos = pos + t.size(); - LYXERR(Debug::FIND, "Regexp after escaping: " << s); - LYXERR(Debug::FIND, "new_pos: " << new_pos); - if (new_pos == s.size()) - break; - size_t end_pos = find_matching_brace(s, new_pos + 7); - LYXERR(Debug::FIND, "end_pos: " << end_pos); - t = apply_escapes(s.substr(new_pos + 8, end_pos - (new_pos + 8)), get_lyx_unescapes()); - LYXERR(Debug::FIND, "t : " << t); - if (end_pos == s.size()) { - s.replace(new_pos, end_pos - new_pos, t); - pos = s.size(); - LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); - break; - } - s.replace(new_pos, end_pos + 1 - new_pos, t); + size_t new_pos = s.find("\\regexp{{{", pos); + if (new_pos == string::npos) + new_pos = s.size(); + LYXERR(Debug::FIND, "new_pos: " << new_pos); + string t = apply_escapes(s.substr(pos, new_pos - pos), get_lyx_unescapes()); + LYXERR(Debug::FIND, "t : " << t); + t = apply_escapes(t, get_regexp_escapes()); + LYXERR(Debug::FIND, "t : " << t); + s.replace(pos, new_pos - pos, t); + new_pos = pos + t.size(); + LYXERR(Debug::FIND, "Regexp after escaping: " << s); + LYXERR(Debug::FIND, "new_pos: " << new_pos); + if (new_pos == s.size()) + break; + size_t end_pos = s.find("}}}", new_pos + 10); // find_matching_brace(s, new_pos + 7); + LYXERR(Debug::FIND, "end_pos: " << end_pos); + t = apply_escapes(s.substr(new_pos + 10, end_pos - (new_pos + 10)), get_lyx_unescapes()); + LYXERR(Debug::FIND, "t : " << t); + if (end_pos == s.size()) { + s.replace(new_pos, end_pos - new_pos, t); + pos = s.size(); LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); - pos = new_pos + t.size(); - LYXERR(Debug::FIND, "pos: " << pos); + break; + } + s.replace(new_pos, end_pos + 3 - new_pos, t); + LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); + pos = new_pos + t.size(); + LYXERR(Debug::FIND, "pos: " << pos); } return s; } @@ -573,7 +582,8 @@ bool regex_replace(string const & s, string & t, string const & searchstr, ** Number of open braces that must remain open at the end for the verification to succeed. **/ bool braces_match(string::const_iterator const & beg, - string::const_iterator const & end, int unmatched = 0) + string::const_iterator const & end, + int unmatched = 0) { int open_pars = 0; string::const_iterator it = beg; @@ -689,7 +699,6 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & break; } while (true); LYXERR(Debug::FIND, "Open braces: " << open_braces); - LASSERT(braces_match(par_as_string.begin(), par_as_string.end(), open_braces), /* */); LYXERR(Debug::FIND, "Built MatchStringAdv object: par_as_string = '" << par_as_string << "'"); } else { par_as_string = escape_for_regex(par_as_string); @@ -711,7 +720,6 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & LYXERR(Debug::FIND, "par_as_string now is '" << par_as_string << "'"); LYXERR(Debug::FIND, "Open braces: " << open_braces); LYXERR(Debug::FIND, "Close .*? : " << close_wildcards); - LASSERT(braces_match(par_as_string.begin(), par_as_string.end(), open_braces), /* */); LYXERR(Debug::FIND, "Replaced text (to be used as regex): " << par_as_string); // If entered regexp must match at begin of searched string buffer regexp = boost::regex(string("\\`") + par_as_string); @@ -805,8 +813,6 @@ string MatchStringAdv::normalize(docstring const & s) const LYXERR(Debug::FIND, "Removing stale empty \\emph{}, \\textbf{}, \\*section{} macros from: " << t); while (regex_replace(t, t, "\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph)(\\{\\})+", "")) LYXERR(Debug::FIND, " further removing stale empty \\emph{}, \\textbf{} macros from: " << t); - regex_replace(t, t, "\\{", "@##£$%@("); - regex_replace(t, t, "\\}", "@##£$%@)"); return t; } @@ -872,9 +878,6 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) ParagraphList::const_iterator pit = cur.innerText()->paragraphs().begin(); for (int i = 0; i < cur.pit(); ++i) ++pit; -// ParagraphList::const_iterator pit_end = pit; -// ++pit_end; -// lyx::latexParagraphs(buf, cur.innerText()->paragraphs(), ods, texrow, runparams, string(), pit, pit_end); pos_type const endpos = (len == -1 || cur.pos() + len > int(pit->size())) ? pit->size() : cur.pos() + len; TeXOnePar(buf, *cur.innerText(), pit, ods, texrow, runparams, string(), @@ -898,13 +901,6 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) for (MathData::const_iterator it = md.begin() + cs.pos(); it != it_end; ++it) ods << *it; - // MathData md = cur.cell(); - // MathData::const_iterator it_end = ( ( len == -1 || cur.pos() + len > int(md.size()) ) ? md.end() : md.begin() + cur.pos() + len ); - // for (MathData::const_iterator it = md.begin() + cur.pos(); it != it_end; ++it) { - // MathAtom const & ma = *it; - // ma.nucleus()->latex(buf, ods, runparams); - // } - // Retrieve the math environment type, and add '$' or '$]' // or others (\end{equation}) accordingly for (int s = cur.depth() - 1; s >= 0; --s) { @@ -946,6 +942,8 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match) // Compute the match length int len = 1; + if (cur.pos() + len > cur.lastpos()) + return 0; LYXERR(Debug::FIND, "verifying unmatch with len = " << len); while (cur.pos() + len <= cur.lastpos() && match(cur, len) == 0) { ++len; @@ -985,28 +983,25 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match) /// Find the most backward consecutive match within same paragraph while searching backwards. -void findMostBackwards(DocIterator & cur, MatchStringAdv const & match, int & len) +int findMostBackwards(DocIterator & cur, MatchStringAdv const & match) { DocIterator cur_begin = doc_iterator_begin(cur.buffer()); - len = findAdvFinalize(cur, match); - if (cur != cur_begin) { - Inset & inset = cur.inset(); - int old_len; - DocIterator old_cur; - DocIterator dit2; - do { - old_cur = cur; - old_len = len; - cur.backwardPos(); - LYXERR(Debug::FIND, "findMostBackwards(): old_cur=" - << old_cur << ", old_len=" << len << ", cur=" << cur); - dit2 = cur; - } while (cur != cur_begin && &cur.inset() == &inset && match(cur) - && (len = findAdvFinalize(dit2, match)) > old_len); - cur = old_cur; - len = old_len; + DocIterator tmp_cur = cur; + int len = findAdvFinalize(tmp_cur, match); + Inset & inset = cur.inset(); + for (; cur != cur_begin; cur.backwardPos()) { + LYXERR(Debug::FIND, "findMostBackwards(): cur=" << cur); + DocIterator new_cur = cur; + new_cur.backwardPos(); + if (new_cur == cur || &new_cur.inset() != &inset || !match(new_cur)) + break; + int new_len = findAdvFinalize(new_cur, match); + if (new_len == len) + break; + len = new_len; } - LYXERR(Debug::FIND, "findMostBackwards(): cur=" << cur); + LYXERR(Debug::FIND, "findMostBackwards(): exiting with cur=" << cur); + return len; } @@ -1015,10 +1010,11 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { if (! cur) return 0; // Backup of original position - DocIterator cur_orig(cur); DocIterator cur_begin = doc_iterator_begin(cur.buffer()); if (cur == cur_begin) return 0; + cur.backwardPos(); + DocIterator cur_orig(cur); bool found_match; bool pit_changed = false; found_match = false; @@ -1033,22 +1029,19 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { cur.pos() = cur_orig.pos(); LYXERR(Debug::FIND, "findBackAdv2: cur: " << cur); DocIterator cur_prev_iter; - while (true) { + do { found_match = match(cur); LYXERR(Debug::FIND, "findBackAdv3: found_match=" << found_match << ", cur: " << cur); - if (found_match) { - int len; - findMostBackwards(cur, match, len); - if (cur < cur_orig) - return len; - } - // Prevent infinite loop at begin of document - if (cur == cur_begin || cur == cur_prev_iter) + if (found_match) + return findMostBackwards(cur, match); + + // Stop if begin of document reached + if (cur == cur_begin) break; cur_prev_iter = cur; cur.backwardPos(); - } + } while (true); } if (cur == cur_begin) break; @@ -1147,9 +1140,12 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M return; DocIterator sel_beg = cur.selectionBegin(); DocIterator sel_end = cur.selectionEnd(); - LASSERT(&sel_beg.inset() == &sel_end.inset(), /**/); + if (&sel_beg.inset() != &sel_end.inset() + || sel_beg.pit() != sel_end.pit()) + return; int sel_len = sel_end.pos() - sel_beg.pos(); - LYXERR(Debug::FIND, "sel_beg: " << sel_beg << ", sel_end: " << sel_end << ", sel_len: " << sel_len << endl); + LYXERR(Debug::FIND, "sel_beg: " << sel_beg << ", sel_end: " << sel_end + << ", sel_len: " << sel_len << endl); if (sel_len == 0) return; LASSERT(sel_len > 0, /**/);