Merge branch 'vimprobable2' of ssh://vimprobable.org/home/vimprobable.org/web/public/vimprobable into vimprobable2
This commit is contained in:
commit
c71676c4e0
6
LICENSE
6
LICENSE
|
@ -1,6 +1,8 @@
|
|||
Copyright (c) 2009 Leon Winter
|
||||
Copyright (c) 2009 Hannes Schueller
|
||||
Copyright (c) 2009 Matto Fransen
|
||||
Copyright (c) 2009, 2010 Hannes Schueller
|
||||
Copyright (c) 2009, 2010 Matto Fransen
|
||||
Copyright (c) 2010 Hans-Peter Deifel
|
||||
Copyright (c) 2010 Thomas Adams
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
|
29
config.h
29
config.h
|
@ -1,13 +1,15 @@
|
|||
/*
|
||||
(c) 2009 by Leon Winter
|
||||
(c) 2009 by Hannes Schueller
|
||||
(c) 2009 by Matto Fransen
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
/* general settings */
|
||||
char startpage[241] = "http://www.vimprobable.org/";
|
||||
char useragent[120] = "Vimprobable2/0.9.5.0";
|
||||
char useragent[120] = "Vimprobable2/0.9.6.0";
|
||||
static const gboolean enablePlugins = TRUE; /* TRUE keeps plugins enabled */
|
||||
static const gboolean enableJava = TRUE; /* FALSE disables Java applets */
|
||||
|
||||
|
@ -49,14 +51,6 @@ static const char progressborderright = ']';
|
|||
#define COOKIES_STORAGE_FILENAME "%s/.config/vimprobable/cookies", getenv("HOME")
|
||||
#define COOKIES_STORAGE_READONLY FALSE /* if TRUE new cookies will be lost if you quit */
|
||||
|
||||
/* bookmarks */
|
||||
#define BOOKMARKS_STORAGE_FILENAME "%s/.config/vimprobable/bookmarks", getenv("HOME")
|
||||
|
||||
/* history */
|
||||
#define HISTORY_MAX_ENTRIES 1000
|
||||
#define HISTORY_STORAGE_FILENAME "%s/.config/vimprobable/history", getenv("HOME")
|
||||
#define CLOSED_URL_FILENAME "%s/.config/vimprobable/closed", getenv("HOME")
|
||||
|
||||
/* downloads directory */
|
||||
#define DOWNLOADS_PATH "%s", getenv("HOME")
|
||||
|
||||
|
@ -69,7 +63,6 @@ static const char progressborderright = ']';
|
|||
/* proxy */
|
||||
static const gboolean use_proxy = TRUE; /* TRUE if you're going to use a proxy (whose address
|
||||
is specified in http_proxy environment variable), false otherwise */
|
||||
|
||||
/* scrolling */
|
||||
static unsigned int scrollstep = 40; /* cursor difference in pixel */
|
||||
static unsigned int pagingkeep = 40; /* pixels kept when paging */
|
||||
|
@ -78,6 +71,7 @@ static unsigned int pagingkeep = 40; /* pixels kept when paging */
|
|||
/* searching */
|
||||
#define ENABLE_MATCH_HIGHLITING
|
||||
static const int searchoptions = CaseInsensitive | Wrapping;
|
||||
gboolean complete_case_sensitive = TRUE;
|
||||
|
||||
/* search engines */
|
||||
static Searchengine searchengines[] = {
|
||||
|
@ -101,8 +95,8 @@ Command commands[] = {
|
|||
{ "fo", navigate, {NavigationForward} },
|
||||
{ "forward", navigate, {NavigationForward} },
|
||||
{ "javascript", script, {Silent} },
|
||||
{ "o", open, {TargetCurrent} },
|
||||
{ "open", open, {TargetCurrent} },
|
||||
{ "o", open_arg, {TargetCurrent} },
|
||||
{ "open", open_arg, {TargetCurrent} },
|
||||
{ "q", quit, {0} },
|
||||
{ "quit", quit, {0} },
|
||||
{ "re", navigate, {NavigationReload} },
|
||||
|
@ -112,8 +106,8 @@ Command commands[] = {
|
|||
{ "qt", search_tag, {0} },
|
||||
{ "st", navigate, {NavigationCancel} },
|
||||
{ "stop", navigate, {NavigationCancel} },
|
||||
{ "t", open, {TargetNew} },
|
||||
{ "tabopen", open, {TargetNew} },
|
||||
{ "t", open_arg, {TargetNew} },
|
||||
{ "tabopen", open_arg, {TargetNew} },
|
||||
{ "print", print_frame, {0} },
|
||||
{ "bma", bookmark, {0} },
|
||||
{ "bookmark", bookmark, {0} },
|
||||
|
@ -141,7 +135,7 @@ static Mouse mouse[] = {
|
|||
/* modmask, modkey, button, function, argument */
|
||||
{ 0, 0, MOUSE_BUTTON_2, paste, {TargetCurrent | ClipboardPrimary | ClipboardGTK, rememberedURI} },
|
||||
{ GDK_CONTROL_MASK, 0, MOUSE_BUTTON_2, paste, {TargetNew | ClipboardPrimary | ClipboardGTK} },
|
||||
{ GDK_CONTROL_MASK, 0, MOUSE_BUTTON_1, open, {TargetNew, rememberedURI} },
|
||||
{ GDK_CONTROL_MASK, 0, MOUSE_BUTTON_1, open_arg, {TargetNew, rememberedURI} },
|
||||
};
|
||||
|
||||
/* settings (arguments of :set command) */
|
||||
|
@ -177,4 +171,5 @@ static Setting browsersettings[] = {
|
|||
{ "qmark", NULL, "", FALSE, FALSE, FALSE, FALSE },
|
||||
{ "proxy", NULL, "", FALSE, TRUE, FALSE, FALSE },
|
||||
{ "scrollbars", NULL, "", FALSE, TRUE, FALSE, FALSE },
|
||||
{ "completioncase", NULL, "", FALSE, TRUE, FALSE, FALSE },
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
(c) 2009 by Leon Winter
|
||||
(c) 2009 by Hannes Schueller
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <webkit/webkit.h>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
(c) 2009 by Leon Winter
|
||||
(c) 2009 by Hannes Schueller
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
|
6
keymap.h
6
keymap.h
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
#ifndef _KEYMAP
|
||||
|
@ -75,8 +77,8 @@ Key keys[] = {
|
|||
{ 0, GDK_g, GDK_u, descend, {NthSubdir} },
|
||||
{ GDK_SHIFT_MASK, GDK_g, GDK_U, descend, {Rootdir} },
|
||||
|
||||
{ 0, GDK_g, GDK_h, open, {TargetCurrent, startpage} },
|
||||
{ GDK_SHIFT_MASK, GDK_g, GDK_H, open, {TargetNew, startpage} },
|
||||
{ 0, GDK_g, GDK_h, open_arg, {TargetCurrent, startpage} },
|
||||
{ GDK_SHIFT_MASK, GDK_g, GDK_H, open_arg, {TargetNew, startpage} },
|
||||
|
||||
{ 0, 0, GDK_p, paste, {TargetCurrent | ClipboardPrimary | ClipboardGTK} },
|
||||
{ GDK_SHIFT_MASK, 0, GDK_P, paste, {TargetNew | ClipboardPrimary | ClipboardGTK} },
|
||||
|
|
444
main.c
444
main.c
|
@ -3,6 +3,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
@ -49,7 +51,7 @@ static gboolean focus_input(const Arg *arg);
|
|||
static gboolean input(const Arg *arg);
|
||||
static gboolean navigate(const Arg *arg);
|
||||
static gboolean number(const Arg *arg);
|
||||
static gboolean open(const Arg *arg);
|
||||
static gboolean open_arg(const Arg *arg);
|
||||
static gboolean paste(const Arg *arg);
|
||||
static gboolean quickmark(const Arg *arg);
|
||||
static gboolean quit(const Arg *arg);
|
||||
|
@ -86,7 +88,7 @@ void toggle_scrollbars(gboolean onoff);
|
|||
gboolean process_keypress(GdkEventKey *event);
|
||||
void fill_suggline(char * suggline, const char * command, const char *fill_with);
|
||||
GtkWidget * fill_eventbox(const char * completion_line);
|
||||
|
||||
static void mop_up(void);
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
@ -139,6 +141,21 @@ int maxcommands = 0;
|
|||
int commandpointer = 0;
|
||||
KeyList *keylistroot = NULL;
|
||||
|
||||
/* Cookie support. */
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
static SoupCookieJar *session_cookie_jar = NULL;
|
||||
static SoupCookieJar *file_cookie_jar = NULL;
|
||||
static time_t cookie_timeout = 4800;
|
||||
static char *cookie_store;
|
||||
static void setup_cookies(void);
|
||||
static const char *get_cookies(SoupURI *soup_uri);
|
||||
static void load_all_cookies(void);
|
||||
static void save_all_cookies(void);
|
||||
static void new_generic_request(SoupSession *soup_ses, SoupMessage *soup_msg, gpointer unused);
|
||||
static void update_cookie_jar(SoupCookie *new);
|
||||
static void handle_cookie_request(SoupMessage *soup_msg, gpointer unused);
|
||||
static int lock;
|
||||
#endif
|
||||
/* callbacks */
|
||||
void
|
||||
window_destroyed_cb(GtkWidget *window, gpointer func_data) {
|
||||
|
@ -197,7 +214,7 @@ webview_open_in_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, gpo
|
|||
if (strlen(rememberedURI) > 0) {
|
||||
a.s = rememberedURI;
|
||||
}
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -205,7 +222,7 @@ gboolean
|
|||
webview_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request,
|
||||
WebKitWebNavigationAction *action, WebKitWebPolicyDecision *decision, gpointer user_data) {
|
||||
Arg a = { .i = TargetNew, .s = (char*)webkit_network_request_get_uri(request) };
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
webkit_web_policy_decision_ignore(decision);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -325,7 +342,7 @@ webview_keypress_cb(WebKitWebView *webview, GdkEventKey *event) {
|
|||
memset(inputBuffer, 0, 65);
|
||||
if (event->keyval == GDK_Escape) {
|
||||
a.i = Info;
|
||||
a.s = "";
|
||||
a.s = g_strdup("");
|
||||
echo(&a);
|
||||
} else if (current_modkey == 0 && ((event->keyval >= GDK_1 && event->keyval <= GDK_9)
|
||||
|| (event->keyval == GDK_0 && count))) {
|
||||
|
@ -569,7 +586,6 @@ inputbox_activate_cb(GtkEntry *entry, gpointer user_data) {
|
|||
a.i = Error;
|
||||
a.s = g_strdup_printf("Not a browser command: %s", &text[1]);
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
} else if (!success) {
|
||||
a.i = Error;
|
||||
if (error_msg != NULL) {
|
||||
|
@ -580,7 +596,6 @@ inputbox_activate_cb(GtkEntry *entry, gpointer user_data) {
|
|||
a.s = g_strdup_printf("Unknown error. Please file a bug report!");
|
||||
}
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
}
|
||||
} else if ((forward = text[0] == '/') || text[0] == '?') {
|
||||
webkit_web_view_unmark_text_matches(webview);
|
||||
|
@ -725,19 +740,18 @@ GtkWidget * fill_eventbox(const char * completion_line) {
|
|||
|
||||
gboolean
|
||||
complete(const Arg *arg) {
|
||||
FILE *f;
|
||||
const char *filename;
|
||||
char *str, *s, *p, *markup, *entry, *searchfor, command[32] = "", suggline[512] = "", *url, **suggurls;
|
||||
char *str, *p, *s, *markup, *entry, *searchfor, command[32] = "", suggline[512] = "", **suggurls;
|
||||
size_t listlen, len, cmdlen;
|
||||
int i, spacepos;
|
||||
gboolean highlight = FALSE, finished = FALSE;
|
||||
Listelement *elementlist = NULL, *elementpointer;
|
||||
gboolean highlight = FALSE;
|
||||
GtkBox *row;
|
||||
GtkWidget *row_eventbox, *el;
|
||||
GtkBox *_table;
|
||||
GdkColor color;
|
||||
static GtkWidget *table, **widgets, *top_border;
|
||||
static char **suggestions, *prefix;
|
||||
static int n = 0, current = -1;
|
||||
static int n = 0, m, current = -1;
|
||||
|
||||
str = (char*)gtk_entry_get_text(GTK_ENTRY(inputbox));
|
||||
len = strlen(str);
|
||||
|
@ -770,9 +784,8 @@ complete(const Arg *arg) {
|
|||
return TRUE;
|
||||
if (!widgets) {
|
||||
prefix = g_strdup_printf(str);
|
||||
listlen = LENGTH(commands);
|
||||
widgets = malloc(sizeof(GtkWidget*) * listlen);
|
||||
suggestions = malloc(sizeof(char*) * listlen);
|
||||
widgets = malloc(sizeof(GtkWidget*) * MAX_LIST_SIZE);
|
||||
suggestions = malloc(sizeof(char*) * MAX_LIST_SIZE);
|
||||
top_border = gtk_event_box_new();
|
||||
gtk_widget_set_size_request(GTK_WIDGET(top_border), 0, 1);
|
||||
gdk_color_parse(completioncolor[2], &color);
|
||||
|
@ -782,9 +795,11 @@ complete(const Arg *arg) {
|
|||
_table = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
||||
highlight = len > 1;
|
||||
if (strchr(str, ' ') == NULL) {
|
||||
/* command completion */
|
||||
listlen = LENGTH(commands);
|
||||
for (i = 0; i < listlen; i++) {
|
||||
cmdlen = strlen(commands[i].cmd);
|
||||
if (!highlight || (len - 1 <= cmdlen && !strncmp(&str[1], commands[i].cmd, len - 1))) {
|
||||
if (!highlight || (n < MAX_LIST_SIZE && len - 1 <= cmdlen && !strncmp(&str[1], commands[i].cmd, len - 1))) {
|
||||
p = s = malloc(sizeof(char*) * (highlight ? sizeof(COMPLETION_TAG_OPEN) + sizeof(COMPLETION_TAG_CLOSE) - 1 : 1) + cmdlen);
|
||||
if (highlight) {
|
||||
memcpy(p, COMPLETION_TAG_OPEN, sizeof(COMPLETION_TAG_OPEN) - 1);
|
||||
|
@ -811,114 +826,69 @@ complete(const Arg *arg) {
|
|||
}
|
||||
} else {
|
||||
entry = (char *)malloc(512 * sizeof(char));
|
||||
if (entry != NULL) {
|
||||
memset(entry, 0, 512);
|
||||
suggurls = malloc(sizeof(char*) * listlen);
|
||||
if (suggurls != NULL) {
|
||||
spacepos = strcspn(str, " ");
|
||||
searchfor = (str + spacepos + 1);
|
||||
strncpy(command, (str + 1), spacepos - 1);
|
||||
if (strlen(command) == 3 && strncmp(command, "set", 3) == 0) {
|
||||
/* browser settings */
|
||||
listlen = LENGTH(browsersettings);
|
||||
for (i = 0; i < listlen; i++) {
|
||||
if (strstr(browsersettings[i].name, searchfor) != NULL) {
|
||||
/* match */
|
||||
fill_suggline(suggline, command, browsersettings[i].name);
|
||||
suggurls[n] = (char *)malloc(sizeof(char) * 512 + 1);
|
||||
strncpy(suggurls[n], suggline, 512);
|
||||
suggestions[n] = suggurls[n];
|
||||
row_eventbox = fill_eventbox(suggline);
|
||||
gtk_box_pack_start(_table, GTK_WIDGET(row_eventbox), FALSE, FALSE, 0);
|
||||
widgets[n++] = row_eventbox;
|
||||
}
|
||||
if (entry == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
memset(entry, 0, 512);
|
||||
suggurls = malloc(sizeof(char*) * MAX_LIST_SIZE);
|
||||
if (suggurls == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
spacepos = strcspn(str, " ");
|
||||
searchfor = (str + spacepos + 1);
|
||||
strncpy(command, (str + 1), spacepos - 1);
|
||||
if (strlen(command) == 3 && strncmp(command, "set", 3) == 0) {
|
||||
/* browser settings */
|
||||
listlen = LENGTH(browsersettings);
|
||||
for (i = 0; i < listlen; i++) {
|
||||
if (n < MAX_LIST_SIZE && strstr(browsersettings[i].name, searchfor) != NULL) {
|
||||
/* match */
|
||||
fill_suggline(suggline, command, browsersettings[i].name);
|
||||
suggurls[n] = (char *)malloc(sizeof(char) * 512 + 1);
|
||||
strncpy(suggurls[n], suggline, 512);
|
||||
suggestions[n] = suggurls[n];
|
||||
row_eventbox = fill_eventbox(suggline);
|
||||
gtk_box_pack_start(_table, GTK_WIDGET(row_eventbox), FALSE, FALSE, 0);
|
||||
widgets[n++] = row_eventbox;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
/* URL completion using the current command */
|
||||
filename = g_strdup_printf(BOOKMARKS_STORAGE_FILENAME);
|
||||
f = fopen(filename, "r");
|
||||
if (f != NULL) {
|
||||
while (finished != TRUE) {
|
||||
if ((char *)NULL == fgets(entry, 512, f)) {
|
||||
/* check if end of file was reached / error occured */
|
||||
if (!feof(f)) {
|
||||
break;
|
||||
}
|
||||
/* end of file reached */
|
||||
finished = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (strstr(entry, searchfor) != NULL) {
|
||||
/* found in bookmarks */
|
||||
if (strchr(entry, ' ') != NULL) {
|
||||
url = strtok(entry, " ");
|
||||
} else {
|
||||
url = strtok(entry, "\n");
|
||||
}
|
||||
fill_suggline(suggline, command, url);
|
||||
suggurls[n] = (char *)malloc(sizeof(char) * 512 + 1);
|
||||
strncpy(suggurls[n], suggline, 512);
|
||||
suggestions[n] = suggurls[n];
|
||||
row_eventbox = fill_eventbox(suggline);
|
||||
gtk_box_pack_start(_table, GTK_WIDGET(row_eventbox), FALSE, FALSE, 0);
|
||||
widgets[n++] = row_eventbox;
|
||||
}
|
||||
if (n >= listlen) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
/* history */
|
||||
if (n < listlen) {
|
||||
filename = g_strdup_printf(HISTORY_STORAGE_FILENAME);
|
||||
f = fopen(filename, "r");
|
||||
if (f != NULL) {
|
||||
finished = FALSE;
|
||||
while (finished != TRUE) {
|
||||
if ((char *)NULL == fgets(entry, 512, f)) {
|
||||
/* check if end of file was reached / error occured */
|
||||
if (!feof(f)) {
|
||||
break;
|
||||
}
|
||||
/* end of file reached */
|
||||
finished = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (strstr(entry, searchfor) != NULL) {
|
||||
/* found in history */
|
||||
if (strchr(entry, ' ') != NULL) {
|
||||
url = strtok(entry, " ");
|
||||
} else {
|
||||
url = strtok(entry, "\n");
|
||||
}
|
||||
fill_suggline(suggline, command, url);
|
||||
suggurls[n] = (char *)malloc(sizeof(char) * 512 + 1);
|
||||
strncpy(suggurls[n], suggline, 512);
|
||||
suggestions[n] = suggurls[n];
|
||||
row_eventbox = fill_eventbox(suggline);
|
||||
gtk_box_pack_start(_table, GTK_WIDGET(row_eventbox), FALSE, FALSE, 0);
|
||||
widgets[n++] = row_eventbox;
|
||||
}
|
||||
if (n >= listlen) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (suggurls != NULL) {
|
||||
free(suggurls);
|
||||
suggurls = NULL;
|
||||
}
|
||||
}
|
||||
if (entry != NULL) {
|
||||
free(entry);
|
||||
entry = NULL;
|
||||
} else if (strlen(command) == 2 && strncmp(command, "qt", 2) == 0) {
|
||||
/* completion on tags */
|
||||
spacepos = strcspn(str, " ");
|
||||
searchfor = (str + spacepos + 1);
|
||||
elementlist = complete_list(searchfor, 1, elementlist);
|
||||
} else {
|
||||
/* URL completion: bookmarks */
|
||||
elementlist = complete_list(searchfor, 0, elementlist);
|
||||
m = count_list(elementlist);
|
||||
if (m < MAX_LIST_SIZE) {
|
||||
/* URL completion: history */
|
||||
elementlist = complete_list(searchfor, 2, elementlist);
|
||||
}
|
||||
}
|
||||
elementpointer = elementlist;
|
||||
while (elementpointer != NULL) {
|
||||
fill_suggline(suggline, command, elementpointer->element);
|
||||
suggurls[n] = (char *)malloc(sizeof(char) * 512 + 1);
|
||||
strncpy(suggurls[n], suggline, 512);
|
||||
suggestions[n] = suggurls[n];
|
||||
row_eventbox = fill_eventbox(suggline);
|
||||
gtk_box_pack_start(_table, GTK_WIDGET(row_eventbox), FALSE, FALSE, 0);
|
||||
widgets[n++] = row_eventbox;
|
||||
elementpointer = elementpointer->next;
|
||||
if (n >= MAX_LIST_SIZE)
|
||||
break;
|
||||
}
|
||||
free_list(elementlist);
|
||||
if (suggurls != NULL) {
|
||||
free(suggurls);
|
||||
suggurls = NULL;
|
||||
}
|
||||
if (entry != NULL) {
|
||||
free(entry);
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
widgets = realloc(widgets, sizeof(GtkWidget*) * n);
|
||||
suggestions = realloc(suggestions, sizeof(char*) * n);
|
||||
|
@ -997,6 +967,12 @@ echo(const Arg *arg) {
|
|||
set_widget_font_and_color(inputbox, urlboxfont[index], urlboxbgcolor[index], urlboxcolor[index]);
|
||||
gtk_entry_set_text(GTK_ENTRY(inputbox), !arg->s ? "" : arg->s);
|
||||
|
||||
/* TA: Always free arg->s here, rather than relying on the caller to do
|
||||
* this.
|
||||
*/
|
||||
if (arg->s)
|
||||
g_free(arg->s);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1041,7 @@ number(const Arg *arg) {
|
|||
}
|
||||
|
||||
gboolean
|
||||
open(const Arg *arg) {
|
||||
open_arg(const Arg *arg) {
|
||||
char *argv[6];
|
||||
char *s = arg->s, *p, *new;
|
||||
Arg a = { .i = NavigationReload };
|
||||
|
@ -1152,7 +1128,7 @@ paste(const Arg *arg) {
|
|||
/* If we're over a link, open it in a new target. */
|
||||
if (strlen(rememberedURI) > 0) {
|
||||
Arg new_target = { .i = TargetNew, .s = arg->s };
|
||||
open(&new_target);
|
||||
open_arg(&new_target);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1161,7 +1137,7 @@ paste(const Arg *arg) {
|
|||
if (!a.s && arg->i & ClipboardGTK)
|
||||
a.s = gtk_clipboard_wait_for_text(clipboards[1]);
|
||||
if (a.s)
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1198,7 +1174,7 @@ revive(const Arg *arg) {
|
|||
}
|
||||
if (strlen(buffer) > 0) {
|
||||
a.s = buffer;
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -1239,7 +1215,6 @@ search(const Arg *arg) {
|
|||
direction ? "BOTTOM" : "TOP",
|
||||
direction ? "TOP" : "BOTTOM");
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
} else
|
||||
break;
|
||||
} else
|
||||
|
@ -1250,7 +1225,6 @@ search(const Arg *arg) {
|
|||
a.i = Error;
|
||||
a.s = g_strdup_printf("Pattern not found: %s", search_handle);
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1269,15 +1243,15 @@ set(const Arg *arg) {
|
|||
gtk_widget_grab_focus(GTK_WIDGET(webview));
|
||||
break;
|
||||
case ModePassThrough:
|
||||
a.s = "-- PASS THROUGH --";
|
||||
a.s = g_strdup("-- PASS THROUGH --");
|
||||
echo(&a);
|
||||
break;
|
||||
case ModeSendKey:
|
||||
a.s = "-- PASS TROUGH (next) --";
|
||||
a.s = g_strdup("-- PASS TROUGH (next) --");
|
||||
echo(&a);
|
||||
break;
|
||||
case ModeInsert: /* should not be called manually but automatically */
|
||||
a.s = "-- INSERT --";
|
||||
a.s = g_strdup("-- INSERT --");
|
||||
echo(&a);
|
||||
break;
|
||||
case ModeHints:
|
||||
|
@ -1343,13 +1317,12 @@ quickmark(const Arg *a) {
|
|||
char *ptr = strrchr(buf, '\n');
|
||||
*ptr = '\0';
|
||||
Arg x = { .s = buf };
|
||||
if ( strlen(buf)) return open(&x);
|
||||
if ( strlen(buf)) return open_arg(&x);
|
||||
else
|
||||
{
|
||||
x.i = Error;
|
||||
x.s = g_strdup_printf("Quickmark %d not defined", b);
|
||||
echo(&x);
|
||||
g_free(x.s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1372,7 +1345,7 @@ script(const Arg *arg) {
|
|||
}
|
||||
if (arg->i != Silent && value) {
|
||||
a.i = arg->i;
|
||||
a.s = value;
|
||||
a.s = g_strdup(value);
|
||||
echo(&a);
|
||||
}
|
||||
if (value) {
|
||||
|
@ -1395,7 +1368,7 @@ script(const Arg *arg) {
|
|||
a.i = TargetCurrent;
|
||||
memset(followTarget, 0, 8);
|
||||
a.s = (value + 5);
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
}
|
||||
}
|
||||
g_free(value);
|
||||
|
@ -1444,7 +1417,7 @@ fake_key_event(const Arg *a) {
|
|||
err.i = Error;
|
||||
Display *xdpy;
|
||||
if ( (xdpy = XOpenDisplay(NULL)) == NULL ) {
|
||||
err.s = "Couldn't find the XDisplay.";
|
||||
err.s = g_strdup("Couldn't find the XDisplay.");
|
||||
echo(&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1459,7 +1432,7 @@ fake_key_event(const Arg *a) {
|
|||
xk.state = a->i;
|
||||
|
||||
if( ! a->s ) {
|
||||
err.s = "Zero pointer as argument! Check your config.h";
|
||||
err.s = g_strdup("Zero pointer as argument! Check your config.h");
|
||||
echo(&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1472,14 +1445,14 @@ fake_key_event(const Arg *a) {
|
|||
}
|
||||
|
||||
if( (xk.keycode = XKeysymToKeycode(xdpy, keysym)) == NoSymbol ) {
|
||||
err.s = "Couldn't translate keysym to keycode";
|
||||
err.s = g_strdup("Couldn't translate keysym to keycode");
|
||||
echo(&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xk.type = KeyPress;
|
||||
if( !XSendEvent(xdpy, embed, True, KeyPressMask, (XEvent *)&xk) ) {
|
||||
err.s = "XSendEvent failed";
|
||||
err.s = g_strdup("XSendEvent failed");
|
||||
echo(&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1757,6 +1730,10 @@ process_set_line(char *line) {
|
|||
if (strlen(my_pair.what) == 10 && strncmp("scrollbars", my_pair.what, 10) == 0)
|
||||
toggle_scrollbars(boolval);
|
||||
|
||||
/* case sensitivity of completion */
|
||||
if (strlen(my_pair.what) == 14 && strncmp("completioncase", my_pair.what, 14) == 0)
|
||||
complete_case_sensitive = boolval;
|
||||
|
||||
/* reload page? */
|
||||
if (browsersettings[i].reload)
|
||||
webkit_web_view_reload(webview);
|
||||
|
@ -1838,7 +1815,7 @@ search_tag(const Arg * a) {
|
|||
while (s[i] && !isspace(s[i])) url[k++] = s[i++];
|
||||
url[k] = '\0';
|
||||
Arg x = { .i = TargetNew, .s = url };
|
||||
open (&x);
|
||||
open_arg(&x);
|
||||
}
|
||||
}
|
||||
intag = 0;
|
||||
|
@ -2083,9 +2060,7 @@ setup_settings() {
|
|||
SoupURI *proxy_uri;
|
||||
char *filename, *new;
|
||||
int len;
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
SoupCookieJar *cookiejar;
|
||||
#endif
|
||||
|
||||
session = webkit_get_default_session();
|
||||
g_object_set((GObject*)settings, "default-font-size", DEFAULT_FONT_SIZE, NULL);
|
||||
g_object_set((GObject*)settings, "enable-scripts", enablePlugins, NULL);
|
||||
|
@ -2097,12 +2072,7 @@ setup_settings() {
|
|||
g_object_set((GObject*)settings, "user-agent", useragent, NULL);
|
||||
g_object_get((GObject*)settings, "zoom-step", &zoomstep, NULL);
|
||||
webkit_web_view_set_settings(webview, settings);
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
filename = g_strdup_printf(COOKIES_STORAGE_FILENAME);
|
||||
cookiejar = soup_cookie_jar_text_new(filename, COOKIES_STORAGE_READONLY);
|
||||
g_free(filename);
|
||||
soup_session_add_feature(session, (SoupSessionFeature*)cookiejar);
|
||||
#endif
|
||||
|
||||
/* proxy */
|
||||
if (use_proxy == TRUE) {
|
||||
filename = (char *)g_getenv("http_proxy");
|
||||
|
@ -2123,6 +2093,10 @@ setup_settings() {
|
|||
|
||||
void
|
||||
setup_signals() {
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
/* Headers. */
|
||||
g_signal_connect_after((GObject*)session, "request-started", (GCallback)new_generic_request, NULL);
|
||||
#endif
|
||||
/* window */
|
||||
g_object_connect((GObject*)window,
|
||||
"signal::destroy", (GCallback)window_destroyed_cb, NULL,
|
||||
|
@ -2161,6 +2135,174 @@ setup_signals() {
|
|||
"inspect-web-view", (GCallback)inspector_inspect_web_view_cb, NULL);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
void
|
||||
setup_cookies()
|
||||
{
|
||||
if (file_cookie_jar)
|
||||
g_object_unref(file_cookie_jar);
|
||||
|
||||
if (session_cookie_jar)
|
||||
g_object_unref(session_cookie_jar);
|
||||
|
||||
session_cookie_jar = soup_cookie_jar_new();
|
||||
cookie_store = g_strdup_printf(COOKIES_STORAGE_FILENAME);
|
||||
|
||||
lock = open(cookie_store, 0);
|
||||
flock(lock, LOCK_EX);
|
||||
|
||||
load_all_cookies();
|
||||
|
||||
flock(lock, LOCK_UN);
|
||||
close(lock);
|
||||
|
||||
soup_session_add_feature(session, SOUP_SESSION_FEATURE(session_cookie_jar));
|
||||
soup_session_add_feature(session, SOUP_SESSION_FEATURE(file_cookie_jar));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* TA: XXX - we should be using this callback for any header-requests we
|
||||
* receive (hence the name "new_generic_request" -- but for now, its use
|
||||
* is limited to handling cookies.
|
||||
*/
|
||||
void
|
||||
new_generic_request(SoupSession *session, SoupMessage *soup_msg, gpointer unused) {
|
||||
SoupMessageHeaders *soup_msg_h;
|
||||
SoupURI *uri;
|
||||
const char *cookie_str;
|
||||
|
||||
soup_msg_h = soup_msg->request_headers;
|
||||
soup_message_headers_remove(soup_msg_h, "Cookie");
|
||||
uri = soup_message_get_uri(soup_msg);
|
||||
if( (cookie_str = get_cookies(uri)) )
|
||||
soup_message_headers_append(soup_msg_h, "Cookie", cookie_str);
|
||||
|
||||
g_signal_connect_after(G_OBJECT(soup_msg), "got-headers", G_CALLBACK(handle_cookie_request), NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char *
|
||||
get_cookies(SoupURI *soup_uri) {
|
||||
const char *cookie_str;
|
||||
|
||||
cookie_str = soup_cookie_jar_get_cookies(session_cookie_jar, soup_uri, TRUE);
|
||||
|
||||
return cookie_str;
|
||||
}
|
||||
|
||||
void
|
||||
handle_cookie_request(SoupMessage *soup_msg, gpointer unused)
|
||||
{
|
||||
GSList *resp_cookie = NULL;
|
||||
SoupCookie *cookie;
|
||||
|
||||
for(resp_cookie = soup_cookies_from_response(soup_msg);
|
||||
resp_cookie;
|
||||
resp_cookie = g_slist_next(resp_cookie))
|
||||
{
|
||||
SoupDate *soup_date;
|
||||
cookie = soup_cookie_copy((SoupCookie *)resp_cookie->data);
|
||||
|
||||
if (cookie_timeout && cookie->expires == NULL) {
|
||||
soup_date = soup_date_new_from_time_t(time(NULL) + cookie_timeout * 10);
|
||||
soup_cookie_set_expires(cookie, soup_date);
|
||||
}
|
||||
soup_cookie_jar_add_cookie(session_cookie_jar, cookie);
|
||||
update_cookie_jar(cookie);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
update_cookie_jar(SoupCookie *new)
|
||||
{
|
||||
if (!new) {
|
||||
/* Nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* TA: Note that this locking is merely advisory -- because there's
|
||||
* no linking between different vimprobable processes, the cookie jar,
|
||||
* when being written to here, *WILL* be truncated and overwritten
|
||||
* with cookie contents from the specific session saving its cookies
|
||||
* at that time.
|
||||
*
|
||||
* This may or may not contain cookies stored in other Vimprobable
|
||||
* instances, although when those instances save their cookies,
|
||||
* they'll just replace the cookie store's contents.
|
||||
*
|
||||
* The locking should probably be changed to be fcntl() based one day
|
||||
* -- but the caveat with that is all Vimprobable instances would then
|
||||
* block waiting for the cookie file to become availabe. The
|
||||
* advisory locking used here so far seems to work OK, but if we run
|
||||
* into problems in the future, we'll know where to look.
|
||||
*
|
||||
* Ideally, if Vimprobable were ever to want to do this cleanly,
|
||||
* something like using libunique to pass messages between registered
|
||||
* sessions.
|
||||
*/
|
||||
lock = open(cookie_store, 0);
|
||||
flock(lock, LOCK_EX);
|
||||
|
||||
save_all_cookies();
|
||||
load_all_cookies();
|
||||
|
||||
flock(lock, LOCK_UN);
|
||||
close(lock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
save_all_cookies()
|
||||
{
|
||||
GSList *session_cookie_list = soup_cookie_jar_all_cookies(session_cookie_jar);
|
||||
|
||||
for (; session_cookie_list;
|
||||
session_cookie_list = session_cookie_list->next)
|
||||
{
|
||||
soup_cookie_jar_add_cookie(file_cookie_jar, session_cookie_list->data);
|
||||
}
|
||||
|
||||
soup_cookies_free(session_cookie_list);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
load_all_cookies()
|
||||
{
|
||||
file_cookie_jar = soup_cookie_jar_text_new(cookie_store, COOKIES_STORAGE_READONLY);
|
||||
|
||||
/* Put them back in the session store. */
|
||||
GSList *cookies_from_file = soup_cookie_jar_all_cookies(file_cookie_jar);
|
||||
|
||||
for (; cookies_from_file;
|
||||
cookies_from_file = cookies_from_file->next)
|
||||
{
|
||||
soup_cookie_jar_add_cookie(session_cookie_jar, cookies_from_file->data);
|
||||
}
|
||||
|
||||
soup_cookies_free(cookies_from_file);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
mop_up(void) {
|
||||
/* Free up any nasty globals before exiting. */
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
if (cookie_store)
|
||||
g_free(cookie_store);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
static Arg a;
|
||||
|
@ -2202,6 +2344,9 @@ main(int argc, char *argv[]) {
|
|||
setup_modkeys();
|
||||
make_keyslist();
|
||||
setup_gui();
|
||||
#ifdef ENABLE_COOKIE_SUPPORT
|
||||
setup_cookies();
|
||||
#endif
|
||||
|
||||
/* read config file */
|
||||
if (!read_rcfile(configfile)) {
|
||||
|
@ -2209,7 +2354,6 @@ main(int argc, char *argv[]) {
|
|||
a.i = Error;
|
||||
a.s = g_strdup_printf("Error in config file");
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
}
|
||||
|
||||
/* command line argument: URL */
|
||||
|
@ -2221,8 +2365,10 @@ main(int argc, char *argv[]) {
|
|||
|
||||
a.i = TargetCurrent;
|
||||
a.s = url;
|
||||
open(&a);
|
||||
open_arg(&a);
|
||||
gtk_main();
|
||||
|
||||
mop_up();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
2
main.h
2
main.h
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
|
141
utilities.c
141
utilities.c
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
@ -16,6 +18,7 @@ extern int lastcommand, maxcommands, commandpointer;
|
|||
extern KeyList *keylistroot;
|
||||
extern Key keys[];
|
||||
extern char *error_msg;
|
||||
extern gboolean complete_case_sensitive;
|
||||
|
||||
gboolean read_rcfile(const char *config)
|
||||
{
|
||||
|
@ -76,7 +79,6 @@ process_save_qmark(const char *bm, WebKitWebView *webview)
|
|||
a.i = Error;
|
||||
a.s = g_strdup_printf("Invalid quickmark, only 1-9");
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
return TRUE;
|
||||
}
|
||||
if ( uri == NULL ) return FALSE;
|
||||
|
@ -113,7 +115,6 @@ process_save_qmark(const char *bm, WebKitWebView *webview)
|
|||
a.i = Error;
|
||||
a.s = g_strdup_printf("Saved as quickmark %d: %s", mark, uri);
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -404,5 +405,139 @@ give_feedback(const char *feedback)
|
|||
|
||||
a.s = g_strdup_printf(feedback);
|
||||
echo(&a);
|
||||
g_free(a.s);
|
||||
}
|
||||
|
||||
Listelement *
|
||||
complete_list(const char *searchfor, const int mode, Listelement *elementlist)
|
||||
{
|
||||
FILE *f;
|
||||
const char *filename;
|
||||
Listelement *candidatelist = NULL, *candidatepointer = NULL;
|
||||
char s[255] = "", readelement[MAXTAGSIZE + 1] = "";
|
||||
int i, t, n = 0;
|
||||
|
||||
if (mode == 2) {
|
||||
/* open in history file */
|
||||
filename = g_strdup_printf(HISTORY_STORAGE_FILENAME);
|
||||
} else {
|
||||
/* open in bookmark file (for tags and bookmarks) */
|
||||
filename = g_strdup_printf(BOOKMARKS_STORAGE_FILENAME);
|
||||
}
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
g_free((gpointer)filename);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
while (fgets(s, 254, f)) {
|
||||
if (mode == 1) {
|
||||
/* just tags (could be more than one per line) */
|
||||
i = 0;
|
||||
while (s[i] && i < 254) {
|
||||
while (s[i] != '[' && s[i])
|
||||
i++;
|
||||
if (s[i] != '[')
|
||||
continue;
|
||||
i++;
|
||||
t = 0;
|
||||
while (s[i] != ']' && s[i] && t < MAXTAGSIZE)
|
||||
readelement[t++] = s[i++];
|
||||
readelement[t] = '\0';
|
||||
candidatelist = add_list(readelement, candidatelist);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
/* complete string (bookmarks & history) */
|
||||
candidatelist = add_list(s, candidatelist);
|
||||
}
|
||||
candidatepointer = candidatelist;
|
||||
while (candidatepointer != NULL) {
|
||||
if (!complete_case_sensitive) {
|
||||
g_strdown(candidatepointer->element);
|
||||
}
|
||||
if (!strlen(searchfor) || strstr(candidatepointer->element, searchfor) != NULL) {
|
||||
/* only use string up to the first space */
|
||||
memset(readelement, 0, MAXTAGSIZE + 1);
|
||||
if (strchr(candidatepointer->element, ' ') != NULL) {
|
||||
i = strcspn(candidatepointer->element, " ");
|
||||
strncpy(readelement, candidatepointer->element, i);
|
||||
} else {
|
||||
strncpy(readelement, candidatepointer->element, MAXTAGSIZE);
|
||||
}
|
||||
elementlist = add_list(readelement, elementlist);
|
||||
n = count_list(elementlist);
|
||||
}
|
||||
if (n >= MAX_LIST_SIZE)
|
||||
break;
|
||||
candidatepointer = candidatepointer->next;
|
||||
}
|
||||
free_list(candidatelist);
|
||||
candidatelist = NULL;
|
||||
if (n >= MAX_LIST_SIZE)
|
||||
break;
|
||||
}
|
||||
g_free((gpointer)filename);
|
||||
return (elementlist);
|
||||
}
|
||||
|
||||
Listelement *
|
||||
add_list(const char *element, Listelement *elementlist)
|
||||
{
|
||||
int n, i = 0;
|
||||
Listelement *newelement, *elementpointer, *lastelement;
|
||||
|
||||
if (elementlist == NULL) { /* first element */
|
||||
newelement = malloc(sizeof(Listelement));
|
||||
if (newelement == NULL)
|
||||
return (NULL);
|
||||
strncpy(newelement->element, element, 254);
|
||||
newelement->next = NULL;
|
||||
return newelement;
|
||||
}
|
||||
elementpointer = elementlist;
|
||||
n = strlen(element);
|
||||
|
||||
/* check if element is already in list */
|
||||
while (elementpointer != NULL) {
|
||||
if (strlen(elementpointer->element) == n &&
|
||||
strncmp(elementpointer->element, element, n) == 0)
|
||||
return (elementlist);
|
||||
lastelement = elementpointer;
|
||||
elementpointer = elementpointer->next;
|
||||
i++;
|
||||
}
|
||||
/* add to list */
|
||||
newelement = malloc(sizeof(Listelement));
|
||||
if (newelement == NULL)
|
||||
return (NULL);
|
||||
lastelement->next = newelement;
|
||||
strncpy(newelement->element, element, 254);
|
||||
newelement->next = NULL;
|
||||
return elementlist;
|
||||
}
|
||||
|
||||
void
|
||||
free_list(Listelement *elementlist)
|
||||
{
|
||||
Listelement *elementpointer;
|
||||
|
||||
while (elementlist != NULL) {
|
||||
elementpointer = elementlist->next;
|
||||
free(elementlist);
|
||||
elementlist = elementpointer;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
count_list(Listelement *elementlist)
|
||||
{
|
||||
Listelement *elementpointer = elementlist;
|
||||
int n = 0;
|
||||
|
||||
while (elementpointer != NULL) {
|
||||
n++;
|
||||
elementpointer = elementpointer->next;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
@ -24,4 +26,7 @@ gboolean mappings(const Arg *arg);
|
|||
gboolean build_taglist(const Arg *arg, FILE *f);
|
||||
void set_error(const char *error);
|
||||
void give_feedback(const char *feedback);
|
||||
|
||||
Listelement * complete_list(const char *searchfor, const int mode, Listelement *elementlist);
|
||||
Listelement * add_list(const char *element, Listelement *elementlist);
|
||||
int count_list(Listelement *elementlist);
|
||||
void free_list(Listelement *elementlist);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
(c) 2009 by Leon Winter
|
||||
(c) 2009, 2010 by Hannes Schueller
|
||||
(c) 2009, 2010 by Matto Fransen
|
||||
(c) 2010 by Hans-Peter Deifel
|
||||
(c) 2010 by Thomas Adams
|
||||
see LICENSE file
|
||||
*/
|
||||
|
||||
|
@ -141,6 +143,11 @@ struct map_pair {
|
|||
char value[240];
|
||||
} my_pair;
|
||||
|
||||
typedef struct {
|
||||
void *next;
|
||||
char element[255];
|
||||
} Listelement;
|
||||
|
||||
/* constants */
|
||||
#define MOUSE_BUTTON_1 1
|
||||
#define MOUSE_BUTTON_2 2
|
||||
|
@ -150,6 +157,16 @@ struct map_pair {
|
|||
#define BUFFERSIZE 255
|
||||
#define MAXTAGSIZE 200
|
||||
|
||||
/* quickmarks */
|
||||
#define QUICKMARK_FILE "%s/.config/vimprobable/quickmarks", getenv("HOME")
|
||||
/* bookmarks */
|
||||
#define BOOKMARKS_STORAGE_FILENAME "%s/.config/vimprobable/bookmarks", getenv("HOME")
|
||||
|
||||
/* quickmarks */
|
||||
#define QUICKMARK_FILE "%s/.config/vimprobable/quickmarks", getenv("HOME")
|
||||
|
||||
/* history */
|
||||
#define HISTORY_MAX_ENTRIES 1000
|
||||
#define HISTORY_STORAGE_FILENAME "%s/.config/vimprobable/history", getenv("HOME")
|
||||
#define CLOSED_URL_FILENAME "%s/.config/vimprobable/closed", getenv("HOME")
|
||||
|
||||
/* completion list size */
|
||||
#define MAX_LIST_SIZE 40
|
||||
|
|
Loading…
Reference in New Issue