editor: add 'delete_forward' and 'delete' key-binding

This also renames 'backspace' to 'delete_backward' for consistency.
This commit is contained in:
Zack Buhman 2023-06-11 01:27:42 +00:00
parent 3803e501eb
commit 5944e3a360
3 changed files with 83 additions and 11 deletions

View File

@ -83,7 +83,8 @@ struct buffer {
inline static constexpr line<C> * incref(line<C> * l);
inline static constexpr int32_t line_length(line<C> 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<C, R>::put(const uint8_t c)
}
template <int C, int R>
inline constexpr bool buffer<C, R>::backspace()
inline constexpr bool buffer<C, R>::delete_backward()
{
if (this->mode == mode::mark) {
this->mode = mode::normal;
@ -274,11 +275,48 @@ inline constexpr bool buffer<C, R>::backspace()
line<C> * 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 <int C, int R>
inline constexpr bool buffer<C, R>::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<C>*)) * n_lines);
this->length--;
this->lines[this->length] = nullptr;
// no scrolling needed--cursor is already in the correct position
} else {
// c
// 01234
line<C> * 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;

View File

@ -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;

View File

@ -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;
}