Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17f326b7 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi
Browse files

Add beginning of sentence information in PrevWordsInfo.

Bug: 14119293
Bug: 14425059
Change-Id: I65320920e840082b0b697bb621676716d0933e0c
parent c18b1c42
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -1435,12 +1435,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                // We're checking the previous word in the text field against the memorized previous
                // word. If we are composing a word we should have the second word before the cursor
                // memorized, otherwise we should have the first.
                final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion(
                final PrevWordsInfo rereadPrevWordsInfo =
                        mInputLogic.getPrevWordsInfoFromNthPreviousWordForSuggestion(
                                currentSettings.mSpacingAndPunctuations,
                                mInputLogic.mWordComposer.isComposingWord() ? 2 : 1);
                if (!TextUtils.equals(prevWordsInfo.mPrevWord, rereadPrevWord)) {
                if (!TextUtils.equals(prevWordsInfo.mPrevWord, rereadPrevWordsInfo.mPrevWord)) {
                    throw new RuntimeException("Unexpected previous word: "
                            + prevWordsInfo.mPrevWord + " <> " + rereadPrevWord);
                            + prevWordsInfo.mPrevWord + " <> " + rereadPrevWordsInfo.mPrevWord);
                }
            }
        }
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.inputmethod.latin;

import android.util.Log;

// TODO: Support multiple previous words for n-gram.
public class PrevWordsInfo {
    // The previous word. May be null after resetting and before starting a new composing word, or
    // when there is no context like at the start of text for example. It can also be set to null
@@ -23,7 +26,18 @@ public class PrevWordsInfo {
    // or a comma.
    public final String mPrevWord;

    // TODO: Have sentence separator.
    // Whether the current context is beginning of sentence or not.
    public final boolean mIsBeginningOfSentence;

    // Beginning of sentence.
    public PrevWordsInfo() {
        mPrevWord = null;
        mIsBeginningOfSentence = true;
    }

    public PrevWordsInfo(final String prevWord) {
        mPrevWord = prevWord;
        mIsBeginningOfSentence = false;
    }
}
+34 −21
Original line number Diff line number Diff line
@@ -538,10 +538,12 @@ public final class RichInputConnection {
    }

    @SuppressWarnings("unused")
    public String getNthPreviousWord(final SpacingAndPunctuations spacingAndPunctuations,
            final int n) {
    public PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(
            final SpacingAndPunctuations spacingAndPunctuations, final int n) {
        mIC = mParent.getCurrentInputConnection();
        if (null == mIC) return null;
        if (null == mIC) {
            return new PrevWordsInfo(null);
        }
        final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
        if (DEBUG_PREVIOUS_TEXT && null != prev) {
            final int checkLength = LOOKBACK_CHARACTER_NUM - 1;
@@ -561,46 +563,57 @@ public final class RichInputConnection {
                }
            }
        }
        return getNthPreviousWord(prev, spacingAndPunctuations, n);
        return getPrevWordsInfoFromNthPreviousWord(prev, spacingAndPunctuations, n);
    }

    private static boolean isSeparator(final int code, final int[] sortedSeparators) {
        return Arrays.binarySearch(sortedSeparators, code) >= 0;
    }

    // Get the nth word before cursor. n = 1 retrieves the word immediately before the cursor,
    // n = 2 retrieves the word before that, and so on. This splits on whitespace only.
    // Get information of the nth word before cursor. n = 1 retrieves the word immediately before
    // the cursor, n = 2 retrieves the word before that, and so on. This splits on whitespace only.
    // Also, it won't return words that end in a separator (if the nth word before the cursor
    // ends in a separator, it returns null).
    // ends in a separator, it returns information represents beginning-of-sentence).
    // Example :
    // (n = 1) "abc def|" -> def
    // (n = 1) "abc def |" -> def
    // (n = 1) "abc def. |" -> null
    // (n = 1) "abc def . |" -> null
    // (n = 1) "abc def. |" -> beginning-of-sentence
    // (n = 1) "abc def . |" -> beginning-of-sentence
    // (n = 2) "abc def|" -> abc
    // (n = 2) "abc def |" -> abc
    // (n = 2) "abc def. |" -> abc
    // (n = 2) "abc def . |" -> def
    // (n = 2) "abc|" -> null
    // (n = 2) "abc |" -> null
    // (n = 2) "abc. def|" -> null
    public static String getNthPreviousWord(final CharSequence prev,
    // (n = 2) "abc|" -> beginning-of-sentence
    // (n = 2) "abc |" -> beginning-of-sentence
    // (n = 2) "abc. def|" -> beginning-of-sentence
    public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev,
            final SpacingAndPunctuations spacingAndPunctuations, final int n) {
        if (prev == null) return null;
        if (prev == null) return new PrevWordsInfo(null);
        final String[] w = spaceRegex.split(prev);

        // If we can't find n words, or we found an empty word, return null.
        if (w.length < n) return null;
        // If we can't find n words, or we found an empty word, the context is
        // beginning-of-sentence.
        if (w.length < n) {
            return new PrevWordsInfo();
        }
        final String nthPrevWord = w[w.length - n];
        final int length = nthPrevWord.length();
        if (length <= 0) return null;
        if (length <= 0) {
            return  new PrevWordsInfo();
        }

        // If ends in a separator, return null
        // If ends in a sentence separator, the context is beginning-of-sentence.
        final char lastChar = nthPrevWord.charAt(length - 1);
        if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
            new PrevWordsInfo();
        }
        // If ends in a word separator or connector, the context is unclear.
        // TODO: Return meaningful context for this case.
        if (spacingAndPunctuations.isWordSeparator(lastChar)
                || spacingAndPunctuations.isWordConnector(lastChar)) return null;

        return nthPrevWord;
                || spacingAndPunctuations.isWordConnector(lastChar)) {
            return new PrevWordsInfo(null);
        }
        return new PrevWordsInfo(nthPrevWord);
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -371,12 +371,12 @@ public final class WordComposer {
     * Also, batch input needs to know about the current caps mode to display correctly
     * capitalized suggestions.
     * @param mode the mode at the time of start
     * @param previousWord the previous word as context for suggestions. May be null if none.
     * @param prevWordsInfo the information of previous words
     */
    public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode,
            final CharSequence previousWord) {
            final PrevWordsInfo prevWordsInfo) {
        mCapitalizedMode = mode;
        mPrevWordsInfo = new PrevWordsInfo(null == previousWord ? null : previousWord.toString());
        mPrevWordsInfo = prevWordsInfo;
    }

    /**
+19 −16
Original line number Diff line number Diff line
@@ -575,7 +575,7 @@ public final class InputLogic {
        mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()),
                // Prev word is 1st word before cursor
                getNthPreviousWordForSuggestion(
                getPrevWordsInfoFromNthPreviousWordForSuggestion(
                        settingsValues.mSpacingAndPunctuations, 1 /* nthPreviousWord */));
    }

@@ -614,7 +614,8 @@ public final class InputLogic {
                            getCurrentAutoCapsState(settingsValues), getCurrentRecapitalizeState());
                    mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                            getActualCapsMode(settingsValues,
                                    keyboardSwitcher.getKeyboardShiftMode()), commitParts[0]);
                                    keyboardSwitcher.getKeyboardShiftMode()),
                                            new PrevWordsInfo(commitParts[0]));
                    ++mAutoCommitSequenceNumber;
                }
            }
@@ -765,7 +766,8 @@ public final class InputLogic {
                // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
                // yet, so the word we want is the 1st word before the cursor.
                mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                        inputTransaction.mShiftState, getNthPreviousWordForSuggestion(
                        inputTransaction.mShiftState,
                        getPrevWordsInfoFromNthPreviousWordForSuggestion(
                                settingsValues.mSpacingAndPunctuations, 1 /* nthPreviousWord */));
            }
            mConnection.setComposingText(getTextWithUnderline(
@@ -1326,7 +1328,8 @@ public final class InputLogic {
            // Show predictions.
            mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                    WordComposer.CAPS_MODE_OFF,
                    getNthPreviousWordForSuggestion(settingsValues.mSpacingAndPunctuations, 1));
                    getPrevWordsInfoFromNthPreviousWordForSuggestion(
                            settingsValues.mSpacingAndPunctuations, 1));
            mLatinIME.mHandler.postUpdateSuggestionStrip();
            return;
        }
@@ -1374,11 +1377,9 @@ public final class InputLogic {
        // We want the previous word for suggestion. If we have chars in the word
        // before the cursor, then we want the word before that, hence 2; otherwise,
        // we want the word immediately before the cursor, hence 1.
        final CharSequence prevWord = getNthPreviousWordForSuggestion(
        final PrevWordsInfo prevWordsInfo = getPrevWordsInfoFromNthPreviousWordForSuggestion(
                settingsValues.mSpacingAndPunctuations,
                0 == numberOfCharsInWordBeforeCursor ? 1 : 2);
        final PrevWordsInfo prevWordsInfo =
                new PrevWordsInfo(prevWord != null ? prevWord.toString() : null);
        mWordComposer.setComposingWord(codePoints,
                mLatinIME.getCoordinatesForCurrentKeyboard(codePoints), prevWordsInfo);
        mWordComposer.setCursorPositionWithinWord(
@@ -1590,21 +1591,23 @@ public final class InputLogic {
    }

    /**
     * Get the nth previous word before the cursor as context for the suggestion process.
     * Get information fo previous words from the nth previous word before the cursor as context
     * for the suggestion process.
     * @param spacingAndPunctuations the current spacing and punctuations settings.
     * @param nthPreviousWord reverse index of the word to get (1-indexed)
     * @return the nth previous word before the cursor.
     * @return the information of previous words
     */
    // TODO: Make this private
    public CharSequence getNthPreviousWordForSuggestion(
    public PrevWordsInfo getPrevWordsInfoFromNthPreviousWordForSuggestion(
            final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) {
        if (spacingAndPunctuations.mCurrentLanguageHasSpaces) {
            // If we are typing in a language with spaces we can just look up the previous
            // word from textview.
            return mConnection.getNthPreviousWord(spacingAndPunctuations, nthPreviousWord);
            // word information from textview.
            return mConnection.getPrevWordsInfoFromNthPreviousWord(
                    spacingAndPunctuations, nthPreviousWord);
        } else {
            return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? null
                    : mLastComposedWord.mCommittedWord;
            return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? new PrevWordsInfo()
                    : new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString());
        }
    }

@@ -1972,8 +1975,8 @@ public final class InputLogic {
                        suggestedWords);
        // Use the 2nd previous word as the previous word because the 1st previous word is the word
        // to be committed.
        final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(mConnection.getNthPreviousWord(
                settingsValues.mSpacingAndPunctuations, 2));
        final PrevWordsInfo prevWordsInfo = mConnection.getPrevWordsInfoFromNthPreviousWord(
                settingsValues.mSpacingAndPunctuations, 2);
        mConnection.commitText(chosenWordWithSuggestions, 1);
        // Add the word to the user history dictionary
        performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWordsInfo);
Loading