Merge remote-tracking branch 'savannah/master' into HEAD

This commit is contained in:
Andrea Corallo 2020-05-09 14:06:55 +01:00
commit c6eb276076
14 changed files with 329 additions and 63 deletions

View file

@ -2926,7 +2926,8 @@ specifies your default browser.
@vindex browse-url-handlers @vindex browse-url-handlers
You can define that certain URLs are browsed with other functions by You can define that certain URLs are browsed with other functions by
customizing @code{browse-url-handlers}, an alist of regular 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 For more information, view the package commentary by typing @kbd{C-h P
browse-url @key{RET}}. browse-url @key{RET}}.

View file

@ -6395,6 +6395,26 @@ function is the same as specifying a list @code{(c-lineup-assignments
@comment ------------------------------------------------------------ @comment ------------------------------------------------------------
@defun c-lineup-ternary-bodies
@findex lineup-ternary-bodies @r{(c-)}
Line up true and false branches of a ternary operator
(i.e. @code{?:}). More precisely, if the line starts with a colon
which is a part of a said operator it with corresponding question
mark. For example:
@example
@group
return arg % 2 == 0 ? arg / 2
: (3 * arg + 1); @hereFn{c-lineup-ternary-bodies}
@end group
@end example
@workswith @code{arglist-cont}, @code{arglist-cont-nonempty} and
@code{statement-cont}.
@end defun
@comment ------------------------------------------------------------
@defun c-lineup-cascaded-calls @defun c-lineup-cascaded-calls
@findex lineup-cascaded-calls @r{(c-)} @findex lineup-cascaded-calls @r{(c-)}
Line up ``cascaded calls'' under each other. If the line begins with Line up ``cascaded calls'' under each other. If the line begins with

View file

@ -305,21 +305,48 @@ use doxygen by default one might evaluate:
or use it in a custom c-style. or use it in a custom c-style.
*** Added support to line up ? and : of a ternary operator.
The new c-lineup-ternary-bodies function can be used as a lineup
function to align question mark and colon which are part of a ternary
operator (?:). For example:
return arg % 2 == 0 ? arg / 2
: (3 * arg + 1);
To enable, add it to appropriate entries in c-offsets-alist, e.g.:
(c-set-offset 'arglist-cont '(c-lineup-ternary-bodies
c-lineup-gcc-asm-reg))
(c-set-offset 'arglist-cont-nonempty '(c-lineup-ternary-bodies
c-lineup-gcc-asm-reg
c-lineup-arglist))
(c-set-offset 'statement-cont '(c-lineup-ternary-bodies +))
** browse-url ** browse-url
*** Added support for custom URL handlers *** Added support for custom URL handlers
There is a new defvar 'browse-url-default-handlers' and a defcustom There is a new defvar 'browse-url-default-handlers' and a defcustom
'browse-url-handlers' being alists with (REGEXP . FUNCTION) entries 'browse-url-handlers' being alists with (REGEXP-OR-PREDICATE
allowing to define different browsing FUNCTIONs depending on the URL . FUNCTION) entries allowing to define different browsing FUNCTIONs
to be browsed. The defvar is for default handlers provided by Emacs depending on the URL to be browsed. The defvar is for default
itself or external packages, the defcustom is for the user (and allows handlers provided by Emacs itself or external packages, the defcustom
for overriding the default handlers). is for the user (and allows for overriding the default handlers).
Formerly, one could do the same by setting Formerly, one could do the same by setting
'browse-url-browser-function' to such an alist. This usage is still 'browse-url-browser-function' to such an alist. This usage is still
supported but deprecated. 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 * New Modes and Packages in Emacs 28.1

View file

@ -469,10 +469,12 @@ return t."
;; POS is a mouse event; switch to the proper window/buffer ;; POS is a mouse event; switch to the proper window/buffer
(let ((posn (event-start pos))) (let ((posn (event-start pos)))
(with-current-buffer (window-buffer (posn-window posn)) (with-current-buffer (window-buffer (posn-window posn))
(if (posn-string posn) (let* ((str (posn-string posn))
;; mode-line, header-line, or display string event. (str-button (and str (get-text-property (cdr str) 'button (car str)))))
(button-activate (posn-string posn) t) (if str-button
(push-button (posn-point posn) t)))) ;; mode-line, header-line, or display string event.
(button-activate str t)
(push-button (posn-point posn) t)))))
;; POS is just normal position ;; POS is just normal position
(let ((button (button-at (or pos (point))))) (let ((button (button-at (or pos (point)))))
(when button (when button

View file

@ -101,7 +101,10 @@ is what has been dropped. Returns ACTION."
(throw 'done t))) (throw 'done t)))
nil) nil)
(catch 'done (catch 'done
(let ((browser (browse-url-select-handler url))) ;; Autoloaded but the byte-compiler still complains.
(declare-function browse-url-select-handler "browse-url"
(url &optional kind))
(let ((browser (browse-url-select-handler url 'internal)))
(when browser (when browser
(setq ret 'private) (setq ret 'private)
(funcall browser url action) (funcall browser url action)

View file

@ -1317,13 +1317,12 @@ For more details, see Info node `(cl)Loop Facility'.
((memq word '(across across-ref)) ((memq word '(across across-ref))
(let ((temp-vec (make-symbol "--cl-vec--")) (let ((temp-vec (make-symbol "--cl-vec--"))
(temp-len (make-symbol "--cl-len--"))
(temp-idx (make-symbol "--cl-idx--"))) (temp-idx (make-symbol "--cl-idx--")))
(push (list temp-vec (pop cl--loop-args)) loop-for-bindings) (push (list temp-vec (pop cl--loop-args)) loop-for-bindings)
(push (list temp-len `(length ,temp-vec)) loop-for-bindings)
(push (list temp-idx -1) loop-for-bindings) (push (list temp-idx -1) loop-for-bindings)
(push `(setq ,temp-idx (1+ ,temp-idx)) cl--loop-body)
(cl--push-clause-loop-body (cl--push-clause-loop-body
`(< (setq ,temp-idx (1+ ,temp-idx)) ,temp-len)) `(< ,temp-idx (length ,temp-vec)))
(if (eq word 'across-ref) (if (eq word 'across-ref)
(push (list var `(aref ,temp-vec ,temp-idx)) (push (list var `(aref ,temp-vec ,temp-idx))
cl--loop-symbol-macs) cl--loop-symbol-macs)
@ -1337,7 +1336,6 @@ For more details, see Info node `(cl)Loop Facility'.
(error "Expected `of'")))) (error "Expected `of'"))))
(seq (cl--pop2 cl--loop-args)) (seq (cl--pop2 cl--loop-args))
(temp-seq (make-symbol "--cl-seq--")) (temp-seq (make-symbol "--cl-seq--"))
(temp-len (make-symbol "--cl-len--"))
(temp-idx (temp-idx
(if (eq (car cl--loop-args) 'using) (if (eq (car cl--loop-args) 'using)
(if (and (= (length (cadr cl--loop-args)) 2) (if (and (= (length (cadr cl--loop-args)) 2)
@ -1348,19 +1346,16 @@ For more details, see Info node `(cl)Loop Facility'.
(push (list temp-seq seq) loop-for-bindings) (push (list temp-seq seq) loop-for-bindings)
(push (list temp-idx 0) loop-for-bindings) (push (list temp-idx 0) loop-for-bindings)
(if ref (if ref
(progn (let ((temp-len (make-symbol "--cl-len--")))
(push (list temp-len `(length ,temp-seq)) (push (list temp-len `(length ,temp-seq))
loop-for-bindings) loop-for-bindings)
(push (list var `(elt ,temp-seq ,temp-idx)) (push (list var `(elt ,temp-seq ,temp-idx))
cl--loop-symbol-macs) cl--loop-symbol-macs)
(cl--push-clause-loop-body `(< ,temp-idx ,temp-len))) (cl--push-clause-loop-body `(< ,temp-idx ,temp-len)))
;; Evaluate seq length just if needed, that is, when seq is not a cons.
(push (list temp-len (or (consp seq) `(length ,temp-seq)))
loop-for-bindings)
(push (list var nil) loop-for-bindings) (push (list var nil) loop-for-bindings)
(cl--push-clause-loop-body `(and ,temp-seq (cl--push-clause-loop-body `(and ,temp-seq
(or (consp ,temp-seq) (or (consp ,temp-seq)
(< ,temp-idx ,temp-len)))) (< ,temp-idx (length ,temp-seq)))))
(push (list var `(if (consp ,temp-seq) (push (list var `(if (consp ,temp-seq)
(pop ,temp-seq) (pop ,temp-seq)
(aref ,temp-seq ,temp-idx))) (aref ,temp-seq ,temp-idx)))

View file

@ -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 ;; FIXME: `pcase' does not do a good job here of sharing tests&code among
;; various branches. ;; various branches.
`(and (pred eieio-object-p) `(and (pred eieio-object-p)
(app eieio-pcase-slot-index-table ,is) ,@(mapcar (lambda (field)
,@(mapcar (lambda (field) (pcase-exhaustive field
(let* ((name (if (consp field) (car field) field)) (`(,name ,pat)
(pat (if (consp field) (cadr field) field)) `(app (pcase--flip eieio-oref ',name) ,pat))
(i (make-symbol "index"))) ((pred symbolp)
`(and (let (and ,i (pred natnump)) `(app (pcase--flip eieio-oref ',field) ,field))))
(eieio-pcase-slot-index-from-index-table fields))))
,is ',name))
(app (pcase--flip aref ,i) ,pat))))
fields))))
;;; Simple generators, and query functions. None of these would do ;;; Simple generators, and query functions. None of these would do
;; well embedded into an object. ;; well embedded into an object.

View file

@ -119,6 +119,17 @@
;; could be done by setting `browse-url-browser-function' to an alist ;; could be done by setting `browse-url-browser-function' to an alist
;; but this usage is deprecated now. ;; but this usage is deprecated now.
;; All browser functions provided by here have a
;; `browse-url-browser-kind' symbol property set to either `internal'
;; or `external' which determines if they browse the given URL inside
;; Emacs or spawn an external application with it. Some parts of
;; Emacs make use of that, e.g., when an URL is dragged into Emacs, it
;; is not sensible to invoke an external browser with it, so here only
;; internal browsers are considered. Therefore, it is advised to put
;; that property also on custom browser functions.
;; (put 'my-browse-url-in-emacs 'browse-url-browser-kind 'internal)
;; (put 'my-browse-url-externally 'browse-url-browser-kind 'external)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Code: ;;; Code:
@ -593,26 +604,54 @@ down (this *won't* always work)."
"Wrapper command prepended to the Elinks command-line." "Wrapper command prepended to the Elinks command-line."
:type '(repeat (string :tag "Wrapper"))) :type '(repeat (string :tag "Wrapper")))
(defun browse-url--browser-kind (function url)
"Return the browser kind of a browser FUNCTION for URL.
The browser kind is either `internal' (the browser runs inside
Emacs), `external' (the browser is spawned in an external
process), or nil (we don't know)."
(let ((kind (if (symbolp function)
(get function 'browse-url-browser-kind))))
(if (functionp kind)
(funcall kind url)
kind)))
(defun browse-url--mailto (url &rest args) (defun browse-url--mailto (url &rest args)
"Calls `browse-url-mailto-function' with URL and ARGS." "Calls `browse-url-mailto-function' with URL and ARGS."
(funcall browse-url-mailto-function url args)) (funcall browse-url-mailto-function url args))
(defun browse-url--browser-kind-mailto (url)
(browse-url--browser-kind browse-url-mailto-function url))
(put 'browse-url--mailto 'browse-url-browser-kind
#'browse-url--browser-kind-mailto)
(defun browse-url--man (url &rest args) (defun browse-url--man (url &rest args)
"Calls `browse-url-man-function' with URL and ARGS." "Calls `browse-url-man-function' with URL and ARGS."
(funcall browse-url-man-function url args)) (funcall browse-url-man-function url args))
(defun browse-url--browser-kind-man (url)
(browse-url--browser-kind browse-url-man-function url))
(put 'browse-url--man 'browse-url-browser-kind
#'browse-url--browser-kind-man)
(defun browse-url--browser (url &rest args) (defun browse-url--browser (url &rest args)
"Calls `browse-url-browser-function' with URL and ARGS." "Calls `browse-url-browser-function' with URL and ARGS."
(funcall browse-url-browser-function url args)) (funcall browse-url-browser-function url args))
(defun browse-url--browser-kind-browser (url)
(browse-url--browser-kind browse-url-browser-function url))
(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 ;;;###autoload
(defvar browse-url-default-handlers (defvar browse-url-default-handlers
'(("\\`mailto:" . browse-url--mailto) '(("\\`mailto:" . browse-url--mailto)
("\\`man:" . browse-url--man) ("\\`man:" . browse-url--man)
;; Render file:// URLs if they are HTML pages, otherwise just find (browse-url--non-html-file-url-p . browse-url-emacs))
;; the file.
("\\`file://.*\\.html?\\b" . browse-url--browser)
("\\`file://" . browse-url-emacs))
"Like `browse-url-handlers' but populated by Emacs and packages. "Like `browse-url-handlers' but populated by Emacs and packages.
Emacs and external packages capable of browsing certain URLs Emacs and external packages capable of browsing certain URLs
@ -620,46 +659,60 @@ should place their entries in this alist rather than
`browse-url-handlers' which is reserved for the user.") `browse-url-handlers' which is reserved for the user.")
(defcustom browse-url-handlers nil (defcustom browse-url-handlers nil
"An alist with elements of the form (REGEXP HANDLER). "An alist with elements of the form (REGEXP-OR-PREDICATE . HANDLER).
Each REGEXP is matched against the URL to be opened in turn and Each REGEXP-OR-PREDICATE is matched against the URL to be opened
the first match's HANDLER is invoked with the URL. in turn and the first match's HANDLER is invoked with the URL.
A HANDLER must be a function with the same arguments as A HANDLER must be a function with the same arguments as
`browse-url'. `browse-url'.
If no REGEXP matches, the same procedure is performed with the If no REGEXP-OR-PREDICATE matches, the same procedure is
value of `browse-url-default-handlers'. If there is also no performed with the value of `browse-url-default-handlers'. If
match, the URL is opened using the value of there is also no match, the URL is opened using the value of
`browse-url-browser-function'." `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")) :value-type (function :tag "Handler"))
:version "28.1") :version "28.1")
;;;###autoload ;;;###autoload
(defun browse-url-select-handler (url) (defun browse-url-select-handler (url &optional kind)
"Return a handler suitable for browsing URL. "Return a handler of suitable for browsing URL.
This searches `browse-url-handlers', and This searches `browse-url-handlers', and
`browse-url-default-handlers' for a matching handler. Return nil `browse-url-default-handlers' for a matching handler. Return nil
if no handler is found. if no handler is found.
If KIND is given, the search is restricted to handlers whose
function symbol has the symbol-property `browse-url-browser-kind'
set to KIND.
Currently, it also consults `browse-url-browser-function' first Currently, it also consults `browse-url-browser-function' first
if it is set to an alist, although this usage is deprecated since if it is set to an alist, although this usage is deprecated since
Emacs 28.1 and will be removed in a future release." Emacs 28.1 and will be removed in a future release."
(catch 'custom-url-handler (catch 'custom-url-handler
(dolist (regex-handler (dolist (rxpred-handler
(append (append
;; The alist choice of browse-url-browser-function ;; The alist choice of browse-url-browser-function
;; is deprecated since 28.1, so the (unless ...) ;; is deprecated since 28.1, so the (unless ...)
;; can be removed at some point in time. ;; can be removed at some point in time.
(when (and (consp browse-url-browser-function) (when (and (consp browse-url-browser-function)
(not (functionp browse-url-browser-function))) (not (functionp browse-url-browser-function)))
(warn "Having `browse-url-browser-function' set to an (lwarn 'browse-url :warning
"Having `browse-url-browser-function' set to an
alist is deprecated. Use `browse-url-handlers' instead.") alist is deprecated. Use `browse-url-handlers' instead.")
browse-url-browser-function) browse-url-browser-function)
browse-url-handlers browse-url-handlers
browse-url-default-handlers)) browse-url-default-handlers))
(when (string-match-p (car regex-handler) url) (let ((rx-or-pred (car rxpred-handler))
(throw 'custom-url-handler (cdr regex-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 ;; URL encoding
@ -864,7 +917,7 @@ If ARGS are omitted, the default is to pass
;; which may not even exist any more. ;; which may not even exist any more.
(if (stringp (frame-parameter nil 'display)) (if (stringp (frame-parameter nil 'display))
(setenv "DISPLAY" (frame-parameter nil 'display))) (setenv "DISPLAY" (frame-parameter nil 'display)))
(if (functionp nil) (if (functionp function)
(apply function url args) (apply function url args)
(error "No suitable browser for URL %s" url)))) (error "No suitable browser for URL %s" url))))
@ -882,6 +935,34 @@ Optional prefix argument ARG non-nil inverts the value of the option
browse-url-new-window-flag)) browse-url-new-window-flag))
(error "No URL found")))) (error "No URL found"))))
;;;###autoload
(defun browse-url-with-browser-kind (kind url &optional arg)
"Browse URL with a browser of the given browser KIND.
KIND is either `internal' or `external'.
When called interactively, the default browser kind is the
opposite of the browser kind of `browse-url-browser-function'."
(interactive
(let* ((url-arg (browse-url-interactive-arg "URL: "))
;; Default to the inverse kind of the default browser.
(default (if (eq (browse-url--browser-kind
browse-url-browser-function (car url-arg))
'internal)
'external
'internal))
(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
(setq function (if (eq kind 'external)
#'browse-url-default-browser
#'eww)))
(funcall function url arg)))
;;;###autoload ;;;###autoload
(defun browse-url-at-mouse (event) (defun browse-url-at-mouse (event)
"Ask a WWW browser to load a URL clicked with the mouse. "Ask a WWW browser to load a URL clicked with the mouse.
@ -929,12 +1010,18 @@ The optional NEW-WINDOW argument is not used."
(url-unhex-string url) (url-unhex-string url)
url))))) url)))))
(put 'browse-url-default-windows-browser 'browse-url-browser-kind
'external)
(defun browse-url-default-macosx-browser (url &optional _new-window) (defun browse-url-default-macosx-browser (url &optional _new-window)
"Invoke the macOS system's default Web browser. "Invoke the macOS system's default Web browser.
The optional NEW-WINDOW argument is not used." The optional NEW-WINDOW argument is not used."
(interactive (browse-url-interactive-arg "URL: ")) (interactive (browse-url-interactive-arg "URL: "))
(start-process (concat "open " url) nil "open" url)) (start-process (concat "open " url) nil "open" url))
(put 'browse-url-default-macosx-browser 'browse-url-browser-kind
'external)
;; --- Netscape --- ;; --- Netscape ---
(defun browse-url-process-environment () (defun browse-url-process-environment ()
@ -991,6 +1078,10 @@ instead of `browse-url-new-window-flag'."
(lambda (&rest _ignore) (error "No usable browser found")))) (lambda (&rest _ignore) (error "No usable browser found"))))
url args)) url args))
(put 'browse-url-default-browser 'browse-url-browser-kind
;; Well, most probably external if we ignore w3.
'external)
(defun browse-url-can-use-xdg-open () (defun browse-url-can-use-xdg-open ()
"Return non-nil if the \"xdg-open\" program can be used. "Return non-nil if the \"xdg-open\" program can be used.
xdg-open is a desktop utility that calls your preferred web browser." xdg-open is a desktop utility that calls your preferred web browser."
@ -1010,6 +1101,8 @@ The optional argument IGNORED is not used."
(interactive (browse-url-interactive-arg "URL: ")) (interactive (browse-url-interactive-arg "URL: "))
(call-process "xdg-open" nil 0 nil url)) (call-process "xdg-open" nil 0 nil url))
(put 'browse-url-xdg-open 'browse-url-browser-kind 'external)
;;;###autoload ;;;###autoload
(defun browse-url-netscape (url &optional new-window) (defun browse-url-netscape (url &optional new-window)
"Ask the Netscape WWW browser to load URL. "Ask the Netscape WWW browser to load URL.
@ -1053,6 +1146,8 @@ used instead of `browse-url-new-window-flag'."
`(lambda (process change) `(lambda (process change)
(browse-url-netscape-sentinel process ,url))))) (browse-url-netscape-sentinel process ,url)))))
(put 'browse-url-netscape 'browse-url-browser-kind 'external)
(defun browse-url-netscape-sentinel (process url) (defun browse-url-netscape-sentinel (process url)
"Handle a change to the process communicating with Netscape." "Handle a change to the process communicating with Netscape."
(declare (obsolete nil "25.1")) (declare (obsolete nil "25.1"))
@ -1123,6 +1218,8 @@ used instead of `browse-url-new-window-flag'."
`(lambda (process change) `(lambda (process change)
(browse-url-mozilla-sentinel process ,url))))) (browse-url-mozilla-sentinel process ,url)))))
(put 'browse-url-mozilla 'browse-url-browser-kind 'external)
(defun browse-url-mozilla-sentinel (process url) (defun browse-url-mozilla-sentinel (process url)
"Handle a change to the process communicating with Mozilla." "Handle a change to the process communicating with Mozilla."
(or (eq (process-exit-status process) 0) (or (eq (process-exit-status process) 0)
@ -1163,6 +1260,8 @@ instead of `browse-url-new-window-flag'."
'("-new-window"))) '("-new-window")))
(list url))))) (list url)))))
(put 'browse-url-firefox 'browse-url-browser-kind 'external)
;;;###autoload ;;;###autoload
(defun browse-url-chromium (url &optional _new-window) (defun browse-url-chromium (url &optional _new-window)
"Ask the Chromium WWW browser to load URL. "Ask the Chromium WWW browser to load URL.
@ -1180,6 +1279,8 @@ The optional argument NEW-WINDOW is not used."
browse-url-chromium-arguments browse-url-chromium-arguments
(list url))))) (list url)))))
(put 'browse-url-chromium 'browse-url-browser-kind 'external)
(defun browse-url-chrome (url &optional _new-window) (defun browse-url-chrome (url &optional _new-window)
"Ask the Google Chrome WWW browser to load URL. "Ask the Google Chrome WWW browser to load URL.
Default to the URL around or before point. The strings in Default to the URL around or before point. The strings in
@ -1196,6 +1297,8 @@ The optional argument NEW-WINDOW is not used."
browse-url-chrome-arguments browse-url-chrome-arguments
(list url))))) (list url)))))
(put 'browse-url-chrome 'browse-url-browser-kind 'external)
;;;###autoload ;;;###autoload
(defun browse-url-galeon (url &optional new-window) (defun browse-url-galeon (url &optional new-window)
"Ask the Galeon WWW browser to load URL. "Ask the Galeon WWW browser to load URL.
@ -1233,6 +1336,8 @@ used instead of `browse-url-new-window-flag'."
`(lambda (process change) `(lambda (process change)
(browse-url-galeon-sentinel process ,url))))) (browse-url-galeon-sentinel process ,url)))))
(put 'browse-url-galeon 'browse-url-browser-kind 'external)
(defun browse-url-galeon-sentinel (process url) (defun browse-url-galeon-sentinel (process url)
"Handle a change to the process communicating with Galeon." "Handle a change to the process communicating with Galeon."
(declare (obsolete nil "25.1")) (declare (obsolete nil "25.1"))
@ -1279,6 +1384,8 @@ used instead of `browse-url-new-window-flag'."
`(lambda (process change) `(lambda (process change)
(browse-url-epiphany-sentinel process ,url))))) (browse-url-epiphany-sentinel process ,url)))))
(put 'browse-url-epiphany 'browse-url-browser-kind 'external)
(defun browse-url-epiphany-sentinel (process url) (defun browse-url-epiphany-sentinel (process url)
"Handle a change to the process communicating with Epiphany." "Handle a change to the process communicating with Epiphany."
(or (eq (process-exit-status process) 0) (or (eq (process-exit-status process) 0)
@ -1303,6 +1410,8 @@ currently selected window instead."
file-name-handler-alist))) file-name-handler-alist)))
(if same-window (find-file url) (find-file-other-window url)))) (if same-window (find-file url) (find-file-other-window url))))
(put 'browse-url-emacs 'browse-url-browser-kind 'internal)
;;;###autoload ;;;###autoload
(defun browse-url-gnome-moz (url &optional new-window) (defun browse-url-gnome-moz (url &optional new-window)
"Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'. "Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'.
@ -1327,6 +1436,8 @@ used instead of `browse-url-new-window-flag'."
'("--newwin")) '("--newwin"))
(list "--raise" url)))) (list "--raise" url))))
(put 'browse-url-gnome-moz 'browse-url-browser-kind 'external)
;; --- Mosaic --- ;; --- Mosaic ---
;;;###autoload ;;;###autoload
@ -1378,6 +1489,8 @@ used instead of `browse-url-new-window-flag'."
(append browse-url-mosaic-arguments (list url))) (append browse-url-mosaic-arguments (list url)))
(message "Starting %s...done" browse-url-mosaic-program)))) (message "Starting %s...done" browse-url-mosaic-program))))
(put 'browse-url-mosaic 'browse-url-browser-kind 'external)
;; --- Mosaic using CCI --- ;; --- Mosaic using CCI ---
;;;###autoload ;;;###autoload
@ -1410,6 +1523,8 @@ used instead of `browse-url-new-window-flag'."
(process-send-string "browse-url" "disconnect\r\n") (process-send-string "browse-url" "disconnect\r\n")
(delete-process "browse-url")) (delete-process "browse-url"))
(put 'browse-url-cci 'browse-url-browser-kind 'external)
;; --- Conkeror --- ;; --- Conkeror ---
;;;###autoload ;;;###autoload
(defun browse-url-conkeror (url &optional new-window) (defun browse-url-conkeror (url &optional new-window)
@ -1446,6 +1561,9 @@ NEW-WINDOW instead of `browse-url-new-window-flag'."
"window") "window")
"buffer") "buffer")
url)))))) url))))))
(put 'browse-url-conkeror 'browse-url-browser-kind 'external)
;; --- W3 --- ;; --- W3 ---
;; External. ;; External.
@ -1469,6 +1587,8 @@ used instead of `browse-url-new-window-flag'."
(w3-fetch-other-window url) (w3-fetch-other-window url)
(w3-fetch url))) (w3-fetch url)))
(put 'browse-url-w3 'browse-url-browser-kind 'internal)
;;;###autoload ;;;###autoload
(defun browse-url-w3-gnudoit (url &optional _new-window) (defun browse-url-w3-gnudoit (url &optional _new-window)
;; new-window ignored ;; new-window ignored
@ -1483,6 +1603,8 @@ The `browse-url-gnudoit-program' program is used with options given by
(list (concat "(w3-fetch \"" url "\")") (list (concat "(w3-fetch \"" url "\")")
"(raise-frame)")))) "(raise-frame)"))))
(put 'browse-url-w3-gnudoit 'browse-url-browser-kind 'internal)
;; --- Lynx in an xterm --- ;; --- Lynx in an xterm ---
;;;###autoload ;;;###autoload
@ -1500,6 +1622,8 @@ The optional argument NEW-WINDOW is not used."
,@browse-url-xterm-args "-e" ,browse-url-text-browser ,@browse-url-xterm-args "-e" ,browse-url-text-browser
,url))) ,url)))
(put 'browse-url-text-xterm 'browse-url-browser-kind 'external)
;; --- Lynx in an Emacs "term" window --- ;; --- Lynx in an Emacs "term" window ---
(declare-function term-char-mode "term" ()) (declare-function term-char-mode "term" ())
@ -1574,6 +1698,8 @@ used instead of `browse-url-new-window-flag'."
url url
"\r"))))) "\r")))))
(put 'browse-url-text-emacs 'browse-url-browser-kind 'internal)
;; --- mailto --- ;; --- mailto ---
(autoload 'rfc2368-parse-mailto-url "rfc2368") (autoload 'rfc2368-parse-mailto-url "rfc2368")
@ -1621,6 +1747,8 @@ used instead of `browse-url-new-window-flag'."
(unless (bolp) (unless (bolp)
(insert "\n")))))))) (insert "\n"))))))))
(put 'browse-url-mail 'browse-url-browser-kind 'internal)
;; --- man --- ;; --- man ---
(defvar manual-program) (defvar manual-program)
@ -1632,7 +1760,9 @@ used instead of `browse-url-new-window-flag'."
(setq url (replace-regexp-in-string "\\`man:" "" url)) (setq url (replace-regexp-in-string "\\`man:" "" url))
(cond (cond
((executable-find manual-program) (man url)) ((executable-find manual-program) (man url))
(t (woman (replace-regexp-in-string "([[:alnum:]]+)" "" url))))) (t (woman (replace-regexp-in-string "([[:alnum:]]+)" "" url)))))
(put 'browse-url-man 'browse-url-browser-kind 'internal)
;; --- Random browser --- ;; --- Random browser ---
@ -1651,6 +1781,8 @@ don't offer a form of remote control."
0 nil 0 nil
(append browse-url-generic-args (list url)))) (append browse-url-generic-args (list url))))
(put 'browse-url-generic 'browse-url-browser-kind 'external)
;;;###autoload ;;;###autoload
(defun browse-url-kde (url &optional _new-window) (defun browse-url-kde (url &optional _new-window)
"Ask the KDE WWW browser to load URL. "Ask the KDE WWW browser to load URL.
@ -1661,6 +1793,8 @@ The optional argument NEW-WINDOW is not used."
(apply #'start-process (concat "KDE " url) nil browse-url-kde-program (apply #'start-process (concat "KDE " url) nil browse-url-kde-program
(append browse-url-kde-args (list url)))) (append browse-url-kde-args (list url))))
(put 'browse-url-kde 'browse-url-browser-kind 'external)
(defun browse-url-elinks-new-window (url) (defun browse-url-elinks-new-window (url)
"Ask the Elinks WWW browser to load URL in a new window." "Ask the Elinks WWW browser to load URL in a new window."
(let ((process-environment (browse-url-process-environment))) (let ((process-environment (browse-url-process-environment)))
@ -1670,6 +1804,8 @@ The optional argument NEW-WINDOW is not used."
browse-url-elinks-wrapper browse-url-elinks-wrapper
(list "elinks" url))))) (list "elinks" url)))))
(put 'browse-url-elinks-new-window 'browse-url-browser-kind 'external)
;;;###autoload ;;;###autoload
(defun browse-url-elinks (url &optional new-window) (defun browse-url-elinks (url &optional new-window)
"Ask the Elinks WWW browser to load URL. "Ask the Elinks WWW browser to load URL.
@ -1691,6 +1827,8 @@ from `browse-url-elinks-wrapper'."
`(lambda (process change) `(lambda (process change)
(browse-url-elinks-sentinel process ,url)))))) (browse-url-elinks-sentinel process ,url))))))
(put 'browse-url-elinks 'browse-url-browser-kind 'external)
(defun browse-url-elinks-sentinel (process url) (defun browse-url-elinks-sentinel (process url)
"Determines if Elinks is running or a new one has to be started." "Determines if Elinks is running or a new one has to be started."
;; Try to determine if an instance is running or if we have to ;; Try to determine if an instance is running or if we have to

View file

@ -310,6 +310,8 @@ the default EWW buffer."
(url-retrieve url 'eww-render (url-retrieve url 'eww-render
(list url nil (current-buffer))))) (list url nil (current-buffer)))))
(put 'eww 'browse-url-browser-kind 'internal)
(defun eww--dwim-expand-url (url) (defun eww--dwim-expand-url (url)
(setq url (string-trim url)) (setq url (string-trim url))
(cond ((string-match-p "\\`file:/" url)) (cond ((string-match-p "\\`file:/" url))

View file

@ -790,6 +790,38 @@ arglist-cont-nonempty."
(or (c-lineup-assignments langelem) (or (c-lineup-assignments langelem)
c-basic-offset)) c-basic-offset))
(defun c-lineup-ternary-bodies (langelem)
"Line up true and false branches of a ternary operator (i.e. ?:).
More precisely, if the line starts with a colon which is a part of
a said operator it with corresponding question mark; otherwise return
nil. For example:
return arg % 2 == 0 ? arg / 2
: (3 * arg + 1); <- c-lineup-ternary-bodies
Works with: arglist-cont, arglist-cont-nonempty and statement-cont.
"
(save-excursion
(back-to-indentation)
(when (and (eq ?: (char-after))
(not (eq ?: (char-after (1+ (point))))))
(let ((limit (c-langelem-pos langelem)) (depth 1))
(catch 'done
(while (c-syntactic-skip-backward "^?:" limit t)
(goto-char (1- (point)))
(cond ((eq (char-after) ??)
;; If weve found a question mark, decrease depth. If were
;; reached zero, weve found the one we were looking for.
(when (zerop (setq depth (1- depth)))
(throw 'done (vector (current-column)))))
((or (eq ?: (char-before)) (eq ?? (char-before)))
;; Step over :: and ?: operators. We dont have to
;; handle ?: here but doing so saves an iteration.
(if (eq (point) limit)
(throw 'done nil)
(goto-char (1- (point)))))
((setq depth (1+ depth)))))))))) ; Otherwise increase depth.
(defun c-lineup-cascaded-calls (langelem) (defun c-lineup-cascaded-calls (langelem)
"Line up \"cascaded calls\" under each other. "Line up \"cascaded calls\" under each other.
If the line begins with \"->\" or \".\" and the preceding line ends If the line begins with \"->\" or \".\" and the preceding line ends

View file

@ -2541,13 +2541,21 @@ Key bindings:
(defconst c-or-c++-mode--regexp (defconst c-or-c++-mode--regexp
(eval-when-compile (eval-when-compile
(let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*")) (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*")
(headers '("string" "string_view" "iostream" "map" "unordered_map"
"set" "unordered_set" "vector" "tuple")))
(concat "^" ws-maybe "\\(?:" (concat "^" ws-maybe "\\(?:"
"using" ws "\\(?:namespace" ws "std;\\|std::\\)" "using" ws "\\(?:namespace" ws
"\\|" "namespace" "\\(:?" ws id "\\)?" ws-maybe "{" "\\|" id "::"
"\\|" "class" ws id ws-maybe "[:{\n]" "\\|" id ws-maybe "=\\)"
"\\|" "template" ws-maybe "<.*>" "\\|" "\\(?:inline" ws "\\)?namespace"
"\\|" "#include" ws-maybe "<\\(?:string\\|iostream\\|map\\)>" "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{"
"\\|" "class" ws id
"\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]"
"\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]"
"\\|" ws-maybe ":\\)"
"\\|" "template" ws-maybe "<.*?>"
"\\|" "#include" ws-maybe "<" (regexp-opt headers) ">"
"\\)"))) "\\)")))
"A regexp applied to C header files to check if they are really C++.") "A regexp applied to C header files to check if they are really C++.")
@ -2563,6 +2571,7 @@ should be used.
This function attempts to use file contents to determine whether This function attempts to use file contents to determine whether
the code is C or C++ and based on that chooses whether to enable the code is C or C++ and based on that chooses whether to enable
`c-mode' or `c++-mode'." `c-mode' or `c++-mode'."
(interactive)
(if (save-excursion (if (save-excursion
(save-restriction (save-restriction
(save-match-data (save-match-data

View file

@ -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. 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 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 In a buffer, scan runs to end of buffer, unless LIMIT is non-nil.
value cannot exceed that.
If the optional fourth argument LIMIT is non-nil, don't search If the optional fourth argument LIMIT is non-nil, don't search
past position LIMIT; return LIMIT if nothing is found before LIMIT. 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'. 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. */)
(Lisp_Object position, Lisp_Object prop, Lisp_Object object, Lisp_Object limit) (Lisp_Object position, Lisp_Object prop, Lisp_Object object, Lisp_Object limit)
{ {
if (STRINGP (object)) if (STRINGP (object))
@ -832,6 +831,9 @@ last valid position in OBJECT. */)
value = Fget_char_property (position, prop, object); value = Fget_char_property (position, prop, object);
if (!EQ (value, initial_value)) if (!EQ (value, initial_value))
break; break;
if (XFIXNAT (position) >= ZV)
break;
} }
position = unbind_to (count, position); position = unbind_to (count, position);

View file

@ -39,6 +39,15 @@
collect (list c b a)) collect (list c b a))
'((4.0 2 1) (8.3 6 5) (10.4 9 8))))) '((4.0 2 1) (8.3 6 5) (10.4 9 8)))))
(ert-deftest cl-macs-loop-and-arrays ()
"Bug#40727"
(should (equal (cl-loop for y = (- (or x 0)) and x across [1 2]
collect (cons x y))
'((1 . 0) (2 . -1))))
(should (equal (cl-loop for x across [1 2] and y = (- (or x 0))
collect (cons x y))
'((1 . 0) (2 . -1)))))
(ert-deftest cl-macs-loop-destructure () (ert-deftest cl-macs-loop-destructure ()
(should (equal (cl-loop for (a b c) in '((1 2 4.0) (5 6 8.3) (8 9 10.4)) (should (equal (cl-loop for (a b c) in '((1 2 4.0) (5 6 8.3) (8 9 10.4))
collect (list c b a)) collect (list c b a))

View file

@ -40,7 +40,7 @@
(insert content) (insert content)
(setq mode nil) (setq mode nil)
(c-or-c++-mode) (c-or-c++-mode)
(unless(eq expected mode) (unless (eq expected mode)
(ert-fail (ert-fail
(format "expected %s but got %s when testing '%s'" (format "expected %s but got %s when testing '%s'"
expected mode content))))) expected mode content)))))
@ -53,11 +53,18 @@
(funcall do-test (concat " * " content) 'c-mode)) (funcall do-test (concat " * " content) 'c-mode))
'("using \t namespace \t std;" '("using \t namespace \t std;"
"using \t std::string;" "using \t std::string;"
"using Foo = Bar;"
"namespace \t {" "namespace \t {"
"namespace \t foo \t {" "namespace \t foo \t {"
"class \t Blah_42 \t {" "namespace \t foo::bar \t {"
"inline namespace \t foo \t {"
"inline namespace \t foo::bar \t {"
"class \t Blah_42 \t \n" "class \t Blah_42 \t \n"
"class \t Blah_42;"
"class \t Blah_42 \t final {"
"struct \t Blah_42 \t final {"
"class \t _42_Blah:public Foo {" "class \t _42_Blah:public Foo {"
"struct \t _42_Blah:public Foo {"
"template \t < class T >" "template \t < class T >"
"template< class T >" "template< class T >"
"#include <string>" "#include <string>"
@ -67,6 +74,7 @@
(mapc (lambda (content) (funcall do-test content 'c-mode)) (mapc (lambda (content) (funcall do-test content 'c-mode))
'("struct \t Blah_42 \t {" '("struct \t Blah_42 \t {"
"struct template {" "struct template {"
"struct Blah;"
"#include <string.h>"))))) "#include <string.h>")))))
(ert-deftest c-mode-macro-comment () (ert-deftest c-mode-macro-comment ()
@ -78,4 +86,25 @@
(insert macro-string) (insert macro-string)
(c-mode)))) (c-mode))))
(ert-deftest c-lineup-ternary-bodies ()
"Test for c-lineup-ternary-bodies function"
(with-temp-buffer
(c-mode)
(let* ((common-prefix "int value = condition ")
(expected-column (length common-prefix)))
(dolist (test '(("? a : \n b" . nil)
("? a \n ::b" . nil)
("a \n : b" . nil)
("? a \n : b" . t)
("? ::a \n : b" . t)
("? (p ? q : r) \n : b" . t)
("? p ?: q \n : b" . t)
("? p ? : q \n : b" . t)
("? p ? q : r \n : b" . t)))
(delete-region (point-min) (point-max))
(insert common-prefix (car test))
(should (equal
(and (cdr test) (vector expected-column))
(c-lineup-ternary-bodies '(statement-cont . 1))))))))
;;; cc-mode-tests.el ends here ;;; cc-mode-tests.el ends here