mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-12 04:54:27 +00:00
firstLineOf (query) and truncateString (edit) sliced strings at a raw byte offset, splitting a multibyte UTF-8 character into invalid bytes in LLM-facing output (ast_query compact format and edit not-found errors are hot paths). Extract the rune-boundary backoff already used by search's truncateLine into util.RuneBoundary and route all three sites through it. Adds table-driven tests for the primitive and a multibyte case for firstLineOf.
21 lines
528 B
Go
21 lines
528 B
Go
package util
|
|
|
|
import "unicode/utf8"
|
|
|
|
// RuneBoundary returns the largest index j <= i such that s[:j] is valid UTF-8
|
|
// (j falls on a rune start, never inside a multibyte sequence). i is clamped to
|
|
// [0, len(s)]. Callers slicing s[:i] for truncation should slice s[:RuneBoundary(s, i)]
|
|
// instead so a multibyte character is never split into an invalid encoding.
|
|
func RuneBoundary(s string, i int) int {
|
|
if i <= 0 {
|
|
return 0
|
|
}
|
|
if i >= len(s) {
|
|
return len(s)
|
|
}
|
|
for i > 0 && !utf8.RuneStart(s[i]) {
|
|
i--
|
|
}
|
|
return i
|
|
}
|