aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2020-03-25 15:59:19 +0200
committerEli Zaretskii2020-03-25 15:59:19 +0200
commitb85d29f4fd555eda34ffba5b9a6006b5758e2955 (patch)
treea41cac4cced340b143401eb36517b9010a59e122
parented37f038bd6d99fbe0c746d5773c315fed0e3dad (diff)
parentce141686d2d890d9d7c3dd881dc5f9bfb5d6d296 (diff)
downloademacs-b85d29f4fd555eda34ffba5b9a6006b5758e2955.tar.gz
emacs-b85d29f4fd555eda34ffba5b9a6006b5758e2955.zip
Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
-rw-r--r--etc/NEWS16
-rw-r--r--lisp/dired.el33
-rw-r--r--lisp/image/gravatar.el43
-rw-r--r--test/lisp/image/gravatar-tests.el2
4 files changed, 73 insertions, 21 deletions
diff --git a/etc/NEWS b/etc/NEWS
index ba3e691ff91..1be5ad6acc0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -104,8 +104,8 @@ shows equivalent key bindings for all commands that have them.
104*** New option 'dired-mark-region' affects all Dired commands that mark files. 104*** New option 'dired-mark-region' affects all Dired commands that mark files.
105When non-nil and the region is active in Transient Mark mode, 105When non-nil and the region is active in Transient Mark mode,
106then Dired commands operate only on files in the active region. 106then Dired commands operate only on files in the active region.
107The values 'exclusive' and 'inclusive' of this option define 107The values 'file' and 'line' of this option define the details of
108the details of marking the last file at the end of the region. 108marking the file at the end of the region.
109 109
110*** State changing VC operations are supported in dired-mode on files 110*** State changing VC operations are supported in dired-mode on files
111(but still not on directories). 111(but still not on directories).
@@ -114,7 +114,11 @@ the details of marking the last file at the end of the region.
114 114
115--- 115---
116*** Change to default value of 'message-draft-headers' option. 116*** Change to default value of 'message-draft-headers' option.
117No longer includes the Date header. 117The Date header has been removed from the default value, meaning that
118draft or delayed messages will get a Date reflecting when the message
119was sent. To restore the original behavior of dating a message
120from when it is first saved or delayed, add the symbol 'Date back to
121this option.
118 122
119** Help 123** Help
120 124
@@ -186,6 +190,12 @@ key binding
186/ v package-menu-filter-by-version 190/ v package-menu-filter-by-version
187/ / package-menu-filter-clear 191/ / package-menu-filter-clear
188 192
193** Gravatar
194
195---
196*** New user option 'gravatar-service' for host to query for gravatars.
197Defaults to Libravatar, with Unicornify and Gravatar as options.
198
189 199
190* New Modes and Packages in Emacs 28.1 200* New Modes and Packages in Emacs 28.1
191 201
diff --git a/lisp/dired.el b/lisp/dired.el
index 438f5e7d8b4..41bbf9f56a2 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -296,7 +296,7 @@ new Dired buffers."
296 :version "26.1" 296 :version "26.1"
297 :group 'dired) 297 :group 'dired)
298 298
299(defcustom dired-mark-region 'exclusive 299(defcustom dired-mark-region 'file
300 "Defines what commands that mark files do with the active region. 300 "Defines what commands that mark files do with the active region.
301 301
302When nil, marking commands don't operate on all files in the 302When 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
306that mark or unmark files will operate on all files in the region 306that mark or unmark files will operate on all files in the region
307if the region is active in Transient Mark mode. 307if the region is active in Transient Mark mode.
308 308
309When `exclusive', don't mark the file if the end of the region is 309When `file', the region marking is based on the file name.
310This means don't mark the file if the end of the region is
310before the file name displayed on the Dired line, so the file name 311before the file name displayed on the Dired line, so the file name
311is visually outside the region. This behavior is consistent with 312is visually outside the region. This behavior is consistent with
312marking files without the region using the key `m' that advances 313marking 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
315used to select the region, e.g. `M-2 m' marks 2 files, and 316used to select the region, e.g. `M-2 m' marks 2 files, and
316`C-SPC M-2 n m' marks 2 files, and `M-2 S-down m' marks 2 files. 317`C-SPC M-2 n m' marks 2 files, and `M-2 S-down m' marks 2 files.
317 318
318When `inclusive', include the file into marking if the end of the region 319When `line', the region marking is based on Dired lines,
320so include the file into marking if the end of the region
319is anywhere on its Dired line, except the beginning of the line." 321is anywhere on its Dired line, except the beginning of the line."
320 :type '(choice 322 :type '(choice
321 (const :tag "Don't mark files in active region" nil) 323 (const :tag "Don't mark files in active region" nil)
322 (const :tag "Exclude file name outside of region" exclusive) 324 (const :tag "Exclude file name outside of region" file)
323 (const :tag "Include the file at region end line" inclusive)) 325 (const :tag "Include the file at region end line" line))
324 :group 'dired 326 :group 'dired
325 :version "28.1") 327 :version "28.1")
326 328
@@ -646,16 +648,19 @@ of the region if `dired-mark-region' is non-nil. Otherwise, operate
646on the whole buffer. 648on the whole buffer.
647 649
648Return value is the number of files marked, or nil if none were marked." 650Return value is the number of files marked, or nil if none were marked."
649 `(let ((inhibit-read-only t) count 651 `(let* ((inhibit-read-only t) count
650 (beg (if (and dired-mark-region (use-region-p)) 652 (use-region-p (and dired-mark-region
653 (region-active-p)
654 (> (region-end) (region-beginning))))
655 (beg (if use-region-p
651 (save-excursion 656 (save-excursion
652 (goto-char (region-beginning)) 657 (goto-char (region-beginning))
653 (line-beginning-position)) 658 (line-beginning-position))
654 (point-min))) 659 (point-min)))
655 (end (if (and dired-mark-region (use-region-p)) 660 (end (if use-region-p
656 (save-excursion 661 (save-excursion
657 (goto-char (region-end)) 662 (goto-char (region-end))
658 (if (if (eq dired-mark-region 'inclusive) 663 (if (if (eq dired-mark-region 'line)
659 (not (bolp)) 664 (not (bolp))
660 (get-text-property (1- (point)) 'dired-filename)) 665 (get-text-property (1- (point)) 'dired-filename))
661 (line-end-position) 666 (line-end-position)
@@ -673,7 +678,7 @@ Return value is the number of files marked, or nil if none were marked."
673 (if (eq dired-del-marker dired-marker-char) 678 (if (eq dired-del-marker dired-marker-char)
674 " for deletion" 679 " for deletion"
675 "") 680 "")
676 (if (and dired-mark-region (use-region-p)) 681 (if use-region-p
677 " in region" 682 " in region"
678 ""))) 683 "")))
679 (goto-char beg) 684 (goto-char beg)
@@ -691,7 +696,7 @@ Return value is the number of files marked, or nil if none were marked."
691 (if (eq dired-marker-char ?\s) "un" "") 696 (if (eq dired-marker-char ?\s) "un" "")
692 (if (eq dired-marker-char dired-del-marker) 697 (if (eq dired-marker-char dired-del-marker)
693 "flagged" "marked") 698 "flagged" "marked")
694 (if (and dired-mark-region (use-region-p)) 699 (if use-region-p
695 " in region" 700 " in region"
696 "")))) 701 ""))))
697 (and (> count 0) count))) 702 (and (> count 0) count)))
@@ -3645,14 +3650,16 @@ this subdir."
3645 (interactive (list current-prefix-arg t)) 3650 (interactive (list current-prefix-arg t))
3646 (cond 3651 (cond
3647 ;; Mark files in the active region. 3652 ;; Mark files in the active region.
3648 ((and dired-mark-region interactive (use-region-p)) 3653 ((and interactive dired-mark-region
3654 (region-active-p)
3655 (> (region-end) (region-beginning)))
3649 (save-excursion 3656 (save-excursion
3650 (let ((beg (region-beginning)) 3657 (let ((beg (region-beginning))
3651 (end (region-end))) 3658 (end (region-end)))
3652 (dired-mark-files-in-region 3659 (dired-mark-files-in-region
3653 (progn (goto-char beg) (line-beginning-position)) 3660 (progn (goto-char beg) (line-beginning-position))
3654 (progn (goto-char end) 3661 (progn (goto-char end)
3655 (if (if (eq dired-mark-region 'inclusive) 3662 (if (if (eq dired-mark-region 'line)
3656 (not (bolp)) 3663 (not (bolp))
3657 (get-text-property (1- (point)) 'dired-filename)) 3664 (get-text-property (1- (point)) 'dired-filename))
3658 (line-end-position) 3665 (line-end-position)
diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index b8542bc3c35..ff59a72ac87 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -26,6 +26,7 @@
26 26
27(require 'url) 27(require 'url)
28(require 'url-cache) 28(require 'url-cache)
29(require 'dns)
29(eval-when-compile 30(eval-when-compile
30 (require 'subr-x)) 31 (require 'subr-x))
31 32
@@ -118,9 +119,42 @@ a gravatar for a given email address."
118 :version "27.1" 119 :version "27.1"
119 :group 'gravatar) 120 :group 'gravatar)
120 121
121(defconst gravatar-base-url 122(defconst gravatar-service-alist
122 "https://www.gravatar.com/avatar" 123 `((gravatar . ,(lambda (_addr) "https://www.gravatar.com/avatar"))
123 "Base URL for getting gravatars.") 124 (unicornify . ,(lambda (_addr) "https://unicornify.pictures/avatar/"))
125 (libravatar . ,#'gravatar--service-libravatar))
126 "Alist of supported gravatar services.")
127
128(defcustom gravatar-service 'libravatar
129 "Symbol denoting gravatar-like service to use.
130Note that certain services might ignore other options, such as
131`gravatar-default-image' or certain values as with
132`gravatar-rating'."
133 :type `(choice ,@(mapcar (lambda (s) `(const ,(car s)))
134 gravatar-service-alist))
135 :version "28.1"
136 :link '(url-link "https://www.libravatar.org/")
137 :link '(url-link "https://unicornify.pictures/")
138 :link '(url-link "https://gravatar.com/")
139 :group 'gravatar)
140
141(defun gravatar--service-libravatar (addr)
142 "Find domain that hosts avatars for email address ADDR."
143 ;; implements https://wiki.libravatar.org/api/
144 (save-match-data
145 (if (not (string-match ".+@\\(.+\\)" addr))
146 "https://seccdn.libravatar.org/avatar"
147 (let ((domain (match-string 1 addr)))
148 (catch 'found
149 (dolist (record '(("_avatars-sec" . "https")
150 ("_avatars" . "http")))
151 (let* ((query (concat (car record) "._tcp." domain))
152 (result (dns-query query 'SRV)))
153 (when result
154 (throw 'found (format "%s://%s/avatar"
155 (cdr record)
156 result)))))
157 "https://seccdn.libravatar.org/avatar")))))
124 158
125(defun gravatar-hash (mail-address) 159(defun gravatar-hash (mail-address)
126 "Return the Gravatar hash for MAIL-ADDRESS." 160 "Return the Gravatar hash for MAIL-ADDRESS."
@@ -142,7 +176,8 @@ a gravatar for a given email address."
142 "Return the URL of a gravatar for MAIL-ADDRESS." 176 "Return the URL of a gravatar for MAIL-ADDRESS."
143 ;; https://gravatar.com/site/implement/images/ 177 ;; https://gravatar.com/site/implement/images/
144 (format "%s/%s?%s" 178 (format "%s/%s?%s"
145 gravatar-base-url 179 (funcall (alist-get gravatar-service gravatar-service-alist)
180 mail-address)
146 (gravatar-hash mail-address) 181 (gravatar-hash mail-address)
147 (gravatar--query-string))) 182 (gravatar--query-string)))
148 183
diff --git a/test/lisp/image/gravatar-tests.el b/test/lisp/image/gravatar-tests.el
index e66b5c6803d..66098fa0116 100644
--- a/test/lisp/image/gravatar-tests.el
+++ b/test/lisp/image/gravatar-tests.el
@@ -67,6 +67,6 @@
67 (gravatar-force-default nil) 67 (gravatar-force-default nil)
68 (gravatar-size nil)) 68 (gravatar-size nil))
69 (should (equal (gravatar-build-url "foo") "\ 69 (should (equal (gravatar-build-url "foo") "\
70https://www.gravatar.com/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g")))) 70https://seccdn.libravatar.org/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g"))))
71 71
72;;; gravatar-tests.el ends here 72;;; gravatar-tests.el ends here