diff options
| -rw-r--r-- | txt.c | 58 |
1 files changed, 41 insertions, 17 deletions
@@ -56,6 +56,15 @@ static void txt_buf_append(Txt *b, TxtBufIdx bi, const char *s, u32 n) { buf->n += n; } +static isize txt_buf_dedup(Txt *b, TxtBufIdx bi, const char *s, u32 n) { + TxtBuf *buf = &b->buf[bi]; + if (buf->n >= n && !memcmp(buf->s + (buf->n - n), s, n)) { + return buf->n - n; + } else { + return -1; + } +} + TxtLoc txt_add_piece(Txt *b, TxtLoc l) { if (l.p > 0 && !l.i) { l.p--; @@ -79,23 +88,6 @@ insert: return l; } -TxtLoc txt_insert(TxtLoc l, const char *s, u32 n) { - l = txt_add_piece(l.t, l); - TxtPiece *p = &l.t->ptbl.v[l.p]; - txt_buf_append(l.t, p->buf, s, n); - p->n += n; - l.t->len += n; - l.i = p->n; - return l; -} - -TxtLoc txt_insert_c(TxtLoc l, u32 ch) { - char buf[6]; - u32 n = utf8_encode_len(&ch, 1); - utf8_encode(buf, &ch, 1); - return txt_insert(l, buf, n); -} - static int txt_are_pieces_adjacent(Txt *t, u32 a, u32 b) { TxtPiece *pa = &t->ptbl.v[a]; TxtPiece *pb = &t->ptbl.v[b]; @@ -136,6 +128,30 @@ static TxtLoc txt_join_or_kill(TxtLoc l) { return l; } +TxtLoc txt_insert(TxtLoc l, const char *s, u32 n) { + l = txt_add_piece(l.t, l); + TxtPiece *p = &l.t->ptbl.v[l.p]; + isize ext = txt_buf_dedup(l.t, p->buf, s, n); + if (p->n > 0 || ext == -1) { + txt_buf_append(l.t, p->buf, s, n); + } else { + p->ofs = ext; + } + p->n += n; + l.t->len += n; + l.i = p->n; + l = txt_join_or_kill(l); + l.i = l.t->ptbl.v[l.p].n; + return l; +} + +TxtLoc txt_insert_c(TxtLoc l, u32 ch) { + char buf[6]; + u32 n = utf8_encode_len(&ch, 1); + utf8_encode(buf, &ch, 1); + return txt_insert(l, buf, n); +} + TxtLoc txt_delete(TxtLoc l, u32 n) { u32 pi = txt_split_piece(l.t, l.p, l.i); if (pi > 0) pi--; @@ -160,6 +176,14 @@ TxtLoc txt_delete(TxtLoc l, u32 n) { return txt_join_or_kill(l); } +TxtLoc txt_delete_range(TxtLoc lo, TxtLoc hi) { + /* TODO: figure out nr. of chars, then delete all at once */ + while (txt_before(lo, hi)) { + hi = txt_delete(hi, 1); + } + return lo; +} + TxtLoc txt_delete_c(TxtLoc l) { while (!at_start(l) && (txt_byte(bprev(l)) & 0xc0) == 0x80) l = txt_delete(l, 1); |
