summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2024-11-07 13:47:50 +0100
committerAlbert Cervin <albert@acervin.com>2024-11-07 13:47:50 +0100
commit3e5359d062fa2f0d48e6f7675802b875e11ee109 (patch)
treeafe7358b9e62abbc2d54e710c849f3769fe47994
parent8259a3c5d4caf31423d8ca3108c4f2a1f9bd78af (diff)
downloaddged-3e5359d062fa2f0d48e6f7675802b875e11ee109.tar.gz
dged-3e5359d062fa2f0d48e6f7675802b875e11ee109.tar.xz
dged-3e5359d062fa2f0d48e6f7675802b875e11ee109.zip
Fix location after inserting multi-line
Previously assumed that column was 0 if more than one line was inserted. This was never correct.
-rw-r--r--src/dged/buffer.c29
-rw-r--r--test/buffer.c29
2 files changed, 38 insertions, 20 deletions
diff --git a/src/dged/buffer.c b/src/dged/buffer.c
index 84d2f75..91c1a14 100644
--- a/src/dged/buffer.c
+++ b/src/dged/buffer.c
@@ -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(
diff --git a/test/buffer.c b/test/buffer.c
index efc479e..f40166e 100644
--- a/test/buffer.c
+++ b/test/buffer.c
@@ -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);
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);
}
@@ -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);
}
@@ -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);
}