commit - e98a72dfcad90436d2d2590757b55f78cd28601c
commit + 740f578bf26b43ced66468985fa8c84e862b2a9d
blob - a5847c463c7f75320b500f978acd57640cbf2ba4
blob + 58ffb2dfc41727a43ccedd0bfb3bd72658309012
--- fs.c
+++ fs.c
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ * Handles the data in ~/.telescope
+ */
+
#include "telescope.h"
#include <errno.h>
static void serve_bookmarks(uint32_t);
static void handle_get(struct imsg*, size_t);
static void handle_quit(struct imsg*, size_t);
+static void handle_bookmark_page(struct imsg*, size_t);
static void dispatch_imsg(int, short, void*);
static struct event imsgev;
static struct imsgbuf *ibuf;
+static char bookmark_file[PATH_MAX];
+
static imsg_handlerfn *handlers[] = {
[IMSG_GET] = handle_get,
[IMSG_QUIT] = handle_quit,
+ [IMSG_BOOKMARK_PAGE] = handle_bookmark_page,
};
static void __attribute__((__noreturn__))
serve_bookmarks(uint32_t peerid)
{
const char *t;
- char path[PATH_MAX], buf[BUFSIZ];
+ char buf[BUFSIZ];
size_t r;
FILE *f;
- strlcpy(path, getenv("HOME"), sizeof(path));
- strlcat(path, "/.telescope/bookmarks.gmi", sizeof(path));
-
- if ((f = fopen(path, "r")) == NULL) {
- t = "# error\n\nCan't open ~/.telescope/bookmarks.gmi";
+ if ((f = fopen(bookmark_file, "r")) == NULL) {
+ t = "# error\n\nCan't open bookmarks\n";
imsg_compose(ibuf, IMSG_BUF, peerid, 0, -1, t, strlen(t));
imsg_compose(ibuf, IMSG_EOF, peerid, 0, -1, NULL, 0);
imsg_flush(ibuf);
}
static void
+handle_bookmark_page(struct imsg *imsg, size_t datalen)
+{
+ char *data;
+ int res;
+ FILE *f;
+
+ data = imsg->data;
+ if (data[datalen-1] != '\0')
+ die();
+
+ if ((f = fopen(bookmark_file, "a")) == NULL) {
+ res = errno;
+ goto end;
+ }
+ fprintf(f, "=> %s\n", data);
+ fclose(f);
+
+ res = 0;
+end:
+ imsg_compose(ibuf, IMSG_BOOKMARK_OK, 0, 0, -1, &res, sizeof(res));
+ imsg_flush(ibuf);
+}
+
+static void
dispatch_imsg(int fd, short ev, void *d)
{
struct imsgbuf *ibuf = d;
{
ibuf = b;
+ strlcpy(bookmark_file, getenv("HOME"), sizeof(bookmark_file));
+ strlcat(bookmark_file, "/.telescope/bookmarks.gmi", sizeof(bookmark_file));
+
event_init();
event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, dispatch_imsg, ibuf);
blob - 6d3c77320242a17abb3375bb5be608c085a67389
blob + 21547939e0c28d01e393d3693bb503e67d988ea8
--- telescope.c
+++ telescope.c
static void handle_imsg_got_meta(struct imsg*, size_t);
static void handle_imsg_buf(struct imsg*, size_t);
static void handle_imsg_eof(struct imsg*, size_t);
+static void handle_imsg_bookmark_ok(struct imsg*, size_t);
static void dispatch_imsg(int, short, void*);
static void load_page_from_str(struct tab*, const char*);
static void do_load_url(struct tab*, const char*);
[IMSG_GOT_META] = handle_imsg_got_meta,
[IMSG_BUF] = handle_imsg_buf,
[IMSG_EOF] = handle_imsg_eof,
+ [IMSG_BOOKMARK_OK] = handle_imsg_bookmark_ok,
};
static void __attribute__((__noreturn__))
}
static void
+handle_imsg_bookmark_ok(struct imsg *imsg, size_t datalen)
+{
+ int res;
+
+ if (datalen != sizeof(res))
+ die();
+
+ memcpy(&res, imsg->data, sizeof(res));
+ if (res == 0)
+ ui_notify("Added to bookmarks!");
+ else
+ ui_notify("Failed to add to bookmarks: %s",
+ strerror(res));
+}
+
+static void
dispatch_imsg(int fd, short ev, void *d)
{
struct imsgbuf *ibuf = d;
imsg_flush(netibuf);
}
+void
+add_to_bookmarks(const char *str)
+{
+ imsg_compose(fsibuf, IMSG_BOOKMARK_PAGE, 0, 0, -1, str, strlen(str)+1);
+ imsg_flush(fsibuf);
+}
+
int
main(void)
{
blob - dbbcaa9440b78c25e03f3b714416d3349db6abcb
blob + 001356474322b9cfcdef015a3b66b65180539d89
--- telescope.h
+++ telescope.h
#define GEMINI_URL_LEN 1024
enum imsg_type {
- /* ui <-> client */
+ /* ui <-> client/fs */
IMSG_GET, /* data is URL, peerid the tab id */
IMSG_ERR,
IMSG_CHECK_CERT,
IMSG_BUF,
IMSG_EOF,
IMSG_QUIT,
+
+ /* ui <-> fs */
+ IMSG_BOOKMARK_PAGE,
+ IMSG_BOOKMARK_OK,
};
enum line_type {
int load_previous_page(struct tab*);
int load_next_page(struct tab*);
void stop_tab(struct tab*);
+void add_to_bookmarks(const char*);
/* textplain.c */
void textplain_initparser(struct parser*);
void ui_on_tab_loaded(struct tab*);
void ui_on_tab_refresh(struct tab*);
void ui_require_input(struct tab*, int);
+void ui_notify(const char*, ...) __attribute__((format(printf, 1, 2)));
void ui_end(void);
/* util.c */
blob - 2e2d02e46b2820e4c8a4fc3b2d061e104cbd22dd
blob + 8a0c4bf77dadc993d14ae53f7423151323641856
--- ui.c
+++ ui.c
static void cmd_tab_previous(struct tab*);
static void cmd_load_url(struct tab*);
static void cmd_load_current_url(struct tab*);
+static void cmd_bookmark_page(struct tab*);
static void global_key_unbound(void);
static void ir_select(void);
static void lu_self_insert(void);
static void lu_select(void);
+static void bp_select(void);
static struct vline *nth_line(struct tab*, size_t);
static struct tab *current_tab(void);
static void redraw_modeline(struct tab*);
static void redraw_minibuffer(void);
static void redraw_tab(struct tab*);
+static void vmessage(const char*, va_list);
static void message(const char*, ...) __attribute__((format(printf, 1, 2)));
static void start_loading_anim(struct tab*);
static void update_loading_anim(int, short, void*);
global_set_key("C-M-b", cmd_previous_page);
global_set_key("C-M-f", cmd_next_page);
+ global_set_key("<f7> a", cmd_bookmark_page);
+
/* vi/vi-like */
global_set_key("k", cmd_previous_line);
global_set_key("j", cmd_next_line);
enter_minibuffer(lu_self_insert, lu_select, exit_minibuffer,
&lu_history);
strlcpy(ministate.prompt, "Load URL: ", sizeof(ministate.prompt));
+ strlcpy(ministate.buf, tab->hist_cur->h, sizeof(ministate.buf));
+ ministate.off = strlen(tab->hist_cur->h);
+ ministate.len = ministate.off;
+}
+
+static void
+cmd_bookmark_page(struct tab *tab)
+{
+ enter_minibuffer(lu_self_insert, bp_select, exit_minibuffer, NULL);
+ strlcpy(ministate.prompt, "Bookmark URL: ", sizeof(ministate.prompt));
strlcpy(ministate.buf, tab->hist_cur->h, sizeof(ministate.buf));
ministate.off = strlen(tab->hist_cur->h);
ministate.len = ministate.off;
exit_minibuffer();
minibuffer_hist_save_entry();
load_url_in_tab(current_tab(), ministate.buf);
+}
+
+static void
+bp_select(void)
+{
+ exit_minibuffer();
+ if (*ministate.buf != '\0')
+ add_to_bookmarks(ministate.buf);
+ else
+ message("Abort.");
}
static struct vline *
}
static void
-message(const char *fmt, ...)
+vmessage(const char *fmt, va_list ap)
{
- va_list ap;
-
if (clminibufev_set)
evtimer_del(&clminibufev);
evtimer_set(&clminibufev, handle_clear_minibuf, NULL);
free(ministate.curmesg);
- va_start(ap, fmt);
/* TODO: what to do if the allocation fails here? */
if (vasprintf(&ministate.curmesg, fmt, ap) == -1)
ministate.curmesg = NULL;
- va_end(ap);
redraw_minibuffer();
-
if (in_minibuffer) {
wrefresh(body);
wrefresh(minibuf);
}
static void
+message(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vmessage(fmt, ap);
+ va_end(ap);
+}
+
+static void
start_loading_anim(struct tab *tab)
{
if (tab->s.loading_anim)
}
void
+ui_notify(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vmessage(fmt, ap);
+ va_end(ap);
+}
+
+void
ui_end(void)
{
endwin();