summary refs log tree commit diff
path: root/doc.c
diff options
context:
space:
mode:
authorwrmr2024-11-03 13:32:33 -0500
committerwrmr2024-11-03 13:32:33 -0500
commitd16f78195865c200481123caaa91e52152ffdc41 (patch)
tree4ca9ae1c487f19807018ddf113f1baf608d445c5 /doc.c
parent332db163a4524552b583776bd3ff172b8eadbf5c (diff)
move messy internal line navigation logic into doc.c
Diffstat (limited to 'doc.c')
-rw-r--r--doc.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/doc.c b/doc.c
index d5da6bf..3d1b378 100644
--- a/doc.c
+++ b/doc.c
@@ -5,6 +5,8 @@
 #include "doc.h"
 #include "err.h"
 
+/* initialization / destruction */
+
 void doc_init(struct doc *d) {
 	buf_init(&d->txt, sizeof(struct doc_line));
 	buf_init(&d->lnk, 1);
@@ -22,6 +24,8 @@ void doc_fini(struct doc *d) {
 	buf_free(&d->lnk);
 }
 
+/* line creation */
+
 void doc_new_line(struct doc *d) {
 	buf_grow(&d->txt, sizeof(struct doc_line));
 	*(struct doc_line *)&d->txt.buf[d->txt.sz] = (struct doc_line) {
@@ -49,3 +53,29 @@ void doc_add_textn(struct doc *d, const char *s, size_t n) {
 	d->txt.sz += n;
 	dl->len += n;
 }
+
+/* line navigation */
+
+struct doc_line *doc_line_at(struct doc *d, size_t ofs) {
+	return (struct doc_line *)&d->txt.buf[ofs];
+}
+
+int doc_line_prev(struct doc *d, size_t *ofs) {
+	size_t n = doc_line_at(d, *ofs)->prev + sizeof(struct doc_line);
+	if (*ofs >= n) {
+		*ofs -= n;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int doc_line_next(struct doc *d, size_t *ofs) {
+	size_t n = doc_line_at(d, *ofs)->len + sizeof(struct doc_line);
+	if (*ofs + n < d->txt.sz) {
+		*ofs += n;
+		return 0;
+	} else {
+		return -1;
+	}
+}