Hi all,

Too lazy to split my patches, but the updated
esource-and-quickmark.patch file includes the external source editor
patch as well as a small update I added for my own use, to allow key
binds like:

        Q1

To open quickmark #1 in a new tab/window (I often found myself pressing
gH to get a new tab open, and then q1 immediately after to go to the
quickmark I wanted).

Also, please excuse the patched lines which are just whitespace removal
at the end of said line (new emacs config option I'm using prunes
extraneous white space at the end of lines :) )

Thanks,
-Matt

On Mon, May 12, 2014 at 02:46:32PM +0200, Marcos Cruz wrote:
> En/Je/On 2014-05-12 00:13, Hannes Schüller escribió / skribis / wrote :
> 
> > >   shortcut dd https://duckduckgo.com/html/?q=%s&t=vimprobable
> > >   shortcut ddj https://duckduckgo.com/?q=%s&t=vimprobable
>  
> > Both of these are in the default configuration (as d and dd) as well :)
> 
> Oops :D
> 
> -- 
> Marcos Cruz
> http://programandala.net
> 
> ------------------------------------------------------------------------------
> "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
> Instantly run your Selenium tests across 300+ browser/OS combos.
> Get unparalleled scalability from the best Selenium testing platform available
> Simple to use. Nothing to install. Get started now for free."
> http://p.sf.net/sfu/SauceLabs
> _______________________________________________
> Vimprobable-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/vimprobable-users

-- 
Matthew Carter
[email protected]
diff --git a/config.h b/config.h
index e9d6bba..9b6a7cc 100644
--- a/config.h
+++ b/config.h
@@ -154,6 +154,7 @@ Command commands[COMMANDSIZE] = {
     { "bma",                                           	bookmark,         {0} },
     { "bookmark",                                      	bookmark,         {0} },
     { "source",                                        	view_source,      {0} },
+    { "esource",                                       	edit_source,      {0} },
     { "openeditor",                                   	open_editor,      {0} },
     { "set",                                           	browser_settings, {0} },
     { "map",                                           	mappings,         {0} },
@@ -162,7 +163,7 @@ Command commands[COMMANDSIZE] = {
     { "jumpright",                                      scroll,           {ScrollJumpTo   | DirectionRight} },
     { "jumptop",                                        scroll,           {ScrollJumpTo   | DirectionTop} },
     { "jumpbottom",                                     scroll,           {ScrollJumpTo   | DirectionBottom} },
-    { "pageup",                                         scroll,           {ScrollMove     | DirectionTop      | UnitPage} },	
+    { "pageup",                                         scroll,           {ScrollMove     | DirectionTop      | UnitPage} },
     { "pagedown",                                       scroll,           {ScrollMove     | DirectionBottom   | UnitPage} },
     { "navigationback",   	                            navigate,         {NavigationBack} },
     { "navigationforward",	                            navigate,         {NavigationForward} },
diff --git a/keymap.h b/keymap.h
index 9bbd227..8bedfe2 100644
--- a/keymap.h
+++ b/keymap.h
@@ -25,6 +25,15 @@ Key keys[] = {
     { 0,                    GDK_q,          GDK_7,          quickmark,  { .s = "7" } },
     { 0,                    GDK_q,          GDK_8,          quickmark,  { .s = "8" } },
     { 0,                    GDK_q,          GDK_9,          quickmark,  { .s = "9" } },
+    { 0,                    GDK_Q,          GDK_1,          quickmark,  { .s = "1", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_2,          quickmark,  { .s = "2", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_3,          quickmark,  { .s = "3", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_4,          quickmark,  { .s = "4", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_5,          quickmark,  { .s = "5", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_6,          quickmark,  { .s = "6", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_7,          quickmark,  { .s = "7", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_8,          quickmark,  { .s = "8", .i = 1 } },
+    { 0,                    GDK_Q,          GDK_9,          quickmark,  { .s = "9", .i = 1 } },
     { 0,                    0,              GDK_0,          scroll,     {ScrollJumpTo   | DirectionLeft} },
     { 0,                    0,              GDK_dollar,     scroll,     {ScrollJumpTo   | DirectionRight} },
     { 0,                    GDK_g,          GDK_g,          scroll,     {ScrollJumpTo   | DirectionTop} },
diff --git a/main.c b/main.c
index d70f88a..b1704d7 100644
--- a/main.c
+++ b/main.c
@@ -69,7 +69,9 @@ static gboolean descend(const Arg *arg);
 gboolean echo(const Arg *arg);
 static gboolean focus_input(const Arg *arg);
 static gboolean open_editor(const Arg *arg);
+static gboolean edit_source(const Arg *arg);
 void _resume_from_editor(GPid child_pid, int status, gpointer data);
+void _resume_from_edit_source(GPid child_pid, int status, gpointer data);
 static gboolean input(const Arg *arg);
 static gboolean open_inspector(const Arg * arg);
 static gboolean navigate(const Arg *arg);
@@ -1066,7 +1068,7 @@ static gboolean
 open_inspector(const Arg * arg) {
     gboolean inspect_enabled;
     WebKitWebSettings *settings;
-    State *state = &client.state;    
+    State *state = &client.state;
 
     settings = webkit_web_view_get_settings(client.gui.webview);
     g_object_get(G_OBJECT(settings), "enable-developer-extras", &inspect_enabled, NULL);
@@ -1239,7 +1241,7 @@ open_arg(const Arg *arg) {
         new = NULL;
         /* check for external handlers */
         if (open_handler(s))
-            return TRUE;        
+            return TRUE;
         /* check for search engines */
         p = strchr(s, ' ');
         if (!p) {
@@ -1414,7 +1416,7 @@ revive(const Arg *arg) {
     return FALSE;
 }
 
-static 
+static
 gboolean print_frame(const Arg *arg)
 {
     WebKitWebFrame *frame = webkit_web_view_get_main_frame(client.gui.webview);
@@ -1540,8 +1542,8 @@ quickmark(const Arg *a) {
         char *ptr = strrchr(buf, '\n');
         *ptr = '\0';
         if (strlen(buf)) {
-            Arg x = { .s = buf };
-            return open_arg(&x);
+          Arg x = { .s = buf, .i = a->i ? TargetNew : TargetCurrent };
+          return open_arg(&x);
         } else {
             echo_message(Error, "Quickmark %d not defined", b);
             return false;
@@ -1667,7 +1669,7 @@ zoom(const Arg *arg) {
     return TRUE;
 }
 
-gboolean 
+gboolean
 fake_key_event(const Arg *a) {
     if(!client.state.embed) {
         return FALSE;
@@ -1677,7 +1679,7 @@ fake_key_event(const Arg *a) {
         echo_message(Error, "Couldn't find the XDisplay.");
         return FALSE;
     }
-       
+
     XKeyEvent xk;
     xk.display = xdpy;
     xk.subwindow = None;
@@ -1697,12 +1699,12 @@ fake_key_event(const Arg *a) {
         echo_message(Error, "Couldn't translate %s to keysym", a->s );
         return FALSE;
     }
-    
+
     if( (xk.keycode = XKeysymToKeycode(xdpy, keysym)) == NoSymbol ) {
         echo_message(Error, "Couldn't translate keysym to keycode");
         return FALSE;
     }
-   
+
     xk.type = KeyPress;
     if( !XSendEvent(xdpy, client.state.embed, True, KeyPressMask, (XEvent *)&xk) ) {
         echo_message(Error, "XSendEvent failed");
@@ -1930,7 +1932,7 @@ open_editor(const Arg *arg) {
         g_free(message);
         return FALSE;
     }
-   
+
     /* mark the active text box as "under processing" */
     jsapi_evaluate_script(
         "document.activeElement.disabled = true;"
@@ -1948,14 +1950,79 @@ open_editor(const Arg *arg) {
     return TRUE;
 }
 
+/* open an external editor defined by the protocol handler for
+vimprobableedit on page source */
+static gboolean
+edit_source(const Arg *arg) {
+    char *text = NULL;
+    gboolean success;
+    GPid child_pid;
+    gchar *value = NULL, *message = NULL, *tag = NULL, *edit_url = NULL;
+    gchar *temp_file_name = g_strdup_printf("%s/vimprobableeditXXXXXX",
+      temp_dir);
+    int temp_file_handle = -1;
+
+    jsapi_evaluate_script("document.documentElement.innerHTML", &value, &message);
+    text = g_strdup(value);
+    if (text == NULL) {
+        g_free(value);
+        g_free(message);
+        return FALSE;
+    }
+
+    /* write text into temporary file */
+    temp_file_handle = mkstemp(temp_file_name);
+    if (temp_file_handle == -1) {
+        message = g_strdup_printf("Could not create temporary file: %s",
+            strerror(errno));
+        echo_message(Error, message);
+        g_free(value);
+        g_free(message);
+        g_free(text);
+        return FALSE;
+    }
+    if (write(temp_file_handle, text, strlen(text)) != strlen(text)) {
+        message = g_strdup_printf("Short write to temporary file: %s",
+            strerror(errno));
+        echo_message(Error, message);
+        g_free(value);
+        g_free(message);
+        g_free(text);
+        return FALSE;
+    }
+    close(temp_file_handle);
+    g_free(text);
+
+    /* spawn editor */
+    edit_url = g_strdup_printf("vimprobableedit:%s", temp_file_name);
+    success = open_handler_pid(edit_url, &child_pid);
+    g_free(edit_url);
+    if (!success) {
+        echo_message(Error, "External editor open failed (no handler for"
+            " vimprobableedit protocol?)");
+        unlink(temp_file_name);
+        g_free(value);
+        g_free(message);
+        return FALSE;
+    }
+
+    g_child_watch_add(child_pid, _resume_from_edit_source, temp_file_name);
+
+    /* temp_file_name is freed in _resume_from_editor */
+    g_free(value);
+    g_free(message);
+    g_free(tag);
+    return TRUE;
+}
+
 
 /* pick up from where open_editor left the work to the glib event loop.
 
-This is called when the external editor exits. 
+This is called when the external editor exits.
 
 The data argument points to allocated memory containing the temporary file
 name. */
-void 
+void
 _resume_from_editor(GPid child_pid, int child_status, gpointer data) {
     FILE *fp;
     GString *set_value_js = g_string_new(
@@ -1963,7 +2030,7 @@ _resume_from_editor(GPid child_pid, int child_status, gpointer data) {
     g_spawn_close_pid(child_pid);
     gchar *value = NULL, *message = NULL;
     gchar *temp_file_name = data;
-    gchar buffer[BUF_SIZE] = ""; 
+    gchar buffer[BUF_SIZE] = "";
     gchar *buf_ptr = buffer;
     int char_read;
 
@@ -1991,7 +2058,7 @@ _resume_from_editor(GPid child_pid, int child_status, gpointer data) {
         /* this would be too weird to even emit an error message */
         goto error_exit;
     }
-    jsapi_evaluate_script("document.activeElement.value = '';", 
+    jsapi_evaluate_script("document.activeElement.value = '';",
         &value, &message);
     g_free(value);
     g_free(message);
@@ -2038,6 +2105,82 @@ error_exit:
     g_free(message);
 }
 
+/* pick up from where edit_source left the work to the glib event loop.
+
+This is called when the external editor exits.
+
+The data argument points to allocated memory containing the temporary file
+name. */
+void
+_resume_from_edit_source(GPid child_pid, int child_status, gpointer data) {
+    FILE *fp;
+    GString *set_value_js = g_string_new(
+        "document.documentElement.innerHTML = \"");
+    g_spawn_close_pid(child_pid);
+    gchar *value = NULL, *message = NULL;
+    gchar *temp_file_name = data;
+    gchar buffer[BUF_SIZE] = "";
+    gchar *buf_ptr = buffer;
+    int char_read;
+
+    if (child_status) {
+        echo_message(Error, "External editor returned with non-zero status,"
+            " discarding edits.");
+        goto error_exit;
+    }
+
+    /* re-read the new contents of the file and put it into the HTML element */
+    if (!access(temp_file_name, R_OK) == 0) {
+        message = g_strdup_printf("Could not access temporary file: %s",
+            strerror(errno));
+        goto error_exit;
+    }
+    fp = fopen(temp_file_name, "r");
+    if (fp == NULL) {
+        /* this would be too weird to even emit an error message */
+        goto error_exit;
+    }
+    jsapi_evaluate_script("document.documentElement.innerHTML = '';",
+        &value, &message);
+    g_free(value);
+    g_free(message);
+
+    while (EOF != (char_read = fgetc(fp))) {
+        if (char_read == '\n') {
+            *buf_ptr++ = '\\';
+            *buf_ptr++ = 'n';
+        } else if (char_read == '"') {
+            *buf_ptr++ = '\\';
+            *buf_ptr++ = '"';
+        } else {
+            *buf_ptr++ = char_read;
+        }
+        /* ship out as the buffer when space gets tight.  This has
+        fuzz to save on thinking, plus we have enough space for the
+        trailing "; in any case. */
+        if (buf_ptr-buffer>=BUF_SIZE-10) {
+            *buf_ptr = 0;
+            g_string_append(set_value_js, buffer);
+            buf_ptr = buffer;
+        }
+    }
+    *buf_ptr++ = '"';
+    *buf_ptr++ = ';';
+    *buf_ptr = 0;
+    g_string_append(set_value_js, buffer);
+    fclose(fp);
+
+    jsapi_evaluate_script(set_value_js->str, &value, &message);
+
+error_exit:
+
+    g_string_free(set_value_js, TRUE);
+    unlink(temp_file_name);
+    g_free(temp_file_name);
+    g_free(value);
+    g_free(message);
+}
+
 static gboolean
 focus_input(const Arg *arg) {
     static Arg a;
@@ -2199,16 +2342,16 @@ process_set_line(char *line) {
             } else if (strlen(my_pair.what) == 7 && strncmp("cookies", my_pair.what, 7) == 0) {
                 /* cookie policy */
                 if (strncmp(my_pair.value, "on", 2) == 0 || strncmp(my_pair.value, "true", 4) == 0 ||
-                        strncmp(my_pair.value, "ON", 2) == 0 || strncmp(my_pair.value, "TRUE", 4) == 0 || 
+                        strncmp(my_pair.value, "ON", 2) == 0 || strncmp(my_pair.value, "TRUE", 4) == 0 ||
                         strncmp(my_pair.value, "all", 3) == 0 || strncmp(my_pair.value, "ALL", 3) == 0) {
                     CookiePolicy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
-                } else if (strncmp(my_pair.value, "off", 3) == 0 || strncmp(my_pair.value, "false", 5) == 0 || 
-                        strncmp(my_pair.value, "OFF", 3) == 0 || strncmp(my_pair.value, "FALSE", 5) == 0 || 
-                        strncmp(my_pair.value, "never", 5) == 0 || strncmp(my_pair.value, "NEVER", 5) == 5 || 
+                } else if (strncmp(my_pair.value, "off", 3) == 0 || strncmp(my_pair.value, "false", 5) == 0 ||
+                        strncmp(my_pair.value, "OFF", 3) == 0 || strncmp(my_pair.value, "FALSE", 5) == 0 ||
+                        strncmp(my_pair.value, "never", 5) == 0 || strncmp(my_pair.value, "NEVER", 5) == 5 ||
                         strncmp(my_pair.value, "none", 4) == 0 || strncmp(my_pair.value, "NONE", 4) == 0) {
                     CookiePolicy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
-                } else if (strncmp(my_pair.value, "origin", 6) == 0 || strncmp(my_pair.value, "ORIGIN", 6) == 0 || 
-                        strncmp(my_pair.value, "no_third", 8) == 0 || strncmp(my_pair.value, "NO_THIRD", 8) == 0 || 
+                } else if (strncmp(my_pair.value, "origin", 6) == 0 || strncmp(my_pair.value, "ORIGIN", 6) == 0 ||
+                        strncmp(my_pair.value, "no_third", 8) == 0 || strncmp(my_pair.value, "NO_THIRD", 8) == 0 ||
                         strncmp(my_pair.value, "no third", 8) == 0 || strncmp(my_pair.value, "NO THIRD", 8) == 0) {
                     CookiePolicy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
                 } else {
@@ -2334,7 +2477,7 @@ search_tag(const Arg * a) {
         t = strlen(s) - 1;
         while (isspace(s[t]))
             t--;
-        if (s[t] != ']') continue;      
+        if (s[t] != ']') continue;
         while (t > 0) {
             if (s[t] == ']') {
                 if (!intag)
@@ -2349,7 +2492,7 @@ search_tag(const Arg * a) {
                         while (k < intag)
                             foundtag[i++] = s[k++];
                         foundtag[i] = '\0';
-                        /* foundtag now contains the tag */	
+                        /* foundtag now contains the tag */
                         if (strlen(foundtag) < MAXTAGSIZE && strcmp(tag, foundtag) == 0) {
                             i = 0;
                             while (isspace(s[i])) i++;
@@ -2798,7 +2941,7 @@ setup_cookies()
  *      is limited to handling cookies.
  */
 void
-new_generic_request(SoupSession *session, SoupMessage *soup_msg, gpointer unused) 
+new_generic_request(SoupSession *session, SoupMessage *soup_msg, gpointer unused)
 {
     SoupMessageHeaders *soup_msg_h;
     SoupURI *uri;
@@ -2840,7 +2983,7 @@ handle_cookie_request(SoupMessage *soup_msg, gpointer unused)
 		{
 			SoupDate *soup_date;
 			cookie = soup_cookie_copy((SoupCookie *)resp_cookie->data);
-	
+
 			if (client.config.cookie_timeout && cookie->expires == NULL) {
 				soup_date = soup_date_new_from_time_t(time(NULL) + client.config.cookie_timeout * 10);
 				soup_cookie_set_expires(cookie, soup_date);
@@ -2856,7 +2999,7 @@ handle_cookie_request(SoupMessage *soup_msg, gpointer unused)
 				soup_cookie_jar_add_cookie(client.net.file_cookie_jar, cookie);
 			}
 		}
-	
+
 		soup_cookies_free(cookie_list);
 	}
 
------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet
_______________________________________________
Vimprobable-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vimprobable-users

Reply via email to