Skip to content

Commit

Permalink
refactor: make clear how to get and expand active text for command ex…
Browse files Browse the repository at this point in the history
…press
  • Loading branch information
WhiredPlanck committed Jan 19, 2025
1 parent 3b59952 commit 3128121
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 46 deletions.
17 changes: 12 additions & 5 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.withContext
import timber.log.Timber
import kotlin.system.measureTimeMillis

/**
* Rime JNI and instance methods
Expand All @@ -41,6 +40,15 @@ class Rime :
override var inputStatusCached = InputStatus()
private set

override var compositionCached = RimeProto.Context.Composition()
private set

override var menuCached = RimeProto.Context.Menu()
private set

override var rawInputCached = ""
private set

private val dispatcher =
RimeDispatcher(
object : RimeDispatcher.RimeLooper {
Expand Down Expand Up @@ -206,6 +214,9 @@ class Rime :
}
}
inputContext = data.context // for compatibility
compositionCached = data.context.composition
menuCached = data.context.menu
rawInputCached = data.context.input
}
else -> {}
}
Expand Down Expand Up @@ -272,10 +283,6 @@ class Rime :
@JvmStatic
fun showAsciiPunch(): Boolean = inputStatus?.isAsciiPunch == true || inputStatus?.isAsciiMode == true

@JvmStatic
val composingText: String
get() = inputContext?.composition?.commitTextPreview ?: ""

@JvmStatic
fun simulateKeySequence(sequence: CharSequence): Boolean {
if (!sequence.first().isAsciiPrintable()) return false
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/com/osfans/trime/core/RimeApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ interface RimeApi {

val inputStatusCached: InputStatus

val compositionCached: RimeProto.Context.Composition

val menuCached: RimeProto.Context.Menu

val rawInputCached: String

suspend fun isEmpty(): Boolean

suspend fun processKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ import android.view.inputmethod.InlineSuggestionsResponse
import android.widget.FrameLayout
import androidx.annotation.Keep
import androidx.core.content.ContextCompat
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.lifecycleScope
import com.osfans.trime.BuildConfig
import com.osfans.trime.R
import com.osfans.trime.core.KeyModifiers
import com.osfans.trime.core.KeyValue
import com.osfans.trime.core.Rime
import com.osfans.trime.core.RimeApi
import com.osfans.trime.core.RimeKeyMapping
import com.osfans.trime.core.RimeMessage
Expand Down Expand Up @@ -736,22 +736,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
return true
}

fun getActiveText(type: Int): String {
if (type == 2) return Rime.getRimeRawInput() ?: "" // 當前編碼
var s = Rime.composingText // 當前候選
if (s.isEmpty()) {
val ic = currentInputConnection
var cs = ic?.getSelectedText(0) // 選中字
if (type == 1 && cs.isNullOrEmpty()) cs = lastCommittedText // 剛上屏字
if (cs.isNullOrEmpty() && ic != null) {
cs = ic.getTextBeforeCursor(if (type == 4) 1024 else 1, 0) // 光標前字
}
if (cs.isNullOrEmpty() && ic != null) cs = ic.getTextAfterCursor(1024, 0) // 光標後面所有字
if (cs != null) s = cs.toString()
}
return s
}

private fun forwardKeyEvent(event: KeyEvent): Boolean {
val modifiers = KeyModifiers.fromKeyEvent(event)
val charCode = event.unicodeChar
Expand Down Expand Up @@ -976,6 +960,46 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
}
}

fun getActiveText(type: Int): String {
if (type == 2) return rime.run { rawInputCached } // 當前編碼
var text: CharSequence? = rime.run { compositionCached }.commitTextPreview // 當前候選
if (text.isNullOrEmpty()) {
val info = currentInputEditorInfo
text = EditorInfoCompat.getInitialSelectedText(info, 0) // 選中字
}
if (text.isNullOrEmpty()) {
if (type == 1) text = lastCommittedText // 剛上屏字
}
if (text.isNullOrEmpty()) {
val step = if (type == 4) 1024 else 1
text = getTextAroundCursor(step, before = true)
}
if (text.isNullOrEmpty()) {
text = getTextAroundCursor(before = false)
}
return text.toString()
}

private fun getTextAroundCursor(
initialStep: Int = 1024,
before: Boolean,
): String? {
val info = currentInputEditorInfo ?: return null
var step = initialStep
while (true) {
val text =
if (before) {
EditorInfoCompat.getInitialTextBeforeCursor(info, step, 0)
} else {
EditorInfoCompat.getInitialTextAfterCursor(info, step, 0)
} ?: return null
if (text.length < step) {
return text.toString()
}
step *= 2
}
}

override fun onEvaluateFullscreenMode(): Boolean = false

private var showingDialog: Dialog? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class CommonKeyboardActionListener(

/** Pattern for braced key event to capture `{Escape}` as group 2 */
private val BRACED_KEY_EVENT_WITH_ESCAPE = """^((\{Escape\})?[^{}]+).*$""".toRegex()

private val PLACEHOLDER_PATTERN = Regex(".*(%([1-4]\\$)?s).*")
}

private val prefs = AppPrefs.defaultInstance()
Expand Down Expand Up @@ -115,6 +117,18 @@ class CommonKeyboardActionListener(
}
}

private fun expandActiveText(input: String): String =
if (input.matches(PLACEHOLDER_PATTERN)) {
input.format(
service.getActiveText(1),
service.getActiveText(2),
service.getActiveText(3),
service.getActiveText(4),
)
} else {
input
}

val listener by lazy {
object : KeyboardActionListener {
override fun onPress(keyEventCode: Int) {
Expand Down Expand Up @@ -160,30 +174,7 @@ class CommonKeyboardActionListener(
}
}
KeyEvent.KEYCODE_FUNCTION -> { // Command Express
// Comments from trime.yaml:
// %s或者%1$s爲當前字符
// %2$s爲當前輸入的編碼
// %3$s爲光標前字符
// %4$s爲光標前所有字符
var arg = action.option
val activeTextRegex = Regex(".*%(\\d*)\\$" + "s.*")
if (arg.matches(activeTextRegex)) {
var activeTextMode =
arg.replaceFirst(activeTextRegex, "$1").toDouble().toInt()
if (activeTextMode < 1) {
activeTextMode = 1
}
val activeText = service.getActiveText(activeTextMode)
arg =
String.format(
arg,
service.lastCommittedText,
Rime.getRimeRawInput() ?: "",
activeText,
activeText,
)
}

val arg = expandActiveText(action.option)
when (action.command) {
"liquid_keyboard" -> {
val target =
Expand Down

0 comments on commit 3128121

Please sign in to comment.