commit 0bd6ae773a1ade1bdec2c233df4f260d028fd6c5 (HEAD, refs/remotes/origin/master) Author: Clément Pit-Claudel Date: Sun Apr 26 12:41:42 2020 -0400 Only treat display strings as buttons if they have 'button' property * lisp/button.el (push-button): Use 'posn-point' instead of 'posn-string' if the string doesn't have the 'button' property (Bug#40859). diff --git a/lisp/button.el b/lisp/button.el index b3afc4eca2..3a6a6de774 100644 --- a/lisp/button.el +++ b/lisp/button.el @@ -469,10 +469,12 @@ return t." ;; POS is a mouse event; switch to the proper window/buffer (let ((posn (event-start pos))) (with-current-buffer (window-buffer (posn-window posn)) - (if (posn-string posn) - ;; mode-line, header-line, or display string event. - (button-activate (posn-string posn) t) - (push-button (posn-point posn) t)))) + (let* ((str (posn-string posn)) + (str-button (and str (get-text-property (cdr str) 'button (car str))))) + (if str-button + ;; mode-line, header-line, or display string event. + (button-activate str t) + (push-button (posn-point posn) t))))) ;; POS is just normal position (let ((button (button-at (or pos (point))))) (when button commit 1f149cb392ac4ed99dd1ce2da01178ff0490e746 Author: Federico Tedin Date: Sun May 3 15:47:56 2020 +0200 Prevent hanging in next-single-char-property-change * src/textprop.c (Fnext_single_char_property_change): Clarify in the doc string the behavior when LIMIT is past the end of OBJECT. Stop the search when position gets to end of buffer, for when LIMIT is beyond that. (Bug#40000) diff --git a/src/textprop.c b/src/textprop.c index 960dba3f8d..0876badc87 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -766,14 +766,13 @@ the current buffer), POSITION is a buffer position (integer or marker). If OBJECT is a string, POSITION is a 0-based index into it. In a string, scan runs to the end of the string, unless LIMIT is non-nil. -In a buffer, if LIMIT is nil or omitted, it runs to (point-max), and the -value cannot exceed that. +In a buffer, scan runs to end of buffer, unless LIMIT is non-nil. If the optional fourth argument LIMIT is non-nil, don't search past position LIMIT; return LIMIT if nothing is found before LIMIT. +However, if OBJECT is a buffer and LIMIT is beyond the end of the +buffer, this function returns `point-max', not LIMIT. -The property values are compared with `eq'. -If the property is constant all the way to the end of OBJECT, return the -last valid position in OBJECT. */) +The property values are compared with `eq'. */) (Lisp_Object position, Lisp_Object prop, Lisp_Object object, Lisp_Object limit) { if (STRINGP (object)) @@ -832,6 +831,9 @@ last valid position in OBJECT. */) value = Fget_char_property (position, prop, object); if (!EQ (value, initial_value)) break; + + if (XFIXNAT (position) >= ZV) + break; } position = unbind_to (count, position); commit 0d861f25b288d23368cc7522eb56654724fd758d Author: Tassilo Horn Date: Fri May 8 21:07:56 2020 +0200 Fix reading kind argument in browse-url-with-browser-kind. * lisp/net/browse-url.el (browse-url-with-browser-kind): Convert KIND argument queried from the user to a symbol. diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 9073f89683..f88de98fca 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -950,11 +950,11 @@ opposite of the browser kind of `browse-url-browser-function'." 'internal) 'external 'internal)) - (k (completing-read - (format "Browser kind (default %s): " default) - '(internal external) - nil t nil nil - default))) + (k (intern (completing-read + (format "Browser kind (default %s): " default) + '(internal external) + nil t nil nil + default)))) (cons k url-arg))) (let ((function (browse-url-select-handler url kind))) (unless function commit 909591a4b25901392686f1cf68870260d3016afe Author: Tassilo Horn Date: Fri May 8 20:57:19 2020 +0200 Allow predicates for matching in browse-url-handlers. * lisp/net/browse-url.el (browse-url-handlers): Allow predicates for matching in browse-url-handlers. Adapt docs and customize type. (browse-url-select-handler): Support predicates in addition to regexes. (browse-url--non-html-file-url-p): New defun. (browse-url-default-handlers): Use above predicate entry instead of two entries. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index d1854f31ff..1336da12b0 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2926,7 +2926,8 @@ specifies your default browser. @vindex browse-url-handlers You can define that certain URLs are browsed with other functions by customizing @code{browse-url-handlers}, an alist of regular -expressions paired with functions to browse matching URLs. +expressions or predicates paired with functions to browse matching +URLs. For more information, view the package commentary by typing @kbd{C-h P browse-url @key{RET}}. diff --git a/etc/NEWS b/etc/NEWS index ac93a76ff9..9c71752b62 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -310,16 +310,26 @@ or use it in a custom ‘c-style’. *** Added support for custom URL handlers There is a new defvar 'browse-url-default-handlers' and a defcustom -'browse-url-handlers' being alists with (REGEXP . FUNCTION) entries -allowing to define different browsing FUNCTIONs depending on the URL -to be browsed. The defvar is for default handlers provided by Emacs -itself or external packages, the defcustom is for the user (and allows -for overriding the default handlers). +'browse-url-handlers' being alists with (REGEXP-OR-PREDICATE +. FUNCTION) entries allowing to define different browsing FUNCTIONs +depending on the URL to be browsed. The defvar is for default +handlers provided by Emacs itself or external packages, the defcustom +is for the user (and allows for overriding the default handlers). Formerly, one could do the same by setting 'browse-url-browser-function' to such an alist. This usage is still supported but deprecated. +*** Categorization of browsing functions in internal vs. external + +All standard browsing functions such as 'browse-url-firefox', +'browse-url-mail', or 'eww' have been categorized into internal (URL +is browsed in Emacs) or external (an external application is spawned +with the URL). This is done by adding a 'browse-url-browser-kind' +symbol property to the browsing functions. With a new command +'browse-url-with-browser-kind', an URL can explicitly be browsed with +either an internal or external browser. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index d7b8521563..9073f89683 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -642,15 +642,16 @@ process), or nil (we don't know)." (put 'browse-url--browser 'browse-url-browser-kind #'browse-url--browser-kind-browser) +(defun browse-url--non-html-file-url-p (url) + "Return non-nil if URL is a file:// URL of a non-HTML file." + (and (string-match-p "\\`file://" url) + (not (string-match-p "\\`file://.*\\.html?\\b" url)))) ;;;###autoload (defvar browse-url-default-handlers '(("\\`mailto:" . browse-url--mailto) ("\\`man:" . browse-url--man) - ;; Render file:// URLs if they are HTML pages, otherwise just find - ;; the file. - ("\\`file://.*\\.html?\\b" . browse-url--browser) - ("\\`file://" . browse-url-emacs)) + (browse-url--non-html-file-url-p . browse-url-emacs)) "Like `browse-url-handlers' but populated by Emacs and packages. Emacs and external packages capable of browsing certain URLs @@ -658,18 +659,20 @@ should place their entries in this alist rather than `browse-url-handlers' which is reserved for the user.") (defcustom browse-url-handlers nil - "An alist with elements of the form (REGEXP HANDLER). -Each REGEXP is matched against the URL to be opened in turn and -the first match's HANDLER is invoked with the URL. + "An alist with elements of the form (REGEXP-OR-PREDICATE . HANDLER). +Each REGEXP-OR-PREDICATE is matched against the URL to be opened +in turn and the first match's HANDLER is invoked with the URL. A HANDLER must be a function with the same arguments as `browse-url'. -If no REGEXP matches, the same procedure is performed with the -value of `browse-url-default-handlers'. If there is also no -match, the URL is opened using the value of +If no REGEXP-OR-PREDICATE matches, the same procedure is +performed with the value of `browse-url-default-handlers'. If +there is also no match, the URL is opened using the value of `browse-url-browser-function'." - :type '(alist :key-type (regexp :tag "Regexp") + :type '(alist :key-type (choice + (regexp :tag "Regexp") + (function :tag "Predicate")) :value-type (function :tag "Handler")) :version "28.1") @@ -688,7 +691,7 @@ Currently, it also consults `browse-url-browser-function' first if it is set to an alist, although this usage is deprecated since Emacs 28.1 and will be removed in a future release." (catch 'custom-url-handler - (dolist (regex-handler + (dolist (rxpred-handler (append ;; The alist choice of browse-url-browser-function ;; is deprecated since 28.1, so the (unless ...) @@ -701,11 +704,15 @@ alist is deprecated. Use `browse-url-handlers' instead.") browse-url-browser-function) browse-url-handlers browse-url-default-handlers)) - (when (and (or (null kind) - (eq kind (browse-url--browser-kind - (cdr regex-handler) url))) - (string-match-p (car regex-handler) url)) - (throw 'custom-url-handler (cdr regex-handler)))))) + (let ((rx-or-pred (car rxpred-handler)) + (handler (cdr rxpred-handler))) + (when (and (or (null kind) + (eq kind (browse-url--browser-kind + handler url))) + (if (functionp rx-or-pred) + (funcall rx-or-pred url) + (string-match-p rx-or-pred url))) + (throw 'custom-url-handler handler)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; URL encoding commit 39b2a598d27809c524a123fd53db71783693071e Author: Zhu Zihao Date: Fri May 8 17:01:56 2020 +0800 Make pcase pattern 'eieio' respect slot access related functions. * lisp/emacs-lisp/eieio.el: Make pcase pattern respect slot-missing and slot-unbound diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index fe2b80be01..999d75f79e 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -359,16 +359,13 @@ contents of field NAME is matched against PAT, or they can be of ;; FIXME: `pcase' does not do a good job here of sharing tests&code among ;; various branches. `(and (pred eieio-object-p) - (app eieio-pcase-slot-index-table ,is) - ,@(mapcar (lambda (field) - (let* ((name (if (consp field) (car field) field)) - (pat (if (consp field) (cadr field) field)) - (i (make-symbol "index"))) - `(and (let (and ,i (pred natnump)) - (eieio-pcase-slot-index-from-index-table - ,is ',name)) - (app (pcase--flip aref ,i) ,pat)))) - fields)))) + ,@(mapcar (lambda (field) + (pcase-exhaustive field + (`(,name ,pat) + `(app (pcase--flip eieio-oref ',name) ,pat)) + ((pred symbolp) + `(app (pcase--flip eieio-oref ',field) ,field)))) + fields)))) ;;; Simple generators, and query functions. None of these would do ;; well embedded into an object.