Allow searching in the page (#6).
authorDaniel Carl <danielcarl@gmx.de>
Wed, 6 Feb 2013 23:25:25 +0000 (00:25 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Wed, 6 Feb 2013 23:25:25 +0000 (00:25 +0100)
Extended the keybindings to also save parameters to the commands. This allows
to map commands like 'input :foo' to a keybinding, which make the use more
flexible.

doc/vimp.1.txt
src/command.c
src/command.h
src/config.h
src/keybind.c
src/keybind.h
src/main.c
src/main.h

index ba2b2fd..a6de7b4 100644 (file)
@@ -37,6 +37,9 @@ Follow links, form fields and frames via hints.
 .B Command Mode
 Execute vimp commands from the builtin inputbox (commandline).
 .TP
+.B Search Mode
+Search for strings within the current displayed page.
+.TP
 .B Insert Mode
 Used for editing text elements in a webpage.
 .SH COMMANDS
@@ -155,7 +158,7 @@ Scroll the page N times the "scrollstep" to the top.
 Scroll the page N times the "scrollstep" to the end.
 .SS Keybinding
 To bind a command to a key sequence use the {n,i,c,h}map command. To map a
-keysequence to a command, use this format "nmap {[modkey]key}={command}".
+keysequence to a command, use this format "nmap {[modkey]key}={command}[ params]".
 
 The modkey is a single simple char like "g". The key can also contain
 special keys and modifiers and is given in format like "<ctrl-o>", "<tab>",
@@ -163,10 +166,11 @@ special keys and modifiers and is given in format like "<ctrl-o>", "<tab>",
 
 Example:
 .br
-To add a keybinding to focus the next hint in hinting mode use
-"hmap <shift-tab>=hint-focus-prev"
+"hmap <shift-tab>=hint-focus-prev" to add focus next in in Hinting Mode.
+.br
+"nmap <shift-?>=input :foo" to write :foo into input box and switch to Command Mode.
 .br
-To remove this keybinding use "hunmap <shift-tab>".
+"hunmap <shift-tab>" To remove this keybinding use.
 .TP
 .B nmap
 Add a keybinding used in Normal Mode.
@@ -180,6 +184,9 @@ Add a keybinding used in Command Mode.
 .B hmap
 Add a keybinding used in Hint Mode.
 .TP
+.B smap
+Add keybinding used in Search Mode.
+.TP
 .B nunmap
 Remove a Normal Mode keybinding.
 .TP
@@ -191,6 +198,9 @@ Remove a Command Mode keybinding.
 .TP
 .B hunmap
 Remove a Hint Mode keybinding.
+.TP
+.B sunmap
+Remove a Search Mode keybinding.
 .SS Complete
 .TP
 .B complete
@@ -234,6 +244,9 @@ Yank the selected text into the primary and secondary clipboard.
 .B set
 Set configuration values.
 .TP
+.B search-{forward, backward}
+Search in current page forward or backward.
+.TP
 .B inspect
 Toggles the webinspector for current page. This is only available if the config
 "webinspector" is enabled.
index 8593052..a44458d 100644 (file)
@@ -61,10 +61,12 @@ static CommandInfo cmd_list[] = {
     {"imap",                command_map,         {VP_MODE_INSERT},                                                                   VP_MODE_NORMAL},
     {"cmap",                command_map,         {VP_MODE_COMMAND},                                                                  VP_MODE_NORMAL},
     {"hmap",                command_map,         {VP_MODE_HINTING},                                                                  VP_MODE_NORMAL},
+    {"smap",                command_map,         {VP_MODE_SEARCH},                                                                   VP_MODE_NORMAL},
     {"nunmap",              command_unmap,       {VP_MODE_NORMAL},                                                                   VP_MODE_NORMAL},
     {"iunmap",              command_unmap,       {VP_MODE_INSERT},                                                                   VP_MODE_NORMAL},
     {"cunmap",              command_unmap,       {VP_MODE_COMMAND},                                                                  VP_MODE_NORMAL},
     {"hunmap",              command_unmap,       {VP_MODE_HINTING},                                                                  VP_MODE_NORMAL},
+    {"sunmap",              command_map,         {VP_MODE_SEARCH},                                                                   VP_MODE_NORMAL},
     {"set",                 command_set,         {0},                                                                                VP_MODE_NORMAL},
     {"complete",            command_complete,    {0},                                                                                VP_MODE_COMMAND | VP_MODE_COMPLETE},
     {"complete-back",       command_complete,    {1},                                                                                VP_MODE_COMMAND | VP_MODE_COMPLETE},
@@ -78,6 +80,8 @@ static CommandInfo cmd_list[] = {
     {"hint-focus-prev",     command_hints_focus, {1},                                                                                VP_MODE_HINTING},
     {"yank-uri",            command_yank,        {COMMAND_YANK_PRIMARY | COMMAND_YANK_SECONDARY | COMMAND_YANK_URI},                 VP_MODE_NORMAL},
     {"yank-selection",      command_yank,        {COMMAND_YANK_PRIMARY | COMMAND_YANK_SECONDARY | COMMAND_YANK_SELECTION},           VP_MODE_NORMAL},
+    {"search-forward",      command_search,      {VP_SEARCH_FORWARD},                                                                VP_MODE_SEARCH},
+    {"search-backward",     command_search,      {VP_SEARCH_BACKWARD},                                                               VP_MODE_SEARCH},
 };
 
 static void command_write_input(const gchar* str);
@@ -356,6 +360,37 @@ gboolean command_yank(const Arg* arg)
     return FALSE;
 }
 
+gboolean command_search(const Arg* arg)
+{
+    State* state     = &vp.state;
+    gboolean forward = !(arg->i ^ state->search_dir);
+
+    if (arg->i == VP_SEARCH_OFF && state->search_query) {
+        OVERWRITE_STRING(state->search_query, NULL);
+        webkit_web_view_unmark_text_matches(vp.gui.webview);
+
+        return TRUE;
+    }
+
+    /* copy search query for later use */
+    if (arg->s) {
+        OVERWRITE_STRING(state->search_query, arg->s);
+        /* set dearch dir only when the searching is started */
+        vp.state.search_dir = arg->i;
+
+        vp_set_mode(VP_MODE_SEARCH, FALSE);
+    }
+
+    if (state->search_query) {
+        webkit_web_view_mark_text_matches(vp.gui.webview, state->search_query, FALSE, 0);
+        webkit_web_view_set_highlight_text_matches(vp.gui.webview, TRUE);
+
+        webkit_web_view_search_text(vp.gui.webview, state->search_query, FALSE, forward, TRUE);
+    }
+
+    return TRUE;
+}
+
 static void command_write_input(const gchar* str)
 {
     gint pos = 0;
index 8c5a235..ee198e7 100644 (file)
@@ -58,5 +58,6 @@ gboolean command_inspect(const Arg* arg);
 gboolean command_hints(const Arg* arg);
 gboolean command_hints_focus(const Arg* arg);
 gboolean command_yank(const Arg* arg);
+gboolean command_search(const Arg* arg);
 
 #endif /* end of include guard: COMMAND_H */
index 6e7f077..cd31bac 100644 (file)
@@ -31,6 +31,10 @@ const struct {
     {"nmap gf=source"},
     {"nmap gF=inspect"},
     {"nmap <shift-:>=input"},
+    {"nmap <shift-/>=input /"},
+    {"nmap <shift-?>=input ?"},
+    {"smap n=search-forward"},
+    {"smap N=search-backward"},
     {"nmap o=inputopen"},
     {"nmap t=inputtabopen"},
     {"nmap O=inputopencurrent"},
index ed86337..3806c8a 100644 (file)
@@ -59,10 +59,19 @@ gboolean keybind_add_from_string(const gchar* str, const Mode mode)
     char **string = g_strsplit(line, "=", 2);
 
     guint len = g_strv_length(string);
-    if (len == 2 && command_exists(string[1])) {
+    if (len == 2) {
+        /* split the input string into command and parameter part */
+        gchar** token = g_strsplit(string[1], " ", 2);
+        if (!token[0] || !command_exists(token[0])) {
+            g_strfreev(token);
+            return FALSE;
+        }
+
         Keybind* keybind = g_new0(Keybind, 1);
         keybind->mode    = mode;
-        keybind->command = g_strdup(string[1]);
+        keybind->command = g_strdup(token[0]);
+        keybind->param   = g_strdup(token[1]);
+        g_strfreev(token);
 
         keybind_str_to_keybind(string[0], keybind);
 
@@ -264,7 +273,7 @@ static gboolean keybind_keypress_callback(WebKitWebView* webview, GdkEventKey* e
 
     if (link) {
         Keybind* keybind = (Keybind*)link->data;
-        command_run(keybind->command, NULL);
+        command_run(keybind->command, keybind->param);
 
         return TRUE;
     }
index ef9db09..8b0ff32 100644 (file)
@@ -29,6 +29,7 @@ typedef struct {
     guint  modmask;     /* modemask for the kayval */
     guint  keyval;
     gchar* command;     /* command to run */
+    gchar* param;
 } Keybind;
 
 void keybind_init(void);
index 7f32475..4eb89be 100644 (file)
@@ -161,18 +161,33 @@ static void vp_inputbox_activate_cb(GtkEntry *entry, gpointer user_data)
 
     gtk_widget_grab_focus(GTK_WIDGET(gui->webview));
 
+    if (length <= 1) {
+        return;
+    }
+
     /* do not free or modify text */
     text = gtk_entry_get_text(entry);
 
-    if (1 < length && ':' == text[0]) {
-        completion_clean();
-        success = vp_process_input((text + 1));
-        if (!success) {
-            /* switch to normal mode after running command without success the
-             * mode after success is set by command_run to the value defined
-             * for the command */
-            vp_set_mode(VP_MODE_NORMAL , FALSE);
-        }
+    switch (text[0]) {
+        case '/':
+        case '?':
+            {
+                Arg a = {text[0] == '/' ? VP_SEARCH_FORWARD : VP_SEARCH_BACKWARD, g_strdup(text + 1)};
+                command_search(&a);
+                g_free(a.s);
+            }
+            break;
+
+        case ':':
+            completion_clean();
+            success = vp_process_input((text + 1));
+            if (!success) {
+                /* switch to normal mode after running command without success the
+                 * mode after success is set by command_run to the value defined
+                 * for the command */
+                vp_set_mode(VP_MODE_NORMAL, FALSE);
+            }
+            break;
     }
 }
 
@@ -443,17 +458,22 @@ gboolean vp_set_mode(Mode mode, gboolean clean)
     }
     switch (CLEAN_MODE(mode)) {
         case VP_MODE_NORMAL:
-            /* if previous mode was hinting clear the hints */
             if (GET_CLEAN_MODE() == VP_MODE_HINTING) {
+                /* if previous mode was hinting clear the hints */
                 hints_clear();
-            }
-            /* clean the input if current mode is insert to remove -- INPUT -- */
-            if (GET_CLEAN_MODE() == VP_MODE_INSERT) {
+            } else if (GET_CLEAN_MODE() == VP_MODE_INSERT) {
+                /* clean the input if current mode is insert to remove -- INPUT -- */
                 clean = TRUE;
+            } else if (GET_CLEAN_MODE() == VP_MODE_SEARCH) {
+                /* cleaup previous search */
+                command_search(&((Arg){VP_SEARCH_OFF}));
             }
             gtk_widget_grab_focus(GTK_WIDGET(vp.gui.webview));
             break;
 
+        case VP_MODE_SEARCH:
+            break;
+
         case VP_MODE_COMMAND:
         case VP_MODE_HINTING:
             gtk_widget_grab_focus(GTK_WIDGET(vp.gui.inputbox));
index 4123126..552501e 100644 (file)
@@ -133,6 +133,12 @@ enum {
     VP_SCROLL_UNIT_HALFPAGE = (1 << 4)
 };
 
+typedef enum {
+    VP_SEARCH_FORWARD,
+    VP_SEARCH_BACKWARD,
+    VP_SEARCH_OFF,
+} SearchDirection;
+
 typedef enum {
     VP_MSG_NORMAL,
     VP_MSG_ERROR,
@@ -218,6 +224,8 @@ typedef struct {
     guint           progress;
     StatusType      status;
     gboolean        is_inspecting;
+    SearchDirection search_dir;
+    gchar*          search_query;
 } State;
 
 /* behaviour */