bool find_del, bool check_wrap, bool const auto_wrap,
bool instant, bool onlysel)
{
+ bool const had_selection = bv->cursor().selection();
+
// Clean up previous selections with empty searchstr on instant
if (searchstr.empty() && instant) {
- if (bv->cursor().selection()) {
+ if (had_selection) {
bv->setCursor(bv->cursor().selectionBegin());
bv->clearSelection();
}
if (!searchAllowed(searchstr))
return false;
- DocIterator const endcur = forward ? bv->cursor().selectionEnd() : bv->cursor().selectionBegin();
+ DocIterator const startcur = bv->cursor().selectionBegin();
+ DocIterator const endcur = bv->cursor().selectionEnd();
- if (onlysel && bv->cursor().selection()) {
+ if (onlysel && had_selection) {
docstring const matchstring = bv->cursor().selectionAsString(false);
docstring const lcmatchsting = support::lowercase(matchstring);
if (matchstring == searchstr || (!case_sens && lcmatchsting == lowercase(searchstr))) {
int match_len = forward
? findForward(cur, endcur, match, find_del, onlysel)
- : findBackwards(cur, endcur, match, find_del, onlysel);
+ : findBackwards(cur, startcur, match, find_del, onlysel);
if (match_len > 0)
bv->putSelectionAt(cur, match_len, !forward);
- else if (onlysel && bv->cursor().selection()) {
+ else if (onlysel && had_selection) {
docstring q = _("The search string was not found within the selection.\n"
"Continue search outside?");
int search_answer = frontend::Alert::prompt(_("Search outside selection?"),
return false;
}
else if (check_wrap) {
- DocIterator cur_orig(bv->cursor());
bool wrap = auto_wrap;
if (!auto_wrap) {
docstring q;
find_del, false, false, false, false))
return true;
}
- bv->cursor().setCursor(cur_orig);
+ bv->setCursor(startcur);
+
+ // restore original selection
+ if (had_selection) {
+ bv->cursor().resetAnchor();
+ bv->setSelection(startcur, endcur);
+ }
return false;
}
if (had_selection) {
endcur.fixIfBroken();
bv->cursor().resetAnchor();
- bv->setCursorSelectionTo(endcur);
+ bv->setSelection(startcur, endcur);
}
return num;
// normal blanks
blanks++;
}
- else if ((tempx[i] == '\302' && tempx[i+1] == '\240')
- || (tempx[i] == '\342' && tempx[i+1] == '\202')) {
- // protected space
- // thin space
+ else if (tempx[i] == '\302' && tempx[i+1] == '\240') {
+ // Normal Space
blanks++;
i++;
}
+ else if (tempx[i] == '\342') {
+ if (tempx[i+1] == '\200') {
+ if ((tempx[i+2] == '\257')
+ || (tempx[i+2] == '\203')
+ || (tempx[i+2] == '\202')) {
+ // Non-breaking Thin (1/6 em)
+ // Quad(1 em), (Double quad counts as 2 blanks)
+ // Half Quad
+ blanks++;
+ i += 2;
+ }
+ else if (tempx[i+2] == '\213') {
+ // Ignoring parts of Medium and Thick
+ i += 2;
+ continue;
+ }
+ else if ((tempx[i+2] == '\204') || (tempx[i+2] == '\205')) {
+ // Thick
+ // Medium
+ blanks++;
+ i += 2;
+ }
+ }
+ else if (tempx[i+1] == '\201') {
+ if (tempx[i+2] == '\240') {
+ // Ignoring parts of half quad
+ i += 2;
+ continue;
+ }
+ }
+ else if ((tempx[i+1] == '\220') && (tempx[i+2] == '\243')) {
+ // Visible space
+ blanks++;
+ i += 2;
+ }
+ }
else {
if (blanks > 0) {
temp += getRegexSpaceCount(blanks);
}
else if (sub.str(4) == "mathcircumflex")
replace = "^";
+ else if ((sub.str(4) == "negthinspace") || (sub.str(4) == "negmedspace") || (sub.str(4) == "negthickspace")) {
+ replace = accents[sub.str(4)+"{}"];
+ }
else if (backslashed) {
backslashed = false;
if (withformat) {
return add;
}
+static bool isPartOfMath(Paragraph const & par)
+{
+ if (par.size() < 1)
+ return false;
+ const Inset * isInset = par.getInset(par.size()-1);
+ if (isInset == nullptr)
+ return false;
+ return isInset->inMathed();
+}
+
static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions const & opt)
{
docstring str;
runparams.find_add_feature(OutputParams::SearchNonOutput);
}
string t("");
+ // Only check if the very last entry is inside math to remove trailing space
+ bool isMathInset = false;
for (pos_type pit = pos_type(0); pit < (pos_type)buffer.paragraphs().size(); ++pit) {
Paragraph const & par = buffer.paragraphs().at(pit);
string add = latexNamesToUtf8(par.asString(pos_type(0), par.size(),
LYXERR(Debug::FINDVERBOSE, "Adding to search string: '"
<< add << "'");
t += add;
+ isMathInset = isPartOfMath(par);
}
// Even in ignore-format we have to remove "\text{}, \lyxmathsym{}" parts
while (regex_replace(t, t, "\\\\(text|lyxmathsym|ensuremath)\\{([^\\}]*)\\}", "$2"));
- str = from_utf8(t);
+ // remove trailing space, it may have been added by plaintext() in InsetMathHull.cpp
+ size_t t_size = t.size();
+ if (opt.ignoreformat && (t_size > 1) && (t[t_size-1] == ' ') && isMathInset)
+ str = from_utf8(t.substr(0, t_size-1));
+ else
+ str = from_utf8(t);
}
return str;
}
accents["guillemotleft"] = "«";
accents["hairspace"] = getutf8(0xf0000); // select from free unicode plane 15
accents["thinspace"] = getutf8(0xf0002); // and used _only_ by findadv
- accents["negthinspace"] = getutf8(0xf0003); // to omit backslashed latex macros
+ accents["negthinspace{}"]= getutf8(0xf0003); // to omit backslashed latex macros
accents["medspace"] = getutf8(0xf0004); // See https://en.wikipedia.org/wiki/Private_Use_Areas
- accents["negmedspace"] = getutf8(0xf0005);
+ accents["negmedspace{}"] = getutf8(0xf0005);
accents["thickspace"] = getutf8(0xf0006);
- accents["negthickspace"] = getutf8(0xf0007);
+ accents["negthickspace{}"]= getutf8(0xf0007);
accents["lyx"] = getutf8(0xf0010); // Used logos
accents["LyX"] = getutf8(0xf0010);
accents["tex"] = getutf8(0xf0011);
if (accents.empty())
buildAccentsMap();
static regex const accre("\\\\("
- "([\\S]|[A-Za-z]+)\\{[^\\\\\\{\\}]+\\}"
+ "([\\S]|[A-Za-z]+)\\{[^\\\\\\{\\}]*\\}"
"|([\\S]|[A-Za-z]+)\\{\\\\[ij](math)?\\}"
"|("
"(backslash ([lL]y[xX]|[tT]e[xX]|[lL]a[tT]e[xX]e?|lyxarrow))"
return(t.str());
}
+static string showPos(DocIterator const & cur)
+{
+ stringstream a;
+ string inmath;
+ if (cur.inMathed())
+ inmath = "inMath";
+ else
+ inmath = "inText";
+
+ a << "[idx(" << cur.idx() << "),pit(" << cur.pit() << "),pos(" << cur.pos() << "),depth(" << cur.depth() << ") " << inmath << ")]";
+ return(a.str());
+}
+
docstring stringifyFromCursor(DocIterator const & cur, int len)
{
- LYXERR(Debug::FINDVERBOSE, "Stringifying with len=" << len << " from cursor at pos: " << cur);
+ LYXERR(Debug::FINDVERBOSE, "Stringifying with len=" << len << " from cursor at " << showPos(cur));
if (cur.inTexted()) {
Paragraph const & par = cur.paragraph();
// TODO what about searching beyond/across paragraph breaks ?
if (ignoreFormats.getNonContent()) {
runparams.find_add_feature(OutputParams::SearchNonOutput);
}
- LYXERR(Debug::FINDVERBOSE, "Stringifying with cur: "
- << cur << ", from pos: " << cur.pos() << ", end: " << end);
+ LYXERR(Debug::FINDVERBOSE, "Stringifying with cur = "
+ << showPos(cur) << ", to end: " << end);
docstring res = from_utf8(latexNamesToUtf8(par.asString(cur.pos(), end,
option,
&runparams), false));
- LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Stringified text from pos(" << cur.pos() << ") len(" << len << "): " << res);
+ LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Stringified text from " << showPos(cur) << " len(" << len << "): " << res);
return res;
} else if (cur.inMathed()) {
CursorSlice cs = cur.top();
(( len == -1 || cs.pos() + len > int(md.size()))
? md.end()
: md.begin() + cs.pos() + len );
- MathData md2;
+ MathData md2(cur.buffer());
for (MathData::const_iterator it = md.begin() + cs.pos(); it != it_end; ++it)
md2.push_back(*it);
docstring res = from_utf8(latexNamesToUtf8(asString(md2), false));
LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Stringified math from pos(" << cur.pos() << ") len(" << len << "): " << res);
return res;
}
- LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Don't know how to stringify from here: " << cur);
+ LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Don't know how to stringify from here: " << showPos(cur));
return docstring();
}
docstring latexifyFromCursor(DocIterator const & cur, int len)
{
/*
- LYXERR(Debug::FINDVERBOSE, "Latexifying with len=" << len << " from cursor at pos: " << cur);
+ LYXERR(Debug::FINDVERBOSE, "Latexifying with len=" << len << " from cursor at " << showPos(cur));
LYXERR(Debug::FINDVERBOSE, " with cur.lastpost=" << cur.lastpos() << ", cur.lastrow="
<< cur.lastrow() << ", cur.lastcol=" << cur.lastcol());
*/
endpos = cur.pos() + len;
TeXOnePar(buf, *cur.innerText(), cur.pit(), os, runparams,
string(), cur.pos(), endpos, true);
- LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Latexified text from pos(" << cur.pos() << ") len(" << len << "): " << ods.str());
+ LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Latexified text from " << showPos(cur) << ods.str());
return(ods.str());
} else if (cur.inMathed()) {
// Retrieve the math environment type, and add '$' or '$[' or others (\begin{equation}) accordingly
((len == -1 || cs.pos() + len > int(md.size()))
? md.end()
: md.begin() + cs.pos() + len);
- MathData md2;
+ MathData md2(cur.buffer());
for (MathData::const_iterator it = md.begin() + cs.pos();
it != it_end; ++it)
md2.push_back(*it);
}
LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Latexified math from pos(" << cur.pos() << ") len(" << len << "): " << ods.str());
} else {
- LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Don't know how to stringify from here: " << cur);
+ LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Don't know how to stringify from here: " << showPos(cur));
}
return ods.str();
}
do {
orig_cur = cur;
cur.forwardPos();
- } while (cur.depth() > orig_cur.depth());
+ } while (cur.depth() > orig_cur.depth() && !cur.inMathed());
cur = orig_cur;
while (!theApp()->longOperationCancelled() && cur) {
//(void) findAdvForwardInnermost(cur);
- LYXERR(Debug::FINDVERBOSE, "findForwardAdv() cur: " << cur);
+ LYXERR(Debug::FINDVERBOSE, "findForwardAdv() cur: " << showPos(cur));
MatchResult mres = match(cur, -1, MatchStringAdv::MatchAnyPlace);
string msg = "Starting";
if (repeat > 0)
// This should exit nested insets, if any, or otherwise undefine the currsor.
cur.pos() = cur.lastpos();
}
- LYXERR(Debug::FINDVERBOSE, "Advancing pos: cur=" << cur);
+ LYXERR(Debug::FINDVERBOSE, "Advancing pos: cur=" << showPos(cur));
cur.forwardPos();
}
else { // match_len > 0
MatchResult mr = findAdvFinalize(tmp_cur, match, expected);
Inset & inset = cur.inset();
for (; cur != cur_begin; cur.backwardPos()) {
- LYXERR(Debug::FINDVERBOSE, "findMostBackwards(): cur=" << cur);
+ LYXERR(Debug::FINDVERBOSE, "findMostBackwards(): cur=" << showPos(cur));
DocIterator new_cur = cur;
new_cur.backwardPos();
if (new_cur == cur || &new_cur.inset() != &inset
break;
mr = new_mr;
}
- LYXERR(Debug::FINDVERBOSE, "findMostBackwards(): exiting with cur=" << cur);
+ LYXERR(Debug::FINDVERBOSE, "findMostBackwards(): exiting with cur=" << showPos(cur));
return mr;
}
cur.pos() = cur.lastpos();
else
cur.pos() = cur_orig.pos();
- LYXERR(Debug::FINDVERBOSE, "findBackAdv2: cur: " << cur);
+ LYXERR(Debug::FINDVERBOSE, "findBackAdv2: cur: " << showPos(cur));
DocIterator cur_prev_iter;
do {
found_match = match(cur, -1, MatchStringAdv::MatchFromStart);
LYXERR(Debug::FINDVERBOSE, "findBackAdv3: found_match="
- << (found_match.match_len > 0) << ", cur: " << cur);
+ << (found_match.match_len > 0) << ", cur: " << showPos(cur));
if (found_match.match_len > 0) {
MatchResult found_mr = findMostBackwards(cur, match, found_match);
if (found_mr.pos_len > 0) {
char_type ch1, ch2;
pos_type pos = cur.selectionBegin().pos();
if (pos >= cur.lastpos() - 1) {
- LYXERR(Debug::FINDVERBOSE, "No upper-case at cur: " << cur);
+ LYXERR(Debug::FINDVERBOSE, "No upper-case at cur: " << showPos(cur));
return false;
}
ch1 = cur.paragraph().getChar(pos);
repl_buffer.language(),
cur.getFont().language());
LYXERR(Debug::FINDVERBOSE, "Replacing by pasteParagraphList()ing repl_buffer");
- LYXERR(Debug::FINDVERBOSE, "Before pasteParagraphList() cur=" << cur << endl);
+ LYXERR(Debug::FINDVERBOSE, "Before pasteParagraphList() cur=" << showPos(cur) << endl);
cap::pasteParagraphList(cur, repl_buffer.paragraphs(),
repl_buffer.params().documentClassPtr(),
repl_buffer.params().authors(),
bv->buffer().errorList("Paste"));
- LYXERR(Debug::FINDVERBOSE, "After pasteParagraphList() cur=" << cur << endl);
+ LYXERR(Debug::FINDVERBOSE, "After pasteParagraphList() cur=" << showPos(cur) << endl);
sel_len = repl_buffer.paragraphs().begin()->size();
} else if (cur.inMathed()) {
odocstringstream ods;
(void)regex_replace(to_utf8(repl_latex), s, "\\$(.*)\\$", "$1");
(void)regex_replace(s, s, "\\\\\\[(.*)\\\\\\]", "$1");
repl_latex = from_utf8(s);
- LYXERR(Debug::FINDVERBOSE, "Replacing by insert()ing latex: '" << repl_latex << "' cur=" << cur << " with depth=" << cur.depth());
+ LYXERR(Debug::FINDVERBOSE, "Replacing by insert()ing latex: '" << repl_latex << "' cur=" << showPos(cur) );
MathData ar(cur.buffer());
asArray(repl_latex, ar, Parse::NORMAL);
cur.insert(ar);
sel_len = ar.size();
- LYXERR(Debug::FINDVERBOSE, "After insert() cur=" << cur << " with depth: " << cur.depth() << " and len: " << sel_len);
+ LYXERR(Debug::FINDVERBOSE, "After insert() cur=" << showPos(cur) << " and len: " << sel_len);
}
if (cur.pos() >= sel_len)
cur.pos() -= sel_len;
else
cur.pos() = 0;
- LYXERR(Debug::FINDVERBOSE, "After pos adj cur=" << cur << " with depth: " << cur.depth() << " and len: " << sel_len);
+ LYXERR(Debug::FINDVERBOSE, "After pos adj cur=" << showPos(cur) << " and len: " << sel_len);
bv->putSelectionAt(DocIterator(cur), sel_len, !opt.forward);
bv->processUpdateFlags(Update::Force);
return 1;
MathData md = cs.cell();
int len = -1;
MathData::const_iterator it_end = md.end();
- MathData md2;
+ MathData md2(cur.buffer());
// Start the check with one character before actual cursor position
for (MathData::const_iterator it = md.begin() + cs.pos() - 1;
it != it_end; ++it)
// Should never happen, maybe LASSERT() here?
pos_len = cur.lastpos() - cur.pos();
}
- LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Putting selection at cur=" << cur << " with len: " << pos_len);
+ LYXERR(Debug::FINDVERBOSE|Debug::FIND, "Putting selection at cur=" << showPos(cur) << " with len: " << pos_len);
bv->putSelectionAt(cur, pos_len, !opt.forward);
return true;