charCount is a useful parameter so we don't need to recompute it when looping

This commit is contained in:
devycarol 2025-03-06 20:55:44 -07:00
parent 711e87d28f
commit b6a13a7473
2 changed files with 28 additions and 24 deletions

View file

@ -113,15 +113,17 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
var actualSteps = 0
// corrected steps to avoid splitting chars belonging to the same codepoint
if (steps > 0) {
val text = inputLogic.mConnection.getSelectedText(0) ?: return steps
loopOverCodePoints(text) {
actualSteps += Character.charCount(it)
val text = inputLogic.mConnection.getSelectedText(0)
if (text == null) actualSteps = steps
else loopOverCodePoints(text) { cp, charCount ->
actualSteps += charCount
actualSteps >= steps
}
} else {
val text = inputLogic.mConnection.getTextBeforeCursor(-steps * 4, 0) ?: return steps
loopOverCodePointsBackwards(text) {
actualSteps -= Character.charCount(it)
val text = inputLogic.mConnection.getTextBeforeCursor(-steps * 4, 0)
if (text == null) actualSteps = steps
else loopOverCodePointsBackwards(text) { cp, charCount ->
actualSteps -= charCount
actualSteps <= steps
}
}
@ -217,12 +219,12 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
private fun positiveMoveSteps(text: CharSequence, steps: Int): Int {
var actualSteps = 0
// corrected steps to avoid splitting chars belonging to the same codepoint
loopOverCodePoints(text) {
if (StringUtils.mightBeEmoji(it)) {
loopOverCodePoints(text) { cp, charCount ->
if (StringUtils.mightBeEmoji(cp)) {
actualSteps = 0
true
}
actualSteps += Character.charCount(it)
actualSteps += charCount
actualSteps >= steps
}
return min(actualSteps, text.length)
@ -231,12 +233,12 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
private fun negativeMoveSteps(text: CharSequence, steps: Int): Int {
var actualSteps = 0
// corrected steps to avoid splitting chars belonging to the same codepoint
loopOverCodePointsBackwards(text) {
if (StringUtils.mightBeEmoji(it)) {
loopOverCodePointsBackwards(text) { cp, charCount ->
if (StringUtils.mightBeEmoji(cp)) {
actualSteps = 0
true
}
actualSteps -= Character.charCount(it)
actualSteps -= charCount
actualSteps <= steps
}
return -min(-actualSteps, text.length)

View file

@ -9,33 +9,35 @@ import helium314.keyboard.latin.settings.SpacingAndPunctuations
import java.math.BigInteger
import java.util.Locale
fun loopOverCodePoints(text: CharSequence, loop: (cp: Int) -> Boolean) {
fun loopOverCodePoints(text: CharSequence, loop: (cp: Int, charCount: Int) -> Boolean) {
val s = text.toString()
var offset = 0
while (offset < s.length) {
val cp = s.codePointAt(offset)
if (loop(cp)) return
offset += Character.charCount(cp)
val charCount = Character.charCount(cp)
if (loop(cp, charCount)) return
offset += charCount
}
}
fun loopOverCodePointsBackwards(text: CharSequence, loop: (cp: Int) -> Boolean) {
fun loopOverCodePointsBackwards(text: CharSequence, loop: (cp: Int, charCount: Int) -> Boolean) {
val s = text.toString()
var offset = s.length
while (offset > 0) {
val cp = s.codePointBefore(offset)
if (loop(cp)) return
offset -= Character.charCount(cp)
val charCount = Character.charCount(cp)
if (loop(cp, charCount)) return
offset -= charCount
}
}
fun nonWordCodePointAndNoSpaceBeforeCursor(text: CharSequence, spacingAndPunctuations: SpacingAndPunctuations): Boolean {
var space = false
var nonWordCodePoint = false
loopOverCodePointsBackwards(text) {
if (!space && Character.isWhitespace(it)) space = true
loopOverCodePointsBackwards(text) { cp, charCount ->
if (!space && Character.isWhitespace(cp)) space = true
// treat double quote like a word codepoint for the purpose of this function (not great, maybe clarify name, or extend list of chars?)
if (!nonWordCodePoint && !spacingAndPunctuations.isWordCodePoint(it) && it != '"'.code) {
if (!nonWordCodePoint && !spacingAndPunctuations.isWordCodePoint(cp) && cp != '"'.code) {
nonWordCodePoint = true
}
space && nonWordCodePoint // stop if both are found
@ -45,9 +47,9 @@ fun nonWordCodePointAndNoSpaceBeforeCursor(text: CharSequence, spacingAndPunctua
fun hasLetterBeforeLastSpaceBeforeCursor(text: CharSequence): Boolean {
var letter = false
loopOverCodePointsBackwards(text) {
if (Character.isWhitespace(it)) true
else if (Character.isLetter(it)) {
loopOverCodePointsBackwards(text) { cp, charCount ->
if (Character.isWhitespace(cp)) true
else if (Character.isLetter(cp)) {
letter = true
true
}