Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs

This commit is contained in:
Eli Zaretskii 2020-03-25 15:59:19 +02:00
commit b85d29f4fd
4 changed files with 73 additions and 21 deletions

View file

@ -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).
@ -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
@ -186,6 +190,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

View file

@ -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)

View file

@ -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
(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."
@ -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)))

View file

@ -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