editor: add 'line_kill'

This also adds nullptr checking to decref--it seemed the functions
needing nullptr checks immediately prior to the decref call was
beginning to exceed the functions that had "implied" nullptr checking
as a part of their natural flow-control.
This commit is contained in:
Zack Buhman 2023-06-11 04:26:49 +00:00
parent feb57872e8
commit 8dd460f48f
2 changed files with 27 additions and 4 deletions

View File

@ -101,6 +101,7 @@ struct buffer {
inline constexpr void cursor_scan_word_backward(); inline constexpr void cursor_scan_word_backward();
inline constexpr bool enter(); inline constexpr bool enter();
inline constexpr void line_kill();
inline constexpr void mark_set(); inline constexpr void mark_set();
inline constexpr selection mark_get(); inline constexpr selection mark_get();
inline constexpr void delete_from_line(line<C> *& l, inline constexpr void delete_from_line(line<C> *& l,
@ -180,7 +181,8 @@ inline constexpr void buffer<C, R>::deallocate(line<C> *& l)
template <int C, int R> template <int C, int R>
inline constexpr void buffer<C, R>::decref(line<C> *& l) inline constexpr void buffer<C, R>::decref(line<C> *& l)
{ {
if (l->refcount == 1) if (l == nullptr) return;
else if (l->refcount == 1)
buffer<C, R>::deallocate(l); buffer<C, R>::deallocate(l);
else { else {
l->refcount--; l->refcount--;
@ -585,6 +587,27 @@ inline constexpr bool buffer<C, R>::enter()
return true; return true;
} }
template <int C, int R>
inline constexpr void buffer<C, R>::line_kill()
{
editor::cursor& cur = this->cursor;
if (line_length(this->lines[cur.row]) == 0) {
decref(this->lines[cur.row]);
// shift all lines up by one
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;
} else {
line<C> * l = mutref(this->lines[cur.row]);
l->length = cur.col;
}
}
template <int C, int R> template <int C, int R>
inline constexpr void buffer<C, R>::mark_set() inline constexpr void buffer<C, R>::mark_set()
{ {
@ -719,7 +742,6 @@ template <int C, int R>
inline constexpr void buffer<C, R>::shadow_clear() inline constexpr void buffer<C, R>::shadow_clear()
{ {
for (int32_t i = 0; i < this->shadow.length; i++) for (int32_t i = 0; i < this->shadow.length; i++)
if (this->shadow.lines[i] != nullptr)
decref(this->shadow.lines[i]); decref(this->shadow.lines[i]);
this->shadow.length = 1; this->shadow.length = 1;
@ -815,7 +837,7 @@ inline constexpr void buffer<C, R>::overwrite_line(line<C> *& dst,
//else do nothing //else do nothing
} else if (dst_col == 0 && src_col == 0 && } else if (dst_col == 0 && src_col == 0 &&
line_length(src) >= line_length(dst)) { line_length(src) >= line_length(dst)) {
if (dst != nullptr) decref(dst); decref(dst);
dst = incref(src); dst = incref(src);
} else { } else {
line<C> * dstmut = mutref(dst); line<C> * dstmut = mutref(dst);

View File

@ -139,6 +139,7 @@ inline void keyboard_regular_key(const enum keysym k)
case keysym::E : buffer.cursor_end(); break; case keysym::E : buffer.cursor_end(); break;
case keysym::Y : buffer.shadow_paste(); break; case keysym::Y : buffer.shadow_paste(); break;
case keysym::W : buffer.shadow_cut(); break; case keysym::W : buffer.shadow_cut(); break;
case keysym::K : buffer.line_kill(); break;
default: break; default: break;
} }
break; break;