diff --git a/editor/editor.hpp b/editor/editor.hpp index 10840da..d4d2c2b 100644 --- a/editor/editor.hpp +++ b/editor/editor.hpp @@ -83,7 +83,8 @@ struct buffer { inline static constexpr line * incref(line * l); inline static constexpr int32_t line_length(line const * const l); inline constexpr bool put(uint8_t c); - inline constexpr bool backspace(); + inline constexpr bool delete_backward(); + inline constexpr bool delete_forward(); inline constexpr bool cursor_left(); inline constexpr bool cursor_right(); inline constexpr bool cursor_up(); @@ -239,7 +240,7 @@ inline constexpr bool buffer::put(const uint8_t c) } template -inline constexpr bool buffer::backspace() +inline constexpr bool buffer::delete_backward() { if (this->mode == mode::mark) { this->mode = mode::normal; @@ -274,11 +275,48 @@ inline constexpr bool buffer::backspace() line * l = mutref(this->lines[cur.row]); int32_t length = l->length - cur.col; move(&l->buf[cur.col-1], &l->buf[cur.col], length); + l->length--; cur.col--; scroll_left(); + } + + return true; +} + +template +inline constexpr bool buffer::delete_forward() +{ + if (this->mode == mode::mark) { + this->mode = mode::normal; + return mark_delete(); + } + + editor::cursor& cur = this->cursor; + + if (cur.col < 0 || cur.col > C) + return false; + + if (line_length(this->lines[cur.row]) == 0) { + if (this->length == 1) return false; + decref(this->lines[cur.row]); + // shift all lines up by 1 + int32_t n_lines = this->length - (cur.row + 1); + move(&this->lines[cur.row], + &this->lines[cur.row+1], + (sizeof (line*)) * n_lines); + this->length--; + this->lines[this->length] = nullptr; + // no scrolling needed--cursor is already in the correct position + } else { + // c + // 01234 + line * l = mutref(this->lines[cur.row]); + int32_t length = l->length - cur.col; + move(&l->buf[cur.col], &l->buf[cur.col+1], length); l->length--; - l->buf[l->length] = 0x7f; + + // no scrolling needed--cursor is already in the correct position } return true; diff --git a/editor/main_saturn.cpp b/editor/main_saturn.cpp index 1f11694..814fe8e 100644 --- a/editor/main_saturn.cpp +++ b/editor/main_saturn.cpp @@ -92,7 +92,8 @@ inline void keyboard_regular_key(const enum keysym k) switch (modifier_state) { case MODIFIER_NONE: switch (k) { - case keysym::BACKSPACE : buffer.backspace(); break; + case keysym::BACKSPACE : buffer.delete_backward(); break; + case keysym::DELETE : buffer.delete_forward(); break; case keysym::ARROW_LEFT : buffer.cursor_left(); break; case keysym::ARROW_RIGHT: buffer.cursor_right(); break; case keysym::ARROW_UP : buffer.cursor_up(); break; diff --git a/editor/test_editor.cpp b/editor/test_editor.cpp index 2d762a6..895c0be 100644 --- a/editor/test_editor.cpp +++ b/editor/test_editor.cpp @@ -109,10 +109,10 @@ void test_backspace() assert(l->length == 1); assert(l->buf[0] == 'a'); - assert(b.backspace() == true); + assert(b.delete_backward() == true); assert(l->length == 0); - assert(b.backspace() == false); + assert(b.delete_backward() == false); b.put('b'); b.put('c'); @@ -122,7 +122,7 @@ void test_backspace() assert(l->length == 4); //"bcde" - assert(b.backspace() == true); + assert(b.delete_backward() == true); assert(l->buf[0] == 'b'); assert(l->buf[1] == 'd'); assert(l->buf[2] == 'e'); @@ -202,8 +202,8 @@ void test_enter_backspace1() b.enter(); b.enter(); assert(b.length == 3); - b.backspace(); - b.backspace(); + b.delete_backward(); + b.delete_backward(); assert(b.length == 1); b.enter(); assert(b.length == 2); @@ -223,7 +223,7 @@ void test_enter_backspace2() assert(b.cursor.row == 1); assert(b.cursor.col == 0); assert(b.length == 2); - b.backspace(); + b.delete_backward(); assert(b.cursor.row == 0); assert(b.cursor.col == 1); assert(b.length == 1); @@ -281,7 +281,7 @@ void test_enter_backspace3() assert(b.lines[4] == nullptr); assert(b.length == 4); - b.backspace(); + b.delete_backward(); assert(b.length == 3); assert(b.lines[0]->buf[0] == 'a'); assert(b.lines[1]->length == 0); @@ -731,6 +731,38 @@ void test_shadow_paste_multiline() assert(b.lines[4]->buf[2] == 'x'); } +void test_delete_forward() +{ + buffer<8, 8> b {4, 2}; + b.put('a'); + b.put('b'); + b.put('c'); + b.cursor_left(); + b.cursor_left(); + b.delete_forward(); + assert(b.lines[0]->length == 2); + assert(b.lines[0]->buf[0] == 'a'); + assert(b.lines[0]->buf[1] == 'c'); + + // + b.cursor_end(); + b.enter(); + b.enter(); + b.put('q'); + b.put('w'); + b.cursor_home(); + b.cursor_up(); + assert(b.length == 3); + b.delete_forward(); + assert(b.length == 2); + assert(b.lines[0]->length == 2); + assert(b.lines[0]->buf[0] == 'a'); + assert(b.lines[0]->buf[1] == 'c'); + assert(b.lines[1]->length == 2); + assert(b.lines[1]->buf[0] == 'q'); + assert(b.lines[1]->buf[1] == 'w'); +} + int main() { test_allocate(); @@ -749,6 +781,7 @@ int main() test_selection_delete(); test_shadow_paste_oneline(); test_shadow_paste_multiline(); + test_delete_forward(); return 0; }