Apply this patch like so (in links-x.y directory) patch -p1 < unhistory.diff then, cd intl; ./synclang There is a config file variable, "keep_unhistory". Read the source or email me to find out how to use it. Peter Wang (tjaden@psynet.net) diff -urN mikulas1/default.c mikulas2/default.c --- mikulas1/default.c Mon Nov 13 09:06:05 2000 +++ mikulas2/default.c Mon Nov 13 09:51:50 2000 @@ -898,6 +898,7 @@ 1, NULL, prog_rd, prog_wr, 0, 0, &tn3270_prog, "tn3270", NULL, 1, NULL, bind_rd, NULL, 0, 0, NULL, "bind", NULL, 1, NULL, unbind_rd, NULL, 0, 0, NULL, "unbind", NULL, + 1, NULL, num_rd, NULL, 0, 1, &keep_unhistory, "keep_unhistory", NULL, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, }; diff -urN mikulas1/intl/english.lng mikulas2/intl/english.lng --- mikulas1/intl/english.lng Mon Nov 13 08:58:12 2000 +++ mikulas2/intl/english.lng Mon Nov 13 09:51:29 2000 @@ -78,6 +78,7 @@ T_GOTO_URL, "Go to URL", T_GO_BACK, "Go back", T_HISTORY, "History", +T_UNHISTORY, "Unhistory", T_RELOAD, "Reload", T_SAVE_AS, "Save as", T_SAVE_URL_AS, "Save URL as", @@ -299,6 +300,7 @@ T_HK_GOTO_URL, "G", T_HK_GO_BACK, "B", T_HK_HISTORY, "H", +T_HK_UNHISTORY, "T", T_HK_RELOAD, "R", T_HK_SAVE_AS, "V", T_HK_SAVE_URL_AS, "U", diff -urN mikulas1/kbdbind.c mikulas2/kbdbind.c --- mikulas1/kbdbind.c Mon Nov 13 09:20:35 2000 +++ mikulas2/kbdbind.c Mon Nov 13 09:51:29 2000 @@ -179,6 +179,7 @@ "search-back", "toggle-display-images", "toggle-html-plain", + "unback", "up", "view-image", "zoom-frame", @@ -281,6 +282,8 @@ { ACT_ENTER, KBD_RIGHT, 0 }, { ACT_ENTER, KBD_ENTER, 0 }, { ACT_BACK, KBD_LEFT, 0 }, + { ACT_UNBACK, 'u', 0 }, + { ACT_UNBACK, 'U', 0 }, { ACT_DOWNLOAD, 'd', 0 }, { ACT_DOWNLOAD, 'D', 0 }, { ACT_SEARCH, '/', 0 }, diff -urN mikulas1/links.h mikulas2/links.h --- mikulas1/links.h Mon Nov 13 09:20:24 2000 +++ mikulas2/links.h Mon Nov 13 09:51:29 2000 @@ -1395,6 +1395,7 @@ #define WTD_IMGMAP 2 #define WTD_RELOAD 3 #define WTD_BACK 4 +#define WTD_UNBACK 5 #define cur_loc(x) ((struct location *)((x)->history.next)) @@ -1421,6 +1422,8 @@ struct window *ask; }; +extern int keep_unhistory; + extern struct list_head downloads; struct file_to_load { @@ -1438,6 +1441,7 @@ struct session *next; struct session *prev; struct list_head history; + struct list_head unhistory; struct terminal *term; struct window *win; int id; @@ -1493,6 +1497,7 @@ void abort_loading(struct session *); void goto_imgmap(struct session *, unsigned char *, unsigned char *, unsigned char *); void go_back(struct session *); +void go_unback(struct session *); void reload(struct session*, int); struct frame *ses_find_frame(struct session *, unsigned char *); struct frame *ses_change_frame_url(struct session *, unsigned char *, unsigned char *); @@ -2129,6 +2134,7 @@ ACT_SEARCH_BACK, ACT_TOGGLE_DISPLAY_IMAGES, ACT_TOGGLE_HTML_PLAIN, + ACT_UNBACK, ACT_UP, ACT_VIEW_IMAGE, ACT_ZOOM_FRAME diff -urN mikulas1/menu.c mikulas2/menu.c --- mikulas1/menu.c Mon Nov 13 08:58:12 2000 +++ mikulas2/menu.c Mon Nov 13 09:51:29 2000 @@ -259,9 +259,8 @@ while (steps > 1) { struct location *loc = ses->history.next; if ((void *) loc == &ses->history) return; - loc = loc->next; - if ((void *) loc == &ses->history) return; - destroy_location(loc); + del_from_list(loc); + add_to_list(ses->unhistory, loc); --steps; } @@ -270,6 +269,22 @@ go_back(ses); } +void go_unbackwards(struct terminal *term, void *psteps, struct session *ses) +{ + int steps = (int) psteps; + + abort_loading(ses); + + while (steps--) { + struct location *loc = ses->unhistory.next; + if ((void *) loc == &ses->unhistory) return; + del_from_list(loc); + add_to_list(ses->history, loc); + } + + go_unback(ses); +} + struct menu_item no_hist_menu[] = { TEXT(T_NO_HISTORY), "", M_BAR, NULL, NULL, 0, 0, NULL, NULL, 0, NULL, NULL, 0, 0 @@ -291,6 +306,20 @@ else do_menu(term, mi, ses); } +void unhistory_menu(struct terminal *term, void *ddd, struct session *ses) +{ + struct location *l; + struct menu_item *mi = NULL; + int n = 0; + foreach(l, ses->unhistory) { + if (!mi && !(mi = new_menu(3))) return; + add_to_menu(&mi, stracpy(l->vs.url), "", "", MENU_FUNC go_unbackwards, (void *) n, 0); + n++; + } + if (!n) do_menu(term, no_hist_menu, ses); + else do_menu(term, mi, ses); +} + struct menu_item no_downloads_menu[] = { TEXT(T_NO_DOWNLOADS), "", M_BAR, NULL, NULL, 0, 0, NULL, NULL, 0, NULL, NULL, 0, 0 @@ -970,6 +999,7 @@ TEXT(T_GOTO_URL), "g", TEXT(T_HK_GOTO_URL), MENU_FUNC menu_goto_url, (void *)0, 0, 0, TEXT(T_GO_BACK), "<-", TEXT(T_HK_GO_BACK), MENU_FUNC menu_go_back, (void *)0, 0, 0, TEXT(T_HISTORY), ">", TEXT(T_HK_HISTORY), MENU_FUNC history_menu, (void *)0, 1, 0, + TEXT(T_UNHISTORY), ">", TEXT(T_HK_UNHISTORY), MENU_FUNC unhistory_menu, (void *)0, 1, 0, TEXT(T_RELOAD), "Ctrl-R", TEXT(T_HK_RELOAD), MENU_FUNC menu_reload, (void *)0, 0, 0, }; diff -urN mikulas1/session.c mikulas2/session.c --- mikulas1/session.c Mon Nov 13 08:58:12 2000 +++ mikulas2/session.c Mon Nov 13 09:51:29 2000 @@ -1,5 +1,7 @@ #include "links.h" +int keep_unhistory = 0; + struct list_head downloads = {&downloads, &downloads}; int are_there_downloads() @@ -276,7 +278,8 @@ loc = ses->history.next; if (ses->search_word) mem_free(ses->search_word), ses->search_word = NULL; if ((void *)loc == &ses->history) return; - destroy_location(loc); + del_from_list(loc); + add_to_list(ses->unhistory, loc); loc = ses->history.next; if ((void *)loc == &ses->history) return; if (!strcmp(loc->vs.url, ses->loading_url)) return; @@ -284,6 +287,17 @@ ses_forward(ses); } +void ses_unback(struct session *ses) +{ + struct location *loc; + free_files(ses); + loc = ses->unhistory.next; + if (ses->search_word) mem_free(ses->search_word), ses->search_word = NULL; + if ((void *)loc == &ses->unhistory) return; + del_from_list(loc); + add_to_list(ses->history, loc); +} + void end_load(struct status *, struct session *); void doc_end_load(struct status *, struct session *); void file_end_load(struct status *, struct file_to_load *); @@ -921,7 +935,7 @@ return 2; } if (gp) mem_free(gp); - if (w == WTD_BACK) { + if (w == WTD_BACK || w == WTD_UNBACK) { ses_goto(ses, u, NULL, PRI_MAIN, NC_CACHE, WTD_RELOAD, NULL, end_load, 1); return 2; } @@ -941,6 +955,7 @@ } if (ses->wtd == WTD_IMGMAP) ses_imgmap(ses); if (ses->wtd == WTD_BACK) ses_back(ses); + if (ses->wtd == WTD_UNBACK) ses_unback(ses); if (ses->wtd == WTD_RELOAD) ses_back(ses), ses_forward(ses); if ((*stat)->state >= 0) change_connection(&ses->loading, *stat = &cur_loc(ses)->stat, PRI_MAIN); else cur_loc(ses)->stat.state = ses->loading.state; @@ -1164,6 +1179,7 @@ if ((ses = mem_alloc(sizeof(struct session)))) { memset(ses, 0, sizeof(struct session)); init_list(ses->history); + init_list(ses->unhistory); init_list(ses->scrn_frames); init_list(ses->more_files); ses->term = term; @@ -1316,18 +1332,8 @@ if (ses->screen) detach_formatted(ses->screen), mem_free(ses->screen); foreach(fdc, ses->scrn_frames) detach_formatted(fdc); free_list(ses->scrn_frames); - while ((void *)(l = ses->history.next) != &ses->history) { - struct frame *frm; - while ((void *)(frm = l->frames.next) != &l->frames) { - destroy_vs(&frm->vs); - mem_free(frm->name); - del_from_list(frm); - mem_free(frm); - } - destroy_vs(&l->vs); - del_from_list(l); - mem_free(l); - } + foreach(l, ses->history) destroy_location(l); + foreach(l, ses->unhistory) destroy_location(l); if (ses->loading_url) mem_free(ses->loading_url); if (ses->display_timer != -1) kill_timer(ses->display_timer); if (ses->goto_position) mem_free(ses->goto_position); @@ -1412,6 +1418,18 @@ ses_goto(ses, url, NULL, PRI_MAIN, NC_ALWAYS_CACHE, WTD_BACK, NULL, end_load, 0); } +void go_unback(struct session *ses) +{ + unsigned char *url; + ses->reloadlevel = NC_CACHE; + if (ses->unhistory.next == &ses->unhistory) + return; + abort_loading(ses); + if (!(url = stracpy(((struct location *)ses->unhistory.next)->vs.url))) + return; + ses_goto(ses, url, NULL, PRI_MAIN, NC_ALWAYS_CACHE, WTD_UNBACK, NULL, end_load, 1); +} + void goto_url_w(struct session *ses, unsigned char *url, unsigned char *target, int wtd) { unsigned char *u; @@ -1440,6 +1458,11 @@ abort_loading(ses); ses_goto(ses, u, target, PRI_MAIN, NC_CACHE, wtd, pos, end_load, 0); /*abort_loading(ses);*/ + + if (!keep_unhistory) { + struct location *l; + foreach(l, ses->unhistory) destroy_location(l); + } } void goto_url_f(struct session *ses, unsigned char *url, unsigned char *target) diff -urN mikulas1/view.c mikulas2/view.c --- mikulas1/view.c Mon Nov 13 09:24:27 2000 +++ mikulas2/view.c Mon Nov 13 09:51:29 2000 @@ -1398,6 +1398,11 @@ go_back(ses); } +void unback(struct session *ses, struct f_data_c *f, int a) +{ + go_unback(ses); +} + void selected_item(struct terminal *term, void *pitem, struct session *ses) { int item = (int)pitem; @@ -1966,6 +1971,9 @@ goto x; case ACT_BACK: back(ses, NULL, 0); + goto x; + case ACT_UNBACK: + unback(ses, NULL, 0); goto x; case ACT_RELOAD: reload(ses, -1);