Files
crib-old/src/editor/move_line.cc
T
2026-04-13 10:32:46 +01:00

109 lines
4.2 KiB
C++
Executable File

#include "editor/editor.h"
#include "main.h"
void Editor::move_line_up() {
if (!this->root || this->cursor.row == 0)
return;
if (mode == NORMAL || mode == INSERT) {
uint32_t line_len, line_cluster_len;
LineIterator *it = begin_l_iter(this->root, this->cursor.row);
char *line = next_line(it, &line_len);
if (!line)
return;
if (line_len > 0 && line[line_len - 1] == '\n')
line_len--;
line_cluster_len = count_clusters(line, line_len, 0, line_len);
uint32_t target_row = this->cursor.row - 1;
uint32_t up_by = this->cursor.row - target_row;
if (up_by > 1)
up_by--;
Coord cursor = this->cursor;
edit_erase({cursor.row, 0}, line_cluster_len);
edit_erase({cursor.row, 0}, -1);
edit_insert({cursor.row - up_by, 0}, (char *)"\n", 1);
edit_insert({cursor.row - up_by, 0}, line, line_len);
free(it->buffer);
free(it);
this->cursor = {cursor.row - up_by, cursor.col};
} else if (mode == SELECT) {
uint32_t start_row = MIN(this->cursor.row, this->selection.row);
uint32_t end_row = MAX(this->cursor.row, this->selection.row);
uint32_t start_byte = line_to_byte(this->root, start_row, nullptr);
uint32_t end_byte = line_to_byte(this->root, end_row + 1, nullptr);
char *selected_text = read(this->root, start_byte, end_byte - start_byte);
if (!selected_text)
return;
uint32_t selected_len = count_clusters(selected_text, end_byte - start_byte,
0, end_byte - start_byte);
Coord cursor = this->cursor;
Coord selection = this->selection;
edit_erase({start_row, 0}, selected_len);
edit_insert({start_row - 1, 0}, selected_text, end_byte - start_byte);
free(selected_text);
this->cursor = {cursor.row - 1, cursor.col};
this->selection = {selection.row - 1, selection.col};
}
}
void Editor::move_line_down() {
if (!this->root)
return;
if (mode == NORMAL || mode == INSERT) {
if (this->cursor.row >= this->root->line_count - 1)
return;
uint32_t line_len, line_cluster_len;
LineIterator *it = begin_l_iter(this->root, this->cursor.row);
char *line = next_line(it, &line_len);
if (!line)
return;
if (line_len && line[line_len - 1] == '\n')
line_len--;
line_cluster_len = count_clusters(line, line_len, 0, line_len);
uint32_t target_row = this->cursor.row + 1;
if (target_row >= this->root->line_count) {
free(it->buffer);
free(it);
return;
}
uint32_t down_by = target_row - this->cursor.row;
if (down_by > 1)
down_by--;
uint32_t ln;
line_to_byte(this->root, this->cursor.row + down_by - 1, &ln);
Coord cursor = this->cursor;
edit_erase({cursor.row, 0}, line_cluster_len);
edit_erase({cursor.row, 0}, -1);
edit_insert({cursor.row + down_by, 0}, (char *)"\n", 1);
edit_insert({cursor.row + down_by, 0}, line, line_len);
free(it->buffer);
free(it);
this->cursor = {cursor.row + down_by, cursor.col};
} else if (mode == SELECT) {
if (this->cursor.row >= this->root->line_count - 1 ||
this->selection.row >= this->root->line_count - 1)
return;
uint32_t start_row = MIN(this->cursor.row, this->selection.row);
uint32_t end_row = MAX(this->cursor.row, this->selection.row);
uint32_t target_row = end_row + 1;
if (target_row >= this->root->line_count)
return;
uint32_t down_by = target_row - end_row;
if (down_by > 1)
down_by--;
uint32_t start_byte = line_to_byte(this->root, start_row, nullptr);
uint32_t end_byte = line_to_byte(this->root, end_row + 1, nullptr);
char *selected_text = read(this->root, start_byte, end_byte - start_byte);
if (!selected_text)
return;
uint32_t selected_len = count_clusters(selected_text, end_byte - start_byte,
0, end_byte - start_byte);
Coord cursor = this->cursor;
Coord selection = this->selection;
edit_erase({start_row, 0}, selected_len);
edit_insert({start_row + down_by, 0}, selected_text, end_byte - start_byte);
free(selected_text);
this->cursor = {cursor.row + down_by, cursor.col};
this->selection = {selection.row + down_by, selection.col};
}
}