Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,25 +152,27 @@ class SpanManager {
private fun mergeSpans(spans: List<SpanInfo>): List<SpanInfo> {
if (spans.isEmpty()) return emptyList()

// Group spans by style and merge within each group
val result = mutableListOf<SpanInfo>()
val sorted = spans.sortedBy { it.start }

var current = sorted.first()
var mergeCount = 0

for (i in 1 until sorted.size) {
val next = sorted[i]
if (current.overlaps(next) || current.isAdjacent(next)) {
current = current.merge(next)
mergeCount++
} else {
result.add(current)
current = next
val spansByStyle = spans.groupBy { it.style }

spansByStyle.forEach { (_, styleSpans) ->
val sorted = styleSpans.sortedBy { it.start }
var current = sorted.first()
var mergeCount = 0

for (i in 1 until sorted.size) {
val next = sorted[i]
if (current.overlaps(next) || current.isAdjacent(next)) {
current = current.merge(next)
mergeCount++
} else {
result.add(current)
current = next
}
}
result.add(current)
}
result.add(current)

//println("Style Spans Merged: $mergeCount")

return result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import com.darkrockstudios.texteditor.state.SpanManager
import com.darkrockstudios.texteditor.utils.mergeAnnotatedStrings
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -297,4 +300,39 @@ class TextEditManagerSpanMergeTest {
val blueSpan = result.spanStyles.first { it.start == 12 && it.end == 15 }
assertEquals(Color.Blue, blueSpan.item.color)
}

@Test
fun `test insert character into overlapping styled text - bold and underline`() {
// Arrange - create text with overlapping bold and underline spans
val original = buildAnnotatedString {
append("Welcome")
addStyle(SpanStyle(fontWeight = FontWeight.Bold), 0, 7) // bold
addStyle(SpanStyle(textDecoration = TextDecoration.Underline), 0, 7) // underline
}

// Simulate inserting "a" at position 3 (between "l" and "c")
val newText = buildAnnotatedString {
append("a")
addStyle(SpanStyle(fontWeight = FontWeight.Bold), 0, 1) // bold
addStyle(SpanStyle(textDecoration = TextDecoration.Underline), 0, 1) // underline
}
val insertionIndex = 3

// Act
val result = manager.mergeAnnotatedStrings(original, start = insertionIndex, newText = newText)

// Assert
assertEquals("Welacome", result.text)
// Should have 2 spans: bold(0-8) and underline(0-8)
assertEquals(2, result.spanStyles.size)

val boldSpan = result.spanStyles.find { it.item.fontWeight == FontWeight.Bold }
val underlineSpan = result.spanStyles.find { it.item.textDecoration == TextDecoration.Underline }

assertNotNull(boldSpan)
assertNotNull(underlineSpan)

boldSpan?.let { assertEquals(0, it.start); assertEquals(8, it.end) }
underlineSpan?.let { assertEquals(0, it.start); assertEquals(8, it.end) }
}
}