typedef struct caret_t caret_t; struct caret_t { i64 ifront; union { r1i64_t range; i64 pos[2]; }; }; typedef struct xy_t xy_t; struct xy_t { i64 col; i64 line; }; typedef struct edit16_t edit16_t; struct edit16_t { r1i64_t range; s16_t string; }; // @todo: redo tree typedef array(edit16_t) array_edit16_t; typedef array(caret_t) array_caret_t; typedef struct history16_t history16_t; struct history16_t { array_edit16_t edits; array_caret_t carets; }; typedef array(history16_t) array_history16_t; typedef struct buffer16_id_t buffer16_id_t; struct buffer16_id_t { i64 e; }; typedef struct buffer16_t buffer16_t; struct buffer16_t { s8_t name; buffer16_id_t id; i32 change_id; i8 edit_phase; struct { b8 dirty: 1; b8 history: 1; b8 line_starts: 1; } flags; union { s16_t string; u16 *data; struct { u16 *str; i64 len; }; }; i64 cap; array_i64_t line_starts; array_history16_t undo_stack; array_history16_t redo_stack; alo_t alo; }; const b32 dont_kill_selection = false; const b32 kill_selection = true; /////////////////////////////// // caret helpers fn caret_t caret_make(i64 front, i64 back); fn i64 caret_get_front(caret_t caret); fn i64 caret_get_back(caret_t caret); fn caret_t caret_set_front(caret_t caret, i64 pos); fn caret_t caret_set_back(caret_t caret, i64 pos); fn b32 carets_are_equal(caret_t a, caret_t b); fn b32 carets_overlap(caret_t a, caret_t b); /////////////////////////////// // buffer helpers fn i64 buffer16_pos_to_line(buffer16_t *buffer, i64 pos); fn r1i64_t buffer16_get_line_range(buffer16_t *buffer, i64 line); fn r1i64_t buffer16_get_line_range_full(buffer16_t *buffer, i64 line, i64 *eof); fn xy_t buffer16_pos_to_xy(buffer16_t *buffer, i64 pos); fn i64 buffer16_xy_to_pos(buffer16_t *buffer, xy_t xy); fn i64 buffer16_xy_to_pos_without_new_line(buffer16_t *buffer, xy_t xy); fn s16_t buffer16_get_string(buffer16_t *buffer, r1i64_t range); fn s16_t buffer16_get_line_string(buffer16_t *buffer, i64 line); fn r1i64_t buffer16_get_range_end(buffer16_t *buffer); fn r1i64_t buffer16_get_range(buffer16_t *buffer); fn i64 buffer16_clamp_pos(buffer16_t *buffer, i64 pos); fn r1i64_t buffer16_clamp_range(buffer16_t *buffer, r1i64_t range); fn i64 buffer16_get_word_start(buffer16_t *buffer, i64 pos); fn i64 buffer16_get_word_end(buffer16_t *buffer, i64 pos); fn i64 buffer16_get_next_word_end(buffer16_t *buffer, i64 pos); fn i64 buffer16_get_prev_word_start(buffer16_t *buffer, i64 pos); fn i64 buffer16_get_line_start(buffer16_t *buffer, i64 pos, i64 *eof); fn i64 buffer16_get_line_end(buffer16_t *buffer, i64 pos, i64 *eof); fn i64 buffer16_get_line_start_full(buffer16_t *buffer, i64 pos); fn i64 buffer16_get_line_end_full(buffer16_t *buffer, i64 pos); fn r1i64_t buffer16_enclose_word(buffer16_t *buffer, i64 pos); fn u16 buffer16_get_char(buffer16_t *buffer, i64 pos); fn i64 buffer16_offset_pos_by_line(buffer16_t *buffer, i64 pos, i64 line_offset); /////////////////////////////// // buffer raw textural operations. no history fn void buffer16_raw_grow(buffer16_t *buffer, i64 change_size); fn void buffer16_raw_replace_text(buffer16_t *buffer, r1i64_t range, s16_t string); /////////////////////////////// // buffer multicursor + history fn void buffer16_init(alo_t alo, buffer16_t *buffer, s8_t name, i64 size); fn void buffer16_deinit(buffer16_t *buffer); fn void buffer16_add_edit(array_edit16_t *edits, r1i64_t range, s16_t string); fn array_edit16_t buffer16_begin_edit(alo_t alo, buffer16_t *buffer, array_caret_t *carets); fn void buffer16_end_edit(buffer16_t *buffer, array_edit16_t *edits, array_caret_t *carets, b32 kill_selection); fn void buffer16_merge_carets(buffer16_t *buffer, array_caret_t *carets); fn void buffer16_adjust_carets(array_edit16_t *edits, array_caret_t *carets); fn void buffer16_redo_edit(buffer16_t *buffer, array_caret_t *carets); fn void buffer16_undo_edit(buffer16_t *buffer, array_caret_t *carets); fn void buffer16_save_history_before_merge_cursor(buffer16_t *buffer, array_history16_t *stack, array_caret_t *carets); fn void buffer16_save_history_before_apply_edits(buffer16_t *buffer, array_history16_t *stack, array_edit16_t *edits); fn void buffer16_pre_begin_edit_save_caret_history(buffer16_t *buffer, array_caret_t *carets); fn void buffer16_dealloc_history_entries(buffer16_t *buffer, array_history16_t *entries); fn void buffer16_dealloc_history_array(buffer16_t *buffer, array_history16_t *entries); fn void buffer16_multi_cursor_apply_edits(buffer16_t *buffer, array_edit16_t edits);