Completely rewrite normal_view_source() to use the editor - pkgsrc-localpatches - leot's pkgsrc LOCALPATCHES
 (HTM) hg clone https://bitbucket.org/iamleot/pkgsrc-localpatches
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) changeset a04c4611af5d4b1a7a5c5512a10de44faf9c3899
 (DIR) parent a7fed352255cf2c4d82b96e623a631190c95361c
 (HTM) Author: Leonardo Taccari <iamleot@gmail.com>
       Date:   Wed, 17 Oct 2018 22:37:02 
       
       Completely rewrite normal_view_source() to use the editor
       
       Diffstat:
        wip/vimb3-git/patch-normal_view_support.patch |  119 ++++++++++++++++---------
        1 files changed, 77 insertions(+), 42 deletions(-)
       ---
       diff -r a7fed352255c -r a04c4611af5d wip/vimb3-git/patch-normal_view_support.patch
       --- a/wip/vimb3-git/patch-normal_view_support.patch     Tue Oct 16 12:40:23 2018 +0200
       +++ b/wip/vimb3-git/patch-normal_view_support.patch     Wed Oct 17 22:37:02 2018 +0200
       @@ -1,55 +1,90 @@
       -Add experimental support for normal_view_source()
       +Add experimental support for `gf' command.
        
       -diff --git src/main.h src/main.h
       -index 56ba9e0..656a029 100644
       ---- src/main.h
       -+++ src/main.h
       -@@ -162,6 +162,7 @@ struct State {
       -     guint               scroll_percent;     /* Current position of the viewport in document (percent). */
       -     glong               scroll_top;         /* Current position of the viewport in document (pixel). */
       -     char                *title;             /* Window title of the client. */
       -+    gboolean            view_source;        /* indicates if currently viewing the source */
       +--- src/normal.c.orig
       ++++ src/normal.c
       +@@ -74,6 +74,7 @@ static VbResult normal_search(Client *c, const NormalCmdInfo *info);
       + static VbResult normal_search_selection(Client *c, const NormalCmdInfo *info);
       + static VbResult normal_view_inspector(Client *c, const NormalCmdInfo *info);
       + static VbResult normal_view_source(Client *c, const NormalCmdInfo *info);
       ++static void resume_normal_view_editor(GPid pid, int status, char *file);
       + static VbResult normal_yank(Client *c, const NormalCmdInfo *info);
       + static VbResult normal_zoom(Client *c, const NormalCmdInfo *info);
         
       -     char                *reg[REG_SIZE];     /* holds the yank buffers */
       -     /* TODO rename to reg_{enabled,current} */
       -diff --git src/normal.c src/normal.c
       -index 02ba27b..b49823b 100644
       ---- src/normal.c
       -+++ src/normal.c
       -@@ -743,7 +743,35 @@ static VbResult normal_view_inspector(Client *c, const NormalCmdInfo *info)
       +@@ -743,8 +744,76 @@ static VbResult normal_view_inspector(Client *c, const NormalCmdInfo *info)
         
         static VbResult normal_view_source(Client *c, const NormalCmdInfo *info)
         {
        -    /* TODO the source mode isn't supported anymore use external editor for this */
       -+    char *js;
       ++    char **argv = NULL, *file_path = NULL;
       ++    char *command = NULL;
       ++    int argc;
       ++    GPid pid;
       ++    gboolean success;
       ++    const char *text = NULL, *editor_command;
       ++    GVariant *jsreturn;
       ++    GError *error = NULL;
       ++
       ++    /* get the editor command */
       ++    editor_command = GET_CHAR(c, "editor-command");
       ++    if (!editor_command || !*editor_command) {
       ++        vb_echo(c, MSG_ERROR, TRUE, "No editor-command configured");
       ++        return RESULT_ERROR;
       ++    }
        +
       -+    if (c->state.view_source) {
       -+        js = g_strdup("document.documentElement.innerHTML = " \
       -+            "document.documentElement.innerHTML" \
       -+            ".replace(/^<head><\\/head><body><pre><code>/, '')" \
       -+            ".replace(/&amp;/g,  '&')" \
       -+            ".replace(/&lt;/g,  '<')" \
       -+            ".replace(/&gt;/g,  '>')" \
       -+            ".replace(/&quot;/g, '\"')" \
       -+            ".replace(/&#39;/g,  \"'\")" \
       -+            ".replace(/<\\/code><\\/pre><\\/body>$/, '');");
       -+        c->state.view_source = FALSE;
       -+    } else {
       -+        js = g_strdup("document.documentElement.innerHTML = " \
       -+            "\"<head><\\/head><body><pre><code>\" + " \
       -+            "document.documentElement.innerHTML" \
       -+            ".replace(/&/g,  '&amp;')" \
       -+            ".replace(/</g,  '&lt;')" \
       -+            ".replace(/>/g,  '&gt;')" \
       -+            ".replace(/\"/g, '&quot;')" \
       -+            ".replace(/'/g,  '&#39;');"
       -+            " + \"</code></pre></body>\"");
       -+        c->state.view_source = TRUE;
       ++    /* get the selected input element */
       ++    jsreturn = ext_proxy_eval_script_sync(c, "document.documentElement.innerHTML");
       ++    g_variant_get(jsreturn, "(bs)", &success, &text);
       ++
       ++    if (!success || !text) {
       ++        return RESULT_ERROR;
       ++    }
       ++
       ++    /* create a temp file to pass text to editor */
       ++    if (!util_create_tmp_file(text, &file_path)) {
       ++        goto error;
       ++    }
       ++
       ++    /* spawn editor */
       ++    command = g_strdup_printf(editor_command, file_path);
       ++    if (!g_shell_parse_argv(command, &argc, &argv, NULL)) {
       ++        g_critical("Could not parse editor-command '%s'", command);
       ++        goto error;
        +    }
        +
       -+    ext_proxy_eval_script(c, js, NULL);
       -+    g_free(js);
       ++    success = g_spawn_async(
       ++        NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
       ++        NULL, NULL, &pid, &error
       ++    );
       ++
       ++    if (!success) {
       ++        g_warning("Could not spawn editor-command: %s", error->message);
       ++        g_error_free(error);
       ++        goto error;
       ++    }
       ++    g_strfreev(argv);
       ++
       ++    /* watch the editor process */
       ++    char *file = g_strdup(file_path);
       ++
       ++    g_child_watch_add(pid, (GChildWatchFunc)resume_normal_view_editor, file);
        +
             return RESULT_COMPLETE;
       ++
       ++error:
       ++    unlink(file_path);
       ++    g_free(file_path);
       ++    g_strfreev(argv);
       ++    return RESULT_ERROR;
       ++}
       ++
       ++static void resume_normal_view_editor(GPid pid, int status, char *file)
       ++{
       ++    g_assert(pid);
       ++    g_assert(file);
       ++
       ++    unlink(file);
       ++    g_free(file);
       ++    g_spawn_close_pid(pid);
         }
         
       + static VbResult normal_yank(Client *c, const NormalCmdInfo *info)