From 071df572135081406f7864443ab4e83242c340cf Mon Sep 17 00:00:00 2001 From: JSDurand Date: Mon, 2 Aug 2021 15:19:13 +0800 Subject: new: eww-conf * eww-conf.el (browse-url-browser-function) (browse-url-secondary-browser-function): Now the default is EWW, and the secondary is the external browser. (eww-mode-map): Bind my download function. (durand-eww-download-callback, durand-eww-download): Customized download function that suits my needs. --- eww-conf.el | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) (limited to 'eww-conf.el') diff --git a/eww-conf.el b/eww-conf.el index a6e486f..a546219 100644 --- a/eww-conf.el +++ b/eww-conf.el @@ -12,6 +12,9 @@ (require 'eww) (require 'shr) +(setq browse-url-browser-function #'eww-browse-url) +(setq browse-url-secondary-browser-function 'browse-url-default-browser) + (setq eww-bookmarks-directory load-file-directory) (setq eww-search-prefix "https://lite.duckduckgo.com/lite/?q=") @@ -52,6 +55,7 @@ (define-key eww-mode-map (vector ?E) #'eww-visit-url-on-page) (define-key eww-mode-map (vector ?J) #'eww-jump-to-url-on-page) (define-key eww-mode-map (vector ?m) #'eww-add-bookmark) +(define-key eww-mode-map (vector ?d) #'durand-eww-download) (define-key dired-mode-map (kbd "E") #'eww-open-file) ; to render local HTML files (define-key eww-buffers-mode-map (kbd "d") #'eww-bookmark-kill) ; it actually deletes (define-key eww-bookmark-mode-map (kbd "d") #'eww-bookmark-kill) ; same @@ -68,8 +72,8 @@ (cond ((version<= "28" emacs-version)) ((setq eww-retrieve-command '("wget" "--quiet" "--output-document=-")))) -(define-key eww-mode-map (vector 'C-tab) - #'durand-eww-goto-search-result) +;; (define-key eww-mode-map (vector 'C-tab) +;; #'durand-eww-goto-search-result) ;;;###autoload (defun durand-eww-goto-search-result () @@ -265,6 +269,122 @@ new EWW buffer." nodes)) (display-buffer (get-buffer buf-name))))))) +;; REVIEW: the line containing the universal argument looks longer in +;; the source form, and when expanded in the help buffer, it will fit +;; perfectly. But this does not seem to be the right approach, since +;; this makes it harder to people to read the sources. Is it possible +;; to process the documentation string in the help buffer, so that the +;; documentation strings look nice in every place. + +;;;###autoload +(defun durand-eww-download (&optional url name dir) + "Download URL to DIR as NAME. +URL defaults to the link at point if any, else to the current +page's URL. + +NAME defaults to the title of the current page if it can be +found, else to the last component of the current page's URL, if +any. In addition, the name will be suitably processed so that it +fits into a file name. + +DIR defaults to `eww-download-directory'. + +In interactive uses, with a universal argument (\\[universal-argument]), prompt +for URL, NAME, and DIR, providing the default values for the +users to select." + (interactive + (cond + (current-prefix-arg + (list (let ((default-url (or (get-text-property (point) 'shr-url) + (eww-current-url)))) + (read-string (cond + ((and (stringp default-url) + (not (string= default-url ""))) + (format "Download URL (default %s): " + default-url)) + ("Download URL: ")) + nil nil default-url)) + (let ((default-title + (or (plist-get eww-data :title) + (file-name-nondirectory + (eww-current-url))))) + (read-string (cond + ((and (stringp default-title) + (not (string= default-title ""))) + (format "Download as (default %s) " + default-title)) + ("Download as ")) + nil nil default-title)) + (read-file-name + "Download to: " eww-download-directory + eww-download-directory nil nil + #'file-accessible-directory-p))) + ((list (or (get-text-property (point) 'shr-url) (eww-current-url)) + (or (plist-get eww-data :title) + (file-name-nondirectory (eww-current-url))) + eww-download-directory)))) + ;; Check the validity of DIR + (cond ((and (stringp dir) (not (string= dir "")) + (file-accessible-directory-p dir))) + ((and (stringp dir) (not (string= dir "")) + (file-exists-p dir)) + (user-error "%s is an existing file that is not a directory" + dir)) + ((and (stringp dir) (not (string= dir ""))) + ;; create the dir for the user + (cond ((y-or-n-p "Create a directory to download to? ") + (make-directory dir t)) + ((user-error "A non-existent directory")))) + ((user-error "DIR should be a non-empty string, but got %S" + dir))) + ;; Check the validity of NAME + (cond + ((and (stringp name) (not (string= name "")))) + ((let ((default (or (plist-get eww-data :title) + (file-name-nondirectory + (eww-current-url))))) + (and (stringp default) (not (string= default "")) + (setq name default)))) + ((user-error "NAME should be a non-empty string, but got %S" + name))) + ;; sluggish the name -- taken from Protesilaos' codes + (setq name + (downcase + (replace-regexp-in-string + "-$" "" + (replace-regexp-in-string + "--+" "-" + (replace-regexp-in-string + "\\s-+" "-" + (replace-regexp-in-string + "[][{}!@#$%^&*()_=+'\"?,.\|;:~`‘’“”]*" "" name)))))) + + ;; Check the validity of URL + (cond + ((and (stringp url) (not (string= url "")))) + ((user-error "URL should be a non-empty string, but got %S" + url))) + (url-retrieve url #'durand-eww-download-callback + (list name dir))) + +;;;###autoload +(defun durand-eww-download-callback (status name dir) + "The callback function for `durand-eww-download'. +For the meaning of STATUS, see the documentation of +`url-retrieve'. + +For the meanings of NAME and DIR, see the documentation of +`durand-eww-download'." + (cond + ((plist-get status :error) + (user-error "Error: %S" (plist-get status :error)))) + (let ((file (eww-make-unique-file-name name dir))) + (goto-char (point-min)) + (re-search-forward "\r?\n\r?\n") + (let ((coding-system-for-write 'no-conversion)) + (write-region (point) (point-max) file)) + (message "Saved %s" file))) + (provide 'eww-conf) ;;; eww-conf.el ends here -- cgit v1.2.3-18-g5258