#include "editor/editor.h" #include "utils/utils.h" void selection_bounds(Editor *editor, Coord *out_start, Coord *out_end) { std::shared_lock lock(editor->knot_mtx); Coord start, end; if (editor->cursor >= editor->selection) { uint32_t prev_col; switch (editor->selection_type) { case CHAR: start = editor->selection; end = move_right(editor, editor->cursor, 1); break; case WORD: word_boundaries(editor, editor->selection, &prev_col, nullptr, nullptr, nullptr); start = {editor->selection.row, prev_col}; end = editor->cursor; break; case LINE: start = {editor->selection.row, 0}; end = editor->cursor; break; } } else { start = editor->cursor; uint32_t next_col, line_len; switch (editor->selection_type) { case CHAR: end = move_right(editor, editor->selection, 1); break; case WORD: word_boundaries(editor, editor->selection, nullptr, &next_col, nullptr, nullptr); end = {editor->selection.row, next_col}; break; case LINE: LineIterator *it = begin_l_iter(editor->root, editor->selection.row); char *line = next_line(it, &line_len); if (!line) return; if (line_len > 0 && line[line_len - 1] == '\n') line_len--; end = {editor->selection.row, line_len}; free(it->buffer); free(it); break; } } if (out_start) *out_start = start; if (out_end) *out_end = end; } char *get_selection(Editor *editor, uint32_t *out_len, Coord *out_start) { std::shared_lock lock(editor->knot_mtx); Coord start, end; if (editor->cursor >= editor->selection) { uint32_t prev_col; switch (editor->selection_type) { case CHAR: start = editor->selection; end = move_right(editor, editor->cursor, 1); break; case WORD: word_boundaries(editor, editor->selection, &prev_col, nullptr, nullptr, nullptr); start = {editor->selection.row, prev_col}; end = editor->cursor; break; case LINE: start = {editor->selection.row, 0}; end = editor->cursor; break; } } else { start = editor->cursor; uint32_t next_col, line_len; switch (editor->selection_type) { case CHAR: end = move_right(editor, editor->selection, 1); break; case WORD: word_boundaries(editor, editor->selection, nullptr, &next_col, nullptr, nullptr); end = {editor->selection.row, next_col}; break; case LINE: LineIterator *it = begin_l_iter(editor->root, editor->selection.row); char *line = next_line(it, &line_len); if (!line) return nullptr; if (line_len > 0 && line[line_len - 1] == '\n') line_len--; end = {editor->selection.row, line_len}; free(it->buffer); free(it); break; } } if (out_start) *out_start = start; uint32_t start_byte = line_to_byte(editor->root, start.row, nullptr) + start.col; uint32_t end_byte = line_to_byte(editor->root, end.row, nullptr) + end.col; char *text = read(editor->root, start_byte, end_byte - start_byte); if (out_len) *out_len = end_byte - start_byte; return text; }