Skip to content

Commit

Permalink
Fix location after inserting multi-line
Browse files Browse the repository at this point in the history
Previously assumed that column was 0 if more than one line was
inserted. This was never correct.
  • Loading branch information
abbec committed Nov 7, 2024
1 parent 8259a3c commit 3e5359d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
29 changes: 15 additions & 14 deletions src/dged/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,25 +526,26 @@ struct location buffer_add(struct buffer *buffer, struct location at,

struct location at_bytes = buffer_location_to_byte_coords(buffer, at);

uint32_t lines_added;
uint32_t ignore_;
text_insert_at(buffer->text, at_bytes.line, at_bytes.col, text, nbytes,
&lines_added);
&ignore_);

// move to after inserted text
if (lines_added > 0) {
final = buffer_clamp(buffer, (int64_t)at.line + lines_added, 0);
} else {
uint32_t cols_added = 0, tab_width = get_tab_width(buffer);
struct utf8_codepoint_iterator iter =
create_utf8_codepoint_iterator(text, nbytes, 0);
struct codepoint *codepoint;
while ((codepoint = utf8_next_codepoint(&iter)) != NULL) {
cols_added += visual_char_width(codepoint, tab_width);
uint32_t cols_added = 0, lines_added = 0, tab_width = get_tab_width(buffer);
struct utf8_codepoint_iterator iter =
create_utf8_codepoint_iterator(text, nbytes, 0);
struct codepoint *codepoint;
while ((codepoint = utf8_next_codepoint(&iter)) != NULL) {
if (codepoint->codepoint == '\n') {
cols_added = 0;
++lines_added;
continue;
}
final =
buffer_clamp(buffer, (int64_t)at.line, (int64_t)at.col + cols_added);
}

cols_added += visual_char_width(codepoint, tab_width);
}
final = buffer_clamp(buffer, (int64_t)at.line + lines_added,
(int64_t)at.col + cols_added);
struct location final_bytes = buffer_location_to_byte_coords(buffer, final);

undo_push_add(
Expand Down
29 changes: 23 additions & 6 deletions test/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ static void test_add(void) {
ASSERT(loc.line == 1 && loc.col == strlen(txt),
"Expected buffer to have one line with characters");

buffer_clear(&b);

// test inserting more than one line and that
// we end up after the inserted text
txt = "some chars\non a second line";
loc = buffer_add(&b, (struct location){.line = 0, .col = 0}, (uint8_t *)txt,
strlen(txt));

ASSERT(loc.line == 1 && loc.col == 16,
"Expected to be at end of second line");

// test callback
uint32_t hook_id = buffer_add_insert_hook(&b, add_callback, NULL);
buffer_add(&b, (struct location){.line = 0, .col = 0}, (uint8_t *)"hej", 3);
Expand Down Expand Up @@ -117,6 +128,8 @@ static void test_line_len(void) {
strlen(txt));
ASSERT(buffer_line_length(&b, 0) == 15,
"Expected banana line to be 15 chars wide");

buffer_destroy(&b);
}

static void test_char_movement(void) {
Expand Down Expand Up @@ -150,6 +163,8 @@ static void test_char_movement(void) {
&b, (struct location){.line = 0, .col = 16 + tab_width});
ASSERT(prev.col == 16,
"Expected a tab move backwards to step over the width of a tab");

buffer_destroy(&b);
}

static void test_word_movement(void) {
Expand Down Expand Up @@ -180,6 +195,8 @@ static void test_word_movement(void) {
prev = buffer_previous_word(&b, (struct location){.line = 0, .col = 0});
ASSERT(prev.col == 0 && prev.line == 0,
"Expected previous word to not go before beginning of buffer");

buffer_destroy(&b);
}

void test_copy(void) {
Expand All @@ -191,8 +208,8 @@ void test_copy(void) {
buffer_paste(&b, (struct location){.line = 0, .col = 4});
ASSERT(buffer_line_length(&b, 0) == 8, "Expected text to be copied");
struct text_chunk t = buffer_line(&b, 0);
ASSERT_STR_EQ((const char *)t.text, "copycopy",
"Expected copied text to match");
ASSERT(memcmp(t.text, "copycopy", t.nbytes) == 0,
"Expected copied text to match");
if (t.allocated) {
free(t.text);
}
Expand All @@ -202,8 +219,8 @@ void test_copy(void) {
buffer_paste(&b, (struct location){.line = 0, .col = 0});
ASSERT(buffer_line_length(&b, 0) == 8, "Expected line length to be the same");
t = buffer_line(&b, 0);
ASSERT_STR_EQ((const char *)t.text, "pycocopy",
"Expected cut+pasted text to match");
ASSERT(memcmp(t.text, "pycocopy", t.nbytes) == 0,
"Expected cut+pasted text to match");
if (t.allocated) {
free(t.text);
}
Expand All @@ -213,8 +230,8 @@ void test_copy(void) {
ASSERT(buffer_line_length(&b, 0) == 12,
"Expected line length to have increased when pasting older");
t = buffer_line(&b, 0);
ASSERT_STR_EQ((const char *)t.text, "copypycocopy",
"Expected pasted older text to match");
ASSERT(memcmp(t.text, "copypycocopy", t.nbytes) == 0,
"Expected pasted older text to match");
if (t.allocated) {
free(t.text);
}
Expand Down

0 comments on commit 3e5359d

Please sign in to comment.