summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--main.c6
-rw-r--r--nav.c25
-rw-r--r--net.c2
-rw-r--r--net.h8
-rw-r--r--parse.c23
-rw-r--r--parse.h10
6 files changed, 68 insertions, 6 deletions
diff --git a/main.c b/main.c
index 0c36a34..738a3e9 100644
--- a/main.c
+++ b/main.c
@@ -50,6 +50,12 @@ int cmd_do(char *cmd, struct nav_state *ns) {
 	case 'g':
 		if (nav_to(ns, cmd + 1)) perr("navigation failure");
 		break;
+	case 'p':
+		nav_prev(ns);
+		break;
+	case 'n':
+		nav_next(ns);
+		break;
 	default:
 		perr("?");
 		break;
diff --git a/nav.c b/nav.c
index 3a1d095..59fdca6 100644
--- a/nav.c
+++ b/nav.c
@@ -3,6 +3,7 @@
 
 #include "nav.h"
 #include "net.h"
+#include "parse.h"
 
 /* history */
 
@@ -20,12 +21,27 @@ void nav_fini(struct nav_state *ns) {
 	}
 }
 
-void nav_new(struct nav_state *ns) {
+void nav_push(struct nav_state *ns, struct doc d) {
+	while (ns->histc > ns->cur_doc + 1) {
+		doc_fini(&ns->histv[--ns->histc]);
+	}
 	if (ns->histc == HIST_MAX) {
 		doc_fini(ns->histv);
 		memmove(ns->histv, &ns->histv[1], sizeof(struct doc) * (HIST_MAX - 1));
 		ns->histc--;
 	}
+	ns->histv[ns->histc++] = d;
+	ns->cur_doc = ns->histc - 1;
+}
+
+void nav_prev(struct nav_state *ns) {
+	if (ns->cur_doc > 0) ns->cur_doc--;
+	nav_redraw(ns);
+}
+
+void nav_next(struct nav_state *ns) {
+	if (ns->cur_doc + 1 < ns->histc) ns->cur_doc++;
+	nav_redraw(ns);
 }
 
 /* paging */
@@ -91,7 +107,14 @@ int nav_to(struct nav_state *ns, const char *url) {
 	if (net_fetch(&adr, &buf)) {
 		return -1;
 	}
+	struct doc d;
+	if (parse_doc(adr.type, &d, &buf)) {
+		buf_free(&buf);
+		return -1;
+	}
+	nav_push(ns, d);
 	buf_free(&buf);
+	nav_redraw(ns);
 	return 0;
 }
 
diff --git a/net.c b/net.c
index e90d3c0..b826e96 100644
--- a/net.c
+++ b/net.c
@@ -29,7 +29,7 @@ int net_addr(const char *url, struct addr *adr, enum protocol prot_default) {
 	}
 
 	if (adr->prot == PROT_FILE) {
-		adr->type = TYPE_PLAIN;
+		adr->type = DOC_PLAIN;
 		adr->host_len = 0;
 		size_t n = strlen(url);
 		if (n >= PATH_MAX) return -1;
diff --git a/net.h b/net.h
index 8483120..c3e12ef 100644
--- a/net.h
+++ b/net.h
@@ -14,10 +14,10 @@ enum protocol {
 };
 
 enum doc_type {
-	TYPE_UNKNOWN,
-	TYPE_GOPHERDOC,
-	TYPE_GEMTEXT,
-	TYPE_PLAIN,
+	DOC_UNKNOWN,
+	DOC_GOPHERDOC,
+	DOC_GEMTEXT,
+	DOC_PLAIN,
 };
 
 struct addr {
diff --git a/parse.c b/parse.c
new file mode 100644
index 0000000..a1a68d8
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,23 @@
+#include "parse.h"
+
+int parse_doc(enum doc_type type, struct doc *d, const buf_t *b) {
+	switch (type) {
+	case DOC_PLAIN:
+		doc_init(d);
+		for (size_t i = 0; i < b->sz; i++) {
+			char c = b->buf[i];
+			if (c == '\n') {
+				doc_new_line(d);
+			} else {
+				doc_add_textn(d, &c, 1);
+			}
+		}
+		goto ok;
+	default:
+		goto err;
+	}
+ok:
+	return 0;
+err:
+	return -1;
+}
diff --git a/parse.h b/parse.h
new file mode 100644
index 0000000..4f19285
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,10 @@
+#ifndef PARSE_H
+#define PARSE_H
+
+#include "net.h"
+#include "doc.h"
+#include "buf.h"
+
+int parse_doc(enum doc_type type, struct doc *d, const buf_t *b);
+
+#endif