commit ce141686d2d890d9d7c3dd881dc5f9bfb5d6d296 (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Tue Mar 24 23:58:01 2020 +0200 Rename dired-mark-region choices and ignore empty region. * lisp/dired.el (dired-mark-region): Rename choices 'exclusive' to 'file', and 'inclusive' to 'line'. (dired-mark-if, dired-mark): Check for non-empty region explicitly instead of using use-region-p to ignore non-nil value of use-empty-active-region. (Bug#39902) diff --git a/etc/NEWS b/etc/NEWS index 60d22a70ce..1be5ad6acc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -104,8 +104,8 @@ shows equivalent key bindings for all commands that have them. *** New option 'dired-mark-region' affects all Dired commands that mark files. When non-nil and the region is active in Transient Mark mode, then Dired commands operate only on files in the active region. -The values 'exclusive' and 'inclusive' of this option define -the details of marking the last file at the end of the region. +The values 'file' and 'line' of this option define the details of +marking the file at the end of the region. *** State changing VC operations are supported in dired-mode on files (but still not on directories). diff --git a/lisp/dired.el b/lisp/dired.el index 438f5e7d8b..41bbf9f56a 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -296,7 +296,7 @@ new Dired buffers." :version "26.1" :group 'dired) -(defcustom dired-mark-region 'exclusive +(defcustom dired-mark-region 'file "Defines what commands that mark files do with the active region. When nil, marking commands don't operate on all files in the @@ -306,7 +306,8 @@ When the value of this option is non-nil, then all Dired commands that mark or unmark files will operate on all files in the region if the region is active in Transient Mark mode. -When `exclusive', don't mark the file if the end of the region is +When `file', the region marking is based on the file name. +This means don't mark the file if the end of the region is before the file name displayed on the Dired line, so the file name is visually outside the region. This behavior is consistent with marking files without the region using the key `m' that advances @@ -315,12 +316,13 @@ of keys used to mark files is the same as the number of keys used to select the region, e.g. `M-2 m' marks 2 files, and `C-SPC M-2 n m' marks 2 files, and `M-2 S-down m' marks 2 files. -When `inclusive', include the file into marking if the end of the region +When `line', the region marking is based on Dired lines, +so include the file into marking if the end of the region is anywhere on its Dired line, except the beginning of the line." :type '(choice (const :tag "Don't mark files in active region" nil) - (const :tag "Exclude file name outside of region" exclusive) - (const :tag "Include the file at region end line" inclusive)) + (const :tag "Exclude file name outside of region" file) + (const :tag "Include the file at region end line" line)) :group 'dired :version "28.1") @@ -646,16 +648,19 @@ of the region if `dired-mark-region' is non-nil. Otherwise, operate on the whole buffer. Return value is the number of files marked, or nil if none were marked." - `(let ((inhibit-read-only t) count - (beg (if (and dired-mark-region (use-region-p)) + `(let* ((inhibit-read-only t) count + (use-region-p (and dired-mark-region + (region-active-p) + (> (region-end) (region-beginning)))) + (beg (if use-region-p (save-excursion (goto-char (region-beginning)) (line-beginning-position)) (point-min))) - (end (if (and dired-mark-region (use-region-p)) + (end (if use-region-p (save-excursion (goto-char (region-end)) - (if (if (eq dired-mark-region 'inclusive) + (if (if (eq dired-mark-region 'line) (not (bolp)) (get-text-property (1- (point)) 'dired-filename)) (line-end-position) @@ -673,7 +678,7 @@ Return value is the number of files marked, or nil if none were marked." (if (eq dired-del-marker dired-marker-char) " for deletion" "") - (if (and dired-mark-region (use-region-p)) + (if use-region-p " in region" ""))) (goto-char beg) @@ -691,7 +696,7 @@ Return value is the number of files marked, or nil if none were marked." (if (eq dired-marker-char ?\s) "un" "") (if (eq dired-marker-char dired-del-marker) "flagged" "marked") - (if (and dired-mark-region (use-region-p)) + (if use-region-p " in region" "")))) (and (> count 0) count))) @@ -3645,14 +3650,16 @@ this subdir." (interactive (list current-prefix-arg t)) (cond ;; Mark files in the active region. - ((and dired-mark-region interactive (use-region-p)) + ((and interactive dired-mark-region + (region-active-p) + (> (region-end) (region-beginning))) (save-excursion (let ((beg (region-beginning)) (end (region-end))) (dired-mark-files-in-region (progn (goto-char beg) (line-beginning-position)) (progn (goto-char end) - (if (if (eq dired-mark-region 'inclusive) + (if (if (eq dired-mark-region 'line) (not (bolp)) (get-text-property (1- (point)) 'dired-filename)) (line-end-position) commit e906cd0d58f3197edf15ccb843bc2577b879af61 Author: Robert Pluim Date: Tue Mar 24 22:21:26 2020 +0100 Fix gravatar tests * lisp/image/gravatar.el (gravatar--service-libravatar): Don't error when failing to parse email address, just return the default URL. * test/lisp/image/gravatar-tests.el (gravatar-build-url): Adjust for new default gravatar url. diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el index e13f0075f3..ff59a72ac8 100644 --- a/lisp/image/gravatar.el +++ b/lisp/image/gravatar.el @@ -142,19 +142,19 @@ Note that certain services might ignore other options, such as "Find domain that hosts avatars for email address ADDR." ;; implements https://wiki.libravatar.org/api/ (save-match-data - (unless (string-match ".+@\\(.+\\)" addr) - (error "%s is not an email address" addr)) - (let ((domain (match-string 1 addr))) - (catch 'found - (dolist (record '(("_avatars-sec" . "https") - ("_avatars" . "http"))) - (let* ((query (concat (car record) "._tcp." domain)) - (result (dns-query query 'SRV))) - (when result - (throw 'found (format "%s://%s/avatar" - (cdr record) - result))))) - "https://seccdn.libravatar.org/avatar")))) + (if (not (string-match ".+@\\(.+\\)" addr)) + "https://seccdn.libravatar.org/avatar" + (let ((domain (match-string 1 addr))) + (catch 'found + (dolist (record '(("_avatars-sec" . "https") + ("_avatars" . "http"))) + (let* ((query (concat (car record) "._tcp." domain)) + (result (dns-query query 'SRV))) + (when result + (throw 'found (format "%s://%s/avatar" + (cdr record) + result))))) + "https://seccdn.libravatar.org/avatar"))))) (defun gravatar-hash (mail-address) "Return the Gravatar hash for MAIL-ADDRESS." diff --git a/test/lisp/image/gravatar-tests.el b/test/lisp/image/gravatar-tests.el index e66b5c6803..66098fa011 100644 --- a/test/lisp/image/gravatar-tests.el +++ b/test/lisp/image/gravatar-tests.el @@ -67,6 +67,6 @@ (gravatar-force-default nil) (gravatar-size nil)) (should (equal (gravatar-build-url "foo") "\ -https://www.gravatar.com/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g")))) +https://seccdn.libravatar.org/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g")))) ;;; gravatar-tests.el ends here commit 0fe7200418471bd237a39887d0798ba99631e3ac Author: Robert Pluim Date: Tue Mar 24 21:19:23 2020 +0100 ; fix previous commit diff --git a/etc/NEWS b/etc/NEWS index 308c541198..60d22a70ce 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -192,7 +192,7 @@ key binding ** Gravatar -=== +--- *** New user option 'gravatar-service' for host to query for gravatars. Defaults to Libravatar, with Unicornify and Gravatar as options. commit c3447e76ea05d12af418b9db7b1cd4ff19201c6a Author: Eric Abrahamsen Date: Tue Mar 24 13:08:30 2020 -0700 ; * etc/NEWS: Clarify news entry for message-draft-headers change diff --git a/etc/NEWS b/etc/NEWS index 2150f49b43..308c541198 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -114,7 +114,11 @@ the details of marking the last file at the end of the region. --- *** Change to default value of 'message-draft-headers' option. -No longer includes the Date header. +The Date header has been removed from the default value, meaning that +draft or delayed messages will get a Date reflecting when the message +was sent. To restore the original behavior of dating a message +from when it is first saved or delayed, add the symbol 'Date back to +this option. ** Help commit 421eeff243af683bf0b7c6d9181650a1c6900f9b Author: Philip K Date: Tue Mar 17 15:29:53 2020 +0100 Add support for multiple Gravatar services Now supports Libravatar and Unicornify, next to Gravatar (Bug#39965). * lisp/image/gravatar.el (gravatar-base-url): Remove constant. (gravatar-service-alist): List supported services. (gravatar-service): Add user option to specify service, defaults to Libravatar. (gravatar--service-libravatar): New function, libravatar image host resolver implementation. (gravatar-build-url): Use alist gravatar-service-alist instead of gravatar-base-url. * etc/NEWS: Mention new gravatar service option. diff --git a/etc/NEWS b/etc/NEWS index ba3e691ff9..2150f49b43 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -186,6 +186,12 @@ key binding / v package-menu-filter-by-version / / package-menu-filter-clear +** Gravatar + +=== +*** New user option 'gravatar-service' for host to query for gravatars. +Defaults to Libravatar, with Unicornify and Gravatar as options. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el index b8542bc3c3..e13f0075f3 100644 --- a/lisp/image/gravatar.el +++ b/lisp/image/gravatar.el @@ -26,6 +26,7 @@ (require 'url) (require 'url-cache) +(require 'dns) (eval-when-compile (require 'subr-x)) @@ -118,9 +119,42 @@ a gravatar for a given email address." :version "27.1" :group 'gravatar) -(defconst gravatar-base-url - "https://www.gravatar.com/avatar" - "Base URL for getting gravatars.") +(defconst gravatar-service-alist + `((gravatar . ,(lambda (_addr) "https://www.gravatar.com/avatar")) + (unicornify . ,(lambda (_addr) "https://unicornify.pictures/avatar/")) + (libravatar . ,#'gravatar--service-libravatar)) + "Alist of supported gravatar services.") + +(defcustom gravatar-service 'libravatar + "Symbol denoting gravatar-like service to use. +Note that certain services might ignore other options, such as +`gravatar-default-image' or certain values as with +`gravatar-rating'." + :type `(choice ,@(mapcar (lambda (s) `(const ,(car s))) + gravatar-service-alist)) + :version "28.1" + :link '(url-link "https://www.libravatar.org/") + :link '(url-link "https://unicornify.pictures/") + :link '(url-link "https://gravatar.com/") + :group 'gravatar) + +(defun gravatar--service-libravatar (addr) + "Find domain that hosts avatars for email address ADDR." + ;; implements https://wiki.libravatar.org/api/ + (save-match-data + (unless (string-match ".+@\\(.+\\)" addr) + (error "%s is not an email address" addr)) + (let ((domain (match-string 1 addr))) + (catch 'found + (dolist (record '(("_avatars-sec" . "https") + ("_avatars" . "http"))) + (let* ((query (concat (car record) "._tcp." domain)) + (result (dns-query query 'SRV))) + (when result + (throw 'found (format "%s://%s/avatar" + (cdr record) + result))))) + "https://seccdn.libravatar.org/avatar")))) (defun gravatar-hash (mail-address) "Return the Gravatar hash for MAIL-ADDRESS." @@ -142,7 +176,8 @@ a gravatar for a given email address." "Return the URL of a gravatar for MAIL-ADDRESS." ;; https://gravatar.com/site/implement/images/ (format "%s/%s?%s" - gravatar-base-url + (funcall (alist-get gravatar-service gravatar-service-alist) + mail-address) (gravatar-hash mail-address) (gravatar--query-string)))