summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc.c30
-rw-r--r--doc.h4
-rw-r--r--nav.c17
3 files changed, 37 insertions, 14 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;
+ }
+}
diff --git a/doc.h b/doc.h
index 496b631..972134b 100644
--- a/doc.h
+++ b/doc.h
@@ -30,4 +30,8 @@ void doc_add_line(struct doc *, const char *);
void doc_add_text(struct doc *, const char *);
void doc_add_textn(struct doc *, const char *, size_t);
+struct doc_line *doc_line_at(struct doc *d, size_t ofs);
+int doc_line_prev(struct doc *d, size_t *ofs);
+int doc_line_next(struct doc *d, size_t *ofs);
+
#endif
diff --git a/nav.c b/nav.c
index 8df829e..6d81ddd 100644
--- a/nav.c
+++ b/nav.c
@@ -51,26 +51,15 @@ size_t pg_lines(void) {
}
struct doc_line *nav_cur_line(struct nav_state *ns) {
- return (struct doc_line *)&ns->histv[ns->cur_doc].txt.buf[ns->cur_ofs[ns->cur_doc]];
+ return doc_line_at(&ns->histv[ns->cur_doc], ns->cur_ofs[ns->cur_doc]);
}
int nav_line_up(struct nav_state *ns) {
- if (ns->cur_ofs[ns->cur_doc] > 0) {
- ns->cur_ofs[ns->cur_doc] -= nav_cur_line(ns)->prev + sizeof(struct doc_line);
- return 1;
- } else {
- return 0;
- }
+ return !doc_line_prev(&ns->histv[ns->cur_doc], &ns->cur_ofs[ns->cur_doc]);
}
int nav_line_down(struct nav_state *ns) {
- struct doc_line *l = nav_cur_line(ns);
- if (ns->cur_ofs[ns->cur_doc] + sizeof(struct doc_line) + l->len < ns->histv[ns->cur_doc].txt.sz) {
- ns->cur_ofs[ns->cur_doc] += l->len + sizeof(struct doc_line);
- return 1;
- } else {
- return 0;
- }
+ return !doc_line_next(&ns->histv[ns->cur_doc], &ns->cur_ofs[ns->cur_doc]);
}
void nav_pg_up(struct nav_state *ns) {