diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index f7a77cae7..52b15cec8 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1793,6 +1793,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // The whitelist should be case-insensitive, so it's not possible to be consistent with // a boolean flag. Right now this is handled with a slight hack in // WhitelistDictionary#shouldForciblyAutoCorrectFrom. + final int quotesCount = wordComposer.trailingSingleQuotesCount(); final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected( mSuggest.getUnigramDictionaries(), // If the typed string ends with a single quote, for dictionary lookup purposes @@ -1800,8 +1801,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // typed string in the dictionary (to avoid autocorrecting from an existing // word, so for consistency this lookup should be made WITHOUT the trailing // single quote. - wordComposer.isLastCharASingleQuote() - ? typedWord.subSequence(0, typedWord.length() - 1) : typedWord, + quotesCount > 0 + ? typedWord.subSequence(0, typedWord.length() - quotesCount) : typedWord, preferCapitalization()); if (mCorrectionMode == Suggest.CORRECTION_FULL || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 5a3c348a9..2a36f8266 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -82,8 +82,6 @@ public class Suggest implements Dictionary.WordCallback { public static final String DICT_KEY_USER_BIGRAM = "user_bigram"; public static final String DICT_KEY_WHITELIST ="whitelist"; - private static String SINGLE_QUOTE_AS_STRING = String.valueOf((char)Keyboard.CODE_SINGLE_QUOTE); - private static final boolean DBG = LatinImeLogger.sDBG; private AutoCorrection mAutoCorrection; @@ -109,7 +107,7 @@ public class Suggest implements Dictionary.WordCallback { // TODO: Remove these member variables by passing more context to addWord() callback method private boolean mIsFirstCharCapitalized; private boolean mIsAllUpperCase; - private boolean mIsLastCharASingleQuote; + private int mTrailingSingleQuotesCount; private int mCorrectionMode = CORRECTION_BASIC; @@ -299,13 +297,14 @@ public class Suggest implements Dictionary.WordCallback { mAutoCorrection.init(); mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); mIsAllUpperCase = wordComposer.isAllUpperCase(); - mIsLastCharASingleQuote = wordComposer.isLastCharASingleQuote(); + mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); collectGarbage(mSuggestions, mPrefMaxSuggestions); Arrays.fill(mScores, 0); final String typedWord = wordComposer.getTypedWord(); - final String consideredWord = mIsLastCharASingleQuote - ? typedWord.substring(0, typedWord.length() - 1) : typedWord; + final String consideredWord = mTrailingSingleQuotesCount > 0 + ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount) + : typedWord; if (typedWord != null) { // Treating USER_TYPED as UNIGRAM suggestion for logging now. LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED, @@ -360,9 +359,11 @@ public class Suggest implements Dictionary.WordCallback { if (key.equals(DICT_KEY_USER_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) continue; final Dictionary dictionary = mUnigramDictionaries.get(key); - if (mIsLastCharASingleQuote) { + if (mTrailingSingleQuotesCount > 0) { final WordComposer tmpWordComposer = new WordComposer(wordComposer); - tmpWordComposer.deleteLast(); + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + tmpWordComposer.deleteLast(); + } dictionary.getWords(tmpWordComposer, this, proximityInfo); } else { dictionary.getWords(wordComposer, this, proximityInfo); @@ -380,8 +381,15 @@ public class Suggest implements Dictionary.WordCallback { whitelistedWord); if (whitelistedWord != null) { - mSuggestions.add(0, mIsLastCharASingleQuote - ? whitelistedWord + SINGLE_QUOTE_AS_STRING : whitelistedWord); + if (mTrailingSingleQuotesCount > 0) { + final StringBuilder sb = new StringBuilder(whitelistedWord); + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); + } + mSuggestions.add(0, sb.toString()); + } else { + mSuggestions.add(0, whitelistedWord); + } } if (typedWord != null) { @@ -500,7 +508,7 @@ public class Suggest implements Dictionary.WordCallback { } else { sb.append(word, offset, length); } - if (mIsLastCharASingleQuote) { + for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); } suggestions.add(pos, sb); diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 612b16071..f4d0c1e4f 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -44,7 +44,7 @@ public class WordComposer { private boolean mAutoCapitalized; // Cache this value for performance - private boolean mIsLastCharASingleQuote; + private int mTrailingSingleQuotesCount; /** * Whether the user chose to capitalize the first char of the word. @@ -57,7 +57,7 @@ public class WordComposer { mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; - mIsLastCharASingleQuote = false; + mTrailingSingleQuotesCount = 0; } public WordComposer(WordComposer source) { @@ -72,7 +72,7 @@ public class WordComposer { mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; - mIsLastCharASingleQuote = source.mIsLastCharASingleQuote; + mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; } /** @@ -83,7 +83,7 @@ public class WordComposer { mTypedWord.setLength(0); mCapsCount = 0; mIsFirstCharCapitalized = false; - mIsLastCharASingleQuote = false; + mTrailingSingleQuotesCount = 0; } /** @@ -133,7 +133,11 @@ public class WordComposer { mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); if (Character.isUpperCase(primaryCode)) mCapsCount++; - mIsLastCharASingleQuote = Keyboard.CODE_SINGLE_QUOTE == primaryCode; + if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) { + ++mTrailingSingleQuotesCount; + } else { + mTrailingSingleQuotesCount = 0; + } } /** @@ -165,10 +169,14 @@ public class WordComposer { } if (size() == 0) { mIsFirstCharCapitalized = false; - mIsLastCharASingleQuote = false; + } + if (mTrailingSingleQuotesCount > 0) { + --mTrailingSingleQuotesCount; } else { - mIsLastCharASingleQuote = - Keyboard.CODE_SINGLE_QUOTE == mTypedWord.codePointAt(mTypedWord.length() - 1); + for (int i = mTypedWord.length() - 1; i >= 0; --i) { + if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; + ++mTrailingSingleQuotesCount; + } } } @@ -191,8 +199,8 @@ public class WordComposer { return mIsFirstCharCapitalized; } - public boolean isLastCharASingleQuote() { - return mIsLastCharASingleQuote; + public int trailingSingleQuotesCount() { + return mTrailingSingleQuotesCount; } /**