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

Commit c93cf1c3 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Use sorted int[] to represent word separators

Change-Id: I4103541d99fe59bfcf12379a1298a0a690497846
parent 5b6ebdbe
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.TextRange;
import com.android.inputmethod.research.ResearchLogger;

import java.util.Arrays;
import java.util.regex.Pattern;

/**
@@ -557,8 +558,8 @@ public final class RichInputConnection {
        return getNthPreviousWord(prev, spacingAndPunctuations, n);
    }

    private static boolean isSeparator(int code, String sep) {
        return sep.indexOf(code) != -1;
    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,
@@ -597,29 +598,29 @@ public final class RichInputConnection {
    }

    /**
     * @param separators characters which may separate words
     * @param sortedSeparators a sorted array of code points which may separate words
     * @return the word that surrounds the cursor, including up to one trailing
     *   separator. For example, if the field contains "he|llo world", where |
     *   represents the cursor, then "hello " will be returned.
     */
    public CharSequence getWordAtCursor(String separators) {
    public CharSequence getWordAtCursor(final int[] sortedSeparators) {
        // getWordRangeAtCursor returns null if the connection is null
        TextRange r = getWordRangeAtCursor(separators, 0);
        final TextRange r = getWordRangeAtCursor(sortedSeparators, 0);
        return (r == null) ? null : r.mWord;
    }

    /**
     * Returns the text surrounding the cursor.
     *
     * @param sep a string of characters that split words.
     * @param sortedSeparators a sorted array of code points that split words.
     * @param additionalPrecedingWordsCount the number of words before the current word that should
     *   be included in the returned range
     * @return a range containing the text surrounding the cursor
     */
    public TextRange getWordRangeAtCursor(final String sep,
    public TextRange getWordRangeAtCursor(final int[] sortedSeparators,
            final int additionalPrecedingWordsCount) {
        mIC = mParent.getCurrentInputConnection();
        if (mIC == null || sep == null) {
        if (mIC == null) {
            return null;
        }
        final CharSequence before = mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
@@ -638,7 +639,7 @@ public final class RichInputConnection {
        while (true) { // see comments below for why this is guaranteed to halt
            while (startIndexInBefore > 0) {
                final int codePoint = Character.codePointBefore(before, startIndexInBefore);
                if (isStoppingAtWhitespace == isSeparator(codePoint, sep)) {
                if (isStoppingAtWhitespace == isSeparator(codePoint, sortedSeparators)) {
                    break;  // inner loop
                }
                --startIndexInBefore;
@@ -659,7 +660,7 @@ public final class RichInputConnection {
        int endIndexInAfter = -1;
        while (++endIndexInAfter < after.length()) {
            final int codePoint = Character.codePointAt(after, endIndexInAfter);
            if (isSeparator(codePoint, sep)) {
            if (isSeparator(codePoint, sortedSeparators)) {
                break;
            }
            if (Character.isSupplementaryCodePoint(codePoint)) {
+3 −2
Original line number Diff line number Diff line
@@ -970,7 +970,8 @@ public final class InputLogic {
            if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
            mRecapitalizeStatus.initialize(mConnection.getExpectedSelectionStart(),
                    mConnection.getExpectedSelectionEnd(), selectedText.toString(),
                    settingsValues.mLocale, settingsValues.mSpacingAndPunctuations.mWordSeparators);
                    settingsValues.mLocale,
                    settingsValues.mSpacingAndPunctuations.mSortedWordSeparators);
            // We trim leading and trailing whitespace.
            mRecapitalizeStatus.trim();
        }
@@ -1073,7 +1074,7 @@ public final class InputLogic {
        final int expectedCursorPosition = mConnection.getExpectedSelectionStart();
        if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)) return;
        final TextRange range = mConnection.getWordRangeAtCursor(
                settingsValues.mSpacingAndPunctuations.mWordSeparators,
                settingsValues.mSpacingAndPunctuations.mSortedWordSeparators,
                0 /* additionalPrecedingWordsCount */);
        if (null == range) return; // Happens if we don't have an input connection at all
        if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
+0 −4
Original line number Diff line number Diff line
@@ -181,10 +181,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
        return mSettingsValues.mIsInternal;
    }

    public String getWordSeparators() {
        return mSettingsValues.mSpacingAndPunctuations.mWordSeparators;
    }

    public boolean isWordSeparator(final int code) {
        return mSettingsValues.isWordSeparator(code);
    }
+4 −3
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ public final class SpacingAndPunctuations {
    private final int[] mSortedSymbolsPrecededBySpace;
    private final int[] mSortedSymbolsFollowedBySpace;
    private final int[] mSortedWordConnectors;
    public final int[] mSortedWordSeparators;
    public final SuggestedWords mSuggestPuncList;
    public final String mWordSeparators;
    private final int mSentenceSeparator;
    public final String mSentenceSeparatorAndSpace;
    public final boolean mCurrentLanguageHasSpaces;
@@ -53,10 +53,11 @@ public final class SpacingAndPunctuations {
        // To be able to binary search the code point. See {@link #isWordConnector(int)}.
        mSortedWordConnectors = StringUtils.toSortedCodePointArray(
                res.getString(R.string.symbols_word_connectors));
        mSortedWordSeparators = StringUtils.toSortedCodePointArray(
                res.getString(R.string.symbols_word_separators));
        final String[] suggestPuncsSpec = KeySpecParser.splitKeySpecs(res.getString(
                R.string.suggested_punctuations));
        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
        mWordSeparators = res.getString(R.string.symbols_word_separators);
        mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
        mSentenceSeparatorAndSpace = new String(new int[] {
                mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
@@ -91,7 +92,7 @@ public final class SpacingAndPunctuations {
    }

    public boolean isWordSeparator(final int code) {
        return mWordSeparators.contains(String.valueOf((char)code));
        return Arrays.binarySearch(mSortedWordSeparators, code) >= 0;
    }

    public boolean isWordConnector(final int code) {
+10 −8
Original line number Diff line number Diff line
@@ -37,12 +37,12 @@ public class RecapitalizeStatus {
        CAPS_MODE_ALL_UPPER
    };

    private static final int getStringMode(final String string, final String separators) {
    private static final int getStringMode(final String string, final int[] sortedSeparators) {
        if (StringUtils.isIdenticalAfterUpcase(string)) {
            return CAPS_MODE_ALL_UPPER;
        } else if (StringUtils.isIdenticalAfterDowncase(string)) {
            return CAPS_MODE_ALL_LOWER;
        } else if (StringUtils.isIdenticalAfterCapitalizeEachWord(string, separators)) {
        } else if (StringUtils.isIdenticalAfterCapitalizeEachWord(string, sortedSeparators)) {
            return CAPS_MODE_FIRST_WORD_UPPER;
        } else {
            return CAPS_MODE_ORIGINAL_MIXED_CASE;
@@ -60,26 +60,28 @@ public class RecapitalizeStatus {
    private int mRotationStyleCurrentIndex;
    private boolean mSkipOriginalMixedCaseMode;
    private Locale mLocale;
    private String mSeparators;
    private int[] mSortedSeparators;
    private String mStringAfter;
    private boolean mIsActive;

    private static final int[] EMPTY_STORTED_SEPARATORS = {};

    public RecapitalizeStatus() {
        // By default, initialize with dummy values that won't match any real recapitalize.
        initialize(-1, -1, "", Locale.getDefault(), "");
        initialize(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
        deactivate();
    }

    public void initialize(final int cursorStart, final int cursorEnd, final String string,
            final Locale locale, final String separators) {
            final Locale locale, final int[] sortedSeparators) {
        mCursorStartBefore = cursorStart;
        mStringBefore = string;
        mCursorStartAfter = cursorStart;
        mCursorEndAfter = cursorEnd;
        mStringAfter = string;
        final int initialMode = getStringMode(mStringBefore, separators);
        final int initialMode = getStringMode(mStringBefore, sortedSeparators);
        mLocale = locale;
        mSeparators = separators;
        mSortedSeparators = sortedSeparators;
        if (CAPS_MODE_ORIGINAL_MIXED_CASE == initialMode) {
            mRotationStyleCurrentIndex = 0;
            mSkipOriginalMixedCaseMode = false;
@@ -131,7 +133,7 @@ public class RecapitalizeStatus {
                mStringAfter = mStringBefore.toLowerCase(mLocale);
                break;
            case CAPS_MODE_FIRST_WORD_UPPER:
                mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSeparators,
                mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSortedSeparators,
                        mLocale);
                break;
            case CAPS_MODE_ALL_UPPER:
Loading