Complete Computing Environment: Web Browsing

Table of Contents

Web Browsing using EWW and Qutebrowser

Web browsing is still hard; I want to use the Emacs-native EWW, but without native Javascript or anything that makes the modern "Web Apps" I use at work, well, work, I need a GUI browser. Right now my GUI browser of choice is Qutebrowser, a minimalist modal browser built on top of QtWebEngine.

(provide 'cce-browsers)

We can browse to anything that looks like a URL with C-x m.

(evil-leader/set-key (kbd "u") 'browse-url-at-point)

I use EWW as my default browser in Emacs; certain things, I need to jump out of EWW and in to a real browser with javascript; which I can do if I just hit & – it'll drop me in to a firefox session without a hassle.

There are certain sites that, despite my best abilities, I cannot make work in EWW. For these, I launch Firefox directly, instead of hitting a silly man in the middle.

(setq browse-url-generic-program (executable-find "qutebrowser"))
(setq browse-url-browser-function #'browse-url-firefox)


I use this advice to rename all of the EWW buffers based on their <title> elements.

(unless (version< emacs-version "24.4")
  (defadvice eww-tag-title (after rrix/eww-rename-buffer-ad (cont))
    "Update EWW buffer title with new page load."
    (let ((eww-current-title
           (if (version< emacs-version "25.0")
             (plist-get eww-data :title))))
      (rename-buffer (format "*eww : %s *" (cce/str-chomp eww-current-title)) t)))
  (ad-activate 'eww-tag-title))

Always open links in existing window, if possible.

(setq browse-url-new-window-flag nil)

Part of my Expansion technique is to just open a shitload of browser buffers throughout the day and pick through them in my IDLE times. EWW has basically no session support like emacs-w3m does, which is actually Okay given that that didn't serialize out to any format which I can sync between my workstations easily. Instead, I've crafted this function which uses my W buffer capture template to dump every EWW buffer to my refile.

(install-pkgs '(el-pocket))
(load-library "el-pocket")
(defun rrix/capture-all-eww-buffers ()
  (map 'list (lambda (b)
               (with-current-buffer b
                 (when (eq major-mode 'eww-mode)
                   (let ((url (cond
                               ((version< emacs-version "25.0")
                               ((version< "25.0" emacs-version)
                                (plist-get eww-data :url))))
                         (title (cond
                                 ((version< emacs-version "25.0")
                                 ((version< "25.0" emacs-version)
                                  (plist-get eww-data :title)))))
                     (if (y-or-n-p (format "Capture %s (%s)? " title url))
                           (el-pocket-add url))

Having a global history is an incredibly useful thing to have but EWW doesn't give me one of these out of the box; I advise this in after eww-render like so:

(unless (version< emacs-version "24.4")
  (defvar rrix/eww-global-history '())
  (defadvice eww-render (after rrix/eww-global-history-ad ())
    "Add EWW history to a global history variable"
    (push (list :url (if (version< emacs-version "25.0")
                       (plist-get eww-data :url))
                :title (if (version< emacs-version "25.0")
                         (plist-get eww-data :title))
                :point (point)
                :date (format-time-string "%FT%T%z"))
  (ad-deactivate 'eww-render)
  (add-to-list 'savehist-additional-variables 'rrix/eww-global-history))

I'll need to find some way to load that in to eww-list-histories, though… This is close, but it doesn't work since I'm not loading the full DOM, source and text in to the variable.

(defun rrix/list-eww-histories ()
  (with-current-buffer (get-buffer-create "*eww-global-history*")
    (setq-local eww-history rrix/eww-global-history)

eww-lnum is a package that lets you follow any URL in an eww buffer with a keybinding, similar to Avy

(unless (version< emacs-version "24.4")
  (install-pkgs '(eww-lnum))
  (eval-after-load 'eww-mode (lambda ()
                               (define-key eww-mode-map "f" 'eww-lnum-follow))))

Author: Ryan Rix

Created: 2017-10-03 Tue 10:05

Validate XHTML 1.0