cgmnlm

colorful gemini line mode browser
git clone https://git.clttr.info/cgmnlm.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

commit 3547fd11d57da5c7aa610366d54eef3b47d0b1a4
parent 7a099135cd9dae483679cf51a4b630a5dd64c74e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 20 Sep 2020 19:01:14 -0400

Implement history

Diffstat:
Msrc/gmnlm.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 66 insertions(+), 18 deletions(-)

diff --git a/src/gmnlm.c b/src/gmnlm.c @@ -17,15 +17,42 @@ struct link { struct link *next; }; +struct history { + char *url; + struct history *prev, *next; +}; + static void usage(const char *argv_0) { fprintf(stderr, "usage: %s [gemini://...]\n", argv_0); } +static void +history_free(struct history *history) +{ + if (!history) { + return; + } + history_free(history->next); + free(history); +} + static bool -set_url(struct Curl_URL *url, char *new_url) +set_url(struct Curl_URL *url, char *new_url, struct history **history) { + if (history) { + struct history *next = calloc(1, sizeof(struct history)); + next->url = strdup(new_url); + next->prev = *history; + if (*history) { + if ((*history)->next) { + history_free((*history)->next); + } + (*history)->next = next; + } + *history = next; + } if (curl_url_set(url, CURLUPART_URL, new_url, 0) != CURLUE_OK) { fprintf(stderr, "Error: invalid URL\n"); return false; @@ -138,8 +165,9 @@ main(int argc, char *argv[]) } } + struct history *history; if (optind == argc - 1) { - set_url(url, argv[optind]); + set_url(url, argv[optind], &history); } else { usage(argv[0]); return 1; @@ -161,9 +189,10 @@ main(int argc, char *argv[]) CURLUcode uc = curl_url_get(url, CURLUPART_URL, &plain_url, 0); assert(uc == CURLUE_OK); // Invariant - snprintf(prompt, sizeof(prompt), "\n\t%s\n" - "\tWhere to? [n]: follow Nth link; [o <url>]: open URL; [q]: quit " - "[b]ack; [f]orward\n" + snprintf(prompt, sizeof(prompt), "\nat %s\n" + "[n]: follow Nth link; [o <url>]: open URL; " + "[b]ack; [f]orward; " + "[q]uit\n" "=> ", plain_url); enum gemini_result res = gemini_request(plain_url, &opts, &resp); @@ -201,11 +230,29 @@ main(int argc, char *argv[]) char *in = NULL; ssize_t n = getline(&in, &l, tty); if (n == -1 && feof(tty)) { - prompting = run = false; + run = false; break; } if (strcmp(in, "q\n") == 0) { - prompting = run = false; + run = false; + break; + } + if (strcmp(in, "b\n") == 0) { + if (!history->prev) { + fprintf(stderr, "At beginning of history\n"); + continue; + } + history = history->prev; + set_url(url, history->url, NULL); + break; + } + if (strcmp(in, "f\n") == 0) { + if (!history->next) { + fprintf(stderr, "At end of history\n"); + continue; + } + history = history->next; + set_url(url, history->url, NULL); break; } @@ -221,23 +268,24 @@ main(int argc, char *argv[]) if (!link) { fprintf(stderr, "Error: no such link.\n"); } else { - prompting = false; - set_url(url, link->url); + set_url(url, link->url, &history); + break; } } - - link = links; - while (link) { - struct link *next = link->next; - free(link->url); - free(link); - link = next; - } - free(in); } + + struct link *link = links; + while (link) { + struct link *next = link->next; + free(link->url); + free(link); + link = next; + } + links = NULL; } + history_free(history); SSL_CTX_free(opts.ssl_ctx); curl_url_cleanup(url); return 0;