commit 2ba66cea888e1513fbf169b49e7d75848f4f1ec4 from: Omar Polo date: Mon Mar 22 08:44:36 2021 UTC big refactor: introduce the window abstraction - commands now take a struct window* instead of a raw tab - the struct ui_state is gone - using a window for the minibuffer too helps avoid code duplication - it will let us having more than one window on a tab! :DD It doesn't seem to have broken anything... commit - 3e4339589124ccdd467b8a78fac5bc446d1c6a4a commit + 2ba66cea888e1513fbf169b49e7d75848f4f1ec4 blob - 62d1abff1022bd444ca228e603e046d35fb568e7 blob + ed6846aae47d6767138bba62f10710a0086cbee0 --- keymap.c +++ keymap.c @@ -138,7 +138,7 @@ unkbd(int k) } int -kmap_define_key(struct kmap *map, const char *key, void (*fn)(struct tab*)) +kmap_define_key(struct kmap *map, const char *key, void (*fn)(struct window*)) { int ctrl, meta, k; struct keymap *entry; blob - a9536a55044cea99c682dd52803a835199adcec2 blob + 1e30c4206deb1ba2272e5a6db76cccb91374ac8b --- mime.c +++ mime.c @@ -79,7 +79,7 @@ setup_parser_for(struct tab *tab) for (t = ptable; t->mediatype != NULL; ++t) { if (!fnmatch(t->mediatype, buf, 0)) { - t->parserinit(&tab->page); + t->parserinit(&tab->window.page); return 1; } } blob - 8fe7a56dba344f912662e8ff9a16705ff8a8af73 blob + 18cd4bd46af8e7dbb703c81fa0dcff90c64f24a5 --- telescope.c +++ telescope.c @@ -219,7 +219,7 @@ handle_imsg_buf(struct imsg *imsg, size_t datalen) tab = tab_by_id(imsg->hdr.peerid); - if (!tab->page.parse(&tab->page, imsg->data, datalen)) + if (!tab->window.page.parse(&tab->window.page, imsg->data, datalen)) die(); ui_on_tab_refresh(tab); @@ -228,14 +228,14 @@ handle_imsg_buf(struct imsg *imsg, size_t datalen) static void handle_imsg_eof(struct imsg *imsg, size_t datalen) { - struct tab *t; + struct tab *tab; - t = tab_by_id(imsg->hdr.peerid); - if (!t->page.free(&t->page)) + tab = tab_by_id(imsg->hdr.peerid); + if (!tab->window.page.free(&tab->window.page)) die(); - ui_on_tab_refresh(t); - ui_on_tab_loaded(t); + ui_on_tab_refresh(tab); + ui_on_tab_loaded(tab); } static void @@ -277,10 +277,10 @@ handle_dispatch_imsg(int fd, short ev, void *d) static void load_page_from_str(struct tab *tab, const char *page) { - gemtext_initparser(&tab->page); - if (!tab->page.parse(&tab->page, page, strlen(page))) + gemtext_initparser(&tab->window.page); + if (!tab->window.page.parse(&tab->window.page, page, strlen(page))) die(); - if (!tab->page.free(&tab->page)) + if (!tab->window.page.free(&tab->window.page)) die(); ui_on_tab_refresh(tab); ui_on_tab_loaded(tab); @@ -303,7 +303,7 @@ load_about_url(struct tab *tab, const char *url) len = sizeof(tab->hist_cur->h)-1; strlcpy(tab->hist_cur->h, url, len); - gemtext_initparser(&tab->page); + gemtext_initparser(&tab->window.page); imsg_compose(fsibuf, IMSG_GET, tab->id, 0, -1, tab->hist_cur->h, len+1); blob - 66542243d179f3fad02da48f3b4e9e826c0dc0ca blob + d67ae95d13693918cc02720e02c7374c8695b685 --- telescope.h +++ telescope.h @@ -100,30 +100,6 @@ struct parser { TAILQ_HEAD(, line) head; }; -struct histhead { - TAILQ_HEAD(mhisthead, hist) head; - size_t len; -}; -struct hist { - char h[1025]; - TAILQ_ENTRY(hist) entries; -}; - -struct ui_state { - int curs_x; - int curs_y; - size_t line_off; - size_t line_max; - struct vline *current_line; - size_t line_x; - - short loading_anim; - short loading_anim_step; - struct event loadingev; - - TAILQ_HEAD(vhead, vline) head; -}; - /* * differnt types of trust for a certificate. Following * gemini://thfr.info/gemini/modified-trust-verify.gmi @@ -143,9 +119,28 @@ struct tofu_entry { int verified; }; +struct histhead { + TAILQ_HEAD(mhisthead, hist) head; + size_t len; +}; +struct hist { + char h[1025]; + TAILQ_ENTRY(hist) entries; +}; + +struct window { + struct parser page; + int curs_x; + int curs_y; + size_t line_off; + size_t line_max; + struct vline *current_line; + size_t cpoff; + TAILQ_HEAD(vhead, vline) head; +}; + extern TAILQ_HEAD(tabshead, tab) tabshead; struct tab { - struct parser page; TAILQ_ENTRY(tab) tabs; uint32_t id; uint32_t flags; @@ -160,7 +155,11 @@ struct tab { char meta[GEMINI_URL_LEN]; int redirect_count; - struct ui_state s; + struct window window; + + short loading_anim; + short loading_anim_step; + struct event loadingev; }; struct proto { @@ -182,7 +181,7 @@ struct keymap { int meta; int key; struct kmap map; - void (*fn)(struct tab*); + void (*fn)(struct window*); TAILQ_ENTRY(keymap) keymaps; }; @@ -210,7 +209,7 @@ void hist_push(struct histhead*, struct hist*); /* keymap.c */ int kbd(const char*); const char *unkbd(int); -int kmap_define_key(struct kmap*, const char*, void(*)(struct tab*)); +int kmap_define_key(struct kmap*, const char*, void(*)(struct window*)); /* mime.c */ int setup_parser_for(struct tab*); @@ -263,8 +262,8 @@ size_t utf8_chwidth(uint32_t); size_t utf8_snwidth(const char*, size_t); size_t utf8_swidth(const char*); size_t utf8_swidth_between(const char*, const char*); -char *utf8_next_cp(char*); -char *utf8_prev_cp(char*, char*); +char *utf8_next_cp(const char*); +char *utf8_prev_cp(const char*, const char*); /* util.c */ int mark_nonblock(int); @@ -274,7 +273,7 @@ int unicode_isgraph(uint32_t); void dispatch_imsg(struct imsgbuf*, imsg_handlerfn**, size_t); /* wrap.c */ -int wrap_text(struct tab*, const char*, struct line*, size_t); -int hardwrap_text(struct tab*, struct line*, size_t); +int wrap_text(struct window*, const char*, struct line*, size_t); +int hardwrap_text(struct window*, struct line*, size_t); #endif /* TELESCOPE_H */ blob - 1a5aa87ed74653e99fe573e949121c73ecc07c3f blob + cf5bdd939764a01767120aa57356e7b9af7b4d1b --- ui.c +++ ui.c @@ -52,56 +52,52 @@ static struct event stdioev, winchev; static void load_default_keys(void); -static void empty_vlist(struct tab*); -static void restore_cursor(struct tab *); +static void empty_vlist(struct window*); +static void restore_cursor(struct window*); -static void cmd_previous_line(struct tab*); -static void cmd_next_line(struct tab*); -static void cmd_backward_char(struct tab*); -static void cmd_forward_char(struct tab*); -static void cmd_backward_paragraph(struct tab*); -static void cmd_forward_paragraph(struct tab*); -static void cmd_move_beginning_of_line(struct tab*); -static void cmd_move_end_of_line(struct tab*); -static void cmd_redraw(struct tab*); -static void cmd_scroll_line_down(struct tab*); -static void cmd_scroll_line_up(struct tab*); -static void cmd_scroll_up(struct tab*); -static void cmd_scroll_down(struct tab*); -static void cmd_beginning_of_buffer(struct tab*); -static void cmd_end_of_buffer(struct tab*); -static void cmd_kill_telescope(struct tab*); -static void cmd_push_button(struct tab*); -static void cmd_push_button_new_tab(struct tab*); -static void cmd_previous_button(struct tab*); -static void cmd_next_button(struct tab*); -static void cmd_previous_page(struct tab*); -static void cmd_next_page(struct tab*); -static void cmd_clear_minibuf(struct tab*); -static void cmd_execute_extended_command(struct tab*); -static void cmd_tab_close(struct tab*); -static void cmd_tab_close_other(struct tab*); -static void cmd_tab_new(struct tab*); -static void cmd_tab_next(struct tab*); -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 cmd_goto_bookmarks(struct tab*); +static void cmd_previous_line(struct window*); +static void cmd_next_line(struct window*); +static void cmd_backward_char(struct window*); +static void cmd_forward_char(struct window*); +static void cmd_backward_paragraph(struct window*); +static void cmd_forward_paragraph(struct window*); +static void cmd_move_beginning_of_line(struct window*); +static void cmd_move_end_of_line(struct window*); +static void cmd_redraw(struct window*); +static void cmd_scroll_line_down(struct window*); +static void cmd_scroll_line_up(struct window*); +static void cmd_scroll_up(struct window*); +static void cmd_scroll_down(struct window*); +static void cmd_beginning_of_buffer(struct window*); +static void cmd_end_of_buffer(struct window*); +static void cmd_kill_telescope(struct window*); +static void cmd_push_button(struct window*); +static void cmd_push_button_new_tab(struct window*); +static void cmd_previous_button(struct window*); +static void cmd_next_button(struct window*); +static void cmd_previous_page(struct window*); +static void cmd_next_page(struct window*); +static void cmd_clear_minibuf(struct window*); +static void cmd_execute_extended_command(struct window*); +static void cmd_tab_close(struct window*); +static void cmd_tab_close_other(struct window*); +static void cmd_tab_new(struct window*); +static void cmd_tab_next(struct window*); +static void cmd_tab_previous(struct window*); +static void cmd_load_url(struct window*); +static void cmd_load_current_url(struct window*); +static void cmd_bookmark_page(struct window*); +static void cmd_goto_bookmarks(struct window*); static void global_key_unbound(void); -static void cmd_mini_delete_char(struct tab*); -static void cmd_mini_delete_backward_char(struct tab*); -static void cmd_mini_forward_char(struct tab*); -static void cmd_mini_backward_char(struct tab*); -static void cmd_mini_move_end_of_line(struct tab*); -static void cmd_mini_move_beginning_of_line(struct tab*); -static void cmd_mini_kill_line(struct tab*); -static void cmd_mini_abort(struct tab*); -static void cmd_mini_complete_and_exit(struct tab*); -static void cmd_mini_previous_history_element(struct tab*); -static void cmd_mini_next_history_element(struct tab*); +static void cmd_mini_delete_char(struct window*); +static void cmd_mini_delete_backward_char(struct window*); +static void cmd_mini_kill_line(struct window*); +static void cmd_mini_abort(struct window*); +static void cmd_mini_complete_and_exit(struct window*); +static void cmd_mini_previous_history_element(struct window*); +static void cmd_mini_next_history_element(struct window*); static void minibuffer_hist_save_entry(void); static void minibuffer_taint_hist(void); @@ -114,13 +110,14 @@ 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 vline *nth_line(struct window*, size_t); static struct tab *current_tab(void); +static struct window *current_window(void); static int readkey(void); static void dispatch_stdio(int, short, void*); static void handle_clear_minibuf(int, short, void*); static void handle_resize(int, short, void*); -static int wrap_page(struct tab*); +static int wrap_page(struct window*); static void print_vline(struct vline*); static void redraw_tabline(void); static void redraw_body(struct tab*); @@ -164,15 +161,17 @@ static struct histhead eecmd_history, static int in_minibuffer; static struct { - char *curmesg; + char *curmesg; - char buf[1025]; - char *curs; - size_t cpoff; - char prompt[32]; - void (*donefn)(void); - void (*abortfn)(void); + char prompt[32]; + void (*donefn)(void); + void (*abortfn)(void); + char buf[1025]; + struct line line; + struct vline vline; + struct window window; + struct histhead *history; struct hist *hist_cur; size_t hist_off; @@ -217,29 +216,29 @@ static struct tab_face { }; static void -empty_vlist(struct tab *tab) +empty_vlist(struct window *window) { struct vline *vl, *t; - tab->s.current_line = NULL; - tab->s.line_max = 0; + window->current_line = NULL; + window->line_max = 0; - TAILQ_FOREACH_SAFE(vl, &tab->s.head, vlines, t) { - TAILQ_REMOVE(&tab->s.head, vl, vlines); + TAILQ_FOREACH_SAFE(vl, &window->head, vlines, t) { + TAILQ_REMOVE(&window->head, vl, vlines); free(vl->line); free(vl); } } static inline void -global_set_key(const char *key, void (*fn)(struct tab*)) +global_set_key(const char *key, void (*fn)(struct window*)) { if (!kmap_define_key(&global_map, key, fn)) _exit(1); } static inline void -minibuffer_set_key(const char *key, void (*fn)(struct tab*)) +minibuffer_set_key(const char *key, void (*fn)(struct window*)) { if (!kmap_define_key(&minibuffer_map, key, fn)) _exit(1); @@ -346,14 +345,14 @@ load_default_keys(void) minibuffer_set_key("C-d", cmd_mini_delete_char); minibuffer_set_key("del", cmd_mini_delete_backward_char); - minibuffer_set_key("C-f", cmd_mini_forward_char); - minibuffer_set_key("C-b", cmd_mini_backward_char); - minibuffer_set_key("", cmd_mini_forward_char); - minibuffer_set_key("", cmd_mini_backward_char); - minibuffer_set_key("C-e", cmd_mini_move_end_of_line); - minibuffer_set_key("C-a", cmd_mini_move_beginning_of_line); - minibuffer_set_key("", cmd_mini_move_end_of_line); - minibuffer_set_key("", cmd_mini_move_beginning_of_line); + minibuffer_set_key("C-b", cmd_backward_char); + minibuffer_set_key("C-f", cmd_forward_char); + minibuffer_set_key("", cmd_backward_char); + minibuffer_set_key("", cmd_forward_char); + minibuffer_set_key("C-e", cmd_move_end_of_line); + minibuffer_set_key("C-a", cmd_move_beginning_of_line); + minibuffer_set_key("", cmd_move_end_of_line); + minibuffer_set_key("", cmd_move_beginning_of_line); minibuffer_set_key("C-k", cmd_mini_kill_line); minibuffer_set_key("M-p", cmd_mini_previous_history_element); @@ -363,249 +362,249 @@ load_default_keys(void) } static void -restore_cursor(struct tab *tab) +restore_cursor(struct window *window) { struct vline *vl; const char *prfx; - vl =tab->s.current_line; + vl = window->current_line; if (vl == NULL || vl->line == NULL) - tab->s.curs_x = tab->s.line_x = 0; + window->curs_x = window->cpoff = 0; else - tab->s.curs_x = utf8_snwidth(vl->line, tab->s.line_x); + window->curs_x = utf8_snwidth(vl->line, window->cpoff); if (vl != NULL) { prfx = line_prefixes[vl->parent->type].prfx1; - tab->s.curs_x += utf8_swidth(prfx); + window->curs_x += utf8_swidth(prfx); } } static void -cmd_previous_line(struct tab *tab) +cmd_previous_line(struct window *window) { struct vline *vl; - if (tab->s.current_line == NULL - || (vl = TAILQ_PREV(tab->s.current_line, vhead, vlines)) == NULL) + if (window->current_line == NULL + || (vl = TAILQ_PREV(window->current_line, vhead, vlines)) == NULL) return; - if (--tab->s.curs_y < 0) { - tab->s.curs_y = 0; - cmd_scroll_line_up(tab); + if (--window->curs_y < 0) { + window->curs_y = 0; + cmd_scroll_line_up(window); return; } - tab->s.current_line = vl; - restore_cursor(tab); + window->current_line = vl; + restore_cursor(window); } static void -cmd_next_line(struct tab *tab) +cmd_next_line(struct window *window) { struct vline *vl; - if (tab->s.current_line == NULL - || (vl = TAILQ_NEXT(tab->s.current_line, vlines)) == NULL) + if (window->current_line == NULL + || (vl = TAILQ_NEXT(window->current_line, vlines)) == NULL) return; - if (++tab->s.curs_y > body_lines-1) { - tab->s.curs_y = body_lines-1; - cmd_scroll_line_down(tab); + if (++window->curs_y > body_lines-1) { + window->curs_y = body_lines-1; + cmd_scroll_line_down(window); return; } - tab->s.current_line = vl; - restore_cursor(tab); + window->current_line = vl; + restore_cursor(window); } static void -cmd_backward_char(struct tab *tab) +cmd_backward_char(struct window *window) { - if (tab->s.line_x != 0) - tab->s.line_x--; - restore_cursor(tab); + if (window->cpoff != 0) + window->cpoff--; + restore_cursor(window); } static void -cmd_forward_char(struct tab *tab) +cmd_forward_char(struct window *window) { - tab->s.line_x++; - restore_cursor(tab); + window->cpoff++; + restore_cursor(window); } static void -cmd_backward_paragraph(struct tab *tab) +cmd_backward_paragraph(struct window *window) { do { - if (tab->s.current_line == NULL || - tab->s.current_line == TAILQ_FIRST(&tab->s.head)) { + if (window->current_line == NULL || + window->current_line == TAILQ_FIRST(&window->head)) { message("No previous paragraph"); return; } - cmd_previous_line(tab); - } while (tab->s.current_line->line != NULL || - tab->s.current_line->parent->type != LINE_TEXT); + cmd_previous_line(window); + } while (window->current_line->line != NULL || + window->current_line->parent->type != LINE_TEXT); } static void -cmd_forward_paragraph(struct tab *tab) +cmd_forward_paragraph(struct window *window) { do { - if (tab->s.current_line == NULL || - tab->s.current_line == TAILQ_LAST(&tab->s.head, vhead)) { + if (window->current_line == NULL || + window->current_line == TAILQ_LAST(&window->head, vhead)) { message("No next paragraph"); return; } - cmd_next_line(tab); - } while (tab->s.current_line->line != NULL || - tab->s.current_line->parent->type != LINE_TEXT); + cmd_next_line(window); + } while (window->current_line->line != NULL || + window->current_line->parent->type != LINE_TEXT); } static void -cmd_move_beginning_of_line(struct tab *tab) +cmd_move_beginning_of_line(struct window *window) { - tab->s.line_x = 0; - restore_cursor(tab); + window->cpoff = 0; + restore_cursor(window); } static void -cmd_move_end_of_line(struct tab *tab) +cmd_move_end_of_line(struct window *window) { struct vline *vl; - vl = tab->s.current_line; + vl = window->current_line; if (vl->line == NULL) return; - tab->s.line_x = utf8_cplen(vl->line); - restore_cursor(tab); + window->cpoff = utf8_cplen(vl->line); + restore_cursor(window); } static void -cmd_redraw(struct tab *tab) +cmd_redraw(struct window *window) { handle_resize(0, 0, NULL); } static void -cmd_scroll_line_up(struct tab *tab) +cmd_scroll_line_up(struct window *window) { struct vline *vl; - if (tab->s.line_off == 0) + if (window->line_off == 0) return; - vl = nth_line(tab, --tab->s.line_off); + vl = nth_line(window, --window->line_off); wscrl(body, -1); wmove(body, 0, 0); print_vline(vl); - tab->s.current_line = TAILQ_PREV(tab->s.current_line, vhead, vlines); - restore_cursor(tab); + window->current_line = TAILQ_PREV(window->current_line, vhead, vlines); + restore_cursor(window); } static void -cmd_scroll_line_down(struct tab *tab) +cmd_scroll_line_down(struct window *window) { struct vline *vl; - vl = tab->s.current_line; + vl = window->current_line; if ((vl = TAILQ_NEXT(vl, vlines)) == NULL) return; - tab->s.current_line = vl; + window->current_line = vl; - tab->s.line_off++; + window->line_off++; wscrl(body, 1); - if (tab->s.line_max - tab->s.line_off < (size_t)body_lines) + if (window->line_max - window->line_off < (size_t)body_lines) return; - vl = nth_line(tab, tab->s.line_off + body_lines-1); + vl = nth_line(window, window->line_off + body_lines-1); wmove(body, body_lines-1, 0); print_vline(vl); - restore_cursor(tab); + restore_cursor(window); } static void -cmd_scroll_up(struct tab *tab) +cmd_scroll_up(struct window *window) { size_t off; off = body_lines+1; for (; off > 0; --off) - cmd_scroll_line_up(tab); + cmd_scroll_line_up(window); } static void -cmd_scroll_down(struct tab *tab) +cmd_scroll_down(struct window *window) { size_t off; off = body_lines+1; for (; off > 0; --off) - cmd_scroll_line_down(tab); + cmd_scroll_line_down(window); } static void -cmd_beginning_of_buffer(struct tab *tab) +cmd_beginning_of_buffer(struct window *window) { - tab->s.current_line = TAILQ_FIRST(&tab->s.head); - tab->s.line_off = 0; - tab->s.curs_y = 0; - tab->s.line_x = 0; - restore_cursor(tab); + window->current_line = TAILQ_FIRST(&window->head); + window->line_off = 0; + window->curs_y = 0; + window->cpoff = 0; + restore_cursor(window); } static void -cmd_end_of_buffer(struct tab *tab) +cmd_end_of_buffer(struct window *window) { ssize_t off; - off = tab->s.line_max - body_lines; + off = window->line_max - body_lines; off = MAX(0, off); - tab->s.line_off = off; - tab->s.curs_y = MIN((size_t)body_lines, tab->s.line_max-1); + window->line_off = off; + window->curs_y = MIN((size_t)body_lines, window->line_max-1); - tab->s.current_line = TAILQ_LAST(&tab->s.head, vhead); - tab->s.line_x = body_cols; - restore_cursor(tab); + window->current_line = TAILQ_LAST(&window->head, vhead); + window->cpoff = body_cols; + restore_cursor(window); } static void -cmd_kill_telescope(struct tab *tab) +cmd_kill_telescope(struct window *window) { event_loopbreak(); } static void -cmd_push_button(struct tab *tab) +cmd_push_button(struct window *window) { struct vline *vl; size_t nth; - nth = tab->s.line_off + tab->s.curs_y; - if (nth >= tab->s.line_max) + nth = window->line_off + window->curs_y; + if (nth >= window->line_max) return; - vl = nth_line(tab, nth); + vl = nth_line(window, nth); if (vl->parent->type != LINE_LINK) return; - load_url_in_tab(tab, vl->parent->alt); + load_url_in_tab(current_tab(), vl->parent->alt); } static void -cmd_push_button_new_tab(struct tab *tab) +cmd_push_button_new_tab(struct window *window) { struct vline *vl; size_t nth; - nth = tab->s.line_off + tab->s.curs_y; - if (nth > tab->s.line_max) + nth = window->line_off + window->curs_y; + if (nth > window->line_max) return; - vl = nth_line(tab, nth); + vl = nth_line(window, nth); if (vl->parent->type != LINE_LINK) return; @@ -613,34 +612,36 @@ cmd_push_button_new_tab(struct tab *tab) } static void -cmd_previous_button(struct tab *tab) +cmd_previous_button(struct window *window) { do { - if (tab->s.current_line == NULL || - tab->s.current_line == TAILQ_FIRST(&tab->s.head)) { + if (window->current_line == NULL || + window->current_line == TAILQ_FIRST(&window->head)) { message("No previous link"); return; } - cmd_previous_line(tab); - } while (tab->s.current_line->parent->type != LINE_LINK); + cmd_previous_line(window); + } while (window->current_line->parent->type != LINE_LINK); } static void -cmd_next_button(struct tab *tab) +cmd_next_button(struct window *window) { do { - if (tab->s.current_line == NULL || - tab->s.current_line == TAILQ_LAST(&tab->s.head, vhead)) { + if (window->current_line == NULL || + window->current_line == TAILQ_LAST(&window->head, vhead)) { message("No next link"); return; } - cmd_next_line(tab); - } while (tab->s.current_line->parent->type != LINE_LINK); + cmd_next_line(window); + } while (window->current_line->parent->type != LINE_LINK); } static void -cmd_previous_page(struct tab *tab) +cmd_previous_page(struct window *window) { + struct tab *tab = current_tab(); + if (!load_previous_page(tab)) message("No previous page"); else @@ -648,8 +649,10 @@ cmd_previous_page(struct tab *tab) } static void -cmd_next_page(struct tab *tab) +cmd_next_page(struct window *window) { + struct tab *tab = current_tab(); + if (!load_next_page(tab)) message("No next page"); else @@ -657,16 +660,21 @@ cmd_next_page(struct tab *tab) } static void -cmd_clear_minibuf(struct tab *tab) +cmd_clear_minibuf(struct window *window) { handle_clear_minibuf(0, 0, NULL); } static void -cmd_execute_extended_command(struct tab *tab) +cmd_execute_extended_command(struct window *window) { size_t len; + if (in_minibuffer) { + message("We don't have enable-recursive-minibuffers"); + return; + } + enter_minibuffer(eecmd_self_insert, eecmd_select, exit_minibuffer, &eecmd_history); @@ -681,18 +689,19 @@ cmd_execute_extended_command(struct tab *tab) } static void -cmd_tab_close(struct tab *tab) +cmd_tab_close(struct window *window) { - struct tab *t; + struct tab *tab, *t; + tab = current_tab(); if (TAILQ_PREV(tab, tabshead, tabs) == NULL && TAILQ_NEXT(tab, tabs) == NULL) { message("Can't close the only tab."); return; } - if (evtimer_pending(&tab->s.loadingev, NULL)) - evtimer_del(&tab->s.loadingev); + if (evtimer_pending(&tab->loadingev, NULL)) + evtimer_del(&tab->loadingev); stop_tab(tab); @@ -705,10 +714,11 @@ cmd_tab_close(struct tab *tab) } static void -cmd_tab_close_other(struct tab *tab) +cmd_tab_close_other(struct window *window) { - struct tab *t, *i; + struct tab *tab, *t, *i; + tab = current_tab(); TAILQ_FOREACH_SAFE(t, &tabshead, tabs, i) { if (t->flags & TAB_CURRENT) continue; @@ -720,16 +730,17 @@ cmd_tab_close_other(struct tab *tab) } static void -cmd_tab_new(struct tab *tab) +cmd_tab_new(struct window *window) { new_tab(NEW_TAB_URL); } static void -cmd_tab_next(struct tab *tab) +cmd_tab_next(struct window *window) { - struct tab *t; + struct tab *tab, *t; + tab = current_tab(); tab->flags &= ~TAB_CURRENT; if ((t = TAILQ_NEXT(tab, tabs)) == NULL) @@ -738,10 +749,11 @@ cmd_tab_next(struct tab *tab) } static void -cmd_tab_previous(struct tab *tab) +cmd_tab_previous(struct window *window) { - struct tab *t; + struct tab *tab, *t; + tab = current_tab(); tab->flags &= ~TAB_CURRENT; if ((t = TAILQ_PREV(tab, tabshead, tabs)) == NULL) @@ -750,36 +762,50 @@ cmd_tab_previous(struct tab *tab) } static void -cmd_load_url(struct tab *tab) +cmd_load_url(struct window *window) { + if (in_minibuffer) { + message("We don't have enable-recursive-minibuffers"); + return; + } + enter_minibuffer(lu_self_insert, lu_select, exit_minibuffer, &lu_history); strlcpy(ministate.prompt, "Load URL: ", sizeof(ministate.prompt)); } static void -cmd_load_current_url(struct tab *tab) +cmd_load_current_url(struct window *window) { + struct tab *tab = current_tab(); + + if (in_minibuffer) { + message("We don't have enable-recursive-minibuffers"); + return; + } + 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.curs = strchr(ministate.buf, '\0'); + ministate.window.cpoff = utf8_cplen(ministate.buf); } static void -cmd_bookmark_page(struct tab *tab) +cmd_bookmark_page(struct window *window) { + struct tab *tab = current_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.curs = strchr(ministate.buf, '\0'); + ministate.window.cpoff = utf8_cplen(ministate.buf); } static void -cmd_goto_bookmarks(struct tab *tab) +cmd_goto_bookmarks(struct window *window) { - load_url_in_tab(tab, "about:bookmarks"); + load_url_in_tab(current_tab(), "about:bookmarks"); } static void @@ -789,85 +815,83 @@ global_key_unbound(void) } static void -cmd_mini_delete_char(struct tab *tab) +cmd_mini_delete_char(struct window *window) { - char *n; + char *c, *n; + if (!in_minibuffer) { + message("text is read-only"); + return; + } + minibuffer_taint_hist(); - if (*(n = utf8_next_cp(ministate.curs)) == '\0') + c = utf8_nth(window->current_line->line, window->cpoff); + if (*c == '\0') return; + n = utf8_next_cp(c); - memmove(ministate.curs, n, strlen(n)+1); + memmove(c, n, strlen(n)+1); } static void -cmd_mini_delete_backward_char(struct tab *tab) +cmd_mini_delete_backward_char(struct window *window) { - char *p; + char *c, *p, *start; + if (!in_minibuffer) { + message("text is read-only"); + return; + } + minibuffer_taint_hist(); - if ((p = utf8_prev_cp(ministate.curs, ministate.buf)) == ministate.buf) + c = utf8_nth(window->current_line->line, window->cpoff); + start = window->current_line->line; + if (c == start) return; + p = utf8_prev_cp(c-1, start); - memmove(p, ministate.curs, strlen(ministate.curs)+1); + memmove(p, c, strlen(c)+1); + window->cpoff--; } static void -cmd_mini_forward_char(struct tab *tab) +cmd_mini_kill_line(struct window *window) { - if (*ministate.curs == '\0') - return; - ministate.curs = utf8_next_cp(ministate.curs); - ministate.cpoff++; -} + char *c; -static void -cmd_mini_backward_char(struct tab *tab) -{ - if (ministate.cpoff == 0) + if (!in_minibuffer) { + message("text is read-only"); return; - ministate.cpoff--; - ministate.curs = utf8_prev_cp(ministate.curs-1, ministate.buf); -} + } -static void -cmd_mini_move_end_of_line(struct tab *tab) -{ - ministate.curs = strchr(ministate.buf, '\0'); - ministate.cpoff = utf8_cplen(ministate.buf); -} - -static void -cmd_mini_move_beginning_of_line(struct tab *tab) -{ - ministate.curs = ministate.buf; - ministate.cpoff = 0; -} - -static void -cmd_mini_kill_line(struct tab *tab) -{ minibuffer_taint_hist(); - *ministate.curs = '\0'; + c = utf8_nth(window->current_line->line, window->cpoff); + *c = '\0'; } static void -cmd_mini_abort(struct tab *tab) +cmd_mini_abort(struct window *window) { + if (!in_minibuffer) + return; + ministate.abortfn(); } static void -cmd_mini_complete_and_exit(struct tab *tab) +cmd_mini_complete_and_exit(struct window *window) { + if (!in_minibuffer) + return; + minibuffer_taint_hist(); ministate.donefn(); } static void -cmd_mini_previous_history_element(struct tab *tab) +cmd_mini_previous_history_element(struct window *window) { if (ministate.history == NULL) { message("No history"); @@ -885,11 +909,11 @@ cmd_mini_previous_history_element(struct tab *tab) } if (ministate.hist_cur != NULL) - ministate.curs = ministate.hist_cur->h; + window->current_line->line = ministate.hist_cur->h; } static void -cmd_mini_next_history_element(struct tab *tab) +cmd_mini_next_history_element(struct window *window) { if (ministate.history == NULL) { message("No history"); @@ -907,7 +931,7 @@ cmd_mini_next_history_element(struct tab *tab) } if (ministate.hist_cur != NULL) - ministate.curs = ministate.hist_cur->h; + window->current_line->line = ministate.hist_cur->h; } static void @@ -948,7 +972,7 @@ minibuffer_taint_hist(void) static void minibuffer_self_insert(void) { - char tmp[5] = {0}; + char *c, tmp[5] = {0}; size_t len; minibuffer_taint_hist(); @@ -957,13 +981,13 @@ minibuffer_self_insert(void) return; len = utf8_encode(thiskey.cp, tmp); - if (ministate.curs + len > ministate.buf + sizeof(ministate.buf) - 1) + c = utf8_nth(ministate.window.current_line->line, ministate.window.cpoff); + if (c + len > ministate.buf + sizeof(ministate.buf) - 1) return; - memmove(ministate.curs + len, ministate.curs, strlen(ministate.curs)+1); - memcpy(ministate.curs, tmp, len); - ministate.curs = utf8_next_cp(ministate.curs); - ministate.cpoff++; + memmove(c + len, c, strlen(c)+1); + memcpy(c, tmp, len); + ministate.window.cpoff++; } static void @@ -1042,13 +1066,13 @@ bp_select(void) } static struct vline * -nth_line(struct tab *tab, size_t n) +nth_line(struct window *window, size_t n) { struct vline *vl; size_t i; i = 0; - TAILQ_FOREACH(vl, &tab->s.head, vlines) { + TAILQ_FOREACH(vl, &window->head, vlines) { if (i == n) return vl; i++; @@ -1072,6 +1096,14 @@ current_tab(void) abort(); } +static struct window * +current_window(void) +{ + if (in_minibuffer) + return &ministate.window; + return ¤t_tab()->window; +} + static int readkey(void) { @@ -1138,7 +1170,7 @@ dispatch_stdio(int fd, short ev, void *d) else { current_map = base_map; strlcpy(keybuf, "", sizeof(keybuf)); - k->fn(current_tab()); + k->fn(current_window()); } goto done; } @@ -1198,29 +1230,29 @@ handle_resize(int sig, short ev, void *d) tab = current_tab(); - wrap_page(tab); + wrap_page(&tab->window); redraw_tab(tab); } static int -wrap_page(struct tab *tab) +wrap_page(struct window *window) { struct line *l; const struct line *orig; struct vline *vl; const char *prfx; - orig = tab->s.current_line == NULL + orig = window->current_line == NULL ? NULL - : tab->s.current_line->parent; - tab->s.current_line = NULL; + : window->current_line->parent; + window->current_line = NULL; - tab->s.curs_y = 0; - tab->s.line_off = 0; + window->curs_y = 0; + window->line_off = 0; - empty_vlist(tab); + empty_vlist(window); - TAILQ_FOREACH(l, &tab->page.head, lines) { + TAILQ_FOREACH(l, &window->page.head, lines) { prfx = line_prefixes[l->type].prfx1; switch (l->type) { case LINE_TEXT: @@ -1232,29 +1264,29 @@ wrap_page(struct tab *tab) case LINE_QUOTE: case LINE_PRE_START: case LINE_PRE_END: - wrap_text(tab, prfx, l, body_cols); + wrap_text(window, prfx, l, body_cols); break; case LINE_PRE_CONTENT: - hardwrap_text(tab, l, body_cols); + hardwrap_text(window, l, body_cols); break; } - if (orig == l && tab->s.current_line == NULL) { - tab->s.line_off = tab->s.line_max-1; - tab->s.current_line = TAILQ_LAST(&tab->s.head, vhead); + if (orig == l && window->current_line == NULL) { + window->line_off = window->line_max-1; + window->current_line = TAILQ_LAST(&window->head, vhead); while (1) { - vl = TAILQ_PREV(tab->s.current_line, vhead, vlines); + vl = TAILQ_PREV(window->current_line, vhead, vlines); if (vl == NULL || vl->parent != orig) break; - tab->s.current_line = vl; - tab->s.line_off--; + window->current_line = vl; + window->line_off--; } } } - if (tab->s.current_line == NULL) - tab->s.current_line = TAILQ_FIRST(&tab->s.head); + if (window->current_line == NULL) + window->current_line = TAILQ_FIRST(&window->head); return 1; } @@ -1326,7 +1358,7 @@ redraw_tabline(void) current = tab->flags & TAB_CURRENT; - if (*(title = tab->page.title) == '\0') + if (*(title = tab->window.page.title) == '\0') title = tab->hist_cur->h; strlcpy(buf, " ", sizeof(buf)); @@ -1377,7 +1409,7 @@ redraw_modeline(struct tab *tab) { double pct; int x, y, max_x, max_y; - const char *mode = tab->page.name; + const char *mode = tab->window.page.name; const char *spin = "-\\|/"; werase(modeline); @@ -1385,24 +1417,24 @@ redraw_modeline(struct tab *tab) wmove(modeline, 0, 0); wprintw(modeline, "-%c%c %s ", - spin[tab->s.loading_anim_step], + spin[tab->loading_anim_step], trust_status_char(tab->trust), mode == NULL ? "(none)" : mode); - pct = (tab->s.line_off + tab->s.curs_y) * 100.0 / tab->s.line_max; + pct = (tab->window.line_off + tab->window.curs_y) * 100.0 / tab->window.line_max; - if (tab->s.line_max <= (size_t)body_lines) + if (tab->window.line_max <= (size_t)body_lines) wprintw(modeline, "All "); - else if (tab->s.line_off == 0) + else if (tab->window.line_off == 0) wprintw(modeline, "Top "); - else if (tab->s.line_off + body_lines >= tab->s.line_max) + else if (tab->window.line_off + body_lines >= tab->window.line_max) wprintw(modeline, "Bottom "); else wprintw(modeline, "%.0f%% ", pct); wprintw(modeline, "%d/%d %s ", - tab->s.line_off + tab->s.curs_y, - tab->s.line_max, + tab->window.line_off + tab->window.curs_y, + tab->window.line_max, tab->hist_cur->h); getyx(modeline, y, x); @@ -1420,7 +1452,7 @@ redraw_minibuffer(void) { struct tab *tab; size_t off_y, off_x = 0; - char *start; + char *start, *c; werase(minibuf); @@ -1436,7 +1468,9 @@ redraw_minibuffer(void) start = ministate.hist_cur != NULL ? ministate.hist_cur->h : ministate.buf; - while (utf8_swidth_between(start, ministate.curs) > (size_t)COLS/2) { + c = utf8_nth(ministate.window.current_line->line, + ministate.window.cpoff); + while (utf8_swidth_between(start, c) > (size_t)COLS/2) { start = utf8_next_cp(start); } @@ -1453,13 +1487,13 @@ redraw_minibuffer(void) /* If nothing else, show the URL at point */ if (!in_minibuffer && ministate.curmesg == NULL && *keybuf == '\0') { tab = current_tab(); - if (tab->s.current_line != NULL && - tab->s.current_line->parent->type == LINE_LINK) - waddstr(minibuf, tab->s.current_line->parent->alt); + if (tab->window.current_line != NULL && + tab->window.current_line->parent->type == LINE_LINK) + waddstr(minibuf, tab->window.current_line->parent->alt); } if (in_minibuffer) - wmove(minibuf, 0, off_x + utf8_swidth_between(start, ministate.curs)); + wmove(minibuf, 0, off_x + utf8_swidth_between(start, c)); } static void @@ -1490,12 +1524,12 @@ redraw_body(struct tab *tab) werase(body); - tab->s.line_off = MIN(tab->s.line_max-1, tab->s.line_off); - if (TAILQ_EMPTY(&tab->s.head)) + tab->window.line_off = MIN(tab->window.line_max-1, tab->window.line_off); + if (TAILQ_EMPTY(&tab->window.head)) return; line = 0; - vl = nth_line(tab, tab->s.line_off); + vl = nth_line(&tab->window, tab->window.line_off); for (; vl != NULL; vl = TAILQ_NEXT(vl, vlines)) { wmove(body, line, 0); print_vline(vl); @@ -1504,7 +1538,7 @@ redraw_body(struct tab *tab) break; } - wmove(body, tab->s.curs_y, tab->s.curs_x); + wmove(body, tab->window.curs_y, tab->window.curs_x); } static void @@ -1544,11 +1578,11 @@ message(const char *fmt, ...) static void start_loading_anim(struct tab *tab) { - if (tab->s.loading_anim) + if (tab->loading_anim) return; - tab->s.loading_anim = 1; - evtimer_set(&tab->s.loadingev, update_loading_anim, tab); - evtimer_add(&tab->s.loadingev, &loadingev_timer); + tab->loading_anim = 1; + evtimer_set(&tab->loadingev, update_loading_anim, tab); + evtimer_add(&tab->loadingev, &loadingev_timer); } static void @@ -1556,7 +1590,7 @@ update_loading_anim(int fd, short ev, void *d) { struct tab *tab = d; - tab->s.loading_anim_step = (tab->s.loading_anim_step+1)%4; + tab->loading_anim_step = (tab->loading_anim_step+1)%4; if (tab->flags & TAB_CURRENT) { redraw_modeline(tab); @@ -1566,17 +1600,17 @@ update_loading_anim(int fd, short ev, void *d) wrefresh(minibuf); } - evtimer_add(&tab->s.loadingev, &loadingev_timer); + evtimer_add(&tab->loadingev, &loadingev_timer); } static void stop_loading_anim(struct tab *tab) { - if (!tab->s.loading_anim) + if (!tab->loading_anim) return; - evtimer_del(&tab->s.loadingev); - tab->s.loading_anim = 0; - tab->s.loading_anim_step = 0; + evtimer_del(&tab->loadingev); + tab->loading_anim = 0; + tab->loading_anim_step = 0; if (!(tab->flags & TAB_CURRENT)) return; @@ -1592,13 +1626,13 @@ stop_loading_anim(struct tab *tab) static void load_url_in_tab(struct tab *tab, const char *url) { - empty_vlist(tab); + empty_vlist(&tab->window); message("Loading %s...", url); start_loading_anim(tab); load_url(tab, url); - tab->s.curs_x = 0; - tab->s.curs_y = 0; + tab->window.curs_x = 0; + tab->window.curs_y = 0; redraw_tab(tab); } @@ -1615,8 +1649,9 @@ enter_minibuffer(void (*self_insert_fn)(void), void (* ministate.donefn = donefn; ministate.abortfn = abortfn; memset(ministate.buf, 0, sizeof(ministate.buf)); - ministate.curs = ministate.buf; - ministate.cpoff = 0; + ministate.window.current_line = &ministate.vline; + ministate.window.current_line->line = ministate.buf; + ministate.window.cpoff = 0; strlcpy(ministate.buf, "", sizeof(ministate.prompt)); ministate.history = hist; @@ -1658,7 +1693,7 @@ new_tab(const char *url) TAILQ_INIT(&tab->hist.head); - TAILQ_INIT(&tab->s.head); + TAILQ_INIT(&tab->window.head); tab->id = tab_counter++; switch_to_tab(tab); @@ -1708,6 +1743,10 @@ ui_init(int argc, char * const *argv) TAILQ_INIT(&ir_history.head); TAILQ_INIT(&lu_history.head); + ministate.line.type = LINE_TEXT; + ministate.vline.parent = &ministate.line; + ministate.window.current_line = &ministate.vline; + base_map = &global_map; current_map = &global_map; load_default_keys(); @@ -1767,9 +1806,9 @@ ui_on_tab_loaded(struct tab *tab) void ui_on_tab_refresh(struct tab *tab) { - wrap_page(tab); + wrap_page(&tab->window); if (tab->flags & TAB_CURRENT) { - restore_cursor(tab); + restore_cursor(&tab->window); redraw_tab(tab); } } blob - 98aa6ca7aa2f966abcac792d28ef44e1c84b3624 blob + f7ccfde138d0c9e480b86947d47b87e817f584d7 --- utf8.c +++ utf8.c @@ -180,26 +180,26 @@ utf8_swidth_between(const char *str, const char *end) } char * -utf8_next_cp(char *s) +utf8_next_cp(const char *s) { uint32_t cp = 0, state = 0; for (; *s; ++s) if (!utf8_decode(&state, &cp, *s)) break; - return s+1; + return (char*)s+1; } char * -utf8_prev_cp(char *start, char *base) +utf8_prev_cp(const char *start, const char *base) { uint8_t c; for (; start > base; start--) { c = *start; if ((c & 0xC0) != 0x80) - return start; + return (char*)start; } - return base; + return (char*)base; } blob - 2549ad5a7a36725c17a4881edd957b855975872d blob + f5f79bcaa3f3261bf1b965178514c4a976559398 --- wrap.c +++ wrap.c @@ -36,11 +36,11 @@ */ static int -push_line(struct tab *tab, const struct line *l, const char *buf, size_t len, int cont) +push_line(struct window *window, const struct line *l, const char *buf, size_t len, int cont) { struct vline *vl; - tab->s.line_max++; + window->line_max++; if ((vl = calloc(1, sizeof(*vl))) == NULL) return 0; @@ -55,10 +55,10 @@ push_line(struct tab *tab, const struct line *l, const memcpy(vl->line, buf, len); vl->flags = cont; - if (TAILQ_EMPTY(&tab->s.head)) - TAILQ_INSERT_HEAD(&tab->s.head, vl, vlines); + if (TAILQ_EMPTY(&window->head)) + TAILQ_INSERT_HEAD(&window->head, vl, vlines); else - TAILQ_INSERT_TAIL(&tab->s.head, vl, vlines); + TAILQ_INSERT_TAIL(&window->head, vl, vlines); return 1; } @@ -67,7 +67,7 @@ push_line(struct tab *tab, const struct line *l, const * that when printed will have a leading prefix prfx. */ int -wrap_text(struct tab *tab, const char *prfx, struct line *l, size_t width) +wrap_text(struct window *window, const char *prfx, struct line *l, size_t width) { const char *separators = " \t-"; const char *start, *end, *line, *lastsep, *lastchar; @@ -76,7 +76,7 @@ wrap_text(struct tab *tab, const char *prfx, struct li int cont; if ((line = l->line) == NULL) - return push_line(tab, l, NULL, 0, 0); + return push_line(window, l, NULL, 0, 0); prfxwidth = utf8_swidth(prfx); cur = prfxwidth; @@ -92,7 +92,7 @@ wrap_text(struct tab *tab, const char *prfx, struct li end = lastsep == NULL ? utf8_next_cp((char*)lastchar) : utf8_next_cp((char*)lastsep); - if (!push_line(tab, l, start, end - start, cont)) + if (!push_line(window, l, start, end - start, cont)) return 0; cont = 1; start = end; @@ -106,11 +106,11 @@ wrap_text(struct tab *tab, const char *prfx, struct li cur += w; } - return push_line(tab, l, start, line - start, cont); + return push_line(window, l, start, line - start, cont); } int -hardwrap_text(struct tab *tab, struct line *l, size_t width) +hardwrap_text(struct window *window, struct line *l, size_t width) { const char *line, *start, *lastchar; int cont; @@ -118,7 +118,7 @@ hardwrap_text(struct tab *tab, struct line *l, size_t size_t cur, w; if ((line = l->line) == NULL) - return push_line(tab, l, NULL, 0, 0); + return push_line(window, l, NULL, 0, 0); start = line; lastchar = line; @@ -129,7 +129,7 @@ hardwrap_text(struct tab *tab, struct line *l, size_t continue; w = utf8_chwidth(cp); if (cur + w >= width) { - if (!push_line(tab, l, start, lastchar - start, cont)) + if (!push_line(window, l, start, lastchar - start, cont)) return 0; cont = 1; cur = 0; @@ -140,5 +140,5 @@ hardwrap_text(struct tab *tab, struct line *l, size_t cur += w; } - return push_line(tab, l, start, line - start, cont); + return push_line(window, l, start, line - start, cont); }