From 5387379c241a5b68e46c469a14fc1556ee513459 Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Sun, 21 Jun 2009 14:30:57 +0000 Subject: [PATCH] Introduce Paragraph::isWordSeparator() and use it instead of Paragraph::isLetter(). Note here a change in behavior WRT to word selection: a deleted character is not considered a word separator. This new behavior will impact word finding and spellchecking. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30211 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Buffer.cpp | 6 +++--- src/DocIterator.cpp | 2 +- src/Paragraph.cpp | 28 +++++++++++++--------------- src/Paragraph.h | 6 +++--- src/Text.cpp | 32 ++++++++++++++++---------------- src/buffer_funcs.cpp | 5 +++-- 6 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index ed16070424..b207258041 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -3379,12 +3379,12 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to, string lang_code; // Go backward a bit if needed in order to return the word currently // pointed by 'from'. - while (from && from.pos() && isLetter(from)) + while (from && from.pos() && !isWordSeparator(from)) from.backwardPos(); // OK, we start from here. to = from; while (to.depth()) { - if (isLetter(to)) { + if (!isWordSeparator(to)) { if (!inword) { inword = true; ignoreword = false; @@ -3401,7 +3401,7 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to, if (isDigit(c)) ignoreword = true; } - } else { // !isLetter(cur) + } else { // !isWordSeparator(cur) if (inword && !word.empty() && !ignoreword) return true; inword = false; diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index 6115bf2879..464152c4b2 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -612,7 +612,7 @@ bool operator==(StableDocIterator const & dit1, StableDocIterator const & dit2) bool isLetter(DocIterator const & dit) { - return dit.inTexted() && dit.paragraph().isLetter(dit.pos()); + return dit.inTexted() && !dit.paragraph().isWordSeparator(dit.pos()); } } // namespace lyx diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 1a89df078a..15bf855ef6 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -2464,17 +2464,15 @@ bool Paragraph::isLineSeparator(pos_type pos) const } -/// Used by the spellchecker -bool Paragraph::isLetter(pos_type pos) const +bool Paragraph::isWordSeparator(pos_type pos) const { if (Inset const * inset = getInset(pos)) - return inset->isLetter(); + return !inset->isLetter(); char_type const c = d->text_[pos]; // We want to pass the ' and escape chars to the spellchecker static docstring const quote = from_utf8(lyxrc.spellchecker_esc_chars + '\''); - return (isLetterChar(c) || isDigit(c) || contains(quote, c)) - && pos != size() - && !isDeleted(pos); + return (!isLetterChar(c) && !isDigit(c) && !contains(quote, c)) + || pos == size(); } @@ -2885,7 +2883,7 @@ void Paragraph::changeCase(BufferParams const & bparams, pos_type pos, } } - if (!isLetter(pos) || isDeleted(pos)) { + if (isWordSeparator(pos) || isDeleted(pos)) { // permit capitalization again capitalize = true; } @@ -2938,10 +2936,10 @@ bool Paragraph::find(docstring const & str, bool cs, bool mw, // if necessary, check whether string matches word if (mw) { - if (pos > 0 && isLetter(pos - 1)) + if (pos > 0 && !isWordSeparator(pos - 1)) return false; if (pos + strsize < parsize - && isLetter(pos + strsize)) + && !isWordSeparator(pos + strsize)) return false; } @@ -2996,8 +2994,8 @@ void Paragraph::locateWord(pos_type & from, pos_type & to, switch (loc) { case WHOLE_WORD_STRICT: if (from == 0 || from == size() - || !isLetter(from) - || !isLetter(from - 1)) { + || isWordSeparator(from) + || isWordSeparator(from - 1)) { to = from; return; } @@ -3005,13 +3003,13 @@ void Paragraph::locateWord(pos_type & from, pos_type & to, case WHOLE_WORD: // If we are already at the beginning of a word, do nothing - if (!from || !isLetter(from - 1)) + if (!from || isWordSeparator(from - 1)) break; // no break here, we go to the next case PREVIOUS_WORD: // always move the cursor to the beginning of previous word - while (from && isLetter(from - 1)) + while (from && !isWordSeparator(from - 1)) --from; break; case NEXT_WORD: @@ -3022,7 +3020,7 @@ void Paragraph::locateWord(pos_type & from, pos_type & to, break; } to = from; - while (to < size() && isLetter(to)) + while (to < size() && !isWordSeparator(to)) ++to; } @@ -3034,7 +3032,7 @@ void Paragraph::collectWords() //lyxerr << "Words: "; pos_type n = size(); for (pos_type pos = 0; pos < n; ++pos) { - if (!isLetter(pos)) + if (isWordSeparator(pos)) continue; pos_type from = pos; locateWord(from, pos, WHOLE_WORD); diff --git a/src/Paragraph.h b/src/Paragraph.h index c256faf4fc..eeb4748bba 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -362,9 +362,9 @@ public: bool isSeparator(pos_type pos) const; /// bool isLineSeparator(pos_type pos) const; - /// True if the character/inset at this point can be part of a word. - /// Note that digits in particular are considered as letters - bool isLetter(pos_type pos) const; + /// True if the character/inset at this point is a word separator. + /// Note that digits in particular are not considered as word separator. + bool isWordSeparator(pos_type pos) const; /// True if the element at this point is a character that is not a letter. bool isChar(pos_type pos) const; /// True if the element at this point is a space diff --git a/src/Text.cpp b/src/Text.cpp index c758008d53..7cc44d9901 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -574,8 +574,8 @@ void Text::charInserted(Cursor & cur) // register word if a non-letter was entered if (cur.pos() > 1 - && par.isLetter(cur.pos() - 2) - && !par.isLetter(cur.pos() - 1)) { + && !par.isWordSeparator(cur.pos() - 2) + && par.isWordSeparator(cur.pos() - 1)) { // get the word in front of cursor LASSERT(this == cur.text(), /**/); cur.paragraph().updateWords(); @@ -609,14 +609,14 @@ bool Text::cursorForwardOneWord(Cursor & cur) ++pos; // Skip over either a non-char inset or a full word - if (pos != lastpos && !par.isLetter(pos)) + if (pos != lastpos && par.isWordSeparator(pos)) ++pos; - else while (pos != lastpos && par.isLetter(pos)) + else while (pos != lastpos && !par.isWordSeparator(pos)) ++pos; } else { LASSERT(pos < lastpos, /**/); // see above - if (par.isLetter(pos)) - while (pos != lastpos && par.isLetter(pos)) + if (!par.isWordSeparator(pos)) + while (pos != lastpos && !par.isWordSeparator(pos)) ++pos; else if (par.isChar(pos)) while (pos != lastpos && par.isChar(pos)) @@ -651,17 +651,17 @@ bool Text::cursorBackwardOneWord(Cursor & cur) --pos; // Skip over either a non-char inset or a full word - if (pos != 0 && !par.isLetter(pos - 1) && !par.isChar(pos - 1)) + if (pos != 0 && par.isWordSeparator(pos - 1) && !par.isChar(pos - 1)) --pos; - else while (pos != 0 && par.isLetter(pos - 1)) + else while (pos != 0 && !par.isWordSeparator(pos - 1)) --pos; } else { // Skip over white space while (pos != 0 && par.isSpace(pos - 1)) --pos; - if (pos != 0 && par.isLetter(pos - 1)) - while (pos != 0 && par.isLetter(pos - 1)) + if (pos != 0 && !par.isWordSeparator(pos - 1)) + while (pos != 0 && !par.isWordSeparator(pos - 1)) --pos; else if (pos != 0 && par.isChar(pos - 1)) while (pos != 0 && par.isChar(pos - 1)) @@ -689,9 +689,9 @@ bool Text::cursorVisLeftOneWord(Cursor & cur) // collect some information about current cursor position temp_cur.getSurroundingPos(left_pos, right_pos); left_is_letter = - (left_pos > -1 ? temp_cur.paragraph().isLetter(left_pos) : false); + (left_pos > -1 ? !temp_cur.paragraph().isWordSeparator(left_pos) : false); right_is_letter = - (right_pos > -1 ? temp_cur.paragraph().isLetter(right_pos) : false); + (right_pos > -1 ? !temp_cur.paragraph().isWordSeparator(right_pos) : false); // if we're not at a letter/non-letter boundary, continue moving if (left_is_letter == right_is_letter) @@ -726,9 +726,9 @@ bool Text::cursorVisRightOneWord(Cursor & cur) // collect some information about current cursor position temp_cur.getSurroundingPos(left_pos, right_pos); left_is_letter = - (left_pos > -1 ? temp_cur.paragraph().isLetter(left_pos) : false); + (left_pos > -1 ? !temp_cur.paragraph().isWordSeparator(left_pos) : false); right_is_letter = - (right_pos > -1 ? temp_cur.paragraph().isLetter(right_pos) : false); + (right_pos > -1 ? !temp_cur.paragraph().isWordSeparator(right_pos) : false); // if we're not at a letter/non-letter boundary, continue moving if (left_is_letter == right_is_letter) @@ -1611,8 +1611,8 @@ bool Text::completionSupported(Cursor const & cur) const { Paragraph const & par = cur.paragraph(); return cur.pos() > 0 - && (cur.pos() >= par.size() || !par.isLetter(cur.pos())) - && par.isLetter(cur.pos() - 1); + && (cur.pos() >= par.size() || par.isWordSeparator(cur.pos())) + && !par.isWordSeparator(cur.pos() - 1); } diff --git a/src/buffer_funcs.cpp b/src/buffer_funcs.cpp index f82535bae7..2167bd137c 100644 --- a/src/buffer_funcs.cpp +++ b/src/buffer_funcs.cpp @@ -174,10 +174,11 @@ int countWords(DocIterator const & from, DocIterator const & to) int count = 0; bool inword = false; for (DocIterator dit = from ; dit != to ; dit.forwardPos()) { - // Copied and adapted from isLetter() in ControlSpellChecker + // FIXME: use Paragraph::isWordSeparator + // Copied and adapted from isWordSeparator() in Paragraph if (dit.inTexted() && dit.pos() != dit.lastpos() - && dit.paragraph().isLetter(dit.pos()) + && !dit.paragraph().isWordSeparator(dit.pos()) && !dit.paragraph().isDeleted(dit.pos())) { if (!inword) { ++count;