Compose activity: When selection is nonempty and a "special character" button is pressed, decorate all selected word starts (#1523)

* ComposeActivity: When selection is nonempty and a "special character" button is pressed, decorate all selected word starts
Closes #1417

* ComposeActivity: Tests for word break prepend logic
This commit is contained in:
Levi Bard 2020-01-13 15:21:17 +01:00 committed by Konrad Pozniak
commit c9a28b47c1
2 changed files with 189 additions and 2 deletions

View file

@ -416,12 +416,53 @@ class ComposeActivity : BaseActivity(),
composeEditField.setSelection(start + text.length)
}
fun prependSelectedWordsWith(text: CharSequence) {
// If you select "backward" in an editable, you get SelectionStart > SelectionEnd
val start = composeEditField.selectionStart.coerceAtMost(composeEditField.selectionEnd)
val end = composeEditField.selectionStart.coerceAtLeast(composeEditField.selectionEnd)
val editorText = composeEditField.text
if (start == end) {
// No selection, just insert text at caret
editorText.insert(start, text)
// Set the cursor after the inserted text
composeEditField.setSelection(start + text.length)
} else {
var wasWord: Boolean
var isWord = end < editorText.length && !Character.isWhitespace(editorText[end])
var newEnd = end
// Iterate the selection backward so we don't have to juggle indices on insertion
var index = end - 1
while (index >= start - 1 && index >= 0) {
wasWord = isWord
isWord = !Character.isWhitespace(editorText[index])
if (wasWord && !isWord) {
// We've reached the beginning of a word, perform insert
editorText.insert(index + 1, text)
newEnd += text.length
}
--index
}
if (start == 0 && isWord) {
// Special case when the selection includes the start of the text
editorText.insert(0, text)
newEnd += text.length
}
// Keep the same text (including insertions) selected
composeEditField.setSelection(start, newEnd)
}
}
private fun atButtonClicked() {
replaceTextAtCaret("@")
prependSelectedWordsWith("@")
}
private fun hashButtonClicked() {
replaceTextAtCaret("#")
prependSelectedWordsWith("#")
}
override fun onSaveInstanceState(outState: Bundle) {