#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-" :tangle-mode (identity #o644)
#+title: Web browsing using eww
#+auto_tangle: t

* 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))))
        (cond (bf (switch-to-buffer bf))
              ((string-match-p url "^file://") (eww-open-file url))
              (t (eww url 4)))))

    (setq jao-browse-url-function #'jao-eww-browse-url)
    (setq eww-use-browse-url "^\\(gemini\\|gopher\\):")
  #+end_src
* Email
  #+begin_src emacs-lisp
    (defun jao-eww-html-renderer (handle)
      (let ((shr-use-colors nil)
            (shr-use-fonts nil)
            ;; (mm-html-blocked-images nil)
            (fill-column (min (window-width) 110)))
        (mm-shr handle)))
    (setq mm-text-html-renderer 'jao-eww-html-renderer)
  #+end_src
* Opening URLs
  #+begin_src emacs-lisp
    (defun jao-eww-copy-link ()
      (interactive)
      (when-let (lnk (or (car (eww-links-at-point)) (eww-current-url)))
        (message "%s" lnk)
        (kill-new lnk)))

    (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
* Consult narrowing
  #+begin_src emacs-lisp
    (with-eval-after-load "consult"
      (defvar jao-eww-consult-history nil)
      (defvar jao-eww-buffer-source
        (list :name "eww buffer"
              :category 'eww-buffer
              :hidden t
              :narrow (cons ?e "eww")
              :annotate (lambda (c) (get-text-property 0 'url c))
              :history 'jao-eww-consult-history
              :action (lambda (b)
                        (jao-afio--goto-www)
                        (switch-to-buffer (get-text-property 0 'buffer b)))
              :items
              (lambda ()
                (seq-map (lambda (b)
                           (with-current-buffer b
                             (let ((tl (or (plist-get eww-data :title) ""))
                                   (url (or (eww-current-url) "<no url>")))
                               (propertize (if (string-blank-p tl) url tl)
                                           'buffer b 'url url))))
                         (seq-filter (lambda (b)
                                       (eq 'eww-mode
                                           (buffer-local-value 'major-mode b)))
                                     (buffer-list))))))
      (jao-consult-add-buffer-source 'jao-eww-buffer-source "Web" ?e))
  #+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))
      (let ((nxt (car (jao-eww-session-invisible-buffers))))
        (kill-current-buffer)
        (when nxt (switch-to-buffer nxt nil t))))

    (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
* 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)
               (eww-form-checkbox-selected-symbol "☒")
               (eww-search-prefix "https://search.brave.com/search?q=")
               (shr-width nil)
               (shr-use-colors nil)
               (shr-use-fonts nil)
               (shr-max-width 130)
               (shr-blocked-images nil)
               (shr-inhibit-images t)
               (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)
                                ("c" . jao-eww-copy-link)
                                ("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)
                                ("q" . jao-eww-close)
                                ("x" . jao-rss-subscribe)
                                ("y" . jao-eww-copy-link)
                                ("C-c C-w" . jao-eww-close)
                                ("M-i" . eww-toggle-images))))

  #+end_src