Added search-engine support (#11).
authorDaniel Carl <danielcarl@gmx.de>
Fri, 15 Feb 2013 23:44:26 +0000 (00:44 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Sat, 16 Feb 2013 10:51:36 +0000 (11:51 +0100)
Added a command to add and remove search-engines and extended the open command
to query the search-engine if the shortcut was found as first part of the open
or tabopen command.

doc/vimp.1.txt
src/command.c
src/command.h
src/config.h
src/main.c
src/main.h
src/searchengine.c [new file with mode: 0644]
src/searchengine.h [new file with mode: 0644]

index f3a07ce..4063c0e 100644 (file)
@@ -236,12 +236,22 @@ Yank the current url to the primary and secondary clipboard.
 .TP
 .B yank-selection
 Yank the selected text into the primary and secondary clipboard.
+.SS Searchengines
+Searchengines allows to query a searchengine instead of typing a full url. If
+a searchengine with shortcut 'dd' is defined you can use 'dd search terms' to
+perform a search query.
+.TP
+.B searchengine-add shortcut=uri
+Adds a searchengine with the shortcut and search uri. The uri must not contain
+more than one '%s' placeholder.
+
+Example: searchengine-add dl=https://duckduckgo.com/lite/?q=%s
 .SS Misc
 .TP
 .B set
 Set configuration values.
 .TP
-.IB [N] search-{forward, backward}
+.IB [N] "search-{forward, backward}"
 Search in current page forward or backward.
 .TP
 .B inspect
index 98d9731..64df99d 100644 (file)
@@ -24,6 +24,7 @@
 #include "completion.h"
 #include "hints.h"
 #include "util.h"
+#include "searchengine.h"
 
 static CommandInfo cmd_list[] = {
     /* command              function             arg                                                                                 mode */
@@ -84,6 +85,8 @@ static CommandInfo cmd_list[] = {
     {"tabopen-clipboard",   command_paste,       {VP_CLIPBOARD_PRIMARY | VP_CLIPBOARD_SECONDARY | VP_TARGET_NEW}},
     {"search-forward",      command_search,      {VP_SEARCH_FORWARD}},
     {"search-backward",     command_search,      {VP_SEARCH_BACKWARD}},
+    {"searchengine-add",    command_searchengine,{1}},
+    {"searchengine-remove", command_searchengine,{0}},
 };
 
 static void command_write_input(const gchar* str);
@@ -131,7 +134,25 @@ gboolean command_run(const gchar* name, const gchar* param)
 
 gboolean command_open(const Arg* arg)
 {
-    return vp_load_uri(arg);
+    gchar* uri = NULL;
+    gboolean result;
+    /* check for searchengine handles */
+    /* split into handle and searchterms */
+    char **string = g_strsplit(arg->s, " ", 2);
+    if (g_strv_length(string) == 2
+        && (uri = searchengine_get_uri(string[0]))
+    ) {
+        gchar* term = soup_uri_encode(string[1], "&");
+        Arg a  = {arg->i, g_strdup_printf(uri, term)};
+        result = vp_load_uri(&a);
+        g_free(term);
+        g_free(a.s);
+    } else {
+        result = vp_load_uri(arg);
+    }
+    g_strfreev(string);
+
+    return result;
 }
 
 gboolean command_open_home(const Arg* arg)
@@ -441,6 +462,27 @@ gboolean command_search(const Arg* arg)
     return TRUE;
 }
 
+gboolean command_searchengine(const Arg* arg)
+{
+    gboolean result;
+    if (arg->i) {
+        /* add the searchengine */
+        gchar **string = g_strsplit(arg->s, "=", 2);
+        if (g_strv_length(string) != 2) {
+            return FALSE;
+        }
+        result = searchengine_add(string[0], string[1]);
+        g_strfreev(string);
+    } else {
+        /* remove the search engine */
+        result = searchengine_remove(arg->s);
+    }
+
+    vp_set_mode(VP_MODE_NORMAL, FALSE);
+
+    return result;
+}
+
 static void command_write_input(const gchar* str)
 {
     gint pos = 0;
index cd9a15a..4b4e1c0 100644 (file)
@@ -59,5 +59,6 @@ gboolean command_hints_focus(const Arg* arg);
 gboolean command_yank(const Arg* arg);
 gboolean command_paste(const Arg* arg);
 gboolean command_search(const Arg* arg);
+gboolean command_searchengine(const Arg* arg);
 
 #endif /* end of include guard: COMMAND_H */
index 853cdda..8b359e5 100644 (file)
@@ -22,6 +22,9 @@
 
 #include "stdlib.h"
 
+/* time in seconds after that message will be removed from inputbox if the
+ * message where only temporary */
+#define MESSAGE_TIMEOUT             5
 #define SETTING_MAX_CONNS           25
 #define SETTING_MAX_CONNS_PER_HOST  5
 
@@ -74,6 +77,8 @@ const struct {
     {"cmap <shift-tab>=complete-back"},
     {"hmap <tab>=hint-focus-next"},
     {"hmap <shift-tab>=hint-focus-prev"},
+    {"searchengine-add dl=https://duckduckgo.com/lite/?q=%s"},
+    {"searchengine-add dd=https://duckduckgo.com/?q=%s"},
     {NULL}
 };
 
index f2f7fea..69fc76c 100644 (file)
@@ -26,6 +26,7 @@
 #include "completion.h"
 #include "dom.h"
 #include "hints.h"
+#include "searchengine.h"
 
 /* variables */
 static gchar **args;
@@ -401,6 +402,7 @@ void vp_clean_up(void)
     setting_cleanup();
     keybind_cleanup();
     completion_clean();
+    searchengine_cleanup();
 }
 
 void vp_clean_input(void)
@@ -575,7 +577,7 @@ void vp_echo(const MessageType type, gboolean hide, const char *error, ...)
     );
     gtk_entry_set_text(GTK_ENTRY(vp.gui.inputbox), message);
     if (hide) {
-        g_timeout_add_seconds(2, (GSourceFunc)vp_hide_message, NULL);
+        g_timeout_add_seconds(MESSAGE_TIMEOUT, (GSourceFunc)vp_hide_message, NULL);
     }
 }
 
index ee82bdb..bfe4fb2 100644 (file)
@@ -233,6 +233,7 @@ typedef struct {
     GHashTable* commands;
     GSList*     keys;
     GString*    modkeys;
+    GSList*     searchengines;
 } Behaviour;
 
 typedef struct {
diff --git a/src/searchengine.c b/src/searchengine.c
new file mode 100644 (file)
index 0000000..e24bb5a
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * vimp - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "main.h"
+#include "searchengine.h"
+
+static GSList* searchengine_find(const gchar* handle);
+static gboolean searchengine_is_valid_uri(const gchar* uri);
+
+
+void searchengine_cleanup(void)
+{
+    if (vp.behave.searchengines) {
+        g_slist_free(vp.behave.searchengines);
+    }
+}
+
+gboolean searchengine_add(const gchar* handle, const gchar* uri)
+{
+    /* validate if the uri contains only one %s sequence */
+    if (!searchengine_is_valid_uri(uri)) {
+        return FALSE;
+    }
+    Searchengine* s = g_new0(Searchengine, 1);
+
+    s->handle = g_strdup(handle);
+    s->uri    = g_strdup(uri);
+
+    vp.behave.searchengines = g_slist_prepend(vp.behave.searchengines, s);
+
+    return TRUE;
+}
+
+gboolean searchengine_remove(const gchar* handle)
+{
+    GSList* list = searchengine_find(handle);
+
+    if (list) {
+        Searchengine* s = (Searchengine*)list->data;
+        g_free(s->handle);
+        g_free(s->uri);
+
+        vp.behave.searchengines = g_slist_delete_link(vp.behave.searchengines, list);
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gchar* searchengine_get_uri(const gchar* handle)
+{
+    GSList* list = searchengine_find(handle);
+
+    if (list) {
+        return ((Searchengine*)list->data)->uri;
+    }
+
+    return NULL;
+}
+
+static GSList* searchengine_find(const gchar* handle)
+{
+    GSList* s;
+    for (s = vp.behave.searchengines; s != NULL; s = s->next) {
+        if (!strcmp(((Searchengine*)s->data)->handle, handle)) {
+            return s;
+        }
+    }
+
+    return NULL;
+}
+
+static gboolean searchengine_is_valid_uri(const gchar* uri)
+{
+    gint count = 0;
+
+    for (; *uri; uri++) {
+        if (*uri == '%') {
+            uri++;
+            if (*uri == 's') {
+                count++;
+            }
+        }
+    }
+
+    return count == 1;
+}
diff --git a/src/searchengine.h b/src/searchengine.h
new file mode 100644 (file)
index 0000000..01e905f
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * vimp - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef SEARCHENGINE_H
+#define SEARCHENGINE_H
+
+typedef struct {
+    gchar* handle;
+    gchar* uri;
+} Searchengine;
+
+void searchengine_cleanup(void);
+gboolean searchengine_add(const gchar* handle, const gchar* uri);
+gboolean searchengine_remove(const gchar* handle);
+gchar* searchengine_get_uri(const gchar* handle);
+
+#endif /* end of include guard: SEARCHENGINE_H */