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
This commit is contained in:
Abdelrazak Younes 2009-06-21 14:30:57 +00:00
parent 7a4668b25e
commit 5387379c24
6 changed files with 39 additions and 40 deletions

View File

@ -3379,12 +3379,12 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to,
string lang_code; string lang_code;
// Go backward a bit if needed in order to return the word currently // Go backward a bit if needed in order to return the word currently
// pointed by 'from'. // pointed by 'from'.
while (from && from.pos() && isLetter(from)) while (from && from.pos() && !isWordSeparator(from))
from.backwardPos(); from.backwardPos();
// OK, we start from here. // OK, we start from here.
to = from; to = from;
while (to.depth()) { while (to.depth()) {
if (isLetter(to)) { if (!isWordSeparator(to)) {
if (!inword) { if (!inword) {
inword = true; inword = true;
ignoreword = false; ignoreword = false;
@ -3401,7 +3401,7 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to,
if (isDigit(c)) if (isDigit(c))
ignoreword = true; ignoreword = true;
} }
} else { // !isLetter(cur) } else { // !isWordSeparator(cur)
if (inword && !word.empty() && !ignoreword) if (inword && !word.empty() && !ignoreword)
return true; return true;
inword = false; inword = false;

View File

@ -612,7 +612,7 @@ bool operator==(StableDocIterator const & dit1, StableDocIterator const & dit2)
bool isLetter(DocIterator const & dit) bool isLetter(DocIterator const & dit)
{ {
return dit.inTexted() && dit.paragraph().isLetter(dit.pos()); return dit.inTexted() && !dit.paragraph().isWordSeparator(dit.pos());
} }
} // namespace lyx } // namespace lyx

View File

@ -2464,17 +2464,15 @@ bool Paragraph::isLineSeparator(pos_type pos) const
} }
/// Used by the spellchecker bool Paragraph::isWordSeparator(pos_type pos) const
bool Paragraph::isLetter(pos_type pos) const
{ {
if (Inset const * inset = getInset(pos)) if (Inset const * inset = getInset(pos))
return inset->isLetter(); return !inset->isLetter();
char_type const c = d->text_[pos]; char_type const c = d->text_[pos];
// We want to pass the ' and escape chars to the spellchecker // We want to pass the ' and escape chars to the spellchecker
static docstring const quote = from_utf8(lyxrc.spellchecker_esc_chars + '\''); static docstring const quote = from_utf8(lyxrc.spellchecker_esc_chars + '\'');
return (isLetterChar(c) || isDigit(c) || contains(quote, c)) return (!isLetterChar(c) && !isDigit(c) && !contains(quote, c))
&& pos != size() || pos == size();
&& !isDeleted(pos);
} }
@ -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 // permit capitalization again
capitalize = true; capitalize = true;
} }
@ -2938,10 +2936,10 @@ bool Paragraph::find(docstring const & str, bool cs, bool mw,
// if necessary, check whether string matches word // if necessary, check whether string matches word
if (mw) { if (mw) {
if (pos > 0 && isLetter(pos - 1)) if (pos > 0 && !isWordSeparator(pos - 1))
return false; return false;
if (pos + strsize < parsize if (pos + strsize < parsize
&& isLetter(pos + strsize)) && !isWordSeparator(pos + strsize))
return false; return false;
} }
@ -2996,8 +2994,8 @@ void Paragraph::locateWord(pos_type & from, pos_type & to,
switch (loc) { switch (loc) {
case WHOLE_WORD_STRICT: case WHOLE_WORD_STRICT:
if (from == 0 || from == size() if (from == 0 || from == size()
|| !isLetter(from) || isWordSeparator(from)
|| !isLetter(from - 1)) { || isWordSeparator(from - 1)) {
to = from; to = from;
return; return;
} }
@ -3005,13 +3003,13 @@ void Paragraph::locateWord(pos_type & from, pos_type & to,
case WHOLE_WORD: case WHOLE_WORD:
// If we are already at the beginning of a word, do nothing // If we are already at the beginning of a word, do nothing
if (!from || !isLetter(from - 1)) if (!from || isWordSeparator(from - 1))
break; break;
// no break here, we go to the next // no break here, we go to the next
case PREVIOUS_WORD: case PREVIOUS_WORD:
// always move the cursor to the beginning of previous word // always move the cursor to the beginning of previous word
while (from && isLetter(from - 1)) while (from && !isWordSeparator(from - 1))
--from; --from;
break; break;
case NEXT_WORD: case NEXT_WORD:
@ -3022,7 +3020,7 @@ void Paragraph::locateWord(pos_type & from, pos_type & to,
break; break;
} }
to = from; to = from;
while (to < size() && isLetter(to)) while (to < size() && !isWordSeparator(to))
++to; ++to;
} }
@ -3034,7 +3032,7 @@ void Paragraph::collectWords()
//lyxerr << "Words: "; //lyxerr << "Words: ";
pos_type n = size(); pos_type n = size();
for (pos_type pos = 0; pos < n; ++pos) { for (pos_type pos = 0; pos < n; ++pos) {
if (!isLetter(pos)) if (isWordSeparator(pos))
continue; continue;
pos_type from = pos; pos_type from = pos;
locateWord(from, pos, WHOLE_WORD); locateWord(from, pos, WHOLE_WORD);

View File

@ -362,9 +362,9 @@ public:
bool isSeparator(pos_type pos) const; bool isSeparator(pos_type pos) const;
/// ///
bool isLineSeparator(pos_type pos) const; bool isLineSeparator(pos_type pos) const;
/// True if the character/inset at this point can be part of a word. /// True if the character/inset at this point is a word separator.
/// Note that digits in particular are considered as letters /// Note that digits in particular are not considered as word separator.
bool isLetter(pos_type pos) const; bool isWordSeparator(pos_type pos) const;
/// True if the element at this point is a character that is not a letter. /// True if the element at this point is a character that is not a letter.
bool isChar(pos_type pos) const; bool isChar(pos_type pos) const;
/// True if the element at this point is a space /// True if the element at this point is a space

View File

@ -574,8 +574,8 @@ void Text::charInserted(Cursor & cur)
// register word if a non-letter was entered // register word if a non-letter was entered
if (cur.pos() > 1 if (cur.pos() > 1
&& par.isLetter(cur.pos() - 2) && !par.isWordSeparator(cur.pos() - 2)
&& !par.isLetter(cur.pos() - 1)) { && par.isWordSeparator(cur.pos() - 1)) {
// get the word in front of cursor // get the word in front of cursor
LASSERT(this == cur.text(), /**/); LASSERT(this == cur.text(), /**/);
cur.paragraph().updateWords(); cur.paragraph().updateWords();
@ -609,14 +609,14 @@ bool Text::cursorForwardOneWord(Cursor & cur)
++pos; ++pos;
// Skip over either a non-char inset or a full word // Skip over either a non-char inset or a full word
if (pos != lastpos && !par.isLetter(pos)) if (pos != lastpos && par.isWordSeparator(pos))
++pos; ++pos;
else while (pos != lastpos && par.isLetter(pos)) else while (pos != lastpos && !par.isWordSeparator(pos))
++pos; ++pos;
} else { } else {
LASSERT(pos < lastpos, /**/); // see above LASSERT(pos < lastpos, /**/); // see above
if (par.isLetter(pos)) if (!par.isWordSeparator(pos))
while (pos != lastpos && par.isLetter(pos)) while (pos != lastpos && !par.isWordSeparator(pos))
++pos; ++pos;
else if (par.isChar(pos)) else if (par.isChar(pos))
while (pos != lastpos && par.isChar(pos)) while (pos != lastpos && par.isChar(pos))
@ -651,17 +651,17 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
--pos; --pos;
// Skip over either a non-char inset or a full word // 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; --pos;
else while (pos != 0 && par.isLetter(pos - 1)) else while (pos != 0 && !par.isWordSeparator(pos - 1))
--pos; --pos;
} else { } else {
// Skip over white space // Skip over white space
while (pos != 0 && par.isSpace(pos - 1)) while (pos != 0 && par.isSpace(pos - 1))
--pos; --pos;
if (pos != 0 && par.isLetter(pos - 1)) if (pos != 0 && !par.isWordSeparator(pos - 1))
while (pos != 0 && par.isLetter(pos - 1)) while (pos != 0 && !par.isWordSeparator(pos - 1))
--pos; --pos;
else if (pos != 0 && par.isChar(pos - 1)) else if (pos != 0 && par.isChar(pos - 1))
while (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 // collect some information about current cursor position
temp_cur.getSurroundingPos(left_pos, right_pos); temp_cur.getSurroundingPos(left_pos, right_pos);
left_is_letter = 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_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 we're not at a letter/non-letter boundary, continue moving
if (left_is_letter == right_is_letter) if (left_is_letter == right_is_letter)
@ -726,9 +726,9 @@ bool Text::cursorVisRightOneWord(Cursor & cur)
// collect some information about current cursor position // collect some information about current cursor position
temp_cur.getSurroundingPos(left_pos, right_pos); temp_cur.getSurroundingPos(left_pos, right_pos);
left_is_letter = 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_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 we're not at a letter/non-letter boundary, continue moving
if (left_is_letter == right_is_letter) if (left_is_letter == right_is_letter)
@ -1611,8 +1611,8 @@ bool Text::completionSupported(Cursor const & cur) const
{ {
Paragraph const & par = cur.paragraph(); Paragraph const & par = cur.paragraph();
return cur.pos() > 0 return cur.pos() > 0
&& (cur.pos() >= par.size() || !par.isLetter(cur.pos())) && (cur.pos() >= par.size() || par.isWordSeparator(cur.pos()))
&& par.isLetter(cur.pos() - 1); && !par.isWordSeparator(cur.pos() - 1);
} }

View File

@ -174,10 +174,11 @@ int countWords(DocIterator const & from, DocIterator const & to)
int count = 0; int count = 0;
bool inword = false; bool inword = false;
for (DocIterator dit = from ; dit != to ; dit.forwardPos()) { 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() if (dit.inTexted()
&& dit.pos() != dit.lastpos() && dit.pos() != dit.lastpos()
&& dit.paragraph().isLetter(dit.pos()) && !dit.paragraph().isWordSeparator(dit.pos())
&& !dit.paragraph().isDeleted(dit.pos())) { && !dit.paragraph().isDeleted(dit.pos())) {
if (!inword) { if (!inword) {
++count; ++count;