X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=269b2123707207bbdb095a0db123ff1fdd87ef0f;hb=952853eb2358472644e45f3fe3a6f3a68fac3556;hp=a19724b8cea126e8da86b3b9a4c6a5d4ac6daf47;hpb=48bba7fb74b11313006a9c9effd134f83a439398;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index a19724b8ce..269b212370 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -45,6 +45,7 @@ #include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" +#include "support/FileName.h" #include "support/gettext.h" #include "support/lassert.h" #include "support/lstrings.h" @@ -121,23 +122,6 @@ int findBackwards(DocIterator & cur, MatchString const & match, } -bool findChange(DocIterator & cur, bool next) -{ - if (!next) - cur.backwardPos(); - for (; cur; next ? cur.forwardPos() : cur.backwardPos()) - if (cur.inTexted() && cur.paragraph().isChanged(cur.pos())) { - if (!next) - // if we search backwards, take a step forward - // to correctly set the anchor - cur.forwardPos(); - return true; - } - - return false; -} - - bool searchAllowed(docstring const & str) { if (str.empty()) { @@ -154,7 +138,9 @@ bool findOne(BufferView * bv, docstring const & searchstr, if (!searchAllowed(searchstr)) return false; - DocIterator cur = bv->cursor(); + DocIterator cur = forward + ? bv->cursor().selectionEnd() + : bv->cursor().selectionBegin(); MatchString const match(searchstr, case_sens, whole); @@ -278,7 +264,8 @@ pair replaceOne(BufferView * bv, docstring searchstr, cap::replaceSelectionWithString(cur, replacestr); if (forward) { cur.pos() += replacestr.length(); - LASSERT(cur.pos() <= cur.lastpos(), /* */); + LASSERT(cur.pos() <= cur.lastpos(), + cur.pos() = cur.lastpos()); } if (findnext) findOne(bv, searchstr, case_sens, whole, forward, false); @@ -377,7 +364,7 @@ bool lyxreplace(BufferView * bv, Buffer const & buf = bv->buffer(); if (!update) { // emit message signal. - buf.message(_("String not found!")); + buf.message(_("String not found.")); } else { if (replace_count == 0) { buf.message(_("String found.")); @@ -395,40 +382,41 @@ bool lyxreplace(BufferView * bv, if (findOne(bv, search, casesensitive, matchword, forward)) update = true; else - bv->message(_("String not found!")); + bv->message(_("String not found.")); } return update; } -bool findNextChange(BufferView * bv) +namespace { +bool findChange(DocIterator & cur, bool next) { - return findChange(bv, true); -} - + if (!next) + cur.backwardPos(); + for (; cur; next ? cur.forwardPos() : cur.backwardPos()) + if (cur.inTexted() && cur.paragraph().isChanged(cur.pos())) { + if (!next) + // if we search backwards, take a step forward + // to correctly set the anchor + cur.forwardPos(); + return true; + } -bool findPreviousChange(BufferView * bv) -{ - return findChange(bv, false); + return false; } 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().normalAnchor())) - bv->cursor().setCursorToAnchor(); - } - - DocIterator cur = bv->cursor(); + Cursor cur(*bv); + cur.setCursor(next ? bv->cursor().selectionEnd() + : bv->cursor().selectionBegin()); // Are we within a change ? Then first search forward (backward), // clear the selection and search the other way around (see the end // of this function). This will avoid changes to be selected half. bool search_both_sides = false; - DocIterator tmpcur = cur; + Cursor tmpcur = cur; // Leave math first while (tmpcur.inMathed()) tmpcur.pop_back(); @@ -447,24 +435,24 @@ bool findChange(BufferView * bv, bool next) if (!findChange(cur, next)) return false; - bv->cursor().setCursor(cur); - bv->cursor().resetAnchor(); + bv->mouseSetCursor(cur, false); + + CursorSlice & tip = cur.top(); if (!next) // take a step into the change - cur.backwardPos(); + tip.backwardPos(); - Change orig_change = cur.paragraph().lookupChange(cur.pos()); + Change orig_change = tip.paragraph().lookupChange(tip.pos()); - CursorSlice & tip = cur.top(); if (next) { - for (; !tip.at_end(); tip.forwardPos()) { + for (; tip.pit() < tip.lastpit() || tip.pos() < tip.lastpos(); tip.forwardPos()) { Change change = tip.paragraph().lookupChange(tip.pos()); if (!change.isSimilarTo(orig_change)) break; } } else { - for (; !tip.at_begin();) { + for (; tip.pit() > 0 || tip.pos() > 0;) { tip.backwardPos(); Change change = tip.paragraph().lookupChange(tip.pos()); if (!change.isSimilarTo(orig_change)) { @@ -475,17 +463,30 @@ bool findChange(BufferView * bv, bool next) } } - // Now put cursor to end of selection: - bv->cursor().setCursor(cur); - bv->cursor().setSelection(); - - if (search_both_sides) { - bv->cursor().setSelection(false); + if (!search_both_sides) { + // Now set the selection. + bv->mouseSetCursor(cur, true); + } else { + bv->mouseSetCursor(cur, false); findChange(bv, !next); } return true; } +} + + +bool findNextChange(BufferView * bv) +{ + return findChange(bv, true); +} + + +bool findPreviousChange(BufferView * bv) +{ + return findChange(bv, false); +} + namespace { @@ -495,54 +496,62 @@ typedef vector > Escapes; /// @note Beware of order Escapes const & get_regexp_escapes() { + typedef std::pair P; + static Escapes escape_map; if (escape_map.empty()) { - escape_map.push_back(pair("$", "_x_$")); - escape_map.push_back(pair("{", "_x_{")); - escape_map.push_back(pair("}", "_x_}")); - escape_map.push_back(pair("[", "_x_[")); - escape_map.push_back(pair("]", "_x_]")); - escape_map.push_back(pair("(", "_x_(")); - escape_map.push_back(pair(")", "_x_)")); - escape_map.push_back(pair("+", "_x_+")); - escape_map.push_back(pair("*", "_x_*")); - escape_map.push_back(pair(".", "_x_.")); - escape_map.push_back(pair("\\", "(?:\\\\|\\\\backslash)")); - escape_map.push_back(pair("~", "(?:\\\\textasciitilde|\\\\sim)")); - escape_map.push_back(pair("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)")); - escape_map.push_back(pair("_x_", "\\")); + escape_map.push_back(P("$", "_x_$")); + escape_map.push_back(P("{", "_x_{")); + escape_map.push_back(P("}", "_x_}")); + escape_map.push_back(P("[", "_x_[")); + escape_map.push_back(P("]", "_x_]")); + escape_map.push_back(P("(", "_x_(")); + escape_map.push_back(P(")", "_x_)")); + escape_map.push_back(P("+", "_x_+")); + escape_map.push_back(P("*", "_x_*")); + escape_map.push_back(P(".", "_x_.")); + escape_map.push_back(P("\\", "(?:\\\\|\\\\backslash)")); + escape_map.push_back(P("~", "(?:\\\\textasciitilde|\\\\sim)")); + escape_map.push_back(P("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)")); + escape_map.push_back(P("_x_", "\\")); } return escape_map; } /// A map of lyx escaped strings and their unescaped equivalent. -Escapes const & get_lyx_unescapes() { +Escapes const & get_lyx_unescapes() +{ + typedef std::pair P; + static Escapes escape_map; if (escape_map.empty()) { - escape_map.push_back(pair("\\%", "%")); - escape_map.push_back(pair("\\mathcircumflex ", "^")); - escape_map.push_back(pair("\\mathcircumflex", "^")); - escape_map.push_back(pair("\\backslash ", "\\")); - escape_map.push_back(pair("\\backslash", "\\")); - escape_map.push_back(pair("\\\\{", "_x_<")); - escape_map.push_back(pair("\\\\}", "_x_>")); - escape_map.push_back(pair("\\sim ", "~")); - escape_map.push_back(pair("\\sim", "~")); + escape_map.push_back(P("\\%", "%")); + escape_map.push_back(P("\\mathcircumflex ", "^")); + escape_map.push_back(P("\\mathcircumflex", "^")); + escape_map.push_back(P("\\backslash ", "\\")); + escape_map.push_back(P("\\backslash", "\\")); + escape_map.push_back(P("\\\\{", "_x_<")); + escape_map.push_back(P("\\\\}", "_x_>")); + escape_map.push_back(P("\\sim ", "~")); + escape_map.push_back(P("\\sim", "~")); } return escape_map; } /// A map of escapes turning a regexp matching text to one matching latex. -Escapes const & get_regexp_latex_escapes() { +Escapes const & get_regexp_latex_escapes() +{ + typedef std::pair P; + static Escapes escape_map; if (escape_map.empty()) { - escape_map.push_back(pair("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\})")); - escape_map.push_back(pair("(("(("\\[", "\\{\\[\\}")); - escape_map.push_back(pair("\\]", "\\{\\]\\}")); - escape_map.push_back(pair("\\^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)")); - escape_map.push_back(pair("%", "\\\\\\%")); + escape_map.push_back(P("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\})")); + escape_map.push_back(P("( 0 && t[0] == '\n') + while (!t.empty() && t[0] == '\n') t = t.substr(1); // Remove \n at end - while (t.size() > 0 && t[t.size() - 1] == '\n') + while (!t.empty() && t[t.size() - 1] == '\n') t = t.substr(0, t.size() - 1); size_t pos; // Replace all other \n with spaces @@ -1038,7 +1062,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.params().isLatex(), /* */); + LBUFERR(buf.params().isLatex()); TexRow texrow; odocstringstream ods; @@ -1115,7 +1139,7 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match) cur.forwardPos(); } while (cur && cur.depth() > d && match(cur) > 0); cur = old_cur; - LASSERT(match(cur) > 0, /* */); + LASSERT(match(cur) > 0, return 0); LYXERR(Debug::FIND, "Ok"); // Compute the match length @@ -1203,7 +1227,8 @@ int findMostBackwards(DocIterator & cur, MatchStringAdv const & match) /// Finds backwards -int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { +int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) +{ if (! cur) return 0; // Backup of original position @@ -1258,7 +1283,8 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { docstring stringifyFromForSearch(FindAndReplaceOptions const & opt, DocIterator const & cur, int len) { - LASSERT(cur.pos() >= 0 && cur.pos() <= cur.lastpos(), /* */); + LASSERT(cur.pos() >= 0 && cur.pos() <= cur.lastpos(), + return docstring()); if (!opt.ignoreformat) return latexifyFromCursor(cur, len); else @@ -1282,7 +1308,8 @@ namespace { /** Check if 'len' letters following cursor are all non-lowercase */ -static bool allNonLowercase(DocIterator const & cur, int len) { +static bool allNonLowercase(DocIterator const & cur, int len) +{ pos_type end_pos = cur.pos() + len; for (pos_type pos = cur.pos(); pos != end_pos; ++pos) if (isLowerCase(cur.paragraph().getChar(pos))) @@ -1292,7 +1319,8 @@ static bool allNonLowercase(DocIterator const & cur, int len) { /** Check if first letter is upper case and second one is lower case */ -static bool firstUppercase(DocIterator const & cur) { +static bool firstUppercase(DocIterator const & cur) +{ char_type ch1, ch2; if (cur.pos() >= cur.lastpos() - 1) { LYXERR(Debug::FIND, "No upper-case at cur: " << cur); @@ -1313,13 +1341,15 @@ static bool firstUppercase(DocIterator const & cur) { ** ** \fixme What to do with possible further paragraphs in replace buffer ? **/ -static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase others_case) { +static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase others_case) +{ ParagraphList::iterator pit = buffer.paragraphs().begin(); pos_type right = pos_type(1); pit->changeCase(buffer.params(), pos_type(0), right, first_case); right = pit->size() + 1; pit->changeCase(buffer.params(), right, right, others_case); } + } // anon namespace /// @@ -1339,7 +1369,7 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M << ", sel_len: " << sel_len << endl); if (sel_len == 0) return; - LASSERT(sel_len > 0, /**/); + LASSERT(sel_len > 0, return); if (!matchAdv(sel_beg, sel_len)) return; @@ -1351,7 +1381,7 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M string lyx = oss.str(); Buffer repl_buffer("", false); repl_buffer.setUnnamed(true); - LASSERT(repl_buffer.readString(lyx), /**/); + LASSERT(repl_buffer.readString(lyx), return); if (opt.keep_case && sel_len >= 2) { if (cur.inTexted()) { if (firstUppercase(cur)) @@ -1415,6 +1445,9 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) try { MatchStringAdv matchAdv(bv->buffer(), opt); + int length = bv->cursor().selectionEnd().pos() - bv->cursor().selectionBegin().pos(); + if (length > 0) + bv->putSelectionAt(bv->cursor().selectionBegin(), length, !opt.forward); findAdvReplace(bv, opt, matchAdv); cur = bv->cursor(); if (opt.forward)