From 9586d69bdf90fe24a83c0c6ba22589f28ae6cd03 Mon Sep 17 00:00:00 2001
From: Adrian Velicu <adrianv@google.com>
Date: Mon, 22 Sep 2014 17:35:31 +0900
Subject: [PATCH] Avoid double space when autocorrect is triggered

Bug: 17596034
Change-Id: Iaa6cc066eefd2436195a91791f2628e9a5f1c449
---
 .../latin/inputlogic/InputLogic.java          | 10 +++++++-
 .../inputmethod/latin/BlueUnderlineTests.java |  2 +-
 .../inputmethod/latin/InputLogicTests.java    | 23 ++++++++++++++++++-
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 27af1611aa..d7e1eba8b7 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1591,6 +1591,10 @@ public final class InputLogic {
         final String committedWordString = committedWord.toString();
         final int cancelLength = committedWord.length();
         final String separatorString = mLastComposedWord.mSeparatorString;
+        // If our separator is a space, we won't actually commit it,
+        // but set the space state to PHANTOM so that a space will be inserted
+        // on the next keypress
+        final boolean usePhantomSpace = separatorString.equals(Constants.STRING_SPACE);
         // We want java chars, not codepoints for the following.
         final int separatorLength = separatorString.length();
         // TODO: should we check our saved separator against the actual contents of the text view?
@@ -1611,7 +1615,8 @@ public final class InputLogic {
         if (!TextUtils.isEmpty(committedWord)) {
             mDictionaryFacilitator.removeWordFromPersonalizedDicts(committedWordString);
         }
-        final String stringToCommit = originallyTypedWord + separatorString;
+        final String stringToCommit = originallyTypedWord +
+                (usePhantomSpace ? "" : separatorString);
         final SpannableString textToCommit = new SpannableString(stringToCommit);
         if (committedWord instanceof SpannableString) {
             final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
@@ -1663,6 +1668,9 @@ public final class InputLogic {
             } else {
                 mConnection.commitText(textToCommit, 1);
             }
+            if (usePhantomSpace) {
+                mSpaceState = SpaceState.PHANTOM;
+            }
         } else {
             // For languages without spaces, we revert the typed string but the cursor is flush
             // with the typed word, so we need to resume suggestions right away.
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
index 6e894decfc..30b0881378 100644
--- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -63,7 +63,7 @@ public class BlueUnderlineTests extends InputTestsBase {
         final int typedLength = STRING_TO_TYPE.length();
         final int EXPECTED_SUGGESTION_SPAN_START = -1;
         final int EXPECTED_UNDERLINE_SPAN_START = 0;
-        final int EXPECTED_UNDERLINE_SPAN_END = 4;
+        final int EXPECTED_UNDERLINE_SPAN_END = 3;
         type(STRING_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 59b858dbdc..ec249dab37 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -159,8 +159,11 @@ public class InputLogicTests extends InputTestsBase {
     }
 
     public void testAutoCorrectWithSpaceThenRevert() {
+        // Backspacing to cancel the "tgis"->"this" autocorrection should result in
+        // a "phantom space": if the user presses space immediately after,
+        // only one space will be inserted in total.
         final String STRING_TO_TYPE = "tgis ";
-        final String EXPECTED_RESULT = "tgis ";
+        final String EXPECTED_RESULT = "tgis";
         type(STRING_TO_TYPE);
         mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
         type(Constants.CODE_DELETE);
@@ -168,6 +171,24 @@ public class InputLogicTests extends InputTestsBase {
                 mEditText.getText().toString());
     }
 
+    public void testAutoCorrectWithSpaceThenRevertThenTypeMore() {
+        final String STRING_TO_TYPE_FIRST = "tgis ";
+        final String STRING_TO_TYPE_SECOND = "a";
+        final String EXPECTED_RESULT = "tgis a";
+        type(STRING_TO_TYPE_FIRST);
+        mLatinIME.onUpdateSelection(0, 0,
+                STRING_TO_TYPE_FIRST.length(), STRING_TO_TYPE_FIRST.length(), -1, -1);
+        type(Constants.CODE_DELETE);
+
+        type(STRING_TO_TYPE_SECOND);
+        mLatinIME.onUpdateSelection(STRING_TO_TYPE_FIRST.length(), STRING_TO_TYPE_FIRST.length(),
+                STRING_TO_TYPE_FIRST.length() - 1 + STRING_TO_TYPE_SECOND.length(),
+                STRING_TO_TYPE_FIRST.length() - 1 + STRING_TO_TYPE_SECOND.length(),
+                -1, -1);
+        assertEquals("auto-correct with space then revert then type more", EXPECTED_RESULT,
+                mEditText.getText().toString());
+    }
+
     public void testAutoCorrectToSelfDoesNotRevert() {
         final String STRING_TO_TYPE = "this ";
         final String EXPECTED_RESULT = "this";
-- 
GitLab