text_edit: better handle failure to resize underlying buffer

This commit is contained in:
Håkon Stormo
2024-05-23 23:28:39 +02:00
parent f411fcedb0
commit d3bbe29faa
+31 -13
View File
@@ -7,6 +7,7 @@ package text_edit
*/ */
import "base:runtime" import "base:runtime"
import "core:fmt"
import "core:time" import "core:time"
import "core:mem" import "core:mem"
import "core:strings" import "core:strings"
@@ -183,16 +184,17 @@ undo_check :: proc(s: ^State) {
} }
// insert text into the edit state - deletes the current selection // insert text into the edit state - deletes the current selection
input_text :: proc(s: ^State, text: string) { input_text :: proc(s: ^State, text: string) -> int {
if len(text) == 0 { if len(text) == 0 {
return return 0
} }
if has_selection(s) { if has_selection(s) {
selection_delete(s) selection_delete(s)
} }
insert(s, s.selection[0], text) n := insert(s, s.selection[0], text)
offset := s.selection[0] + len(text) offset := s.selection[0] + n
s.selection = {offset, offset} s.selection = {offset, offset}
return n
} }
// insert slice of runes into the edit state - deletes the current selection // insert slice of runes into the edit state - deletes the current selection
@@ -206,8 +208,11 @@ input_runes :: proc(s: ^State, text: []rune) {
offset := s.selection[0] offset := s.selection[0]
for r in text { for r in text {
b, w := utf8.encode_rune(r) b, w := utf8.encode_rune(r)
insert(s, offset, string(b[:w])) n := insert(s, offset, string(b[:w]))
offset += w offset += n
if n != w {
break
}
} }
s.selection = {offset, offset} s.selection = {offset, offset}
} }
@@ -219,17 +224,29 @@ input_rune :: proc(s: ^State, r: rune) {
} }
offset := s.selection[0] offset := s.selection[0]
b, w := utf8.encode_rune(r) b, w := utf8.encode_rune(r)
insert(s, offset, string(b[:w])) n := insert(s, offset, string(b[:w]))
offset += w offset += n
s.selection = {offset, offset} s.selection = {offset, offset}
} }
// insert a single rune into the edit state - deletes the current selection // insert a single rune into the edit state - deletes the current selection
insert :: proc(s: ^State, at: int, text: string) { insert :: proc(s: ^State, at: int, text: string) -> int {
undo_check(s) undo_check(s)
if s.builder != nil { if s.builder != nil {
inject_at(&s.builder.buf, at, text) if ok, _ := inject_at(&s.builder.buf, at, text); !ok {
n := cap(s.builder.buf) - len(s.builder.buf)
assert(n < len(text))
for is_continuation_byte(text[n]) {
n -= 1
}
if ok, _ := inject_at(&s.builder.buf, at, text[:n]); !ok {
n = 0
}
return n
}
return len(text)
} }
return 0
} }
// remove the wanted range withing, usually the selection within byte indices // remove the wanted range withing, usually the selection within byte indices
@@ -263,11 +280,12 @@ selection_delete :: proc(s: ^State) {
s.selection = {lo, lo} s.selection = {lo, lo}
} }
is_continuation_byte :: proc(b: byte) -> bool {
return b >= 0x80 && b < 0xc0
}
// translates the caret position // translates the caret position
translate_position :: proc(s: ^State, t: Translation) -> int { translate_position :: proc(s: ^State, t: Translation) -> int {
is_continuation_byte :: proc(b: byte) -> bool {
return b >= 0x80 && b < 0xc0
}
is_space :: proc(b: byte) -> bool { is_space :: proc(b: byte) -> bool {
return b == ' ' || b == '\t' || b == '\n' return b == ' ' || b == '\t' || b == '\n'
} }