Merge "Expand characters temporarily skipped in spellchecking"

This commit is contained in:
Roozbeh Pournader
2016-12-20 19:36:50 +00:00
committed by Android (Google) Code Review
2 changed files with 39 additions and 15 deletions

View File

@@ -17,6 +17,8 @@
package android.text.method;
import android.annotation.NonNull;
import android.icu.lang.UCharacter;
import android.icu.lang.UProperty;
import android.icu.text.BreakIterator;
import android.text.CharSequenceCharacterIterator;
import android.text.Selection;
@@ -321,6 +323,27 @@ public class WordIterator implements Selection.PositionIterator {
return false;
}
/**
* Indicates if the codepoint is a mid-word-only punctuation.
*
* At the moment, this is locale-independent, and includes all the characters in
* the MidLetter, MidNumLet, and Single_Quote class of Unicode word breaking algorithm (see
* UAX #29 "Unicode Text Segmentation" at http://unicode.org/reports/tr29/). These are all the
* characters that according to the rules WB6 and WB7 of UAX #29 prevent word breaks if they are
* in the middle of a word, but they become word breaks if they happen at the end of a word
* (accroding to rule WB999 that breaks word in any place that is not prohibited otherwise).
*
* @param locale the locale to consider the codepoint in. Presently ignored.
* @param codePoint the codepoint to check.
* @return True if the codepoint is a mid-word punctuation.
*/
public static boolean isMidWordPunctuation(Locale locale, int codePoint) {
final int wb = UCharacter.getIntPropertyValue(codePoint, UProperty.WORD_BREAK);
return (wb == UCharacter.WordBreak.MIDLETTER
|| wb == UCharacter.WordBreak.MIDNUMLET
|| wb == UCharacter.WordBreak.SINGLE_QUOTE);
}
private boolean isPunctuationStartBoundary(int offset) {
return isOnPunctuation(offset) && !isAfterPunctuation(offset);
}
@@ -331,13 +354,13 @@ public class WordIterator implements Selection.PositionIterator {
private static boolean isPunctuation(int cp) {
final int type = Character.getType(cp);
return (type == Character.CONNECTOR_PUNCTUATION ||
type == Character.DASH_PUNCTUATION ||
type == Character.END_PUNCTUATION ||
type == Character.FINAL_QUOTE_PUNCTUATION ||
type == Character.INITIAL_QUOTE_PUNCTUATION ||
type == Character.OTHER_PUNCTUATION ||
type == Character.START_PUNCTUATION);
return (type == Character.CONNECTOR_PUNCTUATION
|| type == Character.DASH_PUNCTUATION
|| type == Character.END_PUNCTUATION
|| type == Character.FINAL_QUOTE_PUNCTUATION
|| type == Character.INITIAL_QUOTE_PUNCTUATION
|| type == Character.OTHER_PUNCTUATION
|| type == Character.START_PUNCTUATION);
}
private boolean isAfterLetterOrDigit(int offset) {

View File

@@ -277,18 +277,19 @@ public class SpellChecker implements SpellCheckerSessionListener {
// Do not check this word if the user is currently editing it
final boolean isEditing;
// Defer spell check when typing a word with an interior apostrophe.
// TODO: a better solution to this would be to make the word
// iterator locale-sensitive and include the apostrophe in
// languages that use it (such as English).
final boolean apostrophe = (selectionStart == end + 1 && editable.charAt(end) == '\'');
if (mIsSentenceSpellCheckSupported) {
// Defer spell check when typing a word ending with a punctuation like an apostrophe
// which could end up being a mid-word punctuation.
if (selectionStart == end + 1
&& WordIterator.isMidWordPunctuation(
mCurrentLocale, Character.codePointBefore(editable, end + 1))) {
isEditing = false;
} else if (mIsSentenceSpellCheckSupported) {
// Allow the overlap of the cursor and the first boundary of the spell check span
// no to skip the spell check of the following word because the
// following word will never be spell-checked even if the user finishes composing
isEditing = !apostrophe && (selectionEnd <= start || selectionStart > end);
isEditing = selectionEnd <= start || selectionStart > end;
} else {
isEditing = !apostrophe && (selectionEnd < start || selectionStart > end);
isEditing = selectionEnd < start || selectionStart > end;
}
if (start >= 0 && end > start && isEditing) {
spellCheckSpan.setSpellCheckInProgress(true);