#+title: Web browsing using eww * Integration with browse-url and afio #+begin_src emacs-lisp (defun jao-eww-browse-url (url &rest r) "Browse URL using eww." (jao-afio--goto-www) (select-window (frame-first-window)) (let* ((url (url-encode-url url)) (bf (seq-find `(lambda (b) (with-current-buffer b (string= ,url (url-encode-url (eww-current-url))))) (jao-eww-session--list-buffers)))) (if bf (switch-to-buffer bf) (eww url 4)))) (setq jao-browse-url-function #'jao-eww-browse-url) (setq browse-url-browser-function jao-browse-url-function) #+end_src * Email #+begin_src emacs-lisp (defun jao-eww-html-renderer (handle) (let ((shr-use-colors nil) (shr-use-fonts nil) (fill-column (min (window-width) 110))) (mm-shr handle))) (setq mm-text-html-renderer 'jao-eww-html-renderer) #+end_src * Buffer names #+begin_src emacs-lisp (defun jao-eww--title () (if (eq "" (plist-get eww-data :title)) (plist-get eww-data :url) (plist-get eww-data :title))) (defun jao-eww--rename-buffer () (let ((name (jao-eww--title))) (rename-buffer (format "*%s # eww*" name) t))) (add-hook 'eww-after-render-hook #'jao-eww--rename-buffer) (advice-add 'eww-back-url :after #'jao-eww--rename-buffer) (advice-add 'eww-forward-url :after #'jao-eww--rename-buffer) #+end_src * Opening URLs #+begin_src emacs-lisp (defun jao-eww-browse (arg) (interactive "P" eww-mode) (setq eww-prompt-history (cl-remove-duplicates eww-prompt-history :test #'string=)) (let ((url (completing-read (if arg "eww in new buffer: " "eww: ") eww-prompt-history nil nil nil 'eww-prompt-history (eww-current-url)))) (eww url (when arg 4)))) (defun jao-eww-browse-new () (interactive nil eww-mode) (jao-eww-browse t)) (defun jao-eww-reload (images) (interactive "P" eww-mode) (if images (let ((shr-blocked-images nil)) (eww-reload t)) (call-interactively 'eww-reload))) #+end_src * Images #+begin_src emacs-lisp (defun jao-eww-next-image () (interactive nil eww-mode) (when-let (p (text-property-search-forward 'image-displayer nil nil t)) (goto-char (prop-match-beginning p)))) #+end_src * Close page and reopen #+begin_src emacs-lisp (defvar jao-eww--closed-urls ()) (defun jao-eww-close () (interactive nil eww-mode) (when-let (current (eww-current-url)) (add-to-list 'jao-eww--closed-urls current)) (kill-current-buffer) (when-let (b (car (jao-eww-session--list-buffers))) (switch-to-buffer b))) (defun jao-eww-reopen (arg) (interactive "P") (if (> (length jao-eww--closed-urls) 0) (let ((url (completing-read "URL: " jao-eww--closed-urls))) (jao-afio--goto-www) (setq jao-eww--closed-urls (remove url jao-eww--closed-urls)) (eww url (when arg 4))) (message "No previously closed URLs."))) (defun jao-eww-reopen-new () (interactive) (jao-eww-reopen t)) #+end_src * Visiting links in a page #+begin_src emacs-lisp (defun jao-eww--at-link () (and (get-text-property (point) 'shr-url) (not (get-text-property (point) 'eww-form)))) (defun jao-eww--previous-url () (text-property-search-backward 'shr-url nil nil t)) (defun jao-eww--pp-link () (format "%s @ %s" (button-label (point)) (propertize (get-text-property (point) 'shr-url) 'face 'link))) (defun jao-eww-visit-url-on-page (&optional arg) "Visit URL from list of links in the page using completion." (interactive "P") (when (derived-mode-p 'eww-mode) (let ((links)) (save-excursion (goto-char (point-max)) (while (jao-eww--previous-url) (when (jao-eww--at-link) (push (jao-eww--pp-link) links)))) (let* ((selection (completing-read "Browse: " links nil t)) (url (replace-regexp-in-string ".*@ " "" selection))) (eww url (if arg 4 nil)))))) (defun jao-eww-jump-to-url-on-page () "Jump to URL position in the page using completion." (interactive) (when (derived-mode-p 'eww-mode) (let ((links)) (save-excursion (goto-char (point-max)) (while (jao-eww--previous-url) (when (jao-eww--at-link) (push (format "%s ~ %d" (jao-eww--pp-link) (point)) links)))) (let* ((selection (completing-read "Jump to URL in page: " links nil t)) (position (replace-regexp-in-string ".*~ " "" selection)) (point (string-to-number position))) (goto-char point))))) (defun jao-eww--append-html (oldfn &rest args) (let ((p (apply oldfn args))) (when (stringp p) (let ((r (if (string-match-p ".*\\.html$" p) p (concat p ".html")))) (kill-new (format "[[doc:%s]]" r)) r)))) (advice-add 'eww-make-unique-file-name :around #'jao-eww--append-html) #+end_src * eww-lnum #+begin_src emacs-lisp (use-package eww-lnum :ensure t) #+end_src * Sessions #+begin_src emacs-lisp (use-package jao-eww-session :custom ((jao-eww-session-duplicate-tabs 'ask) (jao-eww-session-file "~/.emacs.d/cache/eww-session.eld"))) #+end_src * Package #+begin_src emacs-lisp (use-package eww :demand t :custom ((eww-browse-url-new-window-is-tab nil) (eww-download-directory jao-sink-dir) (eww-header-line-format nil) (shr-width nil) (shr-use-colors nil) (shr-use-fonts nil) (shr-max-width 130) (shr-blocked-images ".*") (shr-max-image-proportion 0.9)) :config (with-eval-after-load "org" (require 'ol-eww nil t)) :bind (:map eww-mode-map (("b" . eww-back-url) ("B" . eww-forward-url) ("d" . eww-download) ("D" . jao-download) ("f" . eww-lnum-follow) ("F" . eww-lnum-universal) ("j" . jao-eww-visit-url-on-page) ("J" . jao-eww-jump-to-url-on-page) ("L" . eww-forward-url) ("N" . jao-eww-next-image) ("o" . jao-eww-browse) ("O" . jao-eww-browse-new) ("r" . jao-eww-reload) ("s" . eww-search-words) ("S" . jao-eww-session-load) ("u" . jao-eww-reopen) ("U" . jao-eww-reopen-new) ("w" . org-eww-copy-for-org-mode) ("W" . jao-eww-close) ("x" . jao-rss-subscribe) ("y" . eww-copy-page-url) ("C-c C-w" . jao-eww-close)))) #+end_src