This patch adds basic support for handling multiple buffers. New
commands are ":buf[fer], :badd, and :bdelete". Buffers are given a
unique constant buffer id starting at 1 in the same manner as vim.
The :badd command takes an optional url argument which it will open
when creating the buffer. If none is provided, it will open a new,
blank buffer.
The :buf[fer] command allows changing to another buffer in the buffer
list and supports tab completion.
The :bdelete command also supports tab completion and takes an
optional buffer argument and deletes it. If no argument is provided,
the current buffer is deleted.
I tried to as closely as possible follow the behavior in vim so that
it would be familiar to use and have been using it for several months
now. The buffer naming used in the tab completion is kind of clunky
but it works well enough. Other than that, I haven't had any serious
problems or complaints.
Please discuss if this is even something we think is worth adding, if
we should make it a compile time conditional feature, if you have
better suggestions for the implementation or tab completion, etc. I'd
appreciate any feedback. And of course please try it out. :)
*NOTE: This patch builds upon my previous patch just submitted to the
list regarding the commands list and COMMANDSIZE variable. These 2
patches are obviously conflicting, so you'll need to apply that one
first to test the buffer support. These changes are also in my
for-next branch on SF.
Regards,
Morgan
From 77e55f9ad85e16a7d72cf8151304e7ccababdcd7 Mon Sep 17 00:00:00 2001
From: Morgan Howe <[email protected]>
Date: Thu, 22 Jan 2015 21:52:57 +0800
Subject: [PATCH 2/2] Initial experimental support for buffers.
This adds the buffer, badd, and bdelete commands for managing multiple
buffers.
---
main.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
main.h | 13 ++++
utilities.c | 170 ++++++++++++++++++++++++----------------
utilities.h | 7 ++
4 files changed, 336 insertions(+), 105 deletions(-)
diff --git a/main.c b/main.c
index cec7273..ac84974 100644
--- a/main.c
+++ b/main.c
@@ -23,6 +23,7 @@
#include "utilities.h"
#include "callbacks.h"
#include "javascript.h"
+#include "main.h"
/* the CLEAN_MOD_*_MASK defines have all the bits set that will be stripped from the modifier bit field */
#define CLEAN_MOD_NUMLOCK_MASK (GDK_MOD2_MASK)
@@ -94,14 +95,21 @@ static gboolean yank(const Arg *arg);
static gboolean view_source(const Arg * arg);
static gboolean zoom(const Arg *arg);
static gboolean fake_key_event(const Arg *arg);
+static gboolean bufadd(const Arg *arg);
+static gboolean bufdelete(const Arg *arg);
+static gboolean bufshow(const Arg *arg);
static void clear_focus(void);
static void update_url(const char *uri);
static void setup_client(void);
static void setup_modkeys(void);
static void setup_gui(void);
-static void setup_settings(void);
+static void setup_settings(WebKitWebView *view);
static void setup_signals(void);
+Buffer *setup_new_webview_buffer(void);
+void destroy_webview_buffer(Buffer *buf);
+void show_webview_buffer(Buffer *buf);
+static void setup_webview_signals(WebKitWebView *view);
static void ascii_bar(int total, int state, char *string);
static gchar *jsapi_ref_to_string(JSContextRef context, JSValueRef ref);
static void jsapi_evaluate_script(const gchar *script, gchar **value, gchar **message);
@@ -123,8 +131,6 @@ 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"
-
/* variables */
static char **args;
@@ -146,8 +152,12 @@ Command commands[] = {
/* command, function, argument */
{ "ba", navigate, {NavigationBack} },
{ "back", navigate, {NavigationBack} },
+ { "badd", bufadd, {TargetCurrent} },
+ { "bdelete", bufdelete, {TargetCurrent} },
{ "bma", bookmark, {0} },
{ "bookmark", bookmark, {0} },
+ { "buf", bufshow, {TargetCurrent} },
+ { "buffer", bufshow, {TargetCurrent} },
{ "clear", clear, {0} },
{ "ec", script, {Info} },
{ "echo", script, {Info} },
@@ -195,8 +205,11 @@ Command commands[] = {
{ "zo", zoom, {ZoomOut | ZoomText} },
};
+static const char * const NO_URI = " ";
+
const size_t COMMANDSIZE = LENGTH(commands);
Client client;
+BufferList bufferlist = { 0, 1, NULL };
/* callbacks */
void
@@ -527,13 +540,11 @@ show_link(const char *link) {
void
webview_hoverlink_cb(WebKitWebView *webview, char *title, char *link, gpointer data) {
- const char *uri = webkit_web_view_get_uri(webview);
-
memset(client.state.rememberedURI, 0, BUF_SIZE);
if (link)
show_link(link);
else
- update_url(uri);
+ update_url(webkit_web_view_get_uri(webview));
}
gboolean
@@ -998,14 +1009,25 @@ complete(const Arg *arg) {
/* completion on tags */
spacepos = strcspn(str, " ");
searchfor = (str + spacepos + 1);
- elementlist = complete_list(searchfor, 1, elementlist);
+ elementlist = complete_list(searchfor, CompleteModeTags, elementlist);
+ } else if ((strlen(command) == 6 && strncmp(command, "buffer", 6) == 0) ||
+ (strlen(command) == 3 && strncmp(command, "buf", 3) == 0)) {
+ /* buffer list completion */
+ spacepos = strcspn(str, " ");
+ searchfor = (str + spacepos + 1);
+ elementlist = complete_list(searchfor, CompleteModeBuffers, elementlist);
+ } else if (strlen(command) == 7 && strncmp(command, "bdelete", 7) == 0) {
+ /* buffer list completion */
+ spacepos = strcspn(str, " ");
+ searchfor = (str + spacepos + 1);
+ elementlist = complete_list(searchfor, CompleteModeBuffers, elementlist);
} else {
/* URL completion: bookmarks */
- elementlist = complete_list(searchfor, 0, elementlist);
+ elementlist = complete_list(searchfor, CompleteModeBookmarks, elementlist);
m = count_list(elementlist);
if (m < MAX_LIST_SIZE) {
/* URL completion: history */
- elementlist = complete_list(searchfor, 2, elementlist);
+ elementlist = complete_list(searchfor, CompleteModeUrlHistory, elementlist);
}
}
elementpointer = elementlist;
@@ -2335,6 +2357,97 @@ search_word(int whichword) {
return c;
}
+gboolean
+bufadd(const Arg *arg) {
+ Gui *gui = &client.gui;
+ Buffer *newbuf = setup_new_webview_buffer();
+ if (newbuf) {
+ show_webview_buffer(newbuf);
+ open_arg(arg);
+ } else {
+ echo_message(Error, "Max number of buffers reached!");
+ }
+ return TRUE;
+}
+
+gboolean
+bufdelete(const Arg *arg) {
+ GSList *elem, *delelem = NULL;
+ Buffer *currbuf = client.buffer;
+ int targetid = 0;
+
+ if (arg->s) {
+ targetid = atoi(arg->s);
+ }
+ for (elem = bufferlist.head; elem; elem = elem->next) {
+ Buffer *buf = (Buffer *)elem->data;
+ if (buf->bufferid == targetid || (arg->s == NULL && buf == currbuf)) {
+ delelem = elem;
+ break;
+ } else if (arg->s) {
+ const char *uri = webkit_web_view_get_uri(buf->webview);
+ if (uri && strstr(uri, arg->s)) {
+ if (delelem) {
+ echo_message(Error, "More than one match for %s", arg->s);
+ delelem = NULL;
+ break;
+ }
+ delelem = elem;
+ }
+ }
+ }
+
+ if (delelem) {
+ Buffer *delbuf = (Buffer *)delelem->data;
+ bufferlist.head = g_slist_delete_link(bufferlist.head, delelem);
+ bufferlist.len--;
+ if (bufferlist.head) {
+ /* If this was the current buffer, we need to show a new one */
+ if (delbuf == currbuf) {
+ show_webview_buffer((Buffer *)bufferlist.head->data);
+ }
+ destroy_webview_buffer(delbuf);
+ } else {
+ /* This is the last buffer, quit */
+ quit(NULL);
+ }
+ }
+ return TRUE;
+}
+
+gboolean
+bufshow(const Arg *arg) {
+ Buffer *newbuf = NULL;
+ int targetid = 0;
+
+ if (arg->s) {
+ targetid = atoi(arg->s);
+ GSList *elem;
+ for (elem = bufferlist.head; elem; elem = elem->next) {
+ Buffer *buf = (Buffer *)elem->data;
+ if (targetid && buf->bufferid == targetid) {
+ newbuf = buf;
+ break;
+ } else {
+ const char *uri = webkit_web_view_get_uri(buf->webview);
+ if (uri && strstr(uri, arg->s)) {
+ if (newbuf) {
+ echo_message(Error, "More than one match for %s", arg->s);
+ newbuf = NULL;
+ break;
+ }
+ newbuf = buf;
+ }
+ }
+ }
+ }
+ if (newbuf) {
+ show_webview_buffer(newbuf);
+ gtk_window_set_title(client.gui.window, webkit_web_view_get_title(newbuf->webview));
+ }
+ return TRUE;
+}
+
static gboolean
process_set_line(char *line) {
char *c;
@@ -2682,8 +2795,10 @@ out:
}
void
-update_url(const char *uri) {
+update_url(const char *uriarg) {
+
Gui *gui = &client.gui;
+ const char *uri = uriarg ? uriarg : NO_URI;
gboolean ssl = g_str_has_prefix(uri, "https://");
GdkColor color;
WebKitWebFrame *frame;
@@ -2831,6 +2946,49 @@ setup_modkeys() {
client.config.modkeys = realloc(client.config.modkeys, &ptr[0] - &client.config.modkeys[0] + 1);
}
+Buffer *
+setup_new_webview_buffer() {
+ Buffer *buf = NULL;
+ if (bufferlist.nextid < UINT_MAX) {
+ buf = malloc(sizeof(*buf));
+ buf->bufferid = bufferlist.nextid++;
+ buf->webview = (WebKitWebView*)webkit_web_view_new();
+ g_object_ref(buf->webview);
+ buf->inspector = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(buf->webview));
+ setup_settings(buf->webview);
+ setup_webview_signals(buf->webview);
+
+ bufferlist.head = g_slist_append(bufferlist.head, buf);
+ bufferlist.len++;
+ }
+
+ return buf;
+}
+
+void
+destroy_webview_buffer(Buffer *buf) {
+ g_object_unref(buf->webview);
+ free(buf);
+}
+
+void
+show_webview_buffer(Buffer *buf) {
+ const char *uri = NULL;
+ Gui *gui = &client.gui;
+ gtk_container_remove(GTK_CONTAINER(gui->viewport), GTK_WIDGET(gui->webview));
+
+ gui->webview = buf->webview;
+ gui->inspector = buf->inspector;
+ client.buffer = buf;
+
+ gtk_container_add(GTK_CONTAINER(gui->viewport), GTK_WIDGET(gui->webview));
+ gtk_widget_set_scroll_adjustments(GTK_WIDGET(gui->webview), gui->adjust_h, gui->adjust_v);
+ gtk_widget_grab_focus(GTK_WIDGET(gui->webview));
+ gtk_widget_show_all(GTK_WIDGET(gui->window));
+
+ update_url(webkit_web_view_get_uri(gui->webview));
+}
+
void
setup_gui() {
Gui *gui = &client.gui;
@@ -2849,7 +3007,6 @@ setup_gui() {
gtk_window_set_default_size(GTK_WINDOW(gui->window), 640, 480);
gui->box = GTK_BOX(gtk_vbox_new(FALSE, 0));
gui->inputbox = gtk_entry_new();
- gui->webview = (WebKitWebView*)webkit_web_view_new();
gui->statusbar = GTK_BOX(gtk_hbox_new(FALSE, 0));
gui->eventbox = gtk_event_box_new();
gui->status_url = gtk_label_new(NULL);
@@ -2857,11 +3014,18 @@ setup_gui() {
GdkColor bg;
PangoFontDescription *font;
GdkGeometry hints = { 1, 1 };
- gui->inspector = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(gui->webview));
+
+ Buffer *buf = setup_new_webview_buffer();
+ gui->webview = buf->webview;
+ gui->inspector = buf->inspector;
+ client.buffer = buf;
+ setup_signals();
+ update_url(NO_URI);
+ update_state();
state->clipboards[0] = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
state->clipboards[1] = gtk_clipboard_get(GDK_NONE);
- setup_settings();
+
gdk_color_parse(statusbgcolor, &bg);
gtk_widget_modify_bg(gui->eventbox, GTK_STATE_NORMAL, &bg);
gtk_widget_set_name(GTK_WIDGET(gui->window), "Vimprobable2");
@@ -2880,7 +3044,6 @@ setup_gui() {
gui->pane = gtk_vpaned_new();
gtk_paned_pack1(GTK_PANED(gui->pane), GTK_WIDGET(gui->box), TRUE, TRUE);
- setup_signals();
gtk_container_add(GTK_CONTAINER(gui->viewport), GTK_WIDGET(gui->webview));
/* Ensure we set the scroll adjustments now, so that if we're not drawing
@@ -2909,7 +3072,7 @@ setup_gui() {
}
void
-setup_settings() {
+setup_settings(WebKitWebView *view) {
WebKitWebSettings *settings = (WebKitWebSettings*)webkit_web_settings_new();
char *filename, *file_url;
@@ -2931,30 +3094,19 @@ setup_settings() {
g_free(filename);
g_object_set(G_OBJECT(settings), "user-agent", useragent, NULL);
g_object_get(G_OBJECT(settings), "zoom-step", &client.config.zoomstep, NULL);
- webkit_web_view_set_settings(client.gui.webview, settings);
+ webkit_web_view_set_settings(view, settings);
/* proxy */
toggle_proxy(use_proxy);
}
void
-setup_signals() {
- WebKitWebFrame *frame = webkit_web_view_get_main_frame(client.gui.webview);
-#ifdef ENABLE_COOKIE_SUPPORT
- /* Headers. */
- g_signal_connect_after(G_OBJECT(client.net.session), "request-started", G_CALLBACK(new_generic_request), NULL);
-#endif
- /* Accept-language header */
- g_object_set(G_OBJECT(client.net.session), "accept-language", acceptlanguage, NULL);
- /* window */
- g_object_connect(G_OBJECT(client.gui.window),
- "signal::destroy", G_CALLBACK(window_destroyed_cb), NULL,
- NULL);
- /* frame */
- g_signal_connect(G_OBJECT(frame),
- "scrollbars-policy-changed", G_CALLBACK(blank_cb), NULL);
+setup_webview_signals(WebKitWebView *view)
+{
+ WebKitWebFrame *frame = webkit_web_view_get_main_frame(view);
+ WebKitWebInspector *inspector = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(view));
/* webview */
- g_object_connect(G_OBJECT(client.gui.webview),
+ g_object_connect(G_OBJECT(view),
"signal::title-changed", G_CALLBACK(webview_title_changed_cb), NULL,
"signal::load-progress-changed", G_CALLBACK(webview_progress_changed_cb), NULL,
"signal::load-committed", G_CALLBACK(webview_load_committed_cb), NULL,
@@ -2969,6 +3121,32 @@ setup_signals() {
"signal::create-web-view", G_CALLBACK(webview_open_in_new_window_cb), NULL,
"signal::event", G_CALLBACK(notify_event_cb), NULL,
NULL);
+ /* inspector */
+ g_signal_connect(G_OBJECT(inspector),
+ "inspect-web-view", G_CALLBACK(inspector_new_cb), NULL);
+ g_signal_connect(G_OBJECT(inspector),
+ "show-window", G_CALLBACK(inspector_show_cb), NULL);
+ g_signal_connect(G_OBJECT(inspector),
+ "close-window", G_CALLBACK(inspector_close_cb), NULL);
+ g_signal_connect(G_OBJECT(inspector),
+ "finished", G_CALLBACK(inspector_finished_cb), NULL);
+ /* frame */
+ g_signal_connect(G_OBJECT(frame),
+ "scrollbars-policy-changed", G_CALLBACK(blank_cb), NULL);
+}
+
+void
+setup_signals() {
+#ifdef ENABLE_COOKIE_SUPPORT
+ /* Headers. */
+ g_signal_connect_after(G_OBJECT(client.net.session), "request-started", G_CALLBACK(new_generic_request), NULL);
+#endif
+ /* Accept-language header */
+ g_object_set(G_OBJECT(client.net.session), "accept-language", acceptlanguage, NULL);
+ /* window */
+ g_object_connect(G_OBJECT(client.gui.window),
+ "signal::destroy", G_CALLBACK(window_destroyed_cb), NULL,
+ NULL);
/* webview adjustment */
g_object_connect(G_OBJECT(client.gui.adjust_v),
"signal::value-changed", G_CALLBACK(webview_scroll_cb), NULL,
@@ -2980,15 +3158,6 @@ setup_signals() {
"signal::key-release-event", G_CALLBACK(inputbox_keyrelease_cb), NULL,
"signal::changed", G_CALLBACK(inputbox_changed_cb), NULL,
NULL);
- /* inspector */
- g_signal_connect(G_OBJECT(client.gui.inspector),
- "inspect-web-view", G_CALLBACK(inspector_new_cb), NULL);
- g_signal_connect(G_OBJECT(client.gui.inspector),
- "show-window", G_CALLBACK(inspector_show_cb), NULL);
- g_signal_connect(G_OBJECT(client.gui.inspector),
- "close-window", G_CALLBACK(inspector_close_cb), NULL);
- g_signal_connect(G_OBJECT(client.gui.inspector),
- "finished", G_CALLBACK(inspector_finished_cb), NULL);
}
#ifdef ENABLE_USER_SCRIPTFILE
diff --git a/main.h b/main.h
index 4636257..d223c9f 100644
--- a/main.h
+++ b/main.h
@@ -63,10 +63,23 @@ typedef struct {
} Network;
typedef struct {
+ unsigned int bufferid;
+ WebKitWebView *webview;
+ WebKitWebInspector *inspector;
+} Buffer;
+
+typedef struct {
+ int len;
+ int nextid;
+ GSList *head;
+} BufferList;
+
+typedef struct {
Gui gui;
State state;
Config config;
Network net;
+ Buffer *buffer;
} Client;
diff --git a/utilities.c b/utilities.c
index 72e2322..11661d7 100644
--- a/utilities.c
+++ b/utilities.c
@@ -14,6 +14,7 @@
#include "utilities.h"
extern Client client;
+extern BufferList bufferlist;
extern Command commands[];
extern const size_t COMMANDSIZE;
extern Key keys[];
@@ -549,86 +550,127 @@ echo_message(const MessageType type, const char *format, ...)
va_end(ap);
}
-Listelement *
-complete_list(const char *searchfor, const int mode, Listelement *elementlist)
+static Listelement *
+complete_list_add_candidate(const char *s, 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;
+ Listelement *candidatelist = NULL, *candidatepointer = NULL;
+ char readelement[MAXTAGSIZE + 1] = "";
- if (mode == 2) {
- /* open in history file */
- filename = g_strdup_printf(HISTORY_STORAGE_FILENAME);
+ if (mode == CompleteModeTags) {
+ /* 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 {
- /* open in bookmark file (for tags and bookmarks) */
- filename = g_strdup_printf(BOOKMARKS_STORAGE_FILENAME);
+ /* complete string (bookmarks & history) */
+ candidatelist = add_list(s, candidatelist);
+ }
+ candidatepointer = candidatelist;
+ while (candidatepointer != NULL) {
+ char str[255];
+ strncpy(str, candidatepointer->element, sizeof(str));
+ if (!complete_case_sensitive) {
+ g_utf8_strdown(str, 255);
+ }
+ if (!strlen(searchfor) || strstr(str, searchfor) != NULL) {
+ memset(readelement, 0, MAXTAGSIZE + 1);
+ if (strchr(candidatepointer->element, ' ') != NULL && mode != CompleteModeBuffers) {
+ /* only use string up to the first space */
+ i = strcspn(candidatepointer->element, " ");
+ if (i > MAXTAGSIZE)
+ i = MAXTAGSIZE;
+ strncpy(readelement, candidatepointer->element, i);
+ } else {
+ strncpy(readelement, candidatepointer->element, MAXTAGSIZE);
+ }
+ /* in the case of URLs without title, remove the line break */
+ if (readelement[strlen(readelement) - 1] == '\n') {
+ readelement[strlen(readelement) - 1] = '\0';
+ }
+ elementlist = add_list(readelement, elementlist);
+ n = count_list(elementlist);
+ }
+ if (n >= MAX_LIST_SIZE)
+ break;
+ candidatepointer = candidatepointer->next;
}
+ free_list(candidatelist);
+ candidatelist = NULL;
+
+ return elementlist;
+}
+
+static Listelement *
+complete_list_from_file(const char *filename, const char *searchfor, const int mode, Listelement *elementlist)
+{
+ char s[255] = "";
+ FILE *f;
+
f = fopen(filename, "r");
if (f == NULL) {
- g_free((gpointer *)filename);
return (elementlist);
}
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) {
- strncpy(s, candidatepointer->element, sizeof(s));
- if (!complete_case_sensitive) {
- g_utf8_strdown(s, 255);
- }
- if (!strlen(searchfor) || strstr(s, searchfor) != NULL) {
- /* only use string up to the first space */
- memset(readelement, 0, MAXTAGSIZE + 1);
- if (strchr(candidatepointer->element, ' ') != NULL) {
- i = strcspn(candidatepointer->element, " ");
- if (i > MAXTAGSIZE)
- i = MAXTAGSIZE;
- strncpy(readelement, candidatepointer->element, i);
- } else {
- strncpy(readelement, candidatepointer->element, MAXTAGSIZE);
- }
- /* in the case of URLs without title, remove the line break */
- if (readelement[strlen(readelement) - 1] == '\n') {
- readelement[strlen(readelement) - 1] = '\0';
- }
- 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)
+ elementlist = complete_list_add_candidate(s, searchfor, mode, elementlist);
+ if (count_list(elementlist) > MAX_LIST_SIZE)
break;
}
- g_free((gpointer)filename);
return (elementlist);
}
+static Listelement *
+complete_list_from_buffers(const char *searchfor, const int mode, Listelement *elementlist)
+{
+ char s[255] = "";
+ GSList *elem;
+ for (elem = bufferlist.head; elem; elem = elem->next) {
+ Buffer *buf = (Buffer *)elem->data;
+ const char *uri = webkit_web_view_get_uri(buf->webview);
+
+ snprintf(s, 254, "%d %c %s\n", buf->bufferid,
+ buf == client.buffer ? '%' : ' ', uri ? uri : "[None]");
+ elementlist = complete_list_add_candidate(s, searchfor, mode, elementlist);
+
+ if (count_list(elementlist) > MAX_LIST_SIZE)
+ break;
+ }
+ return elementlist;
+}
+
+Listelement *
+complete_list(const char *searchfor, const int mode, Listelement *elementlist)
+{
+ const char *filename = NULL;
+
+ if (mode == CompleteModeUrlHistory) {
+ /* open in history file */
+ filename = g_strdup_printf(HISTORY_STORAGE_FILENAME);
+ } else if (mode == CompleteModeBuffers) {
+ return complete_list_from_buffers(searchfor, mode, elementlist);
+ } else {
+ /* open in bookmark file (for tags and bookmarks) */
+ filename = g_strdup_printf(BOOKMARKS_STORAGE_FILENAME);
+ }
+ if (filename) {
+ elementlist = complete_list_from_file(filename, searchfor, mode, elementlist);
+ g_free((gpointer)filename);
+ }
+ return elementlist;
+}
+
Listelement *
add_list(const char *element, Listelement *elementlist)
{
diff --git a/utilities.h b/utilities.h
index a2ee5f6..58d0425 100644
--- a/utilities.h
+++ b/utilities.h
@@ -10,6 +10,13 @@
/* config file */
#define RCFILE "%s/vimprobable/vimprobablerc", client.config.config_base
+enum {
+ CompleteModeBookmarks = 0,
+ CompleteModeTags,
+ CompleteModeUrlHistory,
+ CompleteModeBuffers,
+};
+
enum ConfigFileError read_rcfile(const char *config);
void save_command_history(char *line);
gboolean clear(const Arg *arg);
--
2.2.2
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
Vimprobable-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vimprobable-users