Merge "Introduce EMPTY_PREV_WORDS_INFO and BEGINNING_OF_SENTENCE."
commit
9f9988e996
|
@ -224,7 +224,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
*/
|
*/
|
||||||
private void addNameLocked(final String name) {
|
private void addNameLocked(final String name) {
|
||||||
int len = StringUtils.codePointCount(name);
|
int len = StringUtils.codePointCount(name);
|
||||||
PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null);
|
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
// TODO: Better tokenization for non-Latin writing systems
|
// TODO: Better tokenization for non-Latin writing systems
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (Character.isLetter(name.codePointAt(i))) {
|
if (Character.isLetter(name.codePointAt(i))) {
|
||||||
|
|
|
@ -16,20 +16,27 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.util.Log;
|
/**
|
||||||
|
* Class to represent information of previous words. This class is used to add n-gram entries
|
||||||
|
* into binary dictionaries, to get predictions, and to get suggestions.
|
||||||
|
*/
|
||||||
// TODO: Support multiple previous words for n-gram.
|
// TODO: Support multiple previous words for n-gram.
|
||||||
public class PrevWordsInfo {
|
public class PrevWordsInfo {
|
||||||
|
public static final PrevWordsInfo EMPTY_PREV_WORDS_INFO = new PrevWordsInfo(null);
|
||||||
public static final PrevWordsInfo BEGINNING_OF_SENTENCE = new PrevWordsInfo();
|
public static final PrevWordsInfo BEGINNING_OF_SENTENCE = new PrevWordsInfo();
|
||||||
|
|
||||||
// The previous word. May be null after resetting and before starting a new composing word, or
|
// The word immediately before the considered word. null means we don't have any context
|
||||||
// when there is no context like at the start of text for example. It can also be set to null
|
// including the "beginning of sentence context" - we just don't know what to predict.
|
||||||
// externally when the user enters a separator that does not let bigrams across, like a period
|
// An example of that is after a comma.
|
||||||
// or a comma.
|
// For simplicity of implementation, this may also be null transiently after the WordComposer
|
||||||
|
// was reset and before starting a new composing word, but we should never be calling
|
||||||
|
// getSuggetions* in this situation.
|
||||||
|
// This is an empty string when mIsBeginningOfSentence is true.
|
||||||
public final String mPrevWord;
|
public final String mPrevWord;
|
||||||
|
|
||||||
// TODO: Have sentence separator.
|
// TODO: Have sentence separator.
|
||||||
// Whether the current context is beginning of sentence or not.
|
// Whether the current context is beginning of sentence or not. This is true when composing at
|
||||||
|
// the beginning of an input field or composing a word after a sentence separator.
|
||||||
public final boolean mIsBeginningOfSentence;
|
public final boolean mIsBeginningOfSentence;
|
||||||
|
|
||||||
// Beginning of sentence.
|
// Beginning of sentence.
|
||||||
|
|
|
@ -542,7 +542,7 @@ public final class RichInputConnection {
|
||||||
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
|
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
|
||||||
mIC = mParent.getCurrentInputConnection();
|
mIC = mParent.getCurrentInputConnection();
|
||||||
if (null == mIC) {
|
if (null == mIC) {
|
||||||
return new PrevWordsInfo(null);
|
return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
}
|
}
|
||||||
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
|
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
|
||||||
if (DEBUG_PREVIOUS_TEXT && null != prev) {
|
if (DEBUG_PREVIOUS_TEXT && null != prev) {
|
||||||
|
@ -588,30 +588,30 @@ public final class RichInputConnection {
|
||||||
// (n = 2) "abc. def|" -> beginning-of-sentence
|
// (n = 2) "abc. def|" -> beginning-of-sentence
|
||||||
public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev,
|
public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev,
|
||||||
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
|
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
|
||||||
if (prev == null) return new PrevWordsInfo(null);
|
if (prev == null) return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
final String[] w = spaceRegex.split(prev);
|
final String[] w = spaceRegex.split(prev);
|
||||||
|
|
||||||
// If we can't find n words, or we found an empty word, the context is
|
// If we can't find n words, or we found an empty word, the context is
|
||||||
// beginning-of-sentence.
|
// beginning-of-sentence.
|
||||||
if (w.length < n) {
|
if (w.length < n) {
|
||||||
return new PrevWordsInfo();
|
return PrevWordsInfo.BEGINNING_OF_SENTENCE;
|
||||||
}
|
}
|
||||||
final String nthPrevWord = w[w.length - n];
|
final String nthPrevWord = w[w.length - n];
|
||||||
final int length = nthPrevWord.length();
|
final int length = nthPrevWord.length();
|
||||||
if (length <= 0) {
|
if (length <= 0) {
|
||||||
return new PrevWordsInfo();
|
return PrevWordsInfo.BEGINNING_OF_SENTENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ends in a sentence separator, the context is beginning-of-sentence.
|
// If ends in a sentence separator, the context is beginning-of-sentence.
|
||||||
final char lastChar = nthPrevWord.charAt(length - 1);
|
final char lastChar = nthPrevWord.charAt(length - 1);
|
||||||
if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
|
if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
|
||||||
new PrevWordsInfo();
|
return PrevWordsInfo.BEGINNING_OF_SENTENCE;
|
||||||
}
|
}
|
||||||
// If ends in a word separator or connector, the context is unclear.
|
// If ends in a word separator or connector, the context is unclear.
|
||||||
// TODO: Return meaningful context for this case.
|
// TODO: Return meaningful context for this case.
|
||||||
if (spacingAndPunctuations.isWordSeparator(lastChar)
|
if (spacingAndPunctuations.isWordSeparator(lastChar)
|
||||||
|| spacingAndPunctuations.isWordConnector(lastChar)) {
|
|| spacingAndPunctuations.isWordConnector(lastChar)) {
|
||||||
return new PrevWordsInfo(null);
|
return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
}
|
}
|
||||||
return new PrevWordsInfo(nthPrevWord);
|
return new PrevWordsInfo(nthPrevWord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public final class WordComposer {
|
||||||
mIsBatchMode = false;
|
mIsBatchMode = false;
|
||||||
mCursorPositionWithinWord = 0;
|
mCursorPositionWithinWord = 0;
|
||||||
mRejectedBatchModeSuggestion = null;
|
mRejectedBatchModeSuggestion = null;
|
||||||
mPrevWordsInfo = new PrevWordsInfo(null);
|
mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
refreshTypedWordCache();
|
refreshTypedWordCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ public final class WordComposer {
|
||||||
mIsBatchMode = false;
|
mIsBatchMode = false;
|
||||||
mCursorPositionWithinWord = 0;
|
mCursorPositionWithinWord = 0;
|
||||||
mRejectedBatchModeSuggestion = null;
|
mRejectedBatchModeSuggestion = null;
|
||||||
mPrevWordsInfo = new PrevWordsInfo(null);
|
mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
refreshTypedWordCache();
|
refreshTypedWordCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ public final class WordComposer {
|
||||||
// when the user inputs a separator that's not whitespace (including the case of the
|
// when the user inputs a separator that's not whitespace (including the case of the
|
||||||
// double-space-to-period feature).
|
// double-space-to-period feature).
|
||||||
public void discardPreviousWordForSuggestion() {
|
public void discardPreviousWordForSuggestion() {
|
||||||
mPrevWordsInfo = new PrevWordsInfo(null);
|
mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
|
public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
|
||||||
|
|
|
@ -1609,8 +1609,9 @@ public final class InputLogic {
|
||||||
return mConnection.getPrevWordsInfoFromNthPreviousWord(
|
return mConnection.getPrevWordsInfoFromNthPreviousWord(
|
||||||
spacingAndPunctuations, nthPreviousWord);
|
spacingAndPunctuations, nthPreviousWord);
|
||||||
} else {
|
} else {
|
||||||
return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? new PrevWordsInfo()
|
return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ?
|
||||||
: new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString());
|
PrevWordsInfo.BEGINNING_OF_SENTENCE :
|
||||||
|
new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ public final class LanguageModelParam {
|
||||||
final ArrayList<LanguageModelParam> languageModelParams =
|
final ArrayList<LanguageModelParam> languageModelParams =
|
||||||
CollectionUtils.newArrayList();
|
CollectionUtils.newArrayList();
|
||||||
final int N = tokens.size();
|
final int N = tokens.size();
|
||||||
PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null);
|
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
final String tempWord = tokens.get(i);
|
final String tempWord = tokens.get(i);
|
||||||
if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) {
|
if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) {
|
||||||
|
@ -104,7 +104,7 @@ public final class LanguageModelParam {
|
||||||
+ tempWord + "\"");
|
+ tempWord + "\"");
|
||||||
}
|
}
|
||||||
// Sentence terminator found. Split.
|
// Sentence terminator found. Split.
|
||||||
prevWordsInfo = new PrevWordsInfo(null);
|
prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (DEBUG_TOKEN) {
|
if (DEBUG_TOKEN) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class DistracterFilterTest extends InputTestsBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIsDistractorToWordsInDictionaries() {
|
public void testIsDistractorToWordsInDictionaries() {
|
||||||
final PrevWordsInfo EMPTY_PREV_WORDS_INFO = new PrevWordsInfo(null);
|
final PrevWordsInfo EMPTY_PREV_WORDS_INFO = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
|
|
||||||
final Locale localeEnUs = new Locale("en", "US");
|
final Locale localeEnUs = new Locale("en", "US");
|
||||||
String typedWord = "alot";
|
String typedWord = "alot";
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class WordComposerTests extends AndroidTestCase {
|
||||||
CoordinateUtils.newCoordinateArray(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length,
|
CoordinateUtils.newCoordinateArray(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length,
|
||||||
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
||||||
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
|
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
|
||||||
new PrevWordsInfo(null));
|
PrevWordsInfo.EMPTY_PREV_WORDS_INFO);
|
||||||
assertEquals(wc.size(), CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length);
|
assertEquals(wc.size(), CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length);
|
||||||
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
|
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
|
||||||
wc.setCursorPositionWithinWord(3);
|
wc.setCursorPositionWithinWord(3);
|
||||||
|
@ -109,7 +109,7 @@ public class WordComposerTests extends AndroidTestCase {
|
||||||
assertEquals(PREV_WORDS_INFO_STR_WITHIN_BMP, wc.getPrevWordsInfoForSuggestion());
|
assertEquals(PREV_WORDS_INFO_STR_WITHIN_BMP, wc.getPrevWordsInfoForSuggestion());
|
||||||
|
|
||||||
|
|
||||||
final PrevWordsInfo PREV_WORDS_INFO_NULL = new PrevWordsInfo(null);
|
final PrevWordsInfo PREV_WORDS_INFO_NULL = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
|
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
|
||||||
PREV_WORDS_INFO_NULL);
|
PREV_WORDS_INFO_NULL);
|
||||||
wc.setCursorPositionWithinWord(3);
|
wc.setCursorPositionWithinWord(3);
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addToDict(final UserHistoryDictionary dict, final List<String> words) {
|
private static void addToDict(final UserHistoryDictionary dict, final List<String> words) {
|
||||||
PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null);
|
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
|
||||||
for (String word : words) {
|
for (String word : words) {
|
||||||
UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true,
|
UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true,
|
||||||
(int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
|
(int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
|
||||||
|
|
Loading…
Reference in New Issue