Opening page source in external editor

Hello fellow Nyxt hackers. Here’s a small code snippet we’ve collectively came up with on IRC that you can paste to your config and enjoy the source-viewing via edit-source-in-external-editor:

(defun %edit-source-with-external-editor ()
  "Edit page source using `external-editor-program'.
Create a temporary file. The editor runs synchronously so invoke on a
separate thread when possible."
  (let ((page-source (if (current-mode 'web)
                         (plump:serialize (nyxt/web-mode:document-model (current-mode 'web)) nil)
                         (ffi-buffer-get-document (current-buffer)))))
    (uiop:with-temporary-file (:directory (uiop:xdg-data-home nyxt::+data-root+)
                               :pathname p)
      (when (> (length page-source) 0)
        (alexandria:write-string-into-file page-source p :if-exists :supersede))
      (log:debug "External editor ~s opens ~s"
                 (external-editor-program *browser*) p)
      (with-protect ("Failed editing: ~a" :condition)
        (uiop:run-program (append (external-editor-program *browser*)
                                  (list (uiop:native-namestring p)))
                          :ignore-error-status t)))))

(define-command-global edit-source-with-external-editor ()
  "Edit the current page source using `external-editor-program'.
Has no effect on the page, use only to look at sources!"
  (if (external-editor-program *browser*)
      (run-thread
        (%edit-source-with-external-editor))
      (echo-warning "Please set `external-editor-program' browser slot.")))
6 Likes

Fantastic! I just wrote a blog about doing that with Emacs: Nyxt to mold HTML: the first mix of moldable-emacs and browsing - Where parallels cross

I mentioned your approach there because it is more generic! Thanks for sharing!!

1 Like

@aartaka By the way: any chance that we can provide a “dynamic” version of this function? Some websites use JavaScript exceedingly and so the HTML source is pretty dry because the contents is created dynamically.
How difficult would be to use some Parenscript to take a snapshot of the “real” source of the page? I mean the HTML that represents what you are seeing at a certain moment from the browser.
What do you think?

1 Like

@Andrea, it is already there. nyxt/web-mode:document-model parses the page and gets you a fresh and full version of it in an easy to process Lispy data structure (namely plump:node). This command is already dynamic then, see the line with (plump:serialize (nyxt/web-mode:document-model ...) nil).

2 Likes

Super cool stuff!

But why not call it “view-source-with-external-editor” then? It would be less confusing :slight_smile:

What about integrating this in Nyxt upstream?

1 Like

How / where can we set the ‘external-editor-program’ browser slot?

You can set it in your config file (usually ~/.config/nyxt/init.lisp). The snippet is something along the lines of (choose your favorite editor):

(define-configuration browser
  ((external-editor-program '("emacs" "-Q"))))

external-editor-program is set to either of EDITOR or VISUAL by default. If you set those, you don’t need to configure external-editor-program.

1 Like

thank you for the reply … I’ll try it out!

One thing to keep in mind when using a terminal $EDITOR is even though Nyxt defaults to it, it can’t open the terminal window in the first place unless specifically told to, so that’s what I had to use:

;;use kakoune as external-editor
(define-configuration browser
  ((external-editor-program (list "/usr/bin/kitty" "--name" "floating" "/usr/local/bin/kak"))))

"--name" "floating" is not mandatory of course, it just matches with an i3wm rule in my configuration. I suppose Nyxt could use $TERMINAL and $EDITOR in that command too instead of hardcoding the programs?

Thanks a lot for creating this command @aartaka. Glad the command to view source is useful to several users, at least I didn’t bother you for nothing!