emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/native-comp c6eb276 2/2: Merge remote-tracking branch 'savannah/


From: Andrea Corallo
Subject: feature/native-comp c6eb276 2/2: Merge remote-tracking branch 'savannah/master' into HEAD
Date: Sat, 9 May 2020 10:04:01 -0400 (EDT)

branch: feature/native-comp
commit c6eb2760766b402fb620a733d100adfd320e4df5
Merge: 40f655e ae3c510
Author: Andrea Corallo <address@hidden>
Commit: Andrea Corallo <address@hidden>

    Merge remote-tracking branch 'savannah/master' into HEAD
---
 doc/emacs/misc.texi                   |   3 +-
 doc/misc/cc-mode.texi                 |  20 ++++
 etc/NEWS                              |  37 ++++++-
 lisp/button.el                        |  10 +-
 lisp/dnd.el                           |   5 +-
 lisp/emacs-lisp/cl-macs.el            |  15 +--
 lisp/emacs-lisp/eieio.el              |  17 ++--
 lisp/net/browse-url.el                | 176 ++++++++++++++++++++++++++++++----
 lisp/net/eww.el                       |   2 +
 lisp/progmodes/cc-align.el            |  32 +++++++
 lisp/progmodes/cc-mode.el             |  21 ++--
 src/textprop.c                        |  12 ++-
 test/lisp/emacs-lisp/cl-macs-tests.el |   9 ++
 test/lisp/progmodes/cc-mode-tests.el  |  33 ++++++-
 14 files changed, 329 insertions(+), 63 deletions(-)

diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index d1854f3..1336da1 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/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index f9c9f5e..16eac48 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -6395,6 +6395,26 @@ function is the same as specifying a list 
@code{(c-lineup-assignments
 
 @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
 @findex lineup-cascaded-calls @r{(c-)}
 Line up ``cascaded calls'' under each other.  If the line begins with
diff --git a/etc/NEWS b/etc/NEWS
index ac93a76..12406ee 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -305,21 +305,48 @@ use ‘doxygen’ by default one might evaluate:
 
 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
 
 *** 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/button.el b/lisp/button.el
index b3afc4e..3a6a6de 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
diff --git a/lisp/dnd.el b/lisp/dnd.el
index c185794..f47f4a2 100644
--- a/lisp/dnd.el
+++ b/lisp/dnd.el
@@ -101,7 +101,10 @@ is what has been dropped.  Returns ACTION."
           (throw 'done t)))
        nil)
      (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
            (setq ret 'private)
            (funcall browser url action)
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 4408bb5..3317c58 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1317,13 +1317,12 @@ For more details, see Info node `(cl)Loop Facility'.
 
               ((memq word '(across across-ref))
                (let ((temp-vec (make-symbol "--cl-vec--"))
-                      (temp-len (make-symbol "--cl-len--"))
                      (temp-idx (make-symbol "--cl-idx--")))
                  (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 `(setq ,temp-idx (1+ ,temp-idx)) cl--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)
                      (push (list var `(aref ,temp-vec ,temp-idx))
                            cl--loop-symbol-macs)
@@ -1337,7 +1336,6 @@ For more details, see Info node `(cl)Loop Facility'.
                                    (error "Expected `of'"))))
                      (seq (cl--pop2 cl--loop-args))
                      (temp-seq (make-symbol "--cl-seq--"))
-                     (temp-len (make-symbol "--cl-len--"))
                      (temp-idx
                        (if (eq (car cl--loop-args) 'using)
                            (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-idx 0) loop-for-bindings)
                  (if ref
-                      (progn
+                      (let ((temp-len (make-symbol "--cl-len--")))
                        (push (list temp-len `(length ,temp-seq))
                              loop-for-bindings)
                        (push (list var `(elt ,temp-seq ,temp-idx))
                              cl--loop-symbol-macs)
-                       (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)
+                        (cl--push-clause-loop-body `(< ,temp-idx ,temp-len)))
                    (push (list var nil) loop-for-bindings)
                    (cl--push-clause-loop-body `(and ,temp-seq
                                                      (or (consp ,temp-seq)
-                                                         (< ,temp-idx 
,temp-len))))
+                                                         (< ,temp-idx (length 
,temp-seq)))))
                    (push (list var `(if (consp ,temp-seq)
                                          (pop ,temp-seq)
                                        (aref ,temp-seq ,temp-idx)))
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index fe2b80b..999d75f 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.
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index b346653..f88de98 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -119,6 +119,17 @@
 ;; could be done by setting `browse-url-browser-function' to an alist
 ;; 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:
 
@@ -593,26 +604,54 @@ down (this *won't* always work)."
   "Wrapper command prepended to the Elinks command-line."
   :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)
   "Calls `browse-url-mailto-function' with URL and 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)
   "Calls `browse-url-man-function' with URL and 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)
   "Calls `browse-url-browser-function' with URL and 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
 (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
@@ -620,46 +659,60 @@ 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")
 
 ;;;###autoload
-(defun browse-url-select-handler (url)
-  "Return a handler suitable for browsing URL.
+(defun browse-url-select-handler (url &optional kind)
+  "Return a handler of suitable for browsing URL.
 This searches `browse-url-handlers', and
 `browse-url-default-handlers' for a matching handler.  Return nil
 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
 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 ...)
               ;; can be removed at some point in time.
               (when (and (consp 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.")
                 browse-url-browser-function)
               browse-url-handlers
               browse-url-default-handlers))
-      (when (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
@@ -864,7 +917,7 @@ If ARGS are omitted, the default is to pass
     ;; which may not even exist any more.
     (if (stringp (frame-parameter nil 'display))
         (setenv "DISPLAY" (frame-parameter nil 'display)))
-    (if (functionp nil)
+    (if (functionp function)
         (apply function url args)
       (error "No suitable browser for URL %s" url))))
 
@@ -883,6 +936,34 @@ Optional prefix argument ARG non-nil inverts the value of 
the option
       (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
 (defun browse-url-at-mouse (event)
   "Ask a WWW browser to load a URL clicked with the mouse.
 The URL is the one around or before the position of the mouse click
@@ -929,12 +1010,18 @@ The optional NEW-WINDOW argument is not used."
                                 (url-unhex-string url)
                               url)))))
 
+(put 'browse-url-default-windows-browser 'browse-url-browser-kind
+     'external)
+
 (defun browse-url-default-macosx-browser (url &optional _new-window)
   "Invoke the macOS system's default Web browser.
 The optional NEW-WINDOW argument is not used."
   (interactive (browse-url-interactive-arg "URL: "))
   (start-process (concat "open " url) nil "open" url))
 
+(put 'browse-url-default-macosx-browser 'browse-url-browser-kind
+     'external)
+
 ;; --- Netscape ---
 
 (defun browse-url-process-environment ()
@@ -991,6 +1078,10 @@ instead of `browse-url-new-window-flag'."
      (lambda (&rest _ignore) (error "No usable browser found"))))
    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 ()
   "Return non-nil if the \"xdg-open\" program can be used.
 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: "))
   (call-process "xdg-open" nil 0 nil url))
 
+(put 'browse-url-xdg-open 'browse-url-browser-kind 'external)
+
 ;;;###autoload
 (defun browse-url-netscape (url &optional new-window)
   "Ask the Netscape WWW browser to load URL.
@@ -1053,6 +1146,8 @@ used instead of `browse-url-new-window-flag'."
                          `(lambda (process change)
                             (browse-url-netscape-sentinel process ,url)))))
 
+(put 'browse-url-netscape 'browse-url-browser-kind 'external)
+
 (defun browse-url-netscape-sentinel (process url)
   "Handle a change to the process communicating with Netscape."
   (declare (obsolete nil "25.1"))
@@ -1123,6 +1218,8 @@ used instead of `browse-url-new-window-flag'."
                          `(lambda (process change)
                             (browse-url-mozilla-sentinel process ,url)))))
 
+(put 'browse-url-mozilla 'browse-url-browser-kind 'external)
+
 (defun browse-url-mozilla-sentinel (process url)
   "Handle a change to the process communicating with Mozilla."
   (or (eq (process-exit-status process) 0)
@@ -1163,6 +1260,8 @@ instead of `browse-url-new-window-flag'."
                  '("-new-window")))
             (list url)))))
 
+(put 'browse-url-firefox 'browse-url-browser-kind 'external)
+
 ;;;###autoload
 (defun browse-url-chromium (url &optional _new-window)
   "Ask the Chromium WWW browser to load URL.
@@ -1180,6 +1279,8 @@ The optional argument NEW-WINDOW is not used."
            browse-url-chromium-arguments
            (list url)))))
 
+(put 'browse-url-chromium 'browse-url-browser-kind 'external)
+
 (defun browse-url-chrome (url &optional _new-window)
   "Ask the Google Chrome WWW browser to load URL.
 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
            (list url)))))
 
+(put 'browse-url-chrome 'browse-url-browser-kind 'external)
+
 ;;;###autoload
 (defun browse-url-galeon (url &optional new-window)
   "Ask the Galeon WWW browser to load URL.
@@ -1233,6 +1336,8 @@ used instead of `browse-url-new-window-flag'."
                          `(lambda (process change)
                             (browse-url-galeon-sentinel process ,url)))))
 
+(put 'browse-url-galeon 'browse-url-browser-kind 'external)
+
 (defun browse-url-galeon-sentinel (process url)
   "Handle a change to the process communicating with Galeon."
   (declare (obsolete nil "25.1"))
@@ -1279,6 +1384,8 @@ used instead of `browse-url-new-window-flag'."
                          `(lambda (process change)
                             (browse-url-epiphany-sentinel process ,url)))))
 
+(put 'browse-url-epiphany 'browse-url-browser-kind 'external)
+
 (defun browse-url-epiphany-sentinel (process url)
   "Handle a change to the process communicating with Epiphany."
   (or (eq (process-exit-status process) 0)
@@ -1303,6 +1410,8 @@ currently selected window instead."
                file-name-handler-alist)))
     (if same-window (find-file url) (find-file-other-window url))))
 
+(put 'browse-url-emacs 'browse-url-browser-kind 'internal)
+
 ;;;###autoload
 (defun browse-url-gnome-moz (url &optional new-window)
   "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"))
          (list "--raise" url))))
 
+(put 'browse-url-gnome-moz 'browse-url-browser-kind 'external)
+
 ;; --- Mosaic ---
 
 ;;;###autoload
@@ -1378,6 +1489,8 @@ used instead of `browse-url-new-window-flag'."
             (append browse-url-mosaic-arguments (list url)))
       (message "Starting %s...done" browse-url-mosaic-program))))
 
+(put 'browse-url-mosaic 'browse-url-browser-kind 'external)
+
 ;; --- Mosaic using CCI ---
 
 ;;;###autoload
@@ -1410,6 +1523,8 @@ used instead of `browse-url-new-window-flag'."
   (process-send-string "browse-url" "disconnect\r\n")
   (delete-process "browse-url"))
 
+(put 'browse-url-cci 'browse-url-browser-kind 'external)
+
 ;; --- Conkeror ---
 ;;;###autoload
 (defun browse-url-conkeror (url &optional new-window)
@@ -1446,6 +1561,9 @@ NEW-WINDOW instead of `browse-url-new-window-flag'."
                           "window")
                       "buffer")
                     url))))))
+
+(put 'browse-url-conkeror 'browse-url-browser-kind 'external)
+
 ;; --- W3 ---
 
 ;; External.
@@ -1469,6 +1587,8 @@ used instead of `browse-url-new-window-flag'."
       (w3-fetch-other-window url)
     (w3-fetch url)))
 
+(put 'browse-url-w3 'browse-url-browser-kind 'internal)
+
 ;;;###autoload
 (defun browse-url-w3-gnudoit (url &optional _new-window)
   ;; new-window ignored
@@ -1483,6 +1603,8 @@ The `browse-url-gnudoit-program' program is used with 
options given by
                 (list (concat "(w3-fetch \"" url "\")")
                       "(raise-frame)"))))
 
+(put 'browse-url-w3-gnudoit 'browse-url-browser-kind 'internal)
+
 ;; --- Lynx in an xterm ---
 
 ;;;###autoload
@@ -1500,6 +1622,8 @@ The optional argument NEW-WINDOW is not used."
                           ,@browse-url-xterm-args "-e" ,browse-url-text-browser
                           ,url)))
 
+(put 'browse-url-text-xterm 'browse-url-browser-kind 'external)
+
 ;; --- Lynx in an Emacs "term" window ---
 
 (declare-function term-char-mode "term" ())
@@ -1574,6 +1698,8 @@ used instead of `browse-url-new-window-flag'."
                                     url
                                     "\r")))))
 
+(put 'browse-url-text-emacs 'browse-url-browser-kind 'internal)
+
 ;; --- mailto ---
 
 (autoload 'rfc2368-parse-mailto-url "rfc2368")
@@ -1621,6 +1747,8 @@ used instead of `browse-url-new-window-flag'."
                     (unless (bolp)
                       (insert "\n"))))))))
 
+(put 'browse-url-mail 'browse-url-browser-kind 'internal)
+
 ;; --- man ---
 
 (defvar manual-program)
@@ -1632,7 +1760,9 @@ used instead of `browse-url-new-window-flag'."
   (setq url (replace-regexp-in-string "\\`man:" "" url))
   (cond
    ((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 ---
 
@@ -1651,6 +1781,8 @@ don't offer a form of remote control."
         0 nil
         (append browse-url-generic-args (list url))))
 
+(put 'browse-url-generic 'browse-url-browser-kind 'external)
+
 ;;;###autoload
 (defun browse-url-kde (url &optional _new-window)
   "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
         (append browse-url-kde-args (list url))))
 
+(put 'browse-url-kde 'browse-url-browser-kind 'external)
+
 (defun browse-url-elinks-new-window (url)
   "Ask the Elinks WWW browser to load URL in a new window."
   (let ((process-environment (browse-url-process-environment)))
@@ -1670,6 +1804,8 @@ The optional argument NEW-WINDOW is not used."
                   browse-url-elinks-wrapper
                   (list "elinks" url)))))
 
+(put 'browse-url-elinks-new-window 'browse-url-browser-kind 'external)
+
 ;;;###autoload
 (defun browse-url-elinks (url &optional new-window)
   "Ask the Elinks WWW browser to load URL.
@@ -1691,6 +1827,8 @@ from `browse-url-elinks-wrapper'."
                            `(lambda (process change)
                               (browse-url-elinks-sentinel process ,url))))))
 
+(put 'browse-url-elinks 'browse-url-browser-kind 'external)
+
 (defun browse-url-elinks-sentinel (process url)
   "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
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 9cf9ece..a6c1abd 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -310,6 +310,8 @@ the default EWW buffer."
     (url-retrieve url 'eww-render
                   (list url nil (current-buffer)))))
 
+(put 'eww 'browse-url-browser-kind 'internal)
+
 (defun eww--dwim-expand-url (url)
   (setq url (string-trim url))
   (cond ((string-match-p "\\`file:/" url))
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index f30477d..c49bdc5 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -790,6 +790,38 @@ arglist-cont-nonempty."
   (or (c-lineup-assignments langelem)
       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 we’ve found a question mark, decrease depth.  If we’re
+                   ;; reached zero, we’ve 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 don’t 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)
   "Line up \"cascaded calls\" under each other.
 If the line begins with \"->\" or \".\" and the preceding line ends
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index f92d3ef..e3a924e 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2541,13 +2541,21 @@ Key bindings:
 
 (defconst c-or-c++-mode--regexp
   (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 "\\(?:"
-                    "using"     ws "\\(?:namespace" ws "std;\\|std::\\)"
-              "\\|" "namespace" "\\(:?" ws id "\\)?" ws-maybe "{"
-              "\\|" "class"     ws id ws-maybe "[:{\n]"
-              "\\|" "template"  ws-maybe "<.*>"
-              "\\|" "#include"  ws-maybe "<\\(?:string\\|iostream\\|map\\)>"
+                    "using"     ws "\\(?:namespace" ws
+                                     "\\|" id "::"
+                                     "\\|" id ws-maybe "=\\)"
+              "\\|" "\\(?:inline" ws "\\)?namespace"
+                    "\\(:?" 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++.")
 
@@ -2563,6 +2571,7 @@ should be used.
 This function attempts to use file contents to determine whether
 the code is C or C++ and based on that chooses whether to enable
 `c-mode' or `c++-mode'."
+  (interactive)
   (if (save-excursion
         (save-restriction
           (save-match-data
diff --git a/src/textprop.c b/src/textprop.c
index 960dba3..0876bad 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);
diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el 
b/test/lisp/emacs-lisp/cl-macs-tests.el
index 9ca84f1..983e79a 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -39,6 +39,15 @@
                           collect (list c b a))
                  '((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 ()
   (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))
diff --git a/test/lisp/progmodes/cc-mode-tests.el 
b/test/lisp/progmodes/cc-mode-tests.el
index 0729841..64d52a9 100644
--- a/test/lisp/progmodes/cc-mode-tests.el
+++ b/test/lisp/progmodes/cc-mode-tests.el
@@ -40,7 +40,7 @@
                         (insert content)
                         (setq mode nil)
                         (c-or-c++-mode)
-                        (unless(eq expected mode)
+                        (unless (eq expected mode)
                           (ert-fail
                            (format "expected %s but got %s when testing '%s'"
                                    expected mode content)))))
@@ -53,11 +53,18 @@
               (funcall do-test (concat " * " content) 'c-mode))
             '("using \t namespace \t std;"
               "using \t std::string;"
+              "using Foo = Bar;"
               "namespace \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;"
+              "class \t Blah_42 \t final {"
+              "struct \t Blah_42 \t final {"
               "class \t _42_Blah:public Foo {"
+              "struct \t _42_Blah:public Foo {"
               "template \t < class T >"
               "template< class T >"
               "#include <string>"
@@ -67,6 +74,7 @@
       (mapc (lambda (content) (funcall do-test content 'c-mode))
             '("struct \t Blah_42 \t {"
               "struct template {"
+              "struct Blah;"
               "#include <string.h>")))))
 
 (ert-deftest c-mode-macro-comment ()
@@ -78,4 +86,25 @@
       (insert macro-string)
       (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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]