diff --git a/core/text/edit/text_edit.odin b/core/text/edit/text_edit.odin index caccb6be8..08fce0444 100644 --- a/core/text/edit/text_edit.odin +++ b/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)