summaryrefslogtreecommitdiffstats
path: root/src/history.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2024-03-13 19:33:30 +0100
committerLouis Burda <quent.burda@gmail.com>2024-03-13 19:33:42 +0100
commitbba6cce573d46b02dbb207b005721b370cab1698 (patch)
tree8af38b347b29aee7bac14e61db29f89a3a1f98d8 /src/history.c
parent7146f1c08cf06c5865181f6e45b70505ca89d7a2 (diff)
downloadtmus-bba6cce573d46b02dbb207b005721b370cab1698.tar.gz
tmus-bba6cce573d46b02dbb207b005721b370cab1698.zip
Add initial rudimentary grapheme support
Diffstat (limited to 'src/history.c')
-rw-r--r--src/history.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/src/history.c b/src/history.c
index ab12019..d63face 100644
--- a/src/history.c
+++ b/src/history.c
@@ -4,6 +4,8 @@
#include "history.h"
#include "util.h"
+#include "grapheme.h"
+
#include <string.h>
#include <stdlib.h>
@@ -124,6 +126,7 @@ inputln_init(struct inputln *ln)
ln->len = 0;
ln->cap = 0;
ln->cur = 0;
+ ln->curpos = 0;
ln->link = LIST_LINK_INIT;
inputln_resize(ln, 128);
@@ -169,51 +172,56 @@ inputln_resize(struct inputln *ln, size_t size)
void
inputln_left(struct inputln *ln)
{
- ln->cur = MAX(0, ln->cur-1);
+ ln->cur = utf8_next_break_left(ln->buf, ln->cur);
+ ln->curpos = text_width(ln->buf, ln->cur);
}
void
inputln_right(struct inputln *ln)
{
- ln->cur = MIN(ln->len, ln->cur+1);
+ ln->cur = utf8_next_break_right(ln->buf, ln->cur);
+ ln->curpos = text_width(ln->buf, ln->cur);
}
void
-inputln_addch(struct inputln *line, char c)
+inputln_addch(struct inputln *ln, char c)
{
int i;
- if (line->len + 1 >= line->cap) {
- line->cap *= 2;
- line->buf = realloc(line->buf, line->cap);
+ if (ln->len + 1 >= ln->cap) {
+ ln->cap *= 2;
+ ln->buf = realloc(ln->buf, ln->cap);
}
- for (i = line->len; i > line->cur; i--)
- line->buf[i] = line->buf[i-1];
- line->buf[line->cur] = c;
+ for (i = ln->len; i > ln->cur; i--)
+ ln->buf[i] = ln->buf[i-1];
+ ln->buf[ln->cur] = c;
- line->len++;
- line->cur++;
+ ln->len++;
+ ln->cur++;
+ ln->buf[ln->len] = '\0';
- line->buf[line->len] = '\0';
+ ln->curpos = text_width(ln->buf, ln->cur);
}
void
-inputln_del(struct inputln *line, int n)
+inputln_del(struct inputln *ln, int n)
{
+ size_t next;
int i;
- if (!line->cur) return;
+ if (!ln->cur) return;
- n = MIN(n, line->cur);
- for (i = line->cur; i <= line->len; i++)
- line->buf[i-n] = line->buf[i];
+ next = utf8_next_break_left(ln->buf, ln->cur);
+ n = ln->cur - next;
+ for (i = ln->cur; i <= ln->len; i++)
+ ln->buf[i-n] = ln->buf[i];
- for (i = line->len - n; i <= line->len; i++)
- line->buf[i] = 0;
+ ln->len -= n;
+ ln->cur -= n;
+ ln->buf[ln->len] = '\0';
- line->len -= n;
- line->cur -= n;
+ ln->curpos = text_width(ln->buf, ln->cur);
}
void
@@ -227,15 +235,17 @@ inputln_copy(struct inputln *dst, struct inputln *src)
dst->buf = astrdup(src->buf);
dst->cap = src->len + 1;
dst->cur = dst->len;
+ dst->curpos = text_width(dst->buf, dst->len);
}
void
-inputln_replace(struct inputln *line, const char *str)
+inputln_replace(struct inputln *ln, const char *str)
{
- line->len = strlen(str);
- if (line->cap <= line->len)
- inputln_resize(line, line->len + 1);
- strncpy(line->buf, str, line->len + 1);
- line->cur = line->len;
+ ln->len = strlen(str);
+ if (ln->cap <= ln->len)
+ inputln_resize(ln, ln->len + 1);
+ strncpy(ln->buf, str, ln->len + 1);
+ ln->cur = ln->len;
+ ln->curpos = text_width(ln->buf, ln->len);
}