#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"
}
-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()) {
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);
// no selection, non-empty search string: find it
if (!searchstr.empty()) {
findOne(bv, searchstr, case_sens, whole, forward);
- return pair<bool, int>(true, 0);
+ return make_pair(true, 0);
}
// empty search string
if (!cur.inTexted())
// bail in math
- return pair<bool, int>(false, 0);
+ return make_pair(false, 0);
// select current word and treat it as the search string
cur.innerText()->selectWord(cur, WHOLE_WORD);
searchstr = cur.selectionAsString(false);
// if we still don't have a search string, report the error
// and abort.
if (!searchAllowed(searchstr))
- return pair<bool, int>(false, 0);
+ return make_pair(false, 0);
bool have_selection = cur.selection();
docstring const selected = cur.selectionAsString(false);
// just find the search word
if (!have_selection || !match) {
findOne(bv, searchstr, case_sens, whole, forward);
- return pair<bool, int>(true, 0);
+ return make_pair(true, 0);
}
// we're now actually ready to replace. if the buffer is
// read-only, we can't, though.
if (bv->buffer().isReadonly())
- return pair<bool, int>(false, 0);
+ return make_pair(false, 0);
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);
- return pair<bool, int>(true, 1);
+ return make_pair(true, 1);
}
} // namespace anon
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."));
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();
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)) {
}
}
- // 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 {
/// @note Beware of order
Escapes const & get_regexp_escapes()
{
+ typedef std::pair<std::string, std::string> P;
+
static Escapes escape_map;
if (escape_map.empty()) {
- escape_map.push_back(pair<string, string>("$", "_x_$"));
- escape_map.push_back(pair<string, string>("{", "_x_{"));
- escape_map.push_back(pair<string, string>("}", "_x_}"));
- escape_map.push_back(pair<string, string>("[", "_x_["));
- escape_map.push_back(pair<string, string>("]", "_x_]"));
- escape_map.push_back(pair<string, string>("(", "_x_("));
- escape_map.push_back(pair<string, string>(")", "_x_)"));
- escape_map.push_back(pair<string, string>("+", "_x_+"));
- escape_map.push_back(pair<string, string>("*", "_x_*"));
- escape_map.push_back(pair<string, string>(".", "_x_."));
- escape_map.push_back(pair<string, string>("\\", "(?:\\\\|\\\\backslash)"));
- escape_map.push_back(pair<string, string>("~", "(?:\\\\textasciitilde|\\\\sim)"));
- escape_map.push_back(pair<string, string>("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)"));
- escape_map.push_back(pair<string, string>("_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<std::string, std::string> P;
+
static Escapes escape_map;
if (escape_map.empty()) {
- escape_map.push_back(pair<string, string>("\\%", "%"));
- escape_map.push_back(pair<string, string>("\\mathcircumflex ", "^"));
- escape_map.push_back(pair<string, string>("\\mathcircumflex", "^"));
- escape_map.push_back(pair<string, string>("\\backslash ", "\\"));
- escape_map.push_back(pair<string, string>("\\backslash", "\\"));
- escape_map.push_back(pair<string, string>("\\\\{", "_x_<"));
- escape_map.push_back(pair<string, string>("\\\\}", "_x_>"));
- escape_map.push_back(pair<string, string>("\\sim ", "~"));
- escape_map.push_back(pair<string, string>("\\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<std::string, std::string> P;
+
static Escapes escape_map;
if (escape_map.empty()) {
- escape_map.push_back(pair<string, string>("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\})"));
- escape_map.push_back(pair<string, string>("(<?!\\\\\\\\textbackslash)\\{", "\\\\\\{"));
- escape_map.push_back(pair<string, string>("(<?!\\\\\\\\textbackslash\\\\\\{)\\}", "\\\\\\}"));
- escape_map.push_back(pair<string, string>("\\[", "\\{\\[\\}"));
- escape_map.push_back(pair<string, string>("\\]", "\\{\\]\\}"));
- escape_map.push_back(pair<string, string>("\\^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)"));
- escape_map.push_back(pair<string, string>("%", "\\\\\\%"));
+ escape_map.push_back(P("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\})"));
+ escape_map.push_back(P("(<?!\\\\\\\\textbackslash)\\{", "\\\\\\{"));
+ escape_map.push_back(P("(<?!\\\\\\\\textbackslash\\\\\\{)\\}", "\\\\\\}"));
+ escape_map.push_back(P("\\[", "\\{\\[\\}"));
+ escape_map.push_back(P("\\]", "\\{\\]\\}"));
+ escape_map.push_back(P("\\^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)"));
+ escape_map.push_back(P("%", "\\\\\\%"));
}
return escape_map;
}
return s;
}
+
/// Wrapper for lyx::regex_replace with simpler interface
bool regex_replace(string const & s, string & t, string const & searchstr,
string const & replacestr)
return rv;
}
+
/** Checks if supplied string segment is well-formed from the standpoint of matching open-closed braces.
**
** Verify that closed braces exactly match open braces. This avoids that, for example,
return true;
}
+
/** The class performing a match between a position in the document and the FindAdvOptions.
**/
class MatchStringAdv {
}
-static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions const & opt) {
+static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions const & opt)
+{
docstring str;
if (!opt.ignoreformat) {
str = buffer_to_latex(buffer);
/// Return separation pos between the leading material and the rest
-static size_t identifyLeading(string const & s) {
+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)\\*?\\{", "")
// Remove trailing closure of math, macros and environments, so to catch parts of them.
-static int identifyClosing(string & t) {
+static int identifyClosing(string & t)
+{
int open_braces = 0;
do {
LYXERR(Debug::FIND, "identifyClosing(): t now is '" << t << "'");
close_wildcards = 0;
size_t lead_size = 0;
- if (!opt.ignoreformat) {
+ if (opt.ignoreformat) {
+ if (!use_regexp) {
+ // if par_as_string_nolead were emty,
+ // the following call to findAux will always *find* the string
+ // in the checked data, and thus always using the slow
+ // examining of the current text part.
+ par_as_string_nolead = par_as_string;
+ }
+ }
+ else {
lead_size = identifyLeading(par_as_string);
lead_as_string = par_as_string.substr(0, lead_size);
par_as_string_nolead = par_as_string.substr(lead_size, par_as_string.size() - lead_size);
else
t = lyx::to_utf8(s);
// Remove \n at begin
- while (t.size() > 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
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;
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
/// Finds backwards
-int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) {
+int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match)
+{
if (! cur)
return 0;
// Backup of original position
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
/** 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)))
/** 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);
**
** \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
///
<< ", 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;
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))
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)