Loading java/src/com/android/inputmethod/latin/LatinIME.java +12 −19 Original line number Diff line number Diff line Loading @@ -199,7 +199,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private WordComposer mWordComposer = new WordComposer(); private int mCorrectionMode; private String mWordSavedForAutoCorrectCancellation; // Keep track of the last selection range to decide if we need to show word alternatives private int mLastSelectionStart; private int mLastSelectionEnd; Loading Loading @@ -1308,8 +1307,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.onCodeInput(Keyboard.CODE_DUMMY); mSpaceState = SPACE_STATE_NONE; mWordSavedForAutoCorrectCancellation = null; mEnteredText = text; mWordComposer.reset(); } @Override Loading Loading @@ -1363,13 +1362,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.deleteSurroundingText(1, 0); } } else { if (null != mWordSavedForAutoCorrectCancellation) { if (mWordComposer.didAutoCorrectToAnotherWord()) { Utils.Stats.onAutoCorrectionCancellation(); cancelAutoCorrect(ic); mWordSavedForAutoCorrectCancellation = null; return; } else { mWordSavedForAutoCorrectCancellation = null; } if (SPACE_STATE_DOUBLE == spaceState) { Loading Loading @@ -1524,9 +1520,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (ic != null) { ic.beginBatchEdit(); } // Reset the saved word in all cases. If this separator causes an autocorrection, // it will overwrite this null with the actual word we need to save. mWordSavedForAutoCorrectCancellation = null; if (mWordComposer.isComposingWord()) { // In certain languages where single quote is a separator, it's better // not to auto correct, but accept the typed word. For instance, Loading Loading @@ -1810,9 +1803,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint); mExpectingUpdateSelection = true; commitBestWord(autoCorrection); if (!autoCorrection.equals(typedWord)) { mWordSavedForAutoCorrectCancellation = autoCorrection.toString(); } // Add the word to the user unigram dictionary if it's not a known word addToUserUnigramAndBigramDictionaries(autoCorrection, UserUnigramDictionary.FREQUENCY_FOR_TYPED); Loading Loading @@ -2103,28 +2093,31 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // "ic" must not be null private void cancelAutoCorrect(final InputConnection ic) { final int cancelLength = mWordSavedForAutoCorrectCancellation.length(); mWordComposer.resumeSuggestionOnKeptWord(); final String originallyTypedWord = mWordComposer.getTypedWord(); final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull(); final int cancelLength = autoCorrectedTo.length(); final CharSequence separator = ic.getTextBeforeCursor(1, 0); if (DEBUG) { final String wordBeforeCursor = ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength) .toString(); if (!mWordSavedForAutoCorrectCancellation.equals(wordBeforeCursor)) { if (!autoCorrectedTo.equals(wordBeforeCursor)) { throw new RuntimeException("cancelAutoCorrect check failed: we thought we were " + "reverting \"" + mWordSavedForAutoCorrectCancellation + "reverting \"" + autoCorrectedTo + "\", but before the cursor we found \"" + wordBeforeCursor + "\""); } if (mWordComposer.getTypedWord().equals(wordBeforeCursor)) { if (originallyTypedWord.equals(wordBeforeCursor)) { throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel " + "auto correction and revert to \"" + mWordComposer.getTypedWord() + "auto correction and revert to \"" + originallyTypedWord + "\" but we found this very string before the cursor"); } } ic.deleteSurroundingText(cancelLength + 1, 0); mWordComposer.resumeSuggestionOnKeptWord(); ic.commitText(mWordComposer.getTypedWord(), 1); ic.commitText(originallyTypedWord, 1); // Re-insert the separator ic.commitText(separator, 1); mWordComposer.deleteAutoCorrection(); mWordComposer.onCommitWord(); Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); Loading java/src/com/android/inputmethod/latin/WordComposer.java +26 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; import android.text.TextUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; Loading @@ -40,12 +42,14 @@ public class WordComposer { int[] mXCoordinates; int[] mYCoordinates; StringBuilder mTypedWord; CharSequence mAutoCorrection; CharacterStore() { final int N = BinaryDictionary.MAX_WORD_LENGTH; mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; } CharacterStore(final CharacterStore that) { mCodes = new ArrayList<int[]>(that.mCodes); Loading @@ -57,15 +61,14 @@ public class WordComposer { // For better performance than creating a new character store. mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; } } // The currently typing word. May not be null. private CharacterStore mCurrentWord; // The information being kept for resuming suggestion. May be null if wiped. private CharacterStore mWordKeptForSuggestionResuming; // An auto-correction for this word out of the dictionary. private CharSequence mAutoCorrection; private CharacterStore mCommittedWordSavedForSuggestionResuming; private int mCapsCount; Loading @@ -80,9 +83,8 @@ public class WordComposer { public WordComposer() { mCurrentWord = new CharacterStore(); mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null; mTrailingSingleQuotesCount = 0; mAutoCorrection = null; } public WordComposer(WordComposer source) { Loading @@ -91,12 +93,11 @@ public class WordComposer { public void init(WordComposer source) { mCurrentWord = new CharacterStore(source.mCurrentWord); mWordKeptForSuggestionResuming = source.mWordKeptForSuggestionResuming; mCommittedWordSavedForSuggestionResuming = source.mCommittedWordSavedForSuggestionResuming; mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; mAutoCorrection = null; } /** Loading @@ -104,11 +105,10 @@ public class WordComposer { */ public void reset() { mCurrentWord.reset(); mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null; mCapsCount = 0; mIsFirstCharCapitalized = false; mTrailingSingleQuotesCount = 0; mAutoCorrection = null; } /** Loading Loading @@ -167,7 +167,7 @@ public class WordComposer { } else { mTrailingSingleQuotesCount = 0; } mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** Loading Loading @@ -201,7 +201,7 @@ public class WordComposer { int codePoint = word.charAt(i); addKeyInfo(codePoint, keyboard, keyDetector); } mAutoCorrection = null; mCommittedWordSavedForSuggestionResuming = null; } /** Loading Loading @@ -253,7 +253,7 @@ public class WordComposer { ++mTrailingSingleQuotesCount; } } mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** Loading Loading @@ -312,37 +312,44 @@ public class WordComposer { * Sets the auto-correction for this word. */ public void setAutoCorrection(final CharSequence correction) { mAutoCorrection = correction; mCurrentWord.mAutoCorrection = correction; } /** * Remove any auto-correction that may have been set. */ public void deleteAutoCorrection() { mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** * @return the auto-correction for this word, or null if none. */ public CharSequence getAutoCorrectionOrNull() { return mAutoCorrection; return mCurrentWord.mAutoCorrection; } // TODO: pass the information about what was committed and how. Was it an auto-correction? // Was it a completion? Was is what the user typed? public void onCommitWord() { mWordKeptForSuggestionResuming = mCurrentWord; mCommittedWordSavedForSuggestionResuming = mCurrentWord; // TODO: improve performance by swapping buffers instead of creating a new object. mCurrentWord = new CharacterStore(); } public boolean hasWordKeptForSuggestionResuming() { return null != mWordKeptForSuggestionResuming; return null != mCommittedWordSavedForSuggestionResuming; } public void resumeSuggestionOnKeptWord() { mCurrentWord = mWordKeptForSuggestionResuming; mWordKeptForSuggestionResuming = null; mCurrentWord = mCommittedWordSavedForSuggestionResuming; mCommittedWordSavedForSuggestionResuming = null; } public boolean didAutoCorrectToAnotherWord() { return null != mCommittedWordSavedForSuggestionResuming && !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection) && !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord, mCommittedWordSavedForSuggestionResuming.mAutoCorrection); } } Loading
java/src/com/android/inputmethod/latin/LatinIME.java +12 −19 Original line number Diff line number Diff line Loading @@ -199,7 +199,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private WordComposer mWordComposer = new WordComposer(); private int mCorrectionMode; private String mWordSavedForAutoCorrectCancellation; // Keep track of the last selection range to decide if we need to show word alternatives private int mLastSelectionStart; private int mLastSelectionEnd; Loading Loading @@ -1308,8 +1307,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.onCodeInput(Keyboard.CODE_DUMMY); mSpaceState = SPACE_STATE_NONE; mWordSavedForAutoCorrectCancellation = null; mEnteredText = text; mWordComposer.reset(); } @Override Loading Loading @@ -1363,13 +1362,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.deleteSurroundingText(1, 0); } } else { if (null != mWordSavedForAutoCorrectCancellation) { if (mWordComposer.didAutoCorrectToAnotherWord()) { Utils.Stats.onAutoCorrectionCancellation(); cancelAutoCorrect(ic); mWordSavedForAutoCorrectCancellation = null; return; } else { mWordSavedForAutoCorrectCancellation = null; } if (SPACE_STATE_DOUBLE == spaceState) { Loading Loading @@ -1524,9 +1520,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (ic != null) { ic.beginBatchEdit(); } // Reset the saved word in all cases. If this separator causes an autocorrection, // it will overwrite this null with the actual word we need to save. mWordSavedForAutoCorrectCancellation = null; if (mWordComposer.isComposingWord()) { // In certain languages where single quote is a separator, it's better // not to auto correct, but accept the typed word. For instance, Loading Loading @@ -1810,9 +1803,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint); mExpectingUpdateSelection = true; commitBestWord(autoCorrection); if (!autoCorrection.equals(typedWord)) { mWordSavedForAutoCorrectCancellation = autoCorrection.toString(); } // Add the word to the user unigram dictionary if it's not a known word addToUserUnigramAndBigramDictionaries(autoCorrection, UserUnigramDictionary.FREQUENCY_FOR_TYPED); Loading Loading @@ -2103,28 +2093,31 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // "ic" must not be null private void cancelAutoCorrect(final InputConnection ic) { final int cancelLength = mWordSavedForAutoCorrectCancellation.length(); mWordComposer.resumeSuggestionOnKeptWord(); final String originallyTypedWord = mWordComposer.getTypedWord(); final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull(); final int cancelLength = autoCorrectedTo.length(); final CharSequence separator = ic.getTextBeforeCursor(1, 0); if (DEBUG) { final String wordBeforeCursor = ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength) .toString(); if (!mWordSavedForAutoCorrectCancellation.equals(wordBeforeCursor)) { if (!autoCorrectedTo.equals(wordBeforeCursor)) { throw new RuntimeException("cancelAutoCorrect check failed: we thought we were " + "reverting \"" + mWordSavedForAutoCorrectCancellation + "reverting \"" + autoCorrectedTo + "\", but before the cursor we found \"" + wordBeforeCursor + "\""); } if (mWordComposer.getTypedWord().equals(wordBeforeCursor)) { if (originallyTypedWord.equals(wordBeforeCursor)) { throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel " + "auto correction and revert to \"" + mWordComposer.getTypedWord() + "auto correction and revert to \"" + originallyTypedWord + "\" but we found this very string before the cursor"); } } ic.deleteSurroundingText(cancelLength + 1, 0); mWordComposer.resumeSuggestionOnKeptWord(); ic.commitText(mWordComposer.getTypedWord(), 1); ic.commitText(originallyTypedWord, 1); // Re-insert the separator ic.commitText(separator, 1); mWordComposer.deleteAutoCorrection(); mWordComposer.onCommitWord(); Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); Loading
java/src/com/android/inputmethod/latin/WordComposer.java +26 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; import android.text.TextUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; Loading @@ -40,12 +42,14 @@ public class WordComposer { int[] mXCoordinates; int[] mYCoordinates; StringBuilder mTypedWord; CharSequence mAutoCorrection; CharacterStore() { final int N = BinaryDictionary.MAX_WORD_LENGTH; mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; } CharacterStore(final CharacterStore that) { mCodes = new ArrayList<int[]>(that.mCodes); Loading @@ -57,15 +61,14 @@ public class WordComposer { // For better performance than creating a new character store. mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; } } // The currently typing word. May not be null. private CharacterStore mCurrentWord; // The information being kept for resuming suggestion. May be null if wiped. private CharacterStore mWordKeptForSuggestionResuming; // An auto-correction for this word out of the dictionary. private CharSequence mAutoCorrection; private CharacterStore mCommittedWordSavedForSuggestionResuming; private int mCapsCount; Loading @@ -80,9 +83,8 @@ public class WordComposer { public WordComposer() { mCurrentWord = new CharacterStore(); mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null; mTrailingSingleQuotesCount = 0; mAutoCorrection = null; } public WordComposer(WordComposer source) { Loading @@ -91,12 +93,11 @@ public class WordComposer { public void init(WordComposer source) { mCurrentWord = new CharacterStore(source.mCurrentWord); mWordKeptForSuggestionResuming = source.mWordKeptForSuggestionResuming; mCommittedWordSavedForSuggestionResuming = source.mCommittedWordSavedForSuggestionResuming; mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; mAutoCorrection = null; } /** Loading @@ -104,11 +105,10 @@ public class WordComposer { */ public void reset() { mCurrentWord.reset(); mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null; mCapsCount = 0; mIsFirstCharCapitalized = false; mTrailingSingleQuotesCount = 0; mAutoCorrection = null; } /** Loading Loading @@ -167,7 +167,7 @@ public class WordComposer { } else { mTrailingSingleQuotesCount = 0; } mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** Loading Loading @@ -201,7 +201,7 @@ public class WordComposer { int codePoint = word.charAt(i); addKeyInfo(codePoint, keyboard, keyDetector); } mAutoCorrection = null; mCommittedWordSavedForSuggestionResuming = null; } /** Loading Loading @@ -253,7 +253,7 @@ public class WordComposer { ++mTrailingSingleQuotesCount; } } mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** Loading Loading @@ -312,37 +312,44 @@ public class WordComposer { * Sets the auto-correction for this word. */ public void setAutoCorrection(final CharSequence correction) { mAutoCorrection = correction; mCurrentWord.mAutoCorrection = correction; } /** * Remove any auto-correction that may have been set. */ public void deleteAutoCorrection() { mAutoCorrection = null; mCurrentWord.mAutoCorrection = null; } /** * @return the auto-correction for this word, or null if none. */ public CharSequence getAutoCorrectionOrNull() { return mAutoCorrection; return mCurrentWord.mAutoCorrection; } // TODO: pass the information about what was committed and how. Was it an auto-correction? // Was it a completion? Was is what the user typed? public void onCommitWord() { mWordKeptForSuggestionResuming = mCurrentWord; mCommittedWordSavedForSuggestionResuming = mCurrentWord; // TODO: improve performance by swapping buffers instead of creating a new object. mCurrentWord = new CharacterStore(); } public boolean hasWordKeptForSuggestionResuming() { return null != mWordKeptForSuggestionResuming; return null != mCommittedWordSavedForSuggestionResuming; } public void resumeSuggestionOnKeptWord() { mCurrentWord = mWordKeptForSuggestionResuming; mWordKeptForSuggestionResuming = null; mCurrentWord = mCommittedWordSavedForSuggestionResuming; mCommittedWordSavedForSuggestionResuming = null; } public boolean didAutoCorrectToAnotherWord() { return null != mCommittedWordSavedForSuggestionResuming && !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection) && !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord, mCommittedWordSavedForSuggestionResuming.mAutoCorrection); } }