diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 52a9b9a6c..57eaa3836 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -2495,11 +2495,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (null == range) return; // Happens if we don't have an input connection at all // If for some strange reason (editor bug or so) we measure the text before the cursor as // longer than what the entire text is supposed to be, the safe thing to do is bail out. - if (range.mCharsBefore > mLastSelectionStart) return; + final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); + if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return; final ArrayList suggestions = CollectionUtils.newArrayList(); - final String typedWord = range.mWord.toString(); - if (range.mWord instanceof SpannableString) { - final SpannableString spannableString = (SpannableString)range.mWord; + final CharSequence word = range.mWord; + final String typedWord = word.toString(); + if (word instanceof SpannableString) { + final SpannableString spannableString = (SpannableString)word; int i = 0; for (Object object : spannableString.getSpans(0, spannableString.length(), SuggestionSpan.class)) { @@ -2515,9 +2517,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } mWordComposer.setComposingWord(typedWord, mKeyboardSwitcher.getKeyboard()); - mWordComposer.setCursorPositionWithinWord(range.mCharsBefore); - mConnection.setComposingRegion(mLastSelectionStart - range.mCharsBefore, - mLastSelectionEnd + range.mCharsAfter); + mWordComposer.setCursorPositionWithinWord(numberOfCharsInWordBeforeCursor); + mConnection.setComposingRegion( + mLastSelectionStart - numberOfCharsInWordBeforeCursor, + mLastSelectionEnd + range.getNumberOfCharsInWordAfterCursor()); final SuggestedWords suggestedWords; if (suggestions.isEmpty()) { // We come here if there weren't any suggestion spans on this word. We will try to diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 980215de6..4031e77bc 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -17,7 +17,6 @@ package com.android.inputmethod.latin; import android.inputmethodservice.InputMethodService; -import android.text.SpannableString; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -441,25 +440,33 @@ public final class RichInputConnection { * Represents a range of text, relative to the current cursor position. */ public static final class Range { - /** Characters before selection start */ - public final int mCharsBefore; + private final CharSequence mTextAtCursor; + private final int mWordAtCursorStartIndex; + private final int mWordAtCursorEndIndex; + private final int mCursorIndex; - /** - * Characters after selection start, including one trailing word - * separator. - */ - public final int mCharsAfter; - - /** The actual characters that make up a word */ public final CharSequence mWord; - public Range(int charsBefore, int charsAfter, CharSequence word) { - if (charsBefore < 0 || charsAfter < 0) { + public int getNumberOfCharsInWordBeforeCursor() { + return mCursorIndex - mWordAtCursorStartIndex; + } + + public int getNumberOfCharsInWordAfterCursor() { + return mWordAtCursorEndIndex - mCursorIndex; + } + + public Range(final CharSequence textAtCursor, final int wordAtCursorStartIndex, + final int wordAtCursorEndIndex, final int cursorIndex) { + if (wordAtCursorStartIndex < 0 || cursorIndex < wordAtCursorStartIndex + || cursorIndex > wordAtCursorEndIndex + || wordAtCursorEndIndex > textAtCursor.length()) { throw new IndexOutOfBoundsException(); } - this.mCharsBefore = charsBefore; - this.mCharsAfter = charsAfter; - this.mWord = word; + mTextAtCursor = textAtCursor; + mWordAtCursorStartIndex = wordAtCursorStartIndex; + mWordAtCursorEndIndex = wordAtCursorEndIndex; + mCursorIndex = cursorIndex; + mWord = mTextAtCursor.subSequence(mWordAtCursorStartIndex, mWordAtCursorEndIndex); } } @@ -571,10 +578,8 @@ public final class RichInputConnection { } } - final SpannableString word = new SpannableString(TextUtils.concat( - before.subSequence(startIndexInBefore, before.length()), - after.subSequence(0, endIndexInAfter))); - return new Range(before.length() - startIndexInBefore, endIndexInAfter, word); + return new Range(TextUtils.concat(before, after), startIndexInBefore, + before.length() + endIndexInAfter, before.length()); } public boolean isCursorTouchingWord(final SettingsValues settingsValues) {