summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c121
1 files changed, 94 insertions, 27 deletions
diff --git a/main.c b/main.c
index 65de555..c2c9575 100644
--- a/main.c
+++ b/main.c
@@ -29,16 +29,44 @@ struct {
} text;
struct doc {
- struct doc *prev, *next;
struct {
size_t ofs, len, idx;
} txt;
};
#define DOC_MAX 32
-struct doc docv[DOC_MAX];
+struct doc docv[DOC_MAX] = {
+ {
+ .txt = {
+ .ofs = 0,
+ .len = 0,
+ .idx = 0
+ }
+ }
+};
size_t docn = 0, doci = 0;
+void doc_pop(void) {
+ if (docn > 0) {
+ docn--;
+ if (doci > 0) doci--;
+ }
+}
+
+void doc_shift(void) {
+ if (docn > 0) {
+ docn--;
+ memmove(text.buf, text.buf + docv[0].txt.len, text.n - docv[0].txt.len);
+ memmove(&docv[0], &docv[1], docn * sizeof(struct doc));
+ docv[0].txt.ofs = 0;
+ for (int i = 1; i < docn; i++) {
+ docv[i].txt.idx = docv[i - 1].txt.ofs + (docv[i].txt.idx - docv[i].txt.ofs);
+ docv[i].txt.ofs = docv[i - 1].txt.ofs + docv[i - 1].txt.len;
+ }
+ if (docn > 0 && doci >= docn) doci = docn - 1;
+ }
+}
+
int doc_new(void) {
if (doci < docn) {
text.n = docv[doci].txt.ofs;
@@ -52,15 +80,20 @@ int doc_new(void) {
return 0;
}
-int doc_add(char *buf, size_t n) {
+int doc_add(const char *buf, size_t n) {
if (text.n + n > TXT_BUF_SIZE) {
return -1;
}
memcpy(&text.buf[text.n], buf, n);
+ docv[doci].txt.len += n;
text.n += n;
return 0;
}
+int doc_adds(const char *s) {
+ return doc_add(s, strlen(s));
+}
+
void doc_prev(void) {
if (doci > 0) doci--;
}
@@ -69,6 +102,29 @@ void doc_next(void) {
if (doci < docn) doci++;
}
+void doc_back_line(void) {
+ if (doci >= docn) return;
+ struct doc *d = &docv[doci];
+ size_t i = d->txt.idx;
+ while (i > 0 && text.buf[d->txt.idx] != '\n') i--;
+ if (i > 0) i--;
+ while (i > 0 && text.buf[d->txt.idx] != '\n') i--;
+ if (i > 0) i++;
+ d->txt.idx = i;
+}
+
+void doc_print_line(void) {
+ if (doci >= docn) return;
+ struct doc *d = &docv[doci];
+ size_t i = d->txt.idx;
+ size_t n = d->txt.ofs + d->txt.len;
+ while (i < n && text.buf[d->txt.idx] != '\n') {
+ putchar(text.buf[i++]);
+ }
+ if (i < n) i++;
+ d->txt.idx = i;
+}
+
/* pagination */
size_t pg_lines() {
@@ -76,27 +132,21 @@ size_t pg_lines() {
}
int pg_down(const char *_) {
- if (doci >= docn) return -1;
size_t lines = pg_lines();
- size_t i = docv[doci].txt.idx;
- size_t end = docv[doci].txt.ofs + docv[doci].txt.len;
- while (lines > 0 && i < end) {
- putchar(text.buf[i]);
- if (text.buf[i] == '\n') lines--;
- i++;
- }
+ while (lines--) doc_print_line();
return 0;
}
int pg_up(const char *_) {
- if (doci >= docn) return -1;
size_t lines = pg_lines() << 1;
- size_t i = docv[doci].txt.idx;
- while (lines > 0 && i > 0) {
- putchar(text.buf[i]);
- if (text.buf[i] == '\n') lines--;
- i--;
- }
+ while (lines--) doc_back_line();
+ pg_down(_);
+ return 0;
+}
+
+int pg_redraw(const char *_) {
+ size_t lines = pg_lines();
+ while (lines--) doc_back_line();
pg_down(_);
return 0;
}
@@ -107,17 +157,17 @@ int pg_up(const char *_) {
#define PATH_MAX 255
enum doc_type {
+ TYPE_UNKNOWN,
TYPE_GOPHERDOC,
TYPE_GEMTEXT,
TYPE_PLAIN,
- TYPE_UNKNOWN
};
enum protocol {
+ PROT_UNKNOWN,
PROT_FILE,
PROT_GOPHER,
PROT_GEMINI,
- PROT_UNKNOWN,
};
struct addr {
@@ -128,15 +178,24 @@ struct addr {
enum doc_type type;
};
-int url_to_addr(const char *url, struct addr *adr) {
- char *colon = strchr(url, ':');
- adr->prot = PROT_UNKNOWN;
- if (colon) {
- }
- return -1;
+int url_to_addr(const char *url, struct addr *adr, enum protocol prot_default) {
+ adr->prot = prot_default;
+ adr->type = TYPE_PLAIN;
+ adr->host_len = 0;
+ size_t n = strlen(url);
+ if (n > PATH_MAX) return -1;
+ adr->path_len = n;
+ memcpy(adr->path, url, n);
+ return 0;
}
int nav_to(const char *url) {
+ struct addr a;
+ static enum protocol prot_default = PROT_FILE; /* change to gopher later */
+ if (url_to_addr(url, &a, prot_default)) {
+ return -1;
+ }
+ prot_default = a.prot;
return 0;
}
@@ -151,10 +210,16 @@ struct cmd {
int (*fn)(const char *);
};
+int addtxt(const char *s) {
+ return doc_add(s, strlen(s)) || doc_add("\n", 1);
+}
+
struct cmd cmd_tbl[] = {
{ 'g', nav_to },
{ '\n', pg_down },
- { '\b', pg_up },
+ { 'b', pg_up },
+ { 'r', pg_redraw },
+ { 'a', addtxt },
{ 'q', quit }
};
@@ -194,6 +259,8 @@ int cmd_get(char *buf, size_t n) {
int main(void) {
char cmd_buf[1024];
running = 1;
+ doc_new();
+ doc_adds("Press ? for help.\n");
while (running && cmd_get(cmd_buf, sizeof cmd_buf)) {
cmd_do(cmd_buf);
}