diff --git a/src/io/github/sspanak/tt9/ime/TraditionalT9.java b/src/io/github/sspanak/tt9/ime/TraditionalT9.java index d8906cce..6c6b80a1 100644 --- a/src/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/src/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -248,7 +248,7 @@ public class TraditionalT9 extends KeyPadHandler { mInputMode.onAcceptSuggestion(word); commitCurrentSuggestion(); - autoCorrectSpace(word, true); + autoCorrectSpace(word, true, KeyEvent.KEYCODE_ENTER); resetKeyRepeat(); return true; @@ -329,7 +329,7 @@ public class TraditionalT9 extends KeyPadHandler { // Automatically accept the current word, when the next one is a space or punctuation, // instead of requiring "OK" before that. if (mInputMode.shouldAcceptCurrentSuggestion(key, hold, repeat > 0)) { - autoCorrectSpace(acceptIncompleteSuggestion(), false); + autoCorrectSpace(acceptIncompleteSuggestion(), false, key); currentWord = ""; } @@ -359,7 +359,7 @@ public class TraditionalT9 extends KeyPadHandler { String acceptedWord = acceptIncompleteSuggestion(); if (mInputMode.onOtherKey(keyCode)) { - autoCorrectSpace(acceptedWord, false); + autoCorrectSpace(acceptedWord, false, keyCode); getSuggestions(); resetKeyRepeat(); return true; @@ -377,12 +377,12 @@ public class TraditionalT9 extends KeyPadHandler { cancelAutoAccept(); // accept the previously typed word (if any) - autoCorrectSpace(acceptIncompleteSuggestion(), false); + autoCorrectSpace(acceptIncompleteSuggestion(), false, -1); // "type" and accept the text mInputMode.onAcceptSuggestion(text); textField.setText(text); - autoCorrectSpace(text, true); + autoCorrectSpace(text, true, -1); return true; } @@ -670,12 +670,12 @@ public class TraditionalT9 extends KeyPadHandler { } - private void autoCorrectSpace(String currentWord, boolean isWordAcceptedManually) { + private void autoCorrectSpace(String currentWord, boolean isWordAcceptedManually, int nextKey) { if (mInputMode.shouldDeletePrecedingSpace(inputType)) { textField.deletePrecedingSpace(currentWord); } - if (mInputMode.shouldAddAutoSpace(inputType, textField, isWordAcceptedManually)) { + if (mInputMode.shouldAddAutoSpace(inputType, textField, isWordAcceptedManually, nextKey)) { textField.setText(" "); } } diff --git a/src/io/github/sspanak/tt9/ime/modes/InputMode.java b/src/io/github/sspanak/tt9/ime/modes/InputMode.java index 27bffcb4..52d51199 100644 --- a/src/io/github/sspanak/tt9/ime/modes/InputMode.java +++ b/src/io/github/sspanak/tt9/ime/modes/InputMode.java @@ -98,7 +98,7 @@ abstract public class InputMode { // Interaction with the IME. Return "true" if it should perform the respective action. public boolean shouldAcceptCurrentSuggestion(int key, boolean hold, boolean repeat) { return false; } - public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually) { return false; } + public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually, int nextKey) { return false; } public boolean shouldDeletePrecedingSpace(InputType inputType) { return false; } public boolean shouldSelectNextSuggestion() { return false; } diff --git a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java index 8af9cb96..a0d21357 100644 --- a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java +++ b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java @@ -37,6 +37,7 @@ public class ModePredictive extends InputMode { ModePredictive(SettingsStore settings, Language lang) { changeLanguage(lang); + defaultTextCase(); autoSpace = new AutoSpace(settings); autoTextCase = new AutoTextCase(settings); @@ -303,13 +304,13 @@ public class ModePredictive extends InputMode { @Override - public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually) { + public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually, int nextKey) { return autoSpace .setLastWord(lastAcceptedWord) .setLastSequence(lastAcceptedSequence) .setInputType(inputType) .setTextField(textField) - .shouldAddAutoSpace(isWordAcceptedManually); + .shouldAddAutoSpace(isWordAcceptedManually, nextKey); } diff --git a/src/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java b/src/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java index 4a6147f3..d1a0a1bc 100644 --- a/src/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java +++ b/src/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java @@ -8,7 +8,8 @@ import io.github.sspanak.tt9.preferences.SettingsStore; public class AutoSpace { private final Pattern isNumber = Pattern.compile("\\s*\\d+\\s*"); - private final Pattern isPunctuation = Pattern.compile("\\p{Punct}"); + private final Pattern nextIsLetter = Pattern.compile("^\\p{L}+"); + private final Pattern nextIsPunctuation = Pattern.compile("^\\p{Punct}"); private final SettingsStore settings; @@ -49,32 +50,37 @@ public class AutoSpace { * * See the helper functions for the list of rules. */ - public boolean shouldAddAutoSpace(boolean isWordAcceptedManually) { + public boolean shouldAddAutoSpace(boolean isWordAcceptedManually, int nextKey) { String previousChars = textField.getPreviousChars(2); String nextChars = textField.getNextChars(2); return settings.getAutoSpace() - && !isNumber.matcher(previousChars).find() - && ( - shouldAddAutoSpaceAfterPunctuation(previousChars) - || shouldAddAutoSpaceAfterWord(isWordAcceptedManually) - ) + && !inputType.isSpecialized() && !nextChars.startsWith(" ") - && !isPunctuation.matcher(nextChars).find(); + && !isNumber.matcher(previousChars).find() + && !nextIsPunctuation.matcher(nextChars).find() + && ( + shouldAddAfterPunctuation(previousChars, nextKey) + || shouldAddAfterWord(isWordAcceptedManually, nextChars) + ); } /** - * shouldAddAutoSpaceAfterPunctuation + * shouldAddAfterPunctuation * Determines whether to automatically adding a space after certain punctuation signs makes sense. * The rules are similar to the ones in the standard Android keyboard (with some exceptions, * because we are not using a QWERTY keyboard here). */ - private boolean shouldAddAutoSpaceAfterPunctuation(String previousChars) { + private boolean shouldAddAfterPunctuation(String previousChars, int nextKey) { return - !inputType.isSpecialized() - && !previousChars.endsWith(" ") && !previousChars.endsWith("\n") && !previousChars.endsWith("\t") + // no space after whitespace or special characters + !previousChars.endsWith(" ") && !previousChars.endsWith("\n") && !previousChars.endsWith("\t") // previous whitespace + && !lastSequence.equals("0") // previous previous math/special char + && nextKey != 0 // composing (upcoming) whitespace or special character + + // add space after the these && ( previousChars.endsWith(".") || previousChars.endsWith(",") @@ -92,19 +98,15 @@ public class AutoSpace { /** - * shouldAddAutoSpaceAfterPunctuation - * Similar to "shouldAddAutoSpaceAfterPunctuation()", but determines whether to add a space after - * words. + * shouldAddAfterPunctuation + * Similar to "shouldAddAfterPunctuation()", but determines whether to add a space after words. */ - private boolean shouldAddAutoSpaceAfterWord(boolean isWordAcceptedManually) { + private boolean shouldAddAfterWord(boolean isWordAcceptedManually, String nextChars) { return // Do not add space when auto-accepting words, because it feels very confusing when typing. isWordAcceptedManually - // Secondary punctuation - && !lastSequence.equals("0") - // Emoji - && !lastSequence.startsWith("1") - && !inputType.isSpecialized(); + // Right before another word + && !nextIsLetter.matcher(nextChars).find(); }