Переглянути джерело

Add loads of `nil` checks when doing `s.builder`

gingerBill 1 рік тому
батько
коміт
69db9c6390
1 змінених файлів з 22 додано та 9 видалено
  1. 22 9
      core/text/edit/text_edit.odin

+ 22 - 9
core/text/edit/text_edit.odin

@@ -92,7 +92,7 @@ begin :: proc(s: ^State, id: u64, builder: ^strings.Builder) {
 		end(s)
 	}
 	s.id = id
-	s.selection = {len(builder.buf), 0}
+	s.selection = {len(builder.buf, 0}
 	s.builder = builder
 	update_time(s)
 	undo_clear(s, &s.undo)
@@ -137,6 +137,9 @@ clear_all :: proc(s: ^State) -> (cleared: bool) {
 
 // push current text state to the wanted undo|redo stack
 undo_state_push :: proc(s: ^State, undo: ^[dynamic]^Undo_State) -> mem.Allocator_Error {
+	if s.builder != nil {
+		return nil
+	}
 	text := string(s.builder.buf[:])
 	item := (^Undo_State)(mem.alloc(size_of(Undo_State) + len(text), align_of(Undo_State), s.undo_text_allocator) or_return)
 	item.selection = s.selection
@@ -154,7 +157,7 @@ undo :: proc(s: ^State, undo, redo: ^[dynamic]^Undo_State) {
 		undo_state_push(s, redo)
 		item := pop(undo)
 		s.selection = item.selection
-		#no_bounds_check {
+		#no_bounds_check if s.builder != nil {
 			strings.builder_reset(s.builder)
 			strings.write_string(s.builder, string(item.text[:item.len]))
 		}
@@ -224,13 +227,17 @@ input_rune :: proc(s: ^State, r: rune) {
 // insert a single rune into the edit state - deletes the current selection
 insert :: proc(s: ^State, at: int, text: string) {
 	undo_check(s)
-	inject_at(&s.builder.buf, at, text)
+	if s.builder != nil {
+		inject_at(&s.builder.buf, at, text)
+	}
 }
 
 // remove the wanted range withing, usually the selection within byte indices
 remove :: proc(s: ^State, lo, hi: int) {
 	undo_check(s)
-	remove_range(&s.builder.buf, lo, hi)
+	if s.builder != nil {
+		remove_range(&s.builder.buf, lo, hi)
+	}
 }
 
 // true if selection head and tail dont match and form a selection of multiple characters
@@ -244,8 +251,8 @@ has_selection :: proc(s: ^State) -> bool {
 sorted_selection :: proc(s: ^State) -> (lo, hi: int) {
 	lo = min(s.selection[0], s.selection[1])
 	hi = max(s.selection[0], s.selection[1])
-	lo = clamp(lo, 0, len(s.builder.buf))
-	hi = clamp(hi, 0, len(s.builder.buf))
+	lo = clamp(lo, 0, len(s.builder.buf) if s.builder != nil else 0)
+	hi = clamp(hi, 0, len(s.builder.buf) if s.builder != nil else 0)
 	return
 }
 
@@ -265,7 +272,10 @@ translate_position :: proc(s: ^State, t: Translation) -> int {
 		return b == ' ' || b == '\t' || b == '\n'
 	}
 
-	buf := s.builder.buf[:]
+	buf: []byte
+	if s.builder != nil {
+		buf = s.builder.buf[:]
+	}
 	pos := clamp(s.selection[0], 0, len(buf))
 
 	switch t {
@@ -352,7 +362,10 @@ delete_to :: proc(s: ^State, t: Translation) {
 // return the currently selected text
 current_selected_text :: proc(s: ^State) -> string {
 	lo, hi := sorted_selection(s)
-	return string(s.builder.buf[lo:hi])
+	if s.builder != nil {
+		return string(s.builder.buf[lo:hi])
+	}
+	return ""
 }
 
 // copy & delete the current selection when copy() succeeds
@@ -431,7 +444,7 @@ perform_command :: proc(s: ^State, cmd: Command) {
 	case .Cut:               cut(s)
 	case .Copy:              copy(s)
 	case .Paste:             paste(s)
-	case .Select_All:        s.selection = {len(s.builder.buf), 0}
+	case .Select_All:        s.selection = {len(s.builder.buf) if s.builder != nil else 0, 0}
 	case .Backspace:         delete_to(s, .Left)
 	case .Delete:            delete_to(s, .Right)
 	case .Delete_Word_Left:  delete_to(s, .Word_Left)