caretToByteOffset converts a (1-based line, 0-based column) caret position into a byte offset into statement. The column is interpreted as a UTF-16 code-unit offset, matching Monaco/LSP completion positions.
(statement string, caretLine, caretColumn int)
| 315 | // into a byte offset into statement. The column is interpreted as a UTF-16 |
| 316 | // code-unit offset, matching Monaco/LSP completion positions. |
| 317 | func caretToByteOffset(statement string, caretLine, caretColumn int) int { |
| 318 | line := 1 |
| 319 | col := 0 |
| 320 | for i := 0; i < len(statement); { |
| 321 | if line == caretLine && col >= caretColumn { |
| 322 | return i |
| 323 | } |
| 324 | r, size := utf8.DecodeRuneInString(statement[i:]) |
| 325 | if r == '\n' { |
| 326 | if line == caretLine { |
| 327 | return i |
| 328 | } |
| 329 | line++ |
| 330 | col = 0 |
| 331 | } else if r <= 0xFFFF { |
| 332 | col++ |
| 333 | } else { |
| 334 | col += 2 |
| 335 | } |
| 336 | i += size |
| 337 | } |
| 338 | return len(statement) |
| 339 | } |