summaryrefslogtreecommitdiff
path: root/lisp/progmodes
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/ada-xref.el4
-rw-r--r--lisp/progmodes/antlr-mode.el78
-rw-r--r--lisp/progmodes/cc-cmds.el254
-rw-r--r--lisp/progmodes/cc-defs.el96
-rw-r--r--lisp/progmodes/cc-engine.el2088
-rw-r--r--lisp/progmodes/cc-fonts.el649
-rw-r--r--lisp/progmodes/cc-langs.el224
-rw-r--r--lisp/progmodes/cc-mode.el481
-rw-r--r--lisp/progmodes/cc-vars.el150
-rw-r--r--lisp/progmodes/compile.el16
-rw-r--r--lisp/progmodes/cperl-mode.el178
-rw-r--r--lisp/progmodes/cpp.el31
-rw-r--r--lisp/progmodes/ebnf2ps.el2
-rw-r--r--lisp/progmodes/elisp-mode.el23
-rw-r--r--lisp/progmodes/etags.el158
-rw-r--r--lisp/progmodes/flymake.el17
-rw-r--r--lisp/progmodes/gdb-mi.el23
-rw-r--r--lisp/progmodes/grep.el43
-rw-r--r--lisp/progmodes/gud.el41
-rw-r--r--lisp/progmodes/hideif.el4
-rw-r--r--lisp/progmodes/hideshow.el4
-rw-r--r--lisp/progmodes/js.el16
-rw-r--r--lisp/progmodes/make-mode.el1
-rw-r--r--lisp/progmodes/octave.el43
-rw-r--r--lisp/progmodes/prog-mode.el68
-rw-r--r--lisp/progmodes/prolog.el25
-rw-r--r--lisp/progmodes/ps-mode.el2
-rw-r--r--lisp/progmodes/python.el108
-rw-r--r--lisp/progmodes/ruby-mode.el6
-rw-r--r--lisp/progmodes/scheme.el170
-rw-r--r--lisp/progmodes/sh-script.el19
-rw-r--r--lisp/progmodes/sql.el81
-rw-r--r--lisp/progmodes/verilog-mode.el927
-rw-r--r--lisp/progmodes/which-func.el45
34 files changed, 4161 insertions, 1914 deletions
diff --git a/lisp/progmodes/ada-xref.el b/lisp/progmodes/ada-xref.el
index 891c3216079..4da81da7854 100644
--- a/lisp/progmodes/ada-xref.el
+++ b/lisp/progmodes/ada-xref.el
@@ -174,7 +174,7 @@ If GVD is not the debugger used, nothing happens."
:type 'boolean :group 'ada)
(defcustom ada-xref-search-with-egrep t
- "If non-nil, use egrep to find the possible declarations for an entity.
+ "If non-nil, use grep -E to find the possible declarations for an entity.
This alternate method is used when the exact location was not found in the
information provided by GNAT. However, it might be expensive if you have a lot
of sources, since it will search in all the files in your project."
@@ -2013,7 +2013,7 @@ This function should be used when the standard algorithm that parses the
exist.
This function attempts to find the possible declarations for the identifier
anywhere in the object path.
-This command requires the external `egrep' program to be available.
+This command requires the external `grep' program to be available.
This works well when one is using an external library and wants to find
the declaration and documentation of the subprograms one is using."
diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el
index b991fa631a6..2d09e431f29 100644
--- a/lisp/progmodes/antlr-mode.el
+++ b/lisp/progmodes/antlr-mode.el
@@ -824,16 +824,11 @@ font-lock keywords according to `font-lock-defaults' used for the code
in the grammar's actions and semantic predicates, see
`antlr-font-lock-maximum-decoration'.")
-(defvar antlr-default-face 'antlr-default)
(defface antlr-default '((t nil))
"Face to prevent strings from language dependent highlighting.
Do not change."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-default-face 'face-alias 'antlr-default)
-(put 'antlr-font-lock-default-face 'obsolete-face "22.1")
-(defvar antlr-keyword-face 'antlr-keyword)
(defface antlr-keyword
(cond-emacs-xemacs
'((((class color) (background light))
@@ -841,11 +836,7 @@ Do not change."
(t :inherit font-lock-keyword-face)))
"ANTLR keywords."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-keyword-face 'face-alias 'antlr-keyword)
-(put 'antlr-font-lock-keyword-face 'obsolete-face "22.1")
-(defvar antlr-syntax-face 'antlr-keyword)
(defface antlr-syntax
(cond-emacs-xemacs
'((((class color) (background light))
@@ -853,11 +844,7 @@ Do not change."
(t :inherit font-lock-constant-face)))
"ANTLR syntax symbols like :, |, (, ), ...."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-syntax-face 'face-alias 'antlr-syntax)
-(put 'antlr-font-lock-syntax-face 'obsolete-face "22.1")
-(defvar antlr-ruledef-face 'antlr-ruledef)
(defface antlr-ruledef
(cond-emacs-xemacs
'((((class color) (background light))
@@ -865,11 +852,7 @@ Do not change."
(t :inherit font-lock-function-name-face)))
"ANTLR rule references (definition)."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-ruledef-face 'face-alias 'antlr-ruledef)
-(put 'antlr-font-lock-ruledef-face 'obsolete-face "22.1")
-(defvar antlr-tokendef-face 'antlr-tokendef)
(defface antlr-tokendef
(cond-emacs-xemacs
'((((class color) (background light))
@@ -877,31 +860,19 @@ Do not change."
(t :inherit font-lock-function-name-face)))
"ANTLR token references (definition)."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-tokendef-face 'face-alias 'antlr-tokendef)
-(put 'antlr-font-lock-tokendef-face 'obsolete-face "22.1")
-(defvar antlr-ruleref-face 'antlr-ruleref)
(defface antlr-ruleref
'((((class color) (background light)) (:foreground "blue4"))
(t :inherit font-lock-type-face))
"ANTLR rule references (usage)."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-ruleref-face 'face-alias 'antlr-ruleref)
-(put 'antlr-font-lock-ruleref-face 'obsolete-face "22.1")
-(defvar antlr-tokenref-face 'antlr-tokenref)
(defface antlr-tokenref
'((((class color) (background light)) (:foreground "orange4"))
(t :inherit font-lock-type-face))
"ANTLR token references (usage)."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-tokenref-face 'face-alias 'antlr-tokenref)
-(put 'antlr-font-lock-tokenref-face 'obsolete-face "22.1")
-(defvar antlr-literal-face 'antlr-literal)
(defface antlr-literal
(cond-emacs-xemacs
'((((class color) (background light))
@@ -911,9 +882,6 @@ Do not change."
It is used to highlight strings matched by the first regexp group of
`antlr-font-lock-literal-regexp'."
:group 'antlr)
-;; backward-compatibility alias
-(put 'antlr-font-lock-literal-face 'face-alias 'antlr-literal)
-(put 'antlr-font-lock-literal-face 'obsolete-face "22.1")
(defcustom antlr-font-lock-literal-regexp "\"\\(\\sw\\(\\sw\\|-\\)*\\)\""
"Regexp matching literals with special syntax highlighting, or nil.
@@ -932,56 +900,58 @@ group. The string matched by the first group is highlighted with
(cond-emacs-xemacs
`((antlr-invalidate-context-cache)
("\\$setType[ \t]*(\\([A-Za-z\300-\326\330-\337]\\sw*\\))"
- (1 antlr-tokendef-face))
- ("\\$\\sw+" (0 antlr-keyword-face))
+ (1 'antlr-tokendef))
+ ("\\$\\sw+" (0 'antlr-keyword))
;; the tokens are already fontified as string/docstrings:
(,(lambda (limit)
(if antlr-font-lock-literal-regexp
(antlr-re-search-forward antlr-font-lock-literal-regexp limit)))
- (1 antlr-literal-face t)
+ (1 'antlr-literal t)
:XEMACS (0 nil)) ; XEmacs bug workaround
(,(lambda (limit)
(antlr-re-search-forward antlr-class-header-regexp limit))
- (1 antlr-keyword-face)
- (2 antlr-ruledef-face)
- (3 antlr-keyword-face)
+ (1 'antlr-keyword)
+ (2 'antlr-ruledef)
+ (3 'antlr-keyword)
(4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser"))
- antlr-keyword-face
- font-lock-type-face)))
+ 'antlr-keyword
+ 'font-lock-type-face)))
(,(lambda (limit)
(antlr-re-search-forward
"\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>"
limit))
- (1 antlr-keyword-face))
+ (1 'antlr-keyword))
(,(lambda (limit)
(antlr-re-search-forward
"^\\(private\\|public\\|protected\\)\\>[ \t]*\\(\\(\\sw+[ \t]*\\(:\\)?\\)\\)?"
limit))
- (1 font-lock-type-face) ; not XEmacs's java level-3 fruit salad
+ (1 'font-lock-type-face) ; not XEmacs's java level-3 fruit salad
(3 (if (antlr-upcase-p (char-after (match-beginning 3)))
- antlr-tokendef-face
- antlr-ruledef-face) nil t)
- (4 antlr-syntax-face nil t))
+ 'antlr-tokendef
+ 'antlr-ruledef)
+ nil t)
+ (4 'antlr-syntax nil t))
(,(lambda (limit)
(antlr-re-search-forward "^\\(\\sw+\\)[ \t]*\\(:\\)?" limit))
(1 (if (antlr-upcase-p (char-after (match-beginning 0)))
- antlr-tokendef-face
- antlr-ruledef-face) nil t)
- (2 antlr-syntax-face nil t))
+ 'antlr-tokendef
+ 'antlr-ruledef)
+ nil t)
+ (2 'antlr-syntax nil t))
(,(lambda (limit)
;; v:ruleref and v:"literal" is allowed...
(antlr-re-search-forward "\\(\\sw+\\)[ \t]*\\([=:]\\)?" limit))
(1 (if (match-beginning 2)
(if (eq (char-after (match-beginning 2)) ?=)
- antlr-default-face
- font-lock-variable-name-face)
+ 'antlr-default
+ 'font-lock-variable-name-face)
(if (antlr-upcase-p (char-after (match-beginning 1)))
- antlr-tokenref-face
- antlr-ruleref-face)))
- (2 antlr-default-face nil t))
+ 'antlr-tokenref
+ 'antlr-ruleref)))
+ (2 'antlr-default nil t))
(,(lambda (limit)
(antlr-re-search-forward "[|&:;(~]\\|)\\([*+?]\\|=>\\)?" limit))
- (0 antlr-syntax-face))))
+ (0 'antlr-syntax))))
"Font-lock keywords for ANTLR's normal grammar code.
See `antlr-font-lock-keywords-alist' for the keywords of actions.")
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index bd71a415557..561e6767e12 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1501,15 +1501,24 @@ No indentation or other \"electric\" behavior is performed."
(setq n (1- n))))
n)
-(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive)
+(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive level)
;; If we are inside a decl-block (in the sense of c-looking-at-decl-block),
;; i.e. something like namespace{} or extern{}, narrow to the insides of
;; that block (NOT including the enclosing braces) if INCLUSIVE is nil,
- ;; otherwise include the braces. If the closing brace is missing,
- ;; (point-max) is used instead.
+ ;; otherwise include the braces and the declaration which introduces them.
+ ;; If the closing brace is missing, (point-max) is used instead. LEVEL, if
+ ;; non-nil, says narrow to the LEVELth decl-block outward, default value
+ ;; being 1.
(let ((paren-state (c-parse-state))
encl-decl)
- (setq encl-decl (and paren-state (c-most-enclosing-decl-block paren-state)))
+ (setq level (or level 1))
+ (while (> level 0)
+ (setq encl-decl (c-most-enclosing-decl-block paren-state))
+ (if encl-decl
+ (progn
+ (while (> (c-pull-open-brace paren-state) encl-decl))
+ (setq level (1- level)))
+ (setq level 0)))
(if encl-decl
(save-excursion
(narrow-to-region
@@ -1610,8 +1619,8 @@ defun."
;; Move back out of any macro/comment/string we happen to be in.
(c-beginning-of-macro)
- (setq pos (c-literal-limits))
- (if pos (goto-char (car pos)))
+ (setq pos (c-literal-start))
+ (if pos (goto-char pos))
(setq where (c-where-wrt-brace-construct))
@@ -1734,8 +1743,8 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
;; Move back out of any macro/comment/string we happen to be in.
(c-beginning-of-macro)
- (setq pos (c-literal-limits))
- (if pos (goto-char (car pos)))
+ (setq pos (c-literal-start))
+ (if pos (goto-char pos))
(setq where (c-where-wrt-brace-construct))
@@ -1793,8 +1802,8 @@ with a brace block."
(save-excursion
;; Move back out of any macro/comment/string we happen to be in.
(c-beginning-of-macro)
- (setq pos (c-literal-limits))
- (if pos (goto-char (car pos)))
+ (setq pos (c-literal-start))
+ (if pos (goto-char pos))
(setq where (c-where-wrt-brace-construct))
@@ -1875,114 +1884,133 @@ with a brace block."
;; This function might do hidden buffer changes.
(save-excursion
(save-restriction
- (when (eq c-defun-tactic 'go-outward)
- (c-narrow-to-most-enclosing-decl-block t) ; e.g. class, namespace
- (or (save-restriction
- (c-narrow-to-most-enclosing-decl-block nil)
-
- ;; Note: Some code duplication in `c-beginning-of-defun' and
- ;; `c-end-of-defun'.
- (catch 'exit
(let ((start (point))
(paren-state (c-parse-state))
- lim pos end-pos)
- (unless (c-safe
- (goto-char (c-least-enclosing-brace paren-state))
- ;; If we moved to the outermost enclosing paren
- ;; then we can use c-safe-position to set the
- ;; limit. Can't do that otherwise since the
- ;; earlier paren pair on paren-state might very
- ;; well be part of the declaration we should go
- ;; to.
- (setq lim (c-safe-position (point) paren-state))
- t)
- ;; At top level. Make sure we aren't inside a literal.
- (setq pos (c-literal-limits
- (c-safe-position (point) paren-state)))
- (if pos (goto-char (car pos))))
-
- (when (c-beginning-of-macro)
- (throw 'exit
- (cons (point)
- (save-excursion
- (c-end-of-macro)
- (forward-line 1)
- (point)))))
+ lim pos end-pos encl-decl-block where)
+ ;; Narrow enclosing brace blocks out, as required by the values of
+ ;; `c-defun-tactic', `near', and the position of point.
+ (when (eq c-defun-tactic 'go-outward)
+ (let ((bounds
+ (save-restriction
+ (if (and (not (save-excursion (c-beginning-of-macro)))
+ (save-restriction
+ (c-narrow-to-most-enclosing-decl-block)
+ (memq (c-where-wrt-brace-construct)
+ '(at-function-end outwith-function)))
+ (not near))
+ (c-narrow-to-most-enclosing-decl-block nil 2)
+ (c-narrow-to-most-enclosing-decl-block))
+ (cons (point-min) (point-max)))))
+ (narrow-to-region (car bounds) (cdr bounds))))
+ (setq paren-state (c-parse-state))
+
+ (or
+ ;; Note: Some code duplication in `c-beginning-of-defun' and
+ ;; `c-end-of-defun'.
+ (catch 'exit
+ (unless (c-safe
+ (goto-char (c-least-enclosing-brace paren-state))
+ ;; If we moved to the outermost enclosing paren
+ ;; then we can use c-safe-position to set the
+ ;; limit. Can't do that otherwise since the
+ ;; earlier paren pair on paren-state might very
+ ;; well be part of the declaration we should go
+ ;; to.
+ (setq lim (c-safe-position (point) paren-state))
+ t)
+ ;; At top level. Make sure we aren't inside a literal.
+ (setq pos (c-literal-start
+ (c-safe-position (point) paren-state)))
+ (if pos (goto-char pos)))
+
+ (when (c-beginning-of-macro)
+ (throw 'exit
+ (cons (point)
+ (save-excursion
+ (c-end-of-macro)
+ (forward-line 1)
+ (point)))))
- (setq pos (point))
- (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
- (= pos (point)))
- ;; We moved back over the previous defun. Skip to the next
- ;; one. Not using c-forward-syntactic-ws here since we
- ;; should not skip a macro. We can also be directly after
- ;; the block in a `c-opt-block-decls-with-vars-key'
- ;; declaration, but then we won't move significantly far
- ;; here.
- (goto-char pos)
- (c-forward-comments)
-
- (when (and near (c-beginning-of-macro))
- (throw 'exit
- (cons (point)
- (save-excursion
- (c-end-of-macro)
- (forward-line 1)
- (point))))))
-
- (if (eobp) (throw 'exit nil))
-
- ;; Check if `c-beginning-of-decl-1' put us after the block in a
- ;; declaration that doesn't end there. We're searching back and
- ;; forth over the block here, which can be expensive.
- (setq pos (point))
- (if (and c-opt-block-decls-with-vars-key
- (progn
- (c-backward-syntactic-ws)
- (eq (char-before) ?}))
- (eq (car (c-beginning-of-decl-1))
- 'previous)
- (save-excursion
- (c-end-of-decl-1)
- (and (> (point) pos)
- (setq end-pos (point)))))
- nil
- (goto-char pos))
+ (setq pos (point))
+ (setq where (and (not (save-excursion (c-beginning-of-macro)))
+ (c-where-wrt-brace-construct)))
+ (when (and (not (eq where 'at-header))
+ (or (and near
+ (memq where
+ '(at-function-end outwith-function)))
+ (eq (car (c-beginning-of-decl-1 lim)) 'previous)
+ (= pos (point))))
+ ;; We moved back over the previous defun. Skip to the next
+ ;; one. Not using c-forward-syntactic-ws here since we
+ ;; should not skip a macro. We can also be directly after
+ ;; the block in a `c-opt-block-decls-with-vars-key'
+ ;; declaration, but then we won't move significantly far
+ ;; here.
+ (goto-char pos)
+ (c-forward-comments)
+
+ (when (and near (c-beginning-of-macro))
+ (throw 'exit
+ (cons (point)
+ (save-excursion
+ (c-end-of-macro)
+ (forward-line 1)
+ (point))))))
- (if (and (not near) (> (point) start))
- nil
+ (if (eobp) (throw 'exit nil))
- ;; Try to be line oriented; position the limits at the
- ;; closest preceding boi, and after the next newline, that
- ;; isn't inside a comment, but if we hit a neighboring
- ;; declaration then we instead use the exact declaration
- ;; limit in that direction.
- (cons (progn
- (setq pos (point))
- (while (and (/= (point) (c-point 'boi))
- (c-backward-single-comment)))
- (if (/= (point) (c-point 'boi))
- pos
- (point)))
- (progn
- (if end-pos
- (goto-char end-pos)
- (c-end-of-decl-1))
- (setq pos (point))
- (while (and (not (bolp))
- (not (looking-at "\\s *$"))
- (c-forward-single-comment)))
- (cond ((bolp)
- (point))
- ((looking-at "\\s *$")
- (forward-line 1)
- (point))
- (t
- pos))))))))
- (and (not near)
- (goto-char (point-min))
- (c-forward-decl-or-cast-1 -1 nil nil)
- (eq (char-after) ?\{)
- (cons (point-min) (point-max))))))))
+ ;; Check if `c-beginning-of-decl-1' put us after the block in a
+ ;; declaration that doesn't end there. We're searching back and
+ ;; forth over the block here, which can be expensive.
+ (setq pos (point))
+ (if (and c-opt-block-decls-with-vars-key
+ (progn
+ (c-backward-syntactic-ws)
+ (eq (char-before) ?}))
+ (eq (car (c-beginning-of-decl-1))
+ 'previous)
+ (save-excursion
+ (c-end-of-decl-1)
+ (and (> (point) pos)
+ (setq end-pos (point)))))
+ nil
+ (goto-char pos))
+
+ (if (and (not near) (> (point) start))
+ nil
+
+ ;; Try to be line oriented; position the limits at the
+ ;; closest preceding boi, and after the next newline, that
+ ;; isn't inside a comment, but if we hit a neighboring
+ ;; declaration then we instead use the exact declaration
+ ;; limit in that direction.
+ (cons (progn
+ (setq pos (point))
+ (while (and (/= (point) (c-point 'boi))
+ (c-backward-single-comment)))
+ (if (/= (point) (c-point 'boi))
+ pos
+ (point)))
+ (progn
+ (if end-pos
+ (goto-char end-pos)
+ (c-end-of-decl-1))
+ (setq pos (point))
+ (while (and (not (bolp))
+ (not (looking-at "\\s *$"))
+ (c-forward-single-comment)))
+ (cond ((bolp)
+ (point))
+ ((looking-at "\\s *$")
+ (forward-line 1)
+ (point))
+ (t
+ pos))))))
+ (and (not near)
+ (goto-char (point-min))
+ (c-forward-decl-or-cast-1 -1 nil nil)
+ (eq (char-after) ?\{)
+ (cons (point-min) (point-max))))))))
(defun c-mark-function ()
"Put mark at end of the current top-level declaration or macro, point at beginning.
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index d60afad92ef..3fdd56124c4 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -206,7 +206,7 @@ This variant works around bugs in `eval-when-compile' in various
(eval-and-compile
(defmacro c--macroexpand-all (form &optional environment)
;; Macro to smooth out the renaming of `cl-macroexpand-all' in Emacs 24.3.
- (if (eq c--mapcan-status 'cl-mapcan)
+ (if (fboundp 'macroexpand-all)
`(macroexpand-all ,form ,environment)
`(cl-macroexpand-all ,form ,environment)))
@@ -493,19 +493,21 @@ must not be within a `c-save-buffer-state', since the user then
wouldn't be able to undo them.
The return value is the value of the last form in BODY."
- `(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
- (inhibit-read-only t) (inhibit-point-motion-hooks t)
- before-change-functions after-change-functions
- deactivate-mark
- buffer-file-name buffer-file-truename ; Prevent primitives checking
- ; for file modification
- ,@varlist)
- (unwind-protect
- (progn ,@body)
- (and (not modified)
- (buffer-modified-p)
- (set-buffer-modified-p nil)))))
-(put 'c-save-buffer-state 'lisp-indent-function 1)
+ (declare (debug t) (indent 1))
+ (if (fboundp 'with-silent-modifications)
+ `(with-silent-modifications (let* ,varlist ,@body))
+ `(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
+ (inhibit-read-only t) (inhibit-point-motion-hooks t)
+ before-change-functions after-change-functions
+ deactivate-mark
+ buffer-file-name buffer-file-truename ; Prevent primitives checking
+ ; for file modification
+ ,@varlist)
+ (unwind-protect
+ (progn ,@body)
+ (and (not modified)
+ (buffer-modified-p)
+ (set-buffer-modified-p nil))))))
(defmacro c-tentative-buffer-changes (&rest body)
"Eval BODY and optionally restore the buffer contents to the state it
@@ -640,13 +642,14 @@ right side of it."
`(c-safe (scan-lists ,from ,count ,depth)))))
(if limit
`(save-restriction
- ,(if (numberp count)
- (if (< count 0)
- `(narrow-to-region ,limit (point-max))
- `(narrow-to-region (point-min) ,limit))
- `(if (< ,count 0)
- (narrow-to-region ,limit (point-max))
- (narrow-to-region (point-min) ,limit)))
+ (when ,limit
+ ,(if (numberp count)
+ (if (< count 0)
+ `(narrow-to-region ,limit (point-max))
+ `(narrow-to-region (point-min) ,limit))
+ `(if (< ,count 0)
+ (narrow-to-region ,limit (point-max))
+ (narrow-to-region (point-min) ,limit))))
,res)
res)))
@@ -661,13 +664,8 @@ leave point unmoved.
A LIMIT for the search may be given. The start position is assumed to be
before it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 0)) (point))))
- (if limit
- `(save-restriction
- (if ,limit
- (narrow-to-region (point-min) ,limit))
- ,res)
- res)))
+ `(let ((dest (c-safe-scan-lists ,(or pos `(point)) 1 0 ,limit)))
+ (when dest (goto-char dest) dest)))
(defmacro c-go-list-backward (&optional pos limit)
"Move backward across one balanced group of parentheses starting at POS or
@@ -676,13 +674,8 @@ leave point unmoved.
A LIMIT for the search may be given. The start position is assumed to be
after it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 0)) (point))))
- (if limit
- `(save-restriction
- (if ,limit
- (narrow-to-region ,limit (point-max)))
- ,res)
- res)))
+ `(let ((dest (c-safe-scan-lists ,(or pos `(point)) -1 0 ,limit)))
+ (when dest (goto-char dest) dest)))
(defmacro c-up-list-forward (&optional pos limit)
"Return the first position after the list sexp containing POS,
@@ -723,12 +716,8 @@ position exists, otherwise nil is returned and the point isn't moved.
A limit for the search may be given. The start position is assumed to
be before it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 1)) t)))
- (if limit
- `(save-restriction
- (narrow-to-region (point-min) ,limit)
- ,res)
- res)))
+ `(let ((dest (c-up-list-forward ,pos ,limit)))
+ (when dest (goto-char dest) t)))
(defmacro c-go-up-list-backward (&optional pos limit)
"Move the point to the position of the start of the list sexp containing POS,
@@ -737,12 +726,8 @@ position exists, otherwise nil is returned and the point isn't moved.
A limit for the search may be given. The start position is assumed to
be after it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 1)) t)))
- (if limit
- `(save-restriction
- (narrow-to-region ,limit (point-max))
- ,res)
- res)))
+ `(let ((dest (c-up-list-backward ,pos ,limit)))
+ (when dest (goto-char dest) t)))
(defmacro c-go-down-list-forward (&optional pos limit)
"Move the point to the first position inside the first list sexp after POS,
@@ -751,12 +736,8 @@ exists, otherwise nil is returned and the point isn't moved.
A limit for the search may be given. The start position is assumed to
be before it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 -1)) t)))
- (if limit
- `(save-restriction
- (narrow-to-region (point-min) ,limit)
- ,res)
- res)))
+ `(let ((dest (c-down-list-forward ,pos ,limit)))
+ (when dest (goto-char dest) t)))
(defmacro c-go-down-list-backward (&optional pos limit)
"Move the point to the last position inside the last list sexp before POS,
@@ -765,13 +746,8 @@ exists, otherwise nil is returned and the point isn't moved.
A limit for the search may be given. The start position is assumed to
be after it."
- (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 -1)) t)))
- (if limit
- `(save-restriction
- (narrow-to-region ,limit (point-max))
- ,res)
- res)))
-
+ `(let ((dest (c-down-list-backward ,pos ,limit)))
+ (when dest (goto-char dest) t)))
(defmacro c-beginning-of-defun-1 ()
;; Wrapper around beginning-of-defun.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 9bcd9d69733..a5d25880744 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -83,8 +83,9 @@
;;
;; 'syntax-table
;; Used to modify the syntax of some characters. It is used to
-;; mark the "<" and ">" of angle bracket parens with paren syntax, and
-;; to "hide" obtrusive characters in preprocessor lines.
+;; mark the "<" and ">" of angle bracket parens with paren syntax, to
+;; "hide" obtrusive characters in preprocessor lines, and to mark C++
+;; raw strings to enable their fontification.
;;
;; This property is used on single characters and is therefore
;; always treated as front and rear nonsticky (or start and end open
@@ -129,6 +130,10 @@
;; 'c-decl-type-start is used when the declarators are types,
;; 'c-decl-id-start otherwise.
;;
+;; 'c-not-decl
+;; Put on the brace which introduces a brace list and on the commas
+;; which separate the element within it.
+;;
;; 'c-awk-NL-prop
;; Used in AWK mode to mark the various kinds of newlines. See
;; cc-awk.el.
@@ -229,8 +234,12 @@
;; The starting position from where we determined `c-macro-cache'.
(defvar c-macro-cache-syntactic nil)
(make-variable-buffer-local 'c-macro-cache-syntactic)
-;; non-nil iff `c-macro-cache' has both elements set AND the cdr is at a
-;; syntactic end of macro, not merely an apparent one.
+;; Either nil, or the syntactic end of the macro currently represented by
+;; `c-macro-cache'.
+(defvar c-macro-cache-no-comment nil)
+(make-variable-buffer-local 'c-macro-cache-no-comment)
+;; Either nil, or the last character of the macro currently represented by
+;; `c-macro-cache' which isn't in a comment. */
(defun c-invalidate-macro-cache (beg end)
;; Called from a before-change function. If the change region is before or
@@ -242,12 +251,14 @@
((< beg (car c-macro-cache))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
((and (cdr c-macro-cache)
(< beg (cdr c-macro-cache)))
(setcdr c-macro-cache nil)
(setq c-macro-cache-start-pos beg
- c-macro-cache-syntactic nil))))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))))
(defun c-macro-is-genuine-p ()
;; Check that the ostensible CPP construct at point is a real one. In
@@ -288,7 +299,8 @@ comment at the start of cc-engine.el for more info."
t))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil)
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil)
(save-restriction
(if lim (narrow-to-region lim (point-max)))
@@ -297,7 +309,7 @@ comment at the start of cc-engine.el for more info."
(forward-line -1))
(back-to-indentation)
(if (and (<= (point) here)
- (looking-at c-opt-cpp-start)
+ (save-match-data (looking-at c-opt-cpp-start))
(c-macro-is-genuine-p))
(progn
(setq c-macro-cache (cons (point) nil)
@@ -323,7 +335,8 @@ comment at the start of cc-engine.el for more info."
(>= (point) (car c-macro-cache)))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
(while (progn
(end-of-line)
(when (and (eq (char-before) ?\\)
@@ -347,14 +360,38 @@ comment at the start of cc-engine.el for more info."
(let* ((here (point))
(there (progn (c-end-of-macro) (point)))
s)
- (unless c-macro-cache-syntactic
+ (if c-macro-cache-syntactic
+ (goto-char c-macro-cache-syntactic)
(setq s (parse-partial-sexp here there))
(while (and (or (nth 3 s) ; in a string
(nth 4 s)) ; in a comment (maybe at end of line comment)
(> there here)) ; No infinite loops, please.
(setq there (1- (nth 8 s)))
(setq s (parse-partial-sexp here there)))
- (setq c-macro-cache-syntactic (car c-macro-cache)))
+ (setq c-macro-cache-syntactic (point)))
+ (point)))
+
+(defun c-no-comment-end-of-macro ()
+ ;; Go to the end of a CPP directive, or a pos just before which isn't in a
+ ;; comment. For this purpose, open strings are ignored.
+ ;;
+ ;; This function must only be called from the beginning of a CPP construct.
+ ;;
+ ;; Note that this function might do hidden buffer changes. See the comment
+ ;; at the start of cc-engine.el for more info.
+ (let* ((here (point))
+ (there (progn (c-end-of-macro) (point)))
+ s)
+ (if c-macro-cache-no-comment
+ (goto-char c-macro-cache-no-comment)
+ (setq s (parse-partial-sexp here there))
+ (while (and (nth 3 s) ; in a string
+ (> there here)) ; No infinite loops, please.
+ (setq here (1+ (nth 8 s)))
+ (setq s (parse-partial-sexp here there)))
+ (when (nth 4 s)
+ (goto-char (1- (nth 8 s))))
+ (setq c-macro-cache-no-comment (point)))
(point)))
(defun c-forward-over-cpp-define-id ()
@@ -385,6 +422,25 @@ comment at the start of cc-engine.el for more info."
;;; Basic utility functions.
+(defun c-delq-from-dotted-list (elt dlist)
+ ;; If ELT is a member of the (possibly dotted) list DLIST, remove all
+ ;; occurrences of it (except for any in the last cdr of DLIST).
+ ;;
+ ;; Call this as (setq DLIST (c-delq-from-dotted-list ELT DLIST)), as
+ ;; sometimes the original structure is changed, sometimes it's not.
+ ;;
+ ;; This function is needed in Emacs < 24.5, and possibly XEmacs, because
+ ;; `delq' throws an error in these versions when given a dotted list.
+ (let ((tail dlist) prev)
+ (while (consp tail)
+ (if (eq (car tail) elt)
+ (if prev
+ (setcdr prev (cdr tail))
+ (setq dlist (cdr dlist)))
+ (setq prev tail))
+ (setq tail (cdr tail)))
+ dlist))
+
(defun c-syntactic-content (from to paren-level)
;; Return the given region as a string where all syntactic
;; whitespace is removed or, where necessary, replaced with a single
@@ -1248,7 +1304,7 @@ comment at the start of cc-engine.el for more info."
c-stmt-delim-chars))
(non-skip-list
(append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
- lit-range vsemi-pos)
+ lit-range lit-start vsemi-pos)
(save-restriction
(widen)
(save-excursion
@@ -1263,8 +1319,8 @@ comment at the start of cc-engine.el for more info."
((and (bolp)
(save-excursion
(progn
- (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment?
- (goto-char (car lit-range)))
+ (if (setq lit-start (c-literal-start from)) ; Have we landed in a string/comment?
+ (goto-char lit-start))
(c-backward-syntactic-ws) ; ? put a limit here, maybe?
(setq vsemi-pos (point))
(c-at-vsemi-p))))
@@ -1543,7 +1599,7 @@ comment at the start of cc-engine.el for more info."
;; two newlines with horizontal whitespace between them.
;;
;; The reason to include the first following char is to cope with
-;; "rung positions" that doesn't have any ordinary whitespace. If
+;; "rung positions" that don't have any ordinary whitespace. If
;; `c-is-sws' is put on a token character it does not have
;; `c-in-sws' set simultaneously. That's the only case when that
;; can occur, and the reason for not extending the `c-in-sws'
@@ -1714,7 +1770,9 @@ comment at the start of cc-engine.el for more info."
;; if it's anything that can't start syntactic ws, so we can bail out
;; early in the majority of cases when there just are a few ws chars.
(skip-chars-forward " \t\n\r\f\v")
- (when (looking-at c-syntactic-ws-start)
+ (when (or (looking-at c-syntactic-ws-start)
+ (and c-opt-cpp-prefix
+ (looking-at c-noise-macro-name-re)))
(setq rung-end-pos (min (1+ (point)) (point-max)))
(if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
@@ -1733,6 +1791,10 @@ comment at the start of cc-engine.el for more info."
(with-silent-modifications
(while
(progn
+ ;; In the following while form, we move over a "ladder" and
+ ;; following simple WS each time round the loop, appending the WS
+ ;; onto the ladder, joining adjacent ladders, and terminating when
+ ;; there is no more WS or we reach EOB.
(while
(when (and rung-is-marked
(get-text-property (point) 'c-in-sws))
@@ -1776,6 +1838,7 @@ comment at the start of cc-engine.el for more info."
(setq rung-pos (point)
last-put-in-sws-pos rung-pos)))
+ ;; Now move over any comments (x)or a CPP construct.
(setq simple-ws-end (point))
(c-forward-comments)
@@ -1801,6 +1864,13 @@ comment at the start of cc-engine.el for more info."
(forward-line 1)
(setq safe-start t)
;; Don't cache at eob in case the buffer is narrowed.
+ (not (eobp)))
+
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-name-re))
+ ;; Skip over a noise macro.
+ (goto-char (match-end 1))
+ (setq safe-start t)
(not (eobp)))))
;; We've searched over a piece of non-white syntactic ws. See if this
@@ -1907,8 +1977,11 @@ comment at the start of cc-engine.el for more info."
(when (and (not (bobp))
(save-excursion
(backward-char)
- (looking-at c-syntactic-ws-end)))
-
+ (or (looking-at c-syntactic-ws-end)
+ (and c-opt-cpp-prefix
+ (looking-at c-symbol-char-key)
+ (progn (c-beginning-of-current-token)
+ (looking-at c-noise-macro-name-re))))))
;; Try to find a rung position in the simple ws preceding point, so that
;; we can get a cache hit even if the last bit of the simple ws has
;; changed recently.
@@ -1927,6 +2000,9 @@ comment at the start of cc-engine.el for more info."
(with-silent-modifications
(while
(progn
+ ;; Each time round the next while form, we move back over a ladder
+ ;; and append any simple WS preceding it, if possible joining with
+ ;; the previous ladder.
(while
(when (and rung-is-marked
(not (bobp))
@@ -2035,6 +2111,15 @@ comment at the start of cc-engine.el for more info."
;; narrowed out, and we can't risk marking the simple ws
;; at the end of it.
(goto-char next-rung-pos)
+ t)
+
+ ((and c-opt-cpp-prefix
+ (save-excursion
+ (and (< (skip-syntax-backward "w_") 0)
+ (progn (setq next-rung-pos (point))
+ (looking-at c-noise-macro-name-re)))))
+ ;; Skipped over a noise macro
+ (goto-char next-rung-pos)
t)))
;; We've searched over a piece of non-white syntactic ws. See if this
@@ -2198,22 +2283,128 @@ comment at the start of cc-engine.el for more info."
(defvar c-state-semi-nonlit-pos-cache nil)
(make-variable-buffer-local 'c-state-semi-nonlit-pos-cache)
-;; A list of buffer positions which are known not to be in a literal. This is
-;; ordered with higher positions at the front of the list. Only those which
-;; are less than `c-state-semi-nonlit-pos-cache-limit' are valid.
+;; A list of elements which are either buffer positions (when such positions
+;; are not in literals) or lists of the form (POS TYPE START), where POS is
+;; a buffer position inside a literal, TYPE is the type of the literal
+;; ('string, 'c, or 'c++) and START is the start of the literal.
(defvar c-state-semi-nonlit-pos-cache-limit 1)
(make-variable-buffer-local 'c-state-semi-nonlit-pos-cache-limit)
-;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'. This is
-;; reduced by buffer changes, and increased by invocations of
-;; `c-state-literal-at'. FIXME!!!
+;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'. This
+;; is reduced by buffer changes, and increased by invocations of
+;; `c-parse-ps-state-below'.
+
+(defsubst c-truncate-semi-nonlit-pos-cache (pos)
+ ;; Truncate the upper bound of the cache `c-state-semi-nonlit-pos-cache' to
+ ;; POS, if it is higher than that position.
+ (setq c-state-semi-nonlit-pos-cache-limit
+ (min c-state-semi-nonlit-pos-cache-limit pos)))
+
+(defun c-state-semi-pp-to-literal (here &optional not-in-delimiter)
+ ;; Do a parse-partial-sexp from a position in the buffer before HERE which
+ ;; isn't in a literal, and return information about HERE, either:
+ ;; (STATE TYPE BEG) if HERE is in a literal; or
+ ;; (STATE) otherwise,
+ ;; where STATE is the parsing state at HERE, TYPE is the type of the literal
+ ;; enclosing HERE, (one of 'string, 'c, 'c++) and BEG is the starting
+ ;; position of that literal (including the delimiter).
+ ;;
+ ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
+ ;; comment opener, this is recognized as being in a comment literal.
+ ;;
+ ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), 7
+ ;; (comment type), and 8 (start of comment/string), and possibly 10 (in
+ ;; newer Emacsen only, the syntax of a position after a potential first char
+ ;; of a two char construct) of STATE are valid.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (save-match-data
+ (let* ((base-and-state (c-parse-ps-state-below here))
+ (base (car base-and-state))
+ (s (cdr base-and-state))
+ (s (parse-partial-sexp base here nil nil s))
+ ty)
+ (cond
+ ((or (nth 3 s) (nth 4 s)) ; in a string or comment
+ (setq ty (cond
+ ((nth 3 s) 'string)
+ ((nth 7 s) 'c++)
+ (t 'c)))
+ (list s ty (nth 8 s)))
+
+ ((and (not not-in-delimiter) ; inside a comment starter
+ (not (bobp))
+ (progn (backward-char)
+ (and (not (and (memq 'category-properties c-emacs-features)
+ (looking-at "\\s!")))
+ (looking-at c-comment-start-regexp))))
+ (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++))
+ (list s ty (point)))
+
+ (t (list s))))))))
+
+(defun c-state-full-pp-to-literal (here &optional not-in-delimiter)
+ ;; This function will supersede c-state-pp-to-literal.
+ ;;
+ ;; Do a parse-partial-sexp from a position in the buffer before HERE which
+ ;; isn't in a literal, and return information about HERE, either:
+ ;; (STATE TYPE (BEG . END)) if HERE is in a literal; or
+ ;; (STATE) otherwise,
+ ;; where STATE is the parsing state at HERE, TYPE is the type of the literal
+ ;; enclosing HERE, (one of 'string, 'c, 'c++) and (BEG . END) is the
+ ;; boundaries of that literal (including the delimiters).
+ ;;
+ ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
+ ;; comment opener, this is recognized as being in a comment literal.
+ ;;
+ ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), 7
+ ;; (comment type), and 8 (start of comment/string), and possibly 10 (in
+ ;; newer Emacsen only, the syntax of a position after a potential first char
+ ;; of a two char construct) of STATE are valid.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (save-match-data
+ (let* ((base-and-state (c-parse-ps-state-below here))
+ (base (car base-and-state))
+ (s (cdr base-and-state))
+ (s (parse-partial-sexp base here nil nil s))
+ ty start)
+ (cond
+ ((or (nth 3 s) (nth 4 s)) ; in a string or comment
+ (setq ty (cond
+ ((nth 3 s) 'string)
+ ((nth 7 s) 'c++)
+ (t 'c)))
+ (setq start (nth 8 s))
+ (parse-partial-sexp here (point-max)
+ nil ; TARGETDEPTH
+ nil ; STOPBEFORE
+ s ; OLDSTATE
+ 'syntax-table) ; stop at end of literal
+ (list s ty (cons start (point))))
+
+ ((and (not not-in-delimiter) ; inside a comment starter
+ (not (bobp))
+ (progn (backward-char)
+ (and (not (and (memq 'category-properties c-emacs-features)
+ (looking-at "\\s!")))
+ (looking-at c-comment-start-regexp))))
+ (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
+ start (point))
+ (forward-comment 1)
+ (list s ty (cons start (point))))
+
+ (t (list s))))))))
(defsubst c-state-pp-to-literal (from to &optional not-in-delimiter)
;; Do a parse-partial-sexp from FROM to TO, returning either
;; (STATE TYPE (BEG . END)) if TO is in a literal; or
;; (STATE) otherwise,
;; where STATE is the parsing state at TO, TYPE is the type of the literal
- ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal.
+ ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal,
+ ;; including the delimiters.
;;
;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
;; comment opener, this is recognized as being in a comment literal.
@@ -2222,32 +2413,130 @@ comment at the start of cc-engine.el for more info."
;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of
;; STATE are valid.
(save-excursion
- (let ((s (parse-partial-sexp from to))
- ty co-st)
- (cond
- ((or (nth 3 s) (nth 4 s)) ; in a string or comment
- (setq ty (cond
- ((nth 3 s) 'string)
- ((nth 7 s) 'c++)
- (t 'c)))
- (parse-partial-sexp (point) (point-max)
- nil ; TARGETDEPTH
- nil ; STOPBEFORE
- s ; OLDSTATE
- 'syntax-table) ; stop at end of literal
- `(,s ,ty (,(nth 8 s) . ,(point))))
-
- ((and (not not-in-delimiter) ; inside a comment starter
- (not (bobp))
- (progn (backward-char)
- (and (not (looking-at "\\s!"))
- (looking-at c-comment-start-regexp))))
- (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
- co-st (point))
- (forward-comment 1)
- `(,s ,ty (,co-st . ,(point))))
-
- (t `(,s))))))
+ (save-match-data
+ (let ((s (parse-partial-sexp from to))
+ ty co-st)
+ (cond
+ ((or (nth 3 s) (nth 4 s)) ; in a string or comment
+ (setq ty (cond
+ ((nth 3 s) 'string)
+ ((nth 7 s) 'c++)
+ (t 'c)))
+ (parse-partial-sexp (point) (point-max)
+ nil ; TARGETDEPTH
+ nil ; STOPBEFORE
+ s ; OLDSTATE
+ 'syntax-table) ; stop at end of literal
+ `(,s ,ty (,(nth 8 s) . ,(point))))
+
+ ((and (not not-in-delimiter) ; inside a comment starter
+ (not (bobp))
+ (progn (backward-char)
+ (and (not (looking-at "\\s!"))
+ (looking-at c-comment-start-regexp))))
+ (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
+ co-st (point))
+ (forward-comment 1)
+ `(,s ,ty (,co-st . ,(point))))
+
+ (t `(,s)))))))
+
+(defun c-cache-to-parse-ps-state (elt)
+ ;; Create a list suitable to use as the old-state parameter to
+ ;; `parse-partial-sexp', out of ELT. ELT is either just a number, a buffer
+ ;; position, or it is a list (POS TYPE STARTING-POS). Here POS is the
+ ;; buffer position the other elements are pertinent for, TYPE is either 'c
+ ;; or 'c++ (for a comment) or a character (for a string delimiter) or t
+ ;; (meaning a string fence opened the string), STARTING-POS is the starting
+ ;; position of the comment or string.
+ (if (consp elt)
+ (let ((depth 0) (containing nil) (last nil)
+ in-string in-comment (after-quote nil)
+ (min-depth 0) com-style com-str-start (intermediate nil)
+ (between-syntax nil)
+ (type (cadr elt)))
+ (setq com-str-start (car (cddr elt)))
+ (cond
+ ((or (numberp type) (eq type t)) ; A string
+ (setq in-string type))
+ ((memq type '(c c++)) ; A comment
+ (setq in-comment t
+ com-style (if (eq type 'c++) 1 nil)))
+ (t (c-benign-error "Invalid type %s in c-cache-to-parse-ps-state"
+ elt)))
+ (list depth containing last
+ in-string in-comment after-quote
+ min-depth com-style com-str-start
+ intermediate nil))
+ (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil))))
+
+(defun c-parse-ps-state-to-cache (state)
+ ;; Convert STATE, a `parse-partial-sexp' state valid at POINT, to an element
+ ;; for the `c-state-semi-nonlit-pos-cache' cache. This is either POINT
+ ;; (when point is not in a literal) or a list (POINT TYPE STARTING-POS),
+ ;; where TYPE is the type of the literal, either 'string, 'c, or 'c++, and
+ ;; STARTING-POS is the starting position of the comment or string.
+ (cond
+ ((nth 3 state) ; A string
+ (list (point) (nth 3 state) (nth 8 state)))
+ ((nth 4 state) ; A comment
+ (list (point)
+ (if (eq (nth 7 state) 1) 'c++ 'c)
+ (nth 8 state)))
+ (t ; Neither string nor comment.
+ (point))))
+
+(defsubst c-ps-state-cache-pos (elt)
+ ;; Get the buffer position from ELT, an element from the cache
+ ;; `c-state-semi-nonlit-pos-cache'.
+ (if (atom elt)
+ elt
+ (car elt)))
+
+(defun c-parse-ps-state-below (here)
+ ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where
+ ;; CACHE-POS is a position not very far before HERE for which the
+ ;; parse-partial-sexp STATE is valid. Note that the only valid elements of
+ ;; STATE are those concerning comments and strings; STATE is the state of a
+ ;; null `parse-partial-sexp' scan when CACHE-POS is not in a comment or
+ ;; string.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((c c-state-semi-nonlit-pos-cache)
+ elt state pos npos high-elt)
+ ;; Trim the cache to take account of buffer changes.
+ (while (and c (> (c-ps-state-cache-pos (car c))
+ c-state-semi-nonlit-pos-cache-limit))
+ (setq c (cdr c)))
+ (setq c-state-semi-nonlit-pos-cache c)
+
+ (while (and c (> (c-ps-state-cache-pos (car c)) here))
+ (setq high-elt (car c))
+ (setq c (cdr c)))
+ (setq pos (or (and c (c-ps-state-cache-pos (car c)))
+ (point-min)))
+
+ (if high-elt
+ (setq state (c-cache-to-parse-ps-state (car c)))
+ (setq elt (if c (car c) (point-min)))
+ (setq state
+ (if c
+ (c-cache-to-parse-ps-state (car c))
+ (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil))))
+ (while
+ ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
+ (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here)
+ (setq state (parse-partial-sexp pos npos nil nil state))
+ (setq elt (c-parse-ps-state-to-cache state))
+ (setq c-state-semi-nonlit-pos-cache
+ (cons elt c-state-semi-nonlit-pos-cache))
+ (setq pos npos)))
+
+ (if (> pos c-state-semi-nonlit-pos-cache-limit)
+ (setq c-state-semi-nonlit-pos-cache-limit pos))
+
+ (cons pos state)))))
(defun c-state-safe-place (here)
;; Return a buffer position before HERE which is "safe", i.e. outside any
@@ -2314,45 +2603,6 @@ comment at the start of cc-engine.el for more info."
(setq c-state-nonlit-pos-cache-limit pos))
pos))))
-(defun c-state-semi-safe-place (here)
- ;; Return a buffer position before HERE which is "safe", i.e. outside any
- ;; string or comment. It may be in a macro.
- (save-restriction
- (widen)
- (save-excursion
- (let ((c c-state-semi-nonlit-pos-cache)
- pos npos high-pos lit macro-beg macro-end)
- ;; Trim the cache to take account of buffer changes.
- (while (and c (> (car c) c-state-semi-nonlit-pos-cache-limit))
- (setq c (cdr c)))
- (setq c-state-semi-nonlit-pos-cache c)
-
- (while (and c (> (car c) here))
- (setq high-pos (car c))
- (setq c (cdr c)))
- (setq pos (or (car c) (point-min)))
-
- (unless high-pos
- (while
- ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
- (and
- (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here)
-
- ;; Test for being in a literal. If so, go to after it.
- (progn
- (setq lit (car (cddr (c-state-pp-to-literal pos npos))))
- (or (null lit)
- (prog1 (<= (cdr lit) here)
- (setq npos (cdr lit))))))
-
- (setq pos npos)
- (setq c-state-semi-nonlit-pos-cache
- (cons pos c-state-semi-nonlit-pos-cache))))
-
- (if (> pos c-state-semi-nonlit-pos-cache-limit)
- (setq c-state-semi-nonlit-pos-cache-limit pos))
- pos))))
-
(defun c-state-literal-at (here)
;; If position HERE is inside a literal, return (START . END), the
;; boundaries of the literal (which may be outside the accessible bit of the
@@ -2670,7 +2920,11 @@ comment at the start of cc-engine.el for more info."
(setq ptr (cdr ptr)))
(when (consp ptr)
- (if (eq (cdr ptr) c-state-cache)
+ (if (or (eq (cdr ptr) c-state-cache)
+ (and (consp (cadr ptr))
+ (> (cdr (cadr ptr)) (point-min)))) ; Our new point-min is
+ ; inside a recorded
+ ; brace pair.
(setq c-state-cache nil
c-state-cache-good-pos c-state-min-scan-pos)
(setcdr ptr nil)
@@ -3249,8 +3503,7 @@ comment at the start of cc-engine.el for more info."
;; HERE.
(if (<= here c-state-nonlit-pos-cache-limit)
(setq c-state-nonlit-pos-cache-limit (1- here)))
- (if (<= here c-state-semi-nonlit-pos-cache-limit)
- (setq c-state-semi-nonlit-pos-cache-limit (1- here)))
+ (c-truncate-semi-nonlit-pos-cache here)
;; `c-state-cache':
;; Case 1: if `here' is in a literal containing point-min, everything
@@ -3521,7 +3774,7 @@ comment at the start of cc-engine.el for more info."
conses-not-ok))
(defun c-debug-parse-state ()
- (let ((here (point)) (res1 (c-real-parse-state)) res2)
+ (let ((here (point)) (min-point (point-min)) (res1 (c-real-parse-state)) res2)
(let ((c-state-cache nil)
(c-state-cache-good-pos 1)
(c-state-nonlit-pos-cache nil)
@@ -3548,8 +3801,8 @@ comment at the start of cc-engine.el for more info."
;; "using cache: %s, from scratch: %s")
;; here res1 res2)))
(message (concat "c-parse-state inconsistency at %s: "
- "using cache: %s, from scratch: %s")
- here res1 res2)
+ "using cache: %s, from scratch: %s. POINT-MIN: %s")
+ here res1 res2 min-point)
(message "Old state:")
(c-replay-parse-state-state))
@@ -4025,6 +4278,15 @@ or string literals are ignored. The start point is assumed to be
outside any comment, macro or string literal, or else the content of
that region is taken as syntactically significant text.
+NOERROR, in addition to the values nil, t, and <anything else>
+used in `re-search-forward' can also take the values
+'before-literal and 'after-literal. In these cases, when BOUND
+is also given and is inside a literal, and a search fails, point
+will be left, respectively before or after the literal. Be aware
+that with 'after-literal, if a string or comment is unclosed at
+the end of the buffer, point may be left there, even though it is
+inside a literal there.
+
If PAREN-LEVEL is non-nil, an additional restriction is added to
ignore matches in nested paren sexps. The search will also not go
outside the current list sexp, which has the effect that if the point
@@ -4088,7 +4350,19 @@ comment at the start of cc-engine.el for more info."
(and
(progn
(setq search-pos (point))
- (re-search-forward regexp bound noerror))
+ (if (re-search-forward regexp bound noerror)
+ t
+ ;; Without the following, when PAREN-LEVEL is non-nil, and
+ ;; NOERROR is not nil or t, and the very first search above
+ ;; has just failed, point would end up at BOUND rather than
+ ;; just before the next close paren.
+ (when (and (eq search-pos start)
+ paren-level
+ (not (memq noerror '(nil t))))
+ (setq state (parse-partial-sexp start bound -1))
+ (if (eq (car state) -1)
+ (setq bound (1- (point)))))
+ nil))
(progn
(setq state (parse-partial-sexp
@@ -4236,9 +4510,19 @@ comment at the start of cc-engine.el for more info."
(match-end 0))
;; Search failed. Set point as appropriate.
- (if (eq noerror t)
- (goto-char start)
+ (cond
+ ((eq noerror t)
+ (goto-char start))
+ ((not (memq noerror '(before-literal after-literal)))
(goto-char bound))
+ (t (setq state (parse-partial-sexp state-pos bound nil nil state))
+ (if (or (elt state 3) (elt state 4))
+ (if (eq noerror 'before-literal)
+ (goto-char (elt state 8))
+ (parse-partial-sexp bound (point-max) nil nil
+ state 'syntax-table))
+ (goto-char bound))))
+
nil)))
(defvar safe-pos-list) ; bound in c-syntactic-skip-backward
@@ -4546,8 +4830,7 @@ Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
(save-restriction
(widen)
- (let* ((safe-place (c-state-semi-safe-place (point)))
- (lit (c-state-pp-to-literal safe-place (point))))
+ (let ((lit (c-state-semi-pp-to-literal (point))))
(or (cadr lit)
(and detect-cpp
(save-excursion (c-beginning-of-macro))
@@ -4569,14 +4852,20 @@ Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
(save-excursion
- (let* ((pos (point))
- (lim (or lim (c-state-semi-safe-place pos)))
- (pp-to-lit (save-restriction
- (widen)
- (c-state-pp-to-literal lim pos not-in-delimiter)))
- (state (car pp-to-lit))
- (lit-limits (car (cddr pp-to-lit))))
-
+ (let*
+ ((pos (point))
+ (lit-limits
+ (if lim
+ (let ((s (parse-partial-sexp lim (point))))
+ (when (or (nth 3 s) (nth 4 s))
+ (cons (nth 8 s)
+ (progn (parse-partial-sexp (point) (point-max)
+ nil nil
+ s
+ 'syntax-table)
+ (point)))))
+ (let ((pp-to-lit (c-state-full-pp-to-literal pos not-in-delimiter)))
+ (car (cddr pp-to-lit))))))
(cond
(lit-limits)
@@ -4615,6 +4904,16 @@ comment at the start of cc-engine.el for more info."
(if beg (cons beg end))))))
))))
+(defun c-literal-start (&optional safe-pos)
+ "Return the start of the string or comment surrounding point, or nil if
+point isn't in one. SAFE-POS, if non-nil, is a position before point which is
+a known \"safe position\", i.e. outside of any string or comment."
+ (if safe-pos
+ (let ((s (parse-partial-sexp safe-pos (point))))
+ (and (or (nth 3 s) (nth 4 s))
+ (nth 8 s)))
+ (car (cddr (c-state-semi-pp-to-literal (point))))))
+
;; In case external callers use this; it did have a docstring.
(defalias 'c-literal-limits-fast 'c-literal-limits)
@@ -4679,13 +4978,10 @@ comment at the start of cc-engine.el for more info."
(defsubst c-determine-limit-get-base (start try-size)
;; Get a "safe place" approximately TRY-SIZE characters before START.
- ;; This doesn't preserve point.
+ ;; This defsubst doesn't preserve point.
(let* ((pos (max (- start try-size) (point-min)))
- (base (c-state-semi-safe-place pos))
- (s (parse-partial-sexp base pos)))
- (if (or (nth 4 s) (nth 3 s)) ; comment or string
- (nth 8 s)
- (point))))
+ (s (c-state-semi-pp-to-literal pos)))
+ (or (car (cddr s)) pos)))
(defun c-determine-limit (how-far-back &optional start try-size)
;; Return a buffer position HOW-FAR-BACK non-literal characters from START
@@ -4832,6 +5128,211 @@ comment at the start of cc-engine.el for more info."
(c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face)
(c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Machinery for determining when we're at top level (this including being
+;; directly inside a class or namespace, etc.)
+;;
+;; We maintain a stack of brace depths in structures like classes and
+;; namespaces. The car of this structure, when non-nil, indicates that the
+;; associated position is within a template (etc.) structure, and the value is
+;; the position where the (outermost) template ends. The other elements in
+;; the structure are stacked elements, one each for each enclosing "top level"
+;; structure.
+;;
+;; At the very outermost level, the value of the stack would be (nil 1), the
+;; "1" indicating an enclosure in a notional all-enclosing block. After
+;; passing a keyword such as "namespace", the value would become (nil 0 1).
+;; At this point, passing a semicolon would cause the 0 to be dropped from the
+;; stack (at any other time, a semicolon is ignored). Alternatively, on
+;; passing an opening brace, the stack would become (nil 1 1). Each opening
+;; brace passed causes the cadr to be incremented, and passing closing braces
+;; causes it to be decremented until it reaches 1. On passing a closing brace
+;; when the cadr of the stack is at 1, this causes it to be removed from the
+;; stack, the corresponding namespace (etc.) structure having been closed.
+;;
+;; There is a special stack value -1 which means the C++ colon operator
+;; introducing a list of inherited classes has just been parsed. The value
+;; persists on the stack until the next open brace or semicolon.
+;;
+;; When the car of the stack is non-nil, i.e. when we're in a template (etc.)
+;; structure, braces are not counted. The counting resumes only after passing
+;; the template's closing position, which is recorded in the car of the stack.
+;;
+;; The test for being at top level consists of the cadr being 0 or 1.
+;;
+;; The values of this stack throughout a buffer are cached in a simple linear
+;; cache, every 5000 characters.
+;;
+;; Note to maintainers: This cache mechanism is MUCH faster than recalculating
+;; the stack at every entry to `c-find-decl-spots' using `c-at-toplevel-p' or
+;; the like.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; The approximate interval at which we cache the value of the brace stack.
+(defconst c-bs-interval 5000)
+;; The list of cached values of the brace stack. Each value in the list is a
+;; cons of the position it is valid for and the value of the stack as
+;; described above.
+(defvar c-bs-cache nil)
+(make-variable-buffer-local 'c-bs-cache)
+;; The position of the buffer at and below which entries in `c-bs-cache' are
+;; valid.
+(defvar c-bs-cache-limit 1)
+(make-variable-buffer-local 'c-bs-cache-limit)
+;; The previous buffer position for which the brace stack value was
+;; determined.
+(defvar c-bs-prev-pos most-positive-fixnum)
+(make-variable-buffer-local 'c-bs-prev-pos)
+;; The value of the brace stack at `c-bs-prev-pos'.
+(defvar c-bs-prev-stack nil)
+(make-variable-buffer-local 'c-bs-prev-stack)
+
+(defun c-init-bs-cache ()
+ ;; Initialize the cache in `c-bs-cache' and related variables.
+ (setq c-bs-cache nil
+ c-bs-cache-limit 1
+ c-bs-prev-pos most-positive-fixnum
+ c-bs-prev-stack nil))
+
+(defun c-truncate-bs-cache (pos &rest _ignore)
+ ;; Truncate the upper bound of the cache `c-bs-cache' to POS, if it is
+ ;; higher than that position. This is called as either a before- or
+ ;; after-change-function.
+ (setq c-bs-cache-limit
+ (min c-bs-cache-limit pos)))
+
+(defun c-update-brace-stack (stack from to)
+ ;; Give a brace-stack which has the value STACK at position FROM, update it
+ ;; to it's value at position TO, where TO is after (or equal to) FROM.
+ ;; Return a cons of either TO (if it is outside a literal) and this new
+ ;; value, or of the next position after TO outside a literal and the new
+ ;; value.
+ (let (match kwd-sym (prev-match-pos 1)
+ (s (cdr stack))
+ (bound-<> (car stack))
+ )
+ (save-excursion
+ (cond
+ ((and bound-<> (<= to bound-<>))
+ (goto-char to)) ; Nothing to do.
+ (bound-<>
+ (goto-char bound-<>)
+ (setq bound-<> nil))
+ (t (goto-char from)))
+ (while (and (< (point) to)
+ (c-syntactic-re-search-forward
+ (if (<= (car s) 0)
+ c-brace-stack-thing-key
+ c-brace-stack-no-semi-key)
+ to 'after-literal)
+ (> (point) prev-match-pos)) ; prevent infinite loop.
+ (setq prev-match-pos (point))
+ (setq match (match-string-no-properties 1)
+ kwd-sym (c-keyword-sym match))
+ (cond
+ ((and (equal match "{")
+ (progn (backward-char)
+ (prog1 (looking-at "\\s(")
+ (forward-char))))
+ (setq s (if s
+ (cons (if (<= (car s) 0)
+ 1
+ (1+ (car s)))
+ (cdr s))
+ (list 1))))
+ ((and (equal match "}")
+ (progn (backward-char)
+ (prog1 (looking-at "\\s)")
+ (forward-char))))
+ (setq s
+ (cond
+ ((and s (> (car s) 1))
+ (cons (1- (car s)) (cdr s)))
+ ((and (cdr s) (eq (car s) 1))
+ (cdr s))
+ (t s))))
+ ((and (equal match "<")
+ (progn (backward-char)
+ (prog1 (looking-at "\\s(")
+ (forward-char))))
+ (backward-char)
+ (if (c-forward-<>-arglist nil) ; Should always work.
+ (when (> (point) to)
+ (setq bound-<> (point)))
+ (forward-char)))
+ ((and (equal match ":")
+ s
+ (eq (car s) 0))
+ (setq s (cons -1 (cdr s))))
+ ((and (equal match ",")
+ (eq (car s) -1))) ; at "," in "class foo : bar, ..."
+ ((member match '(";" "," ")"))
+ (when (and s (cdr s) (<= (car s) 0))
+ (setq s (cdr s))))
+ ((c-keyword-member kwd-sym 'c-flat-decl-block-kwds)
+ (push 0 s))))
+ (cons (point)
+ (cons bound-<> s)))))
+
+(defun c-brace-stack-at (here)
+ ;; Given a buffer position HERE, Return the value of the brace stack there.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((c c-bs-cache)
+ (can-use-prev (<= c-bs-prev-pos c-bs-cache-limit))
+ elt stack pos npos high-elt)
+ ;; Trim the cache to take account of buffer changes.
+ (while (and c
+ (> (caar c) c-bs-cache-limit))
+ (setq c (cdr c)))
+ (setq c-bs-cache c)
+
+ (while (and c
+ (> (caar c) here))
+ (setq high-elt (car c))
+ (setq c (cdr c)))
+ (setq pos (or (and c (caar c))
+ (point-min)))
+
+ (setq elt (if c
+ (car c)
+ (cons (point-min)
+ (cons nil (list 1)))))
+ (when (not high-elt)
+ (setq stack (cdr elt))
+ (while
+ ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
+ (<= (setq npos (+ pos c-bs-interval)) here)
+ (setq elt (c-update-brace-stack stack pos npos))
+ (setq npos (car elt))
+ (setq stack (cdr elt))
+ (unless (eq npos (point-max)) ; NPOS could be in a literal at EOB.
+ (setq c-bs-cache (cons elt c-bs-cache)))
+ (setq pos npos)))
+
+ (if (> pos c-bs-cache-limit)
+ (setq c-bs-cache-limit pos))
+
+ ;; Can we just use the previous value?
+ (if (and can-use-prev
+ (<= c-bs-prev-pos here)
+ (> c-bs-prev-pos (car elt)))
+ (setq pos c-bs-prev-pos
+ stack c-bs-prev-stack)
+ (setq pos (car elt)
+ stack (cdr elt)))
+ (if (> here c-bs-cache-limit)
+ (setq c-bs-cache-limit here))
+ (setq elt (c-update-brace-stack stack pos here)
+ c-bs-prev-pos (car elt)
+ c-bs-prev-stack (cdr elt))))))
+
+(defun c-bs-at-toplevel-p (here)
+ ;; Is position HERE at the top level, as indicated by the brace stack?
+ (let ((stack (c-brace-stack-at here)))
+ (or (null stack) ; Probably unnecessary.
+ (<= (cadr stack) 1))))
+
(defmacro c-find-decl-prefix-search ()
;; Macro used inside `c-find-decl-spots'. It ought to be a defun,
;; but it contains lots of free variables that refer to things
@@ -4895,6 +5396,14 @@ comment at the start of cc-engine.el for more info."
(and (< (point) cfd-limit)
(c-got-face-at (point) c-literal-faces))))
t) ; Continue the loop over pseudo matches.
+ ((and c-opt-identifier-concat-key
+ (match-string 1)
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (save-match-data
+ (looking-at c-opt-identifier-concat-key))))
+ ;; Found, e.g., "::" in C++
+ t)
((and (match-string 1)
(string= (match-string 1) ":")
(save-excursion
@@ -4917,6 +5426,7 @@ comment at the start of cc-engine.el for more info."
cfd-re-match nil)
(setq cfd-match-pos cfd-prop-match
cfd-prop-match nil))
+ (setq cfd-top-level (c-bs-at-toplevel-p cfd-match-pos))
(goto-char cfd-match-pos)
@@ -5015,7 +5525,11 @@ comment at the start of cc-engine.el for more info."
;; comments.
(cfd-token-pos 0)
;; The end position of the last entered macro.
- (cfd-macro-end 0))
+ (cfd-macro-end 0)
+ ;; Whether the last position returned from `c-find-decl-prefix-search'
+ ;; is at the top-level (including directly in a class or namespace,
+ ;; etc.).
+ cfd-top-level)
;; Initialize by finding a syntactically relevant start position
;; before the point, and do the first `c-decl-prefix-or-start-re'
@@ -5065,8 +5579,9 @@ comment at the start of cc-engine.el for more info."
;; arrived at something that looks like a start or else
;; resort to `c-literal-limits'.
(unless (looking-at c-literal-start-regexp)
- (let ((range (c-literal-limits)))
- (if range (goto-char (car range)))))
+ (let ((lit-start (c-literal-start)))
+ (if lit-start (goto-char lit-start)))
+ )
(setq start-in-literal (point))) ; end of `and' arm.
@@ -5322,7 +5837,7 @@ comment at the start of cc-engine.el for more info."
nil)))) ; end of when condition
(c-debug-put-decl-spot-faces cfd-match-pos (point))
- (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0))
+ (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0) cfd-top-level)
(setq cfd-prop-match nil))
(when (/= cfd-macro-end 0)
@@ -5577,6 +6092,9 @@ comment at the start of cc-engine.el for more info."
;; Set by c-common-init in cc-mode.el.
(defvar c-new-BEG)
(defvar c-new-END)
+;; Set by c-after-change in cc-mode.el.
+(defvar c-old-BEG)
+(defvar c-old-END)
(defun c-before-change-check-<>-operators (beg end)
;; Unmark certain pairs of "< .... >" which are currently marked as
@@ -5600,12 +6118,12 @@ comment at the start of cc-engine.el for more info."
;; 2010-01-29.
(save-excursion
(c-save-buffer-state
- ((beg-lit-limits (progn (goto-char beg) (c-literal-limits)))
+ ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
(end-lit-limits (progn (goto-char end) (c-literal-limits)))
new-beg new-end beg-limit end-limit)
;; Locate the earliest < after the barrier before the changed region,
;; which isn't already marked as a paren.
- (goto-char (if beg-lit-limits (car beg-lit-limits) beg))
+ (goto-char (or beg-lit-start beg))
(setq beg-limit (c-determine-limit 512))
;; Remove the syntax-table/category properties from each pertinent <...>
@@ -5697,6 +6215,350 @@ comment at the start of cc-engine.el for more info."
'c-decl-arg-start)))))))
(or (c-forward-<>-arglist nil)
(forward-char)))))
+
+
+;; Functions to handle C++ raw strings.
+;;
+;; A valid C++ raw string looks like
+;; R"<id>(<contents>)<id>"
+;; , where <id> is an identifier from 0 to 16 characters long, not containing
+;; spaces, control characters, double quote or left/right paren. <contents>
+;; can include anything which isn't the terminating )<id>", including new
+;; lines, "s, parentheses, etc.
+;;
+;; CC Mode handles C++ raw strings by the use of `syntax-table' text
+;; properties as follows:
+;;
+;; (i) On a validly terminated raw string, no `syntax-table' text properties
+;; are applied to the opening and closing delimiters, but any " in the
+;; contents is given the property value "punctuation" (`(1)') to prevent it
+;; interacting with the "s in the delimiters.
+;;
+;; The font locking routine `c-font-lock-c++-raw-strings' (in cc-fonts.el)
+;; recognizes valid raw strings, and fontifies the delimiters (apart from
+;; the parentheses) with the default face and the parentheses and the
+;; <contents> with font-lock-string-face.
+;;
+;; (ii) A valid, but unterminated, raw string opening delimiter gets the
+;; "punctuation" value (`(1)') of the `syntax-table' text property, and the
+;; open parenthesis gets the "string fence" value (`(15)').
+;;
+;; `c-font-lock-c++-raw-strings' puts c-font-lock-warning-face on the entire
+;; unmatched opening delimiter (from the R up to the open paren), and allows
+;; the rest of the buffer to get font-lock-string-face, caused by the
+;; unmatched "string fence" `syntax-table' text property value.
+;;
+;; (iii) Inside a macro, a valid raw string is handled as in (i). An
+;; unmatched opening delimiter is handled slightly differently. In addition
+;; to the "punctuation" and "string fence" properties on the delimiter,
+;; another "string fence" `syntax-table' property is applied to the last
+;; possible character of the macro before the terminating linefeed (if there
+;; is such a character after the "("). This "last possible" character is
+;; never a backslash escaping the end of line. If the character preceding
+;; this "last possible" character is itself a backslash, this preceding
+;; character gets a "punctuation" `syntax-table' value. If the "(" is
+;; already at the end of the macro, it gets the "punctuation" value, and no
+;; "string fence"s are used.
+;;
+;; The effect on the fontification of either of these tactics is that rest of
+;; the macro (if any) after the "(" gets font-lock-string-face, but the rest
+;; of the file is fontified normally.
+
+
+(defun c-raw-string-pos ()
+ ;; Get POINT's relationship to any containing raw string.
+ ;; If point isn't in a raw string, return nil.
+ ;; Otherwise, return the following list:
+ ;;
+ ;; (POS B\" B\( E\) E\")
+ ;;
+ ;; , where POS is the symbol `open-delim' if point is in the opening
+ ;; delimiter, the symbol `close-delim' if it's in the closing delimiter, and
+ ;; nil if it's in the string body. B\", B\(, E\), E\" are the positions of
+ ;; the opening and closing quotes and parentheses of a correctly terminated
+ ;; raw string. (N.B.: E\) and E\" are NOT on the "outside" of these
+ ;; characters.) If the raw string is not terminated, E\) and E\" are set to
+ ;; nil.
+ ;;
+ ;; Note: this routine is dependant upon the correct syntax-table text
+ ;; properties being set.
+ (let ((state (c-state-semi-pp-to-literal (point)))
+ open-quote-pos open-paren-pos close-paren-pos close-quote-pos id)
+ (save-excursion
+ (when
+ (and
+ (cond
+ ((null (cadr state))
+ (or (eq (char-after) ?\")
+ (search-backward "\"" (max (- (point) 17) (point-min)) t)))
+ ((and (eq (cadr state) 'string)
+ (goto-char (nth 2 state))
+ (or (eq (char-after) ?\")
+ (search-backward "\"" (max (- (point) 17) (point-min)) t))
+ (not (bobp)))))
+ (eq (char-before) ?R)
+ (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)("))
+ (setq open-quote-pos (point)
+ open-paren-pos (match-end 1)
+ id (match-string-no-properties 1))
+ (goto-char (1+ open-paren-pos))
+ (when (and (not (c-get-char-property open-paren-pos 'syntax-table))
+ (search-forward (concat ")" id "\"") nil t))
+ (setq close-paren-pos (match-beginning 0)
+ close-quote-pos (1- (point))))))
+ (and open-quote-pos
+ (list
+ (cond
+ ((<= (point) open-paren-pos)
+ 'open-delim)
+ ((and close-paren-pos
+ (> (point) close-paren-pos))
+ 'close-delim)
+ (t nil))
+ open-quote-pos open-paren-pos close-paren-pos close-quote-pos))))
+
+(defun c-depropertize-raw-string (id open-quote open-paren bound)
+ ;; Point is immediately after a raw string opening delimiter. Remove any
+ ;; `syntax-table' text properties associated with the delimiter (if it's
+ ;; unmatched) or the raw string.
+ ;;
+ ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN
+ ;; are the buffer positions of the delimiter's components. BOUND is the
+ ;; bound for searching for a matching closing delimiter; it is usually nil,
+ ;; but if we're inside a macro, it's the end of the macro.
+ ;;
+ ;; Point is moved to after the (terminated) raw string, or left after the
+ ;; unmatched opening delimiter, as the case may be. The return value is of
+ ;; no significance.
+ (let ((open-paren-prop (c-get-char-property open-paren 'syntax-table)))
+ (cond
+ ((null open-paren-prop)
+ ;; A terminated raw string
+ (when (search-forward (concat ")" id "\"") nil t)
+ (let* ((closing-paren (match-beginning 0))
+ (first-punctuation
+ (save-match-data
+ (goto-char (1+ open-paren))
+ (and (c-search-forward-char-property 'syntax-table '(1)
+ closing-paren)
+ (1- (point)))))
+ )
+ (when first-punctuation
+ (c-clear-char-property-with-value
+ first-punctuation (match-beginning 0) 'syntax-table '(1))
+ (c-truncate-semi-nonlit-pos-cache first-punctuation)
+ ))))
+ ((or (and (equal open-paren-prop '(15)) (null bound))
+ (equal open-paren-prop '(1)))
+ ;; An unterminated raw string either not in a macro, or in a macro with
+ ;; the open parenthesis right up against the end of macro
+ (c-clear-char-property open-quote 'syntax-table)
+ (c-truncate-semi-nonlit-pos-cache open-quote)
+ (c-clear-char-property open-paren 'syntax-table))
+ (t
+ ;; An unterminated string in a macro, with at least one char after the
+ ;; open paren
+ (c-clear-char-property open-quote 'syntax-table)
+ (c-truncate-semi-nonlit-pos-cache open-quote)
+ (c-clear-char-property open-paren 'syntax-table)
+ (let ((after-string-fence-pos
+ (save-excursion
+ (goto-char (1+ open-paren))
+ (c-search-forward-char-property 'syntax-table '(15) bound))))
+ (when after-string-fence-pos
+ (c-clear-char-property (1- after-string-fence-pos) 'syntax-table)))
+ ))))
+
+(defun c-depropertize-raw-strings-in-region (start finish)
+ ;; Remove any `syntax-table' text properties associated with C++ raw strings
+ ;; contained in the region (START FINISH). Point is undefined at entry and
+ ;; exit, and the return value has no significance.
+ (goto-char start)
+ (while (and (< (point) finish)
+ (re-search-forward
+ (concat "\\(" ; 1
+ c-anchored-cpp-prefix ; 2
+ "\\)\\|\\(" ; 3
+ "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" ; 4
+ "\\)")
+ finish t))
+ (when (save-excursion
+ (goto-char (match-beginning 0)) (not (c-in-literal)))
+ (if (match-beginning 4) ; the id
+ ;; We've found a raw string
+ (c-depropertize-raw-string
+ (match-string-no-properties 4) ; id
+ (1+ (match-beginning 3)) ; open quote
+ (match-end 4) ; open paren
+ nil) ; bound
+ ;; We've found a CPP construct. Search for raw strings within it.
+ (goto-char (match-beginning 2)) ; the "#"
+ (c-end-of-macro)
+ (let ((eom (point)))
+ (goto-char (match-end 2)) ; after the "#".
+ (while (and (< (point) eom)
+ (c-syntactic-re-search-forward
+ "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" eom t))
+ (c-depropertize-raw-string
+ (match-string-no-properties 1) ; id
+ (1+ (match-beginning 0)) ; open quote
+ (match-end 1) ; open paren
+ eom))))))) ; bound.
+
+(defun c-before-change-check-raw-strings (beg end)
+ ;; This function clears `syntax-table' text properties from C++ raw strings
+ ;; in the region (c-new-BEG c-new-END). BEG and END are the standard
+ ;; arguments supplied to any before-change function.
+ ;;
+ ;; Point is undefined on both entry and exit, and the return value has no
+ ;; significance.
+ ;;
+ ;; This function is called as a before-change function solely due to its
+ ;; membership of the C++ value of `c-get-state-before-change-functions'.
+ (c-save-buffer-state
+ ((beg-rs (progn (goto-char beg) (c-raw-string-pos)))
+ (beg-plus (if (null beg-rs)
+ beg
+ (max beg
+ (1+ (or (nth 4 beg-rs) (nth 2 beg-rs))))))
+ (end-rs (progn (goto-char end) (c-raw-string-pos))) ; FIXME!!!
+ ; Optimize this so that we don't call
+ ; `c-raw-string-pos' twice when once
+ ; will do. (2016-06-02).
+ (end-minus (if (null end-rs)
+ end
+ (min end (cadr end-rs))))
+ )
+ (when beg-rs
+ (setq c-new-BEG (min c-new-BEG (1- (cadr beg-rs)))))
+ (c-depropertize-raw-strings-in-region c-new-BEG beg-plus)
+
+ (when end-rs
+ (setq c-new-END (max c-new-END
+ (1+ (or (nth 4 end-rs)
+ (nth 2 end-rs))))))
+ (c-depropertize-raw-strings-in-region end-minus c-new-END)))
+
+(defun c-propertize-raw-string-opener (id open-quote open-paren bound)
+ ;; Point is immediately after a raw string opening delimiter. Apply any
+ ;; pertinent `syntax-table' text properties to the delimiter and also the
+ ;; raw string, should there be a valid matching closing delimiter.
+ ;;
+ ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN
+ ;; are the buffer positions of the delimiter's components. BOUND is the
+ ;; bound for searching for a matching closing delimiter; it is usually nil,
+ ;; but if we're inside a macro, it's the end of the macro.
+ ;;
+ ;; Point is moved to after the (terminated) raw string, or left after the
+ ;; unmatched opening delimiter, as the case may be. The return value is of
+ ;; no significance.
+ (if (search-forward (concat ")" id "\"") bound t)
+ (let ((end-string (match-beginning 0))
+ (after-quote (match-end 0)))
+ (goto-char open-paren)
+ (while (progn (skip-syntax-forward "^\"" end-string)
+ (< (point) end-string))
+ (c-put-char-property (point) 'syntax-table '(1)) ; punctuation
+ (c-truncate-semi-nonlit-pos-cache (point))
+ (forward-char))
+ (goto-char after-quote))
+ (c-put-char-property open-quote 'syntax-table '(1)) ; punctuation
+ (c-truncate-semi-nonlit-pos-cache open-quote)
+ (c-put-char-property open-paren 'syntax-table '(15)) ; generic string
+ (when bound
+ ;; In a CPP construct, we try to apply a generic-string `syntax-table'
+ ;; text property to the last possible character in the string, so that
+ ;; only characters within the macro get "stringed out".
+ (goto-char bound)
+ (if (save-restriction
+ (narrow-to-region (1+ open-paren) (point-max))
+ (re-search-backward
+ (eval-when-compile
+ ;; This regular expression matches either an escape pair (which
+ ;; isn't an escaped NL) (submatch 5) or a non-escaped character
+ ;; (which isn't itself a backslash) (submatch 10). The long
+ ;; preambles to these (respectively submatches 2-4 and 6-9)
+ ;; ensure that we have the correct parity for sequences of
+ ;; backslashes, etc..
+ (concat "\\(" ; 1
+ "\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)*" ; 2-4
+ "\\(\\\\.\\)" ; 5
+ "\\|"
+ "\\(\\`\\|[^\\]\\|\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)+\\)" ; 6-9
+ "\\([^\\]\\)" ; 10
+ "\\)"
+ "\\(\\\\\n\\)*\\=")) ; 11
+ (1+ open-paren) t))
+ (if (match-beginning 10)
+ (progn
+ (c-put-char-property (match-beginning 10) 'syntax-table '(15))
+ (c-truncate-semi-nonlit-pos-cache (match-beginning 10)))
+ (c-put-char-property (match-beginning 5) 'syntax-table '(1))
+ (c-put-char-property (1+ (match-beginning 5)) 'syntax-table '(15))
+ (c-truncate-semi-nonlit-pos-cache (1+ (match-beginning 5))))
+ (c-put-char-property open-paren 'syntax-table '(1)))
+ (goto-char bound))))
+
+(defun c-after-change-re-mark-raw-strings (beg end old-len)
+ ;; This function applies `syntax-table' text properties to C++ raw strings
+ ;; beginning in the region (c-new-BEG c-new-END). BEG, END, and OLD-LEN are
+ ;; the standard arguments supplied to any after-change function.
+ ;;
+ ;; Point is undefined on both entry and exit, and the return value has no
+ ;; significance.
+ ;;
+ ;; This function is called as an after-change function solely due to its
+ ;; membership of the C++ value of `c-before-font-lock-functions'.
+ (c-save-buffer-state ()
+ ;; If the region (c-new-BEG c-new-END) has expanded, remove
+ ;; `syntax-table' text-properties from the new piece(s).
+ (when (< c-new-BEG c-old-BEG)
+ (let ((beg-rs (progn (goto-char c-old-BEG) (c-raw-string-pos))))
+ (c-depropertize-raw-strings-in-region
+ c-new-BEG
+ (if beg-rs
+ (1+ (or (nth 4 beg-rs) (nth 2 beg-rs)))
+ c-old-BEG))))
+ (when (> c-new-END c-old-END)
+ (let ((end-rs (progn (goto-char c-old-END) (c-raw-string-pos))))
+ (c-depropertize-raw-strings-in-region
+ (if end-rs
+ (cadr end-rs)
+ c-old-END)
+ c-new-END)))
+
+ (goto-char c-new-BEG)
+ (while (and (< (point) c-new-END)
+ (re-search-forward
+ (concat "\\(" ; 1
+ c-anchored-cpp-prefix ; 2
+ "\\)\\|\\(" ; 3
+ "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" ; 4
+ "\\)")
+ c-new-END t))
+ (when (save-excursion
+ (goto-char (match-beginning 0)) (not (c-in-literal)))
+ (if (match-beginning 4) ; the id
+ ;; We've found a raw string.
+ (c-propertize-raw-string-opener
+ (match-string-no-properties 4) ; id
+ (1+ (match-beginning 3)) ; open quote
+ (match-end 4) ; open paren
+ nil) ; bound
+ ;; We've found a CPP construct. Search for raw strings within it.
+ (goto-char (match-beginning 2)) ; the "#"
+ (c-end-of-macro)
+ (let ((eom (point)))
+ (goto-char (match-end 2)) ; after the "#".
+ (while (and (< (point) eom)
+ (c-syntactic-re-search-forward
+ "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" eom t))
+ (c-propertize-raw-string-opener
+ (match-string-no-properties 1) ; id
+ (1+ (match-beginning 0)) ; open quote
+ (match-end 1) ; open paren
+ eom)))))))) ; bound
+
;; Handling of small scale constructs like types and names.
@@ -5811,13 +6673,16 @@ comment at the start of cc-engine.el for more info."
`(c-forward-type)
`(c-forward-name)))
nil
- (and (looking-at c-keywords-regexp)
- (c-forward-keyword-clause 1))))
+ (cond ((looking-at c-keywords-regexp)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause)))))
(when (memq res '(t known found prefix maybe))
(when c-record-type-identifiers
- ,(if (eq type 'type)
- `(c-record-type-id c-last-identifier-range)
- `(c-record-ref-id c-last-identifier-range)))
+ ,(if (eq type 'type)
+ `(c-record-type-id c-last-identifier-range)
+ `(c-record-ref-id c-last-identifier-range)))
t)))
(defmacro c-forward-id-comma-list (type update-safe-pos)
@@ -5835,6 +6700,17 @@ comment at the start of cc-engine.el for more info."
(c-forward-syntactic-ws)
(c-forward-keyword-prefixed-id ,type)))))
+(defun c-forward-noise-clause ()
+ ;; Point is at a c-noise-macro-with-parens-names macro identifier. Go
+ ;; forward over this name, any parenthesis expression which follows it, and
+ ;; any syntactic WS, ending up at the next token. If there is an unbalanced
+ ;; paren expression, leave point at it. Always Return t.
+ (c-forward-token-2)
+ (if (and (eq (char-after) ?\()
+ (c-go-list-forward))
+ (c-forward-syntactic-ws))
+ t)
+
(defun c-forward-keyword-clause (match)
;; Submatch MATCH in the current match data is assumed to surround a
;; token. If it's a keyword, move over it and any immediately
@@ -5984,7 +6860,6 @@ comment at the start of cc-engine.el for more info."
;; `nconc' doesn't mind that the tail of
;; `c-record-found-types' is t.
(nconc c-record-found-types c-record-type-identifiers)))
- (if (c-major-mode-is 'java-mode) (c-fontify-recorded-types-and-refs))
t)
(goto-char start)
@@ -6030,28 +6905,31 @@ comment at the start of cc-engine.el for more info."
(progn
(c-forward-syntactic-ws)
(when (or (and c-record-type-identifiers all-types)
- (c-major-mode-is 'java-mode))
- ;; All encountered identifiers are types, so set the
- ;; promote flag and parse the type.
- (progn
- (c-forward-syntactic-ws)
- (if (looking-at "\\?")
- (forward-char)
- (when (looking-at c-identifier-start)
+ (not (equal c-inside-<>-type-key "\\(\\<\\>\\)")))
+ (c-forward-syntactic-ws)
+ (cond
+ ((eq (char-after) ??)
+ (forward-char))
+ ((and (looking-at c-identifier-start)
+ (not (looking-at c-keywords-regexp)))
+ (if (or (and all-types c-record-type-identifiers)
+ (c-major-mode-is 'java-mode))
+ ;; All encountered identifiers are types, so set the
+ ;; promote flag and parse the type.
(let ((c-promote-possible-types t)
(c-record-found-types t))
- (c-forward-type))))
+ (c-forward-type))
+ (c-forward-token-2))))
- (c-forward-syntactic-ws)
+ (c-forward-syntactic-ws)
- (when (or (looking-at "extends")
- (looking-at "super"))
- (forward-word-strictly)
- (c-forward-syntactic-ws)
- (let ((c-promote-possible-types t)
- (c-record-found-types t))
- (c-forward-type)
- (c-forward-syntactic-ws)))))
+ (when (looking-at c-inside-<>-type-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (let ((c-promote-possible-types t)
+ (c-record-found-types t))
+ (c-forward-type))
+ (c-forward-syntactic-ws)))
(setq pos (point)) ; e.g. first token inside the '<'
@@ -6372,9 +7250,7 @@ comment at the start of cc-engine.el for more info."
((and c-recognize-<>-arglists
(eq (char-after) ?<))
;; Maybe an angle bracket arglist.
- (when (let ((c-record-type-identifiers t)
- (c-record-found-types t)
- (c-last-identifier-range))
+ (when (let (c-last-identifier-range)
(c-forward-<>-arglist nil))
(c-forward-syntactic-ws)
@@ -6468,6 +7344,17 @@ comment at the start of cc-engine.el for more info."
; "typedef".
(goto-char (match-end 1))
(c-forward-syntactic-ws)
+
+ (while (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((looking-at c-pack-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
+
(setq pos (point))
(setq name-res (c-forward-name))
@@ -6605,6 +7492,12 @@ comment at the start of cc-engine.el for more info."
(goto-char (match-end 1))
(c-forward-syntactic-ws)))
+ ;; Skip any "WS" identifiers (e.g. "final" or "override" in C++)
+ (while (looking-at c-type-decl-suffix-ws-ids-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (setq res t))
+
(when c-opt-type-concat-key ; Only/mainly for pike.
;; Look for a trailing operator that concatenates the type
;; with a following one, and if so step past that one through
@@ -6694,6 +7587,31 @@ comment at the start of cc-engine.el for more info."
(prog1 (car ,ps)
(setq ,ps (cdr ,ps)))))
+(defun c-back-over-compound-identifier ()
+ ;; Point is putatively just after a "compound identifier", i.e. something
+ ;; looking (in C++) like this "FQN::of::base::Class". Move to the start of
+ ;; this construct and return t. If the parsing fails, return nil, leaving
+ ;; point unchanged.
+ (let ((here (point))
+ end)
+ (if (not (c-on-identifier))
+ nil
+ (c-simple-skip-symbol-backward)
+ (while
+ (progn
+ (setq end (point))
+ (c-backward-syntactic-ws)
+ (c-backward-token-2)
+ (and
+ c-opt-identifier-concat-key
+ (looking-at c-opt-identifier-concat-key)
+ (progn
+ (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))))
+ (setq end (point)))
+ (goto-char end)
+ t)))
+
(defun c-back-over-member-initializer-braces ()
;; Point is just after a closing brace/parenthesis. Try to parse this as a
;; C++ member initializer list, going back to just after the introducing ":"
@@ -6704,7 +7622,7 @@ comment at the start of cc-engine.el for more info."
(when (not (c-go-list-backward))
(throw 'done nil))
(c-backward-syntactic-ws)
- (when (not (c-simple-skip-symbol-backward))
+ (when (not (c-back-over-compound-identifier))
(throw 'done nil))
(c-backward-syntactic-ws)
@@ -6716,7 +7634,7 @@ comment at the start of cc-engine.el for more info."
(when (not (c-go-list-backward))
(throw 'done nil))
(c-backward-syntactic-ws)
- (when (not (c-simple-skip-symbol-backward))
+ (when (not (c-back-over-compound-identifier))
(throw 'done nil))
(c-backward-syntactic-ws))
@@ -6727,7 +7645,8 @@ comment at the start of cc-engine.el for more info."
(defmacro c-back-over-list-of-member-inits ()
;; Go back over a list of elements, each looking like:
;; <symbol> (<expression>) ,
- ;; or <symbol> {<expression>} ,
+ ;; or <symbol> {<expression>} , (with possibly a <....> expressions
+ ;; following the <symbol>).
;; when we are putatively immediately after a comma. Stop when we don't see
;; a comma. If either of <symbol> or bracketed <expression> is missing,
;; throw nil to 'level. If the terminating } or ) is unmatched, throw nil
@@ -6740,7 +7659,11 @@ comment at the start of cc-engine.el for more info."
(when (not (c-go-list-backward))
(throw 'done nil))
(c-backward-syntactic-ws)
- (when (not (c-simple-skip-symbol-backward))
+ (while (eq (char-before) ?>)
+ (when (not (c-backward-<>-arglist nil))
+ (throw 'done nil))
+ (c-backward-syntactic-ws))
+ (when (not (c-back-over-compound-identifier))
(throw 'level nil))
(c-backward-syntactic-ws)))
@@ -6762,7 +7685,7 @@ comment at the start of cc-engine.el for more info."
(when (not (c-go-list-backward))
(throw 'done nil))
(c-backward-syntactic-ws))
- (when (c-simple-skip-symbol-backward)
+ (when (c-back-over-compound-identifier)
(c-backward-syntactic-ws))
(c-back-over-list-of-member-inits)
(and (eq (char-before) ?:)
@@ -6778,7 +7701,7 @@ comment at the start of cc-engine.el for more info."
(catch 'level
(goto-char pos)
(c-backward-syntactic-ws)
- (when (not (c-simple-skip-symbol-backward))
+ (when (not (c-back-over-compound-identifier))
(throw 'level nil))
(c-backward-syntactic-ws)
(c-back-over-list-of-member-inits)
@@ -6839,10 +7762,12 @@ comment at the start of cc-engine.el for more info."
;; Assuming point is at the start of a declarator, move forward over it,
;; leaving point at the next token after it (e.g. a ) or a ; or a ,).
;;
- ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT), where ID-START and
- ;; ID-END are the bounds of the declarator's identifier, and
- ;; BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id.
- ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(".
+ ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED),
+ ;; where ID-START and ID-END are the bounds of the declarator's identifier,
+ ;; and BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id.
+ ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(",
+ ;; DECORATED is non-nil when the identifier is embellished by an operator,
+ ;; like "*x", or "(*x)".
;;
;; If ACCEPT-ANON is non-nil, move forward over any "anonymous declarator",
;; i.e. something like the (*) in int (*), such as might be found in a
@@ -6861,7 +7786,7 @@ comment at the start of cc-engine.el for more info."
;; array/struct initialization) or "=" or terminating delimiter
;; (e.g. "," or ";" or "}").
(let ((here (point))
- id-start id-end brackets-after-id paren-depth)
+ id-start id-end brackets-after-id paren-depth decorated)
(or limit (setq limit (point-max)))
(if (and
(< (point) limit)
@@ -6875,31 +7800,41 @@ comment at the start of cc-engine.el for more info."
;; of the while. These are, e.g. "*" in "int *foo" or "(" and
;; "*" in "int (*foo) (void)" (Note similar code in
;; `c-forward-decl-or-cast-1'.)
- (while (and (looking-at c-type-decl-prefix-key)
- (if (and (c-major-mode-is 'c++-mode)
- (match-beginning 3))
- ;; If the third submatch matches in C++ then
- ;; we're looking at an identifier that's a
- ;; prefix only if it specifies a member pointer.
- (progn
- (setq id-start (point))
- (c-forward-name)
- (if (looking-at "\\(::\\)")
- ;; We only check for a trailing "::" and
- ;; let the "*" that should follow be
- ;; matched in the next round.
- t
- ;; It turned out to be the real identifier,
- ;; so flag that and stop.
- (setq got-identifier t)
- nil))
- t))
- (if (eq (char-after) ?\()
- (progn
- (setq paren-depth (1+ paren-depth))
- (forward-char))
- (goto-char (match-end 1)))
- (c-forward-syntactic-ws))
+ (while
+ (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))
+ ((and (looking-at c-type-decl-prefix-key)
+ (if (and (c-major-mode-is 'c++-mode)
+ (match-beginning 3))
+ ;; If the third submatch matches in C++ then
+ ;; we're looking at an identifier that's a
+ ;; prefix only if it specifies a member pointer.
+ (progn
+ (setq id-start (point))
+ (c-forward-name)
+ (if (looking-at "\\(::\\)")
+ ;; We only check for a trailing "::" and
+ ;; let the "*" that should follow be
+ ;; matched in the next round.
+ t
+ ;; It turned out to be the real identifier,
+ ;; so flag that and stop.
+ (setq got-identifier t)
+ nil))
+ t))
+ (if (looking-at c-type-decl-operator-prefix-key)
+ (setq decorated t))
+ (if (eq (char-after) ?\()
+ (progn
+ (setq paren-depth (1+ paren-depth))
+ (forward-char))
+ (goto-char (match-end 1)))
+ (c-forward-syntactic-ws)
+ t)))
;; If we haven't passed the identifier already, do it now.
(unless got-identifier
@@ -6924,9 +7859,13 @@ comment at the start of cc-engine.el for more info."
;; Skip over any trailing bit, such as "__attribute__".
(progn
- (when (looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1))
- (<= (point) limit))
+ (while (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
+ (<= (point) limit))
;; Search syntactically to the end of the declarator (";",
;; ",", a closing paren, eob etc) or to the beginning of an
@@ -6943,7 +7882,7 @@ comment at the start of cc-engine.el for more info."
(setq brackets-after-id t))
(backward-char)
found))
- (list id-start id-end brackets-after-id (match-beginning 1))
+ (list id-start id-end brackets-after-id (match-beginning 1) decorated)
(goto-char here)
nil)))
@@ -6957,9 +7896,9 @@ comment at the start of cc-engine.el for more info."
;; If a declaration is parsed:
;;
;; The point is left at the first token after the first complete
- ;; declarator, if there is one. The return value is a cons where
- ;; the car is the position of the first token in the declarator. (See
- ;; below for the cdr.)
+ ;; declarator, if there is one. The return value is a list of 4 elements,
+ ;; where the first is the position of the first token in the declarator.
+ ;; (See below for the other three.)
;; Some examples:
;;
;; void foo (int a, char *b) stuff ...
@@ -6990,7 +7929,7 @@ comment at the start of cc-engine.el for more info."
;;
;;
;;
- ;; The cdr of the return value is non-nil when a
+ ;; The second element of the return value is non-nil when a
;; `c-typedef-decl-kwds' specifier is found in the declaration.
;; Specifically it is a dotted pair (A . B) where B is t when a
;; `c-typedef-kwds' ("typedef") is present, and A is t when some
@@ -6998,6 +7937,10 @@ comment at the start of cc-engine.el for more info."
;; specifier is present. I.e., (some of) the declared
;; identifier(s) are types.
;;
+ ;; The third element of the return value is non-nil when the declaration
+ ;; parsed might be an expression. The fourth element is the position of
+ ;; the start of the type identifier.
+ ;;
;; If a cast is parsed:
;;
;; The point is left at the first token after the closing paren of
@@ -7015,8 +7958,13 @@ comment at the start of cc-engine.el for more info."
;; inside a function declaration arglist).
;; '<> In an angle bracket arglist.
;; 'arglist Some other type of arglist.
+ ;; 'top Some other context and point is at the top-level (either
+ ;; outside any braces or directly inside a class or namespace,
+ ;; etc.)
;; nil Some other context or unknown context. Includes
;; within the parens of an if, for, ... construct.
+ ;; 'not-decl This value is never supplied to this function. It
+ ;; would mean we're definitely not in a declaration.
;;
;; LAST-CAST-END is the first token after the closing paren of a
;; preceding cast, or nil if none is known. If
@@ -7090,12 +8038,27 @@ comment at the start of cc-engine.el for more info."
cast-end
;; Have we got a new-style C++11 "auto"?
new-style-auto
+ ;; Set when the symbol before `preceding-token-end' is known to
+ ;; terminate the previous construct, or when we're at point-min.
+ at-decl-start
;; Save `c-record-type-identifiers' and
;; `c-record-ref-identifiers' since ranges are recorded
;; speculatively and should be thrown away if it turns out
;; that it isn't a declaration or cast.
(save-rec-type-ids c-record-type-identifiers)
- (save-rec-ref-ids c-record-ref-identifiers))
+ (save-rec-ref-ids c-record-ref-identifiers)
+ ;; Set when we parse a declaration which might also be an expression,
+ ;; such as "a *b". See CASE 16 and CASE 17.
+ maybe-expression)
+
+ (save-excursion
+ (goto-char preceding-token-end)
+ (setq at-decl-start
+ (or (bobp)
+ (let ((tok-end (point)))
+ (c-backward-token-2)
+ (member (buffer-substring-no-properties (point) tok-end)
+ c-pre-start-tokens)))))
(while (c-forward-annotation)
(c-forward-syntactic-ws))
@@ -7105,18 +8068,25 @@ comment at the start of cc-engine.el for more info."
;; macros like __INLINE__, so we recognize both types and known
;; specifiers after them too.
(while
- (let* ((start (point)) kwd-sym kwd-clause-end found-type)
+ (let* ((start (point)) kwd-sym kwd-clause-end found-type noise-start)
+ (cond
;; Look for a specifier keyword clause.
- (when (or (looking-at c-prefix-spec-kwds-re) ;FIXME!!! includes auto
- (and (c-major-mode-is 'java-mode)
- (looking-at "@[A-Za-z0-9]+")))
- (if (save-match-data (looking-at c-typedef-key))
- (setq at-typedef t))
+ ((or (looking-at c-prefix-spec-kwds-re)
+ (and (c-major-mode-is 'java-mode)
+ (looking-at "@[A-Za-z0-9]+")))
+ (save-match-data
+ (if (looking-at c-typedef-key)
+ (setq at-typedef t)))
(setq kwd-sym (c-keyword-sym (match-string 1)))
(save-excursion
(c-forward-keyword-clause 1)
(setq kwd-clause-end (point))))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (setq noise-start (point))
+ (c-forward-noise-clause)
+ (setq kwd-clause-end (point))))
(when (setq found-type (c-forward-type t)) ; brace-block-too
;; Found a known or possible type or a prefix of a known type.
@@ -7154,16 +8124,17 @@ comment at the start of cc-engine.el for more info."
backup-at-type-decl nil
backup-maybe-typeless nil))
- (if kwd-sym
+ (if (or kwd-sym noise-start)
(progn
;; Handle known specifier keywords and
;; `c-decl-hangon-kwds' which can occur after known
;; types.
- (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
- ;; It's a hang-on keyword that can occur anywhere.
+ (if (or (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
+ noise-start)
+ ;; It's a hang-on keyword or noise clause that can occur
+ ;; anywhere.
(progn
- (setq at-decl-or-cast t)
(if at-type
;; Move the identifier start position if
;; we've passed a type.
@@ -7215,8 +8186,12 @@ comment at the start of cc-engine.el for more info."
;; If a known type was found, we still need to skip over any
;; hangon keyword clauses after it. Otherwise it has already
;; been done in the loop above.
- (while (looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1))
+ (while
+ (cond ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
(setq id-start (point)))
((eq at-type 'prefix)
@@ -7297,7 +8272,10 @@ comment at the start of cc-engine.el for more info."
;; arglist paren that gets entered.
c-parse-and-markup-<>-arglists
;; Start of the identifier for which `got-identifier' was set.
- name-start)
+ name-start
+ ;; Position after (innermost) open parenthesis encountered in the
+ ;; prefix operators.
+ after-paren-pos)
(goto-char id-start)
@@ -7308,7 +8286,8 @@ comment at the start of cc-engine.el for more info."
(when (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
- (forward-char)))
+ (forward-char)
+ (setq after-paren-pos (point))))
(while (and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(match-beginning 3))
@@ -7331,7 +8310,8 @@ comment at the start of cc-engine.el for more info."
(if (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
- (forward-char))
+ (forward-char)
+ (setq after-paren-pos (point)))
(unless got-prefix-before-parens
(setq got-prefix-before-parens (= paren-depth 0)))
(setq got-prefix t)
@@ -7340,55 +8320,69 @@ comment at the start of cc-engine.el for more info."
(setq got-parens (> paren-depth 0))
- ;; Skip over an identifier.
+ ;; Try to skip over an identifier.
(or got-identifier
(and (looking-at c-identifier-start)
(setq pos (point))
(setq got-identifier (c-forward-name))
(setq name-start pos)))
- ;; Skip over type decl suffix operators.
- (while (if (looking-at c-type-decl-suffix-key)
+ ;; Skip over type decl suffix operators and trailing noise macros.
+ (while
+ (cond
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))
+
+ ((looking-at c-type-decl-suffix-key)
+ (if (eq (char-after) ?\))
+ (when (> paren-depth 0)
+ (setq paren-depth (1- paren-depth))
+ (forward-char)
+ t)
+ (when (if (save-match-data (looking-at "\\s("))
+ (c-safe (c-forward-sexp 1) t)
+ (goto-char (match-end 1))
+ t)
+ (when (and (not got-suffix-after-parens)
+ (= paren-depth 0))
+ (setq got-suffix-after-parens (match-beginning 0)))
+ (setq got-suffix t))))
- (if (eq (char-after) ?\))
- (when (> paren-depth 0)
- (setq paren-depth (1- paren-depth))
- (forward-char)
- t)
- (when (if (save-match-data (looking-at "\\s("))
- (c-safe (c-forward-sexp 1) t)
- (goto-char (match-end 1))
- t)
- (when (and (not got-suffix-after-parens)
- (= paren-depth 0))
- (setq got-suffix-after-parens (match-beginning 0)))
- (setq got-suffix t)))
-
- ;; No suffix matched. We might have matched the
- ;; identifier as a type and the open paren of a
- ;; function arglist as a type decl prefix. In that
- ;; case we should "backtrack": Reinterpret the last
- ;; type as the identifier, move out of the arglist and
- ;; continue searching for suffix operators.
- ;;
- ;; Do this even if there's no preceding type, to cope
- ;; with old style function declarations in K&R C,
- ;; (con|de)structors in C++ and `c-typeless-decl-kwds'
- ;; style declarations. That isn't applicable in an
- ;; arglist context, though.
- (when (and (= paren-depth 1)
+ (t
+ ;; No suffix matched. We might have matched the
+ ;; identifier as a type and the open paren of a
+ ;; function arglist as a type decl prefix. In that
+ ;; case we should "backtrack": Reinterpret the last
+ ;; type as the identifier, move out of the arglist and
+ ;; continue searching for suffix operators.
+ ;;
+ ;; Do this even if there's no preceding type, to cope
+ ;; with old style function declarations in K&R C,
+ ;; (con|de)structors in C++ and `c-typeless-decl-kwds'
+ ;; style declarations. That isn't applicable in an
+ ;; arglist context, though.
+ (when (and (= paren-depth 1)
(not got-prefix-before-parens)
(not (eq at-type t))
(or backup-at-type
maybe-typeless
backup-maybe-typeless
(when c-recognize-typeless-decls
- (not context)))
+ (and (memq context '(nil top))
+ ;; Deal with C++11's "copy-initialization"
+ ;; where we have <type>(<constant>), by
+ ;; contrasting with a typeless
+ ;; <name>(<type><parameter>, ...).
+ (save-excursion
+ (goto-char after-paren-pos)
+ (c-forward-syntactic-ws)
+ (c-forward-type)))))
(setq pos (c-up-list-forward (point)))
(eq (char-before pos) ?\)))
(c-fdoc-shift-type-backward)
(goto-char pos)
- t))
+ t)))
(c-forward-syntactic-ws))
@@ -7412,6 +8406,11 @@ comment at the start of cc-engine.el for more info."
(setq type-start (point))
(setq at-type (c-forward-type))))
+ ;; Move forward over any "WS" ids (like "final" or "override" in C++)
+ (while (looking-at c-type-decl-suffix-ws-ids-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws))
+
(setq
at-decl-or-cast
(catch 'at-decl-or-cast
@@ -7421,15 +8420,19 @@ comment at the start of cc-engine.el for more info."
;; Encountered something inside parens that isn't matched by
;; the `c-type-decl-*' regexps, so it's not a type decl
;; expression. Try to skip out to the same paren depth to
- ;; not confuse the cast check below.
- (c-safe (goto-char (scan-lists (point) 1 paren-depth)))
+ ;; not confuse the cast check below. If we don't manage this and
+ ;; `at-decl-or-cast' is 'ids we might have an expression like
+ ;; "foo bar ({ ..." which is a valid C++11 initialization.
+ (if (and (not (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
+ (eq at-decl-or-cast 'ids))
+ (c-fdoc-shift-type-backward))
;; If we've found a specifier keyword then it's a
;; declaration regardless.
- (throw 'at-decl-or-cast (eq at-decl-or-cast t)))
+ (throw 'at-decl-or-cast (memq at-decl-or-cast '(t ids))))
(setq at-decl-end
(looking-at (cond ((eq context '<>) "[,>]")
- (context "[,)]")
+ ((not (memq context '(nil top))) "[,\)]")
(t "[,;]"))))
;; Now we've collected info about various characteristics of
@@ -7454,16 +8457,32 @@ comment at the start of cc-engine.el for more info."
maybe-typeless
backup-maybe-typeless
(eq at-decl-or-cast t)
+ ;; Check whether we have "bar (gnu);" where we
+ ;; are directly inside a class (etc.) called "bar".
(save-excursion
- (goto-char name-start)
- (not (memq (c-forward-type) '(nil maybe))))))
+ (and
+ (progn
+ (goto-char name-start)
+ (not (memq (c-forward-type) '(nil maybe))))
+ (progn
+ (goto-char id-start)
+ (c-directly-in-class-called-p
+ (buffer-substring
+ type-start
+ (progn
+ (goto-char type-start)
+ (c-forward-type)
+ (c-backward-syntactic-ws)
+ (point)))))))))
;; Got a declaration of the form "foo bar (gnu);" or "bar
;; (gnu);" where we've recognized "bar" as the type and "gnu"
- ;; as the declarator. In this case it's however more likely
- ;; that "bar" is the declarator and "gnu" a function argument
- ;; or initializer (if `c-recognize-paren-inits' is set),
- ;; since the parens around "gnu" would be superfluous if it's
- ;; a declarator. Shift the type one step backward.
+ ;; as the declarator, and in the latter case, checked that
+ ;; "bar (gnu)" appears directly inside the class "bar". In
+ ;; this case it's however more likely that "bar" is the
+ ;; declarator and "gnu" a function argument or initializer
+ ;; (if `c-recognize-paren-inits' is set), since the parens
+ ;; around "gnu" would be superfluous if it's a declarator.
+ ;; Shift the type one step backward.
(c-fdoc-shift-type-backward)))
;; Found no identifier.
@@ -7542,7 +8561,7 @@ comment at the start of cc-engine.el for more info."
(if (and got-parens
(not got-prefix)
- (not context)
+ (memq context '(nil top))
(not (eq at-type t))
(or backup-at-type
maybe-typeless
@@ -7592,6 +8611,18 @@ comment at the start of cc-engine.el for more info."
;; instantiation expression).
(throw 'at-decl-or-cast nil))))
+ ;; CASE 9.5
+ (when (and (not context) ; i.e. not at top level.
+ (c-major-mode-is 'c++-mode)
+ (eq at-decl-or-cast 'ids)
+ after-paren-pos)
+ ;; We've got something like "foo bar (...)" in C++ which isn't at
+ ;; the top level. This is probably a uniform initialization of bar
+ ;; to the contents of the parens. In this case the declarator ends
+ ;; at the open paren.
+ (goto-char (1- after-paren-pos))
+ (throw 'at-decl-or-cast t))
+
;; CASE 10
(when at-decl-or-cast
;; By now we've located the type in the declaration that we know
@@ -7600,8 +8631,10 @@ comment at the start of cc-engine.el for more info."
;; CASE 11
(when (and got-identifier
- (not context)
(looking-at c-after-suffixed-type-decl-key)
+ (or (eq context 'top)
+ (and (eq context nil)
+ (match-beginning 1)))
(if (and got-parens
(not got-prefix)
(not got-suffix)
@@ -7696,13 +8729,17 @@ comment at the start of cc-engine.el for more info."
(when (and got-prefix-before-parens
at-type
(or at-decl-end (looking-at "=[^=]"))
- (not context)
- (not got-suffix))
- ;; Got something like "foo * bar;". Since we're not inside an
- ;; arglist it would be a meaningless expression because the
- ;; result isn't used. We therefore choose to recognize it as
- ;; a declaration. Do not allow a suffix since it could then
- ;; be a function call.
+ (memq context '(nil top))
+ (or (not got-suffix)
+ at-decl-start))
+ ;; Got something like "foo * bar;". Since we're not inside
+ ;; an arglist it would be a meaningless expression because
+ ;; the result isn't used. We therefore choose to recognize
+ ;; it as a declaration. We only allow a suffix (which makes
+ ;; the construct look like a function call) when
+ ;; `at-decl-start' provides additional evidence that we do
+ ;; have a declaration.
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t))
;; CASE 17
@@ -7714,10 +8751,11 @@ comment at the start of cc-engine.el for more info."
;; be an odd expression or it could be a declaration. Treat
;; it as a declaration if "a" has been used as a type
;; somewhere else (if it's a known type we won't get here).
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t)))
;; CASE 18
- (when (and context
+ (when (and (not (memq context '(nil top)))
(or got-prefix
(and (eq context 'decl)
(not c-recognize-paren-inits)
@@ -7837,9 +8875,11 @@ comment at the start of cc-engine.el for more info."
(goto-char type-start)
(c-forward-type))))
- (cons id-start
+ (list id-start
(and (or at-type-decl at-typedef)
- (cons at-type-decl at-typedef))))
+ (cons at-type-decl at-typedef))
+ maybe-expression
+ type-start))
(t
;; False alarm. Restore the recorded ranges.
@@ -8272,7 +9312,7 @@ comment at the start of cc-engine.el for more info."
(c-forward-objc-directive)))
(setq id-start
- (car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil)))
+ (car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil)))
(< id-start beg)
;; There should not be a '=' or ',' between beg and the
@@ -8598,7 +9638,8 @@ comment at the start of cc-engine.el for more info."
(/= last-stmt-start (point))
(progn
(c-backward-syntactic-ws lim)
- (not (memq (char-before) '(?\; ?} ?: nil))))
+ (not (or (memq (char-before) '(?\; ?} ?: nil))
+ (c-at-vsemi-p))))
(save-excursion
(backward-char)
(not (looking-at "\\s(")))
@@ -8773,6 +9814,22 @@ comment at the start of cc-engine.el for more info."
(c-syntactic-skip-backward c-block-prefix-charset limit t)
(eq (char-before) ?>))))))
+ ;; Skip back over noise clauses.
+ (while (and
+ c-opt-cpp-prefix
+ (eq (char-before) ?\))
+ (let ((after-paren (point)))
+ (if (and (c-go-list-backward)
+ (progn (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))
+ (or (looking-at c-paren-nontype-key)
+ (looking-at c-noise-macro-with-parens-name-re)))
+ (progn
+ (c-syntactic-skip-backward c-block-prefix-charset limit t)
+ t)
+ (goto-char after-paren)
+ nil))))
+
;; Note: Can't get bogus hits inside template arglists below since they
;; have gotten paren syntax above.
(when (and
@@ -8879,6 +9936,26 @@ comment at the start of cc-engine.el for more info."
kwd-start)))
+(defun c-directly-in-class-called-p (name)
+ ;; Check whether point is directly inside a brace block which is the brace
+ ;; block of a class, struct, or union which is called NAME, a string.
+ (let* ((paren-state (c-parse-state))
+ (brace-pos (c-pull-open-brace paren-state))
+ )
+ (when (eq (char-after brace-pos) ?{)
+ (goto-char brace-pos)
+ (save-excursion
+ ; *c-looking-at-decl-block
+ ; containing-sexp goto-start &optional
+ ; limit)
+ (when (and (c-looking-at-decl-block
+ (c-pull-open-brace paren-state)
+ nil)
+ (looking-at c-class-key))
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (looking-at name))))))
+
(defun c-search-uplist-for-classkey (paren-state)
;; Check if the closest containing paren sexp is a declaration
;; block, returning a 2 element vector in that case. Aref 0
@@ -8945,7 +10022,10 @@ comment at the start of cc-engine.el for more info."
((and (eql (char-after) ?:)
(save-excursion
(c-backward-syntactic-ws)
- (c-on-identifier)))
+ (or (c-on-identifier)
+ (progn
+ (c-backward-token-2)
+ (looking-at c-brace-list-key)))))
(setq colon-pos (point))
(forward-char)
(c-forward-syntactic-ws)
@@ -8986,6 +10066,12 @@ comment at the start of cc-engine.el for more info."
t)
((looking-at c-after-brace-list-key) t)
((looking-at c-brace-list-key) nil)
+ ((eq (char-after) ?\()
+ (and (eq (c-backward-token-2) 0)
+ (or (looking-at c-decl-hangon-key)
+ (and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re)))))
+
((and c-recognize-<>-arglists
(eq (char-after) ?<)
(looking-at "\\s("))
@@ -8994,6 +10080,186 @@ comment at the start of cc-engine.el for more info."
(or (looking-at c-brace-list-key)
(progn (goto-char here) nil))))
+(defun c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim)
+ ;; Point is at an open brace. If this starts a brace list, return a list
+ ;; whose car is the buffer position of the start of the construct which
+ ;; introduces the list, and whose cdr is t if we have parsed a keyword
+ ;; matching `c-opt-inexpr-brace-list-key' (e.g. Java's "new"), nil
+ ;; otherwise. Otherwise, if point might be inside an enclosing brace list,
+ ;; return t. If point is definitely neither at nor in a brace list, return
+ ;; nil.
+ ;;
+ ;; CONTAINING-SEXP is the position of the brace/paren/bracket enclosing
+ ;; POINT, or nil if there is no such position, or we do not know it. LIM is
+ ;; a backward search limit.
+ ;;
+ ;; Here, "brace list" does not include the body of an enum.
+ (save-excursion
+ (let ((start (point))
+ (class-key
+ ;; Pike can have class definitions anywhere, so we must
+ ;; check for the class key here.
+ (and (c-major-mode-is 'pike-mode)
+ c-decl-block-key))
+ (braceassignp 'dontknow)
+ inexpr-brace-list bufpos macro-start res pos after-type-id-pos)
+
+ (setq res (c-backward-token-2 1 t lim))
+ ;; Checks to do only on the first sexp before the brace.
+ ;; Have we a C++ initialization, without an "="?
+ (if (and (c-major-mode-is 'c++-mode)
+ (cond
+ ((and (not (eq res 0))
+ (c-go-up-list-backward nil lim) ; FIXME!!! Check ; `lim' 2016-07-12.
+ (eq (char-after) ?\())
+ (setq braceassignp 'c++-noassign))
+ ((looking-at c-pre-id-bracelist-key))
+ ((looking-at c-return-key))
+ ((and (looking-at c-symbol-start)
+ (not (looking-at c-keywords-regexp)))
+ (setq after-type-id-pos (point)))
+ (t nil))
+ (save-excursion
+ (cond
+ ((not (eq res 0))
+ (and (c-go-up-list-backward nil lim) ; FIXME!!! Check `lim' 2016-07-12.
+ (eq (char-after) ?\()))
+ ((looking-at c-pre-id-bracelist-key))
+ ((looking-at c-return-key))
+ (t (setq after-type-id-pos (point))
+ nil))))
+ (setq braceassignp 'c++-noassign))
+
+ (when (and c-opt-inexpr-brace-list-key
+ (eq (char-after) ?\[))
+ ;; In Java, an initialization brace list may follow
+ ;; directly after "new Foo[]", so check for a "new"
+ ;; earlier.
+ (while (eq braceassignp 'dontknow)
+ (setq braceassignp
+ (cond ((/= (c-backward-token-2 1 t lim) 0) nil)
+ ((looking-at c-opt-inexpr-brace-list-key)
+ (setq inexpr-brace-list t)
+ t)
+ ((looking-at "\\sw\\|\\s_\\|[.[]")
+ ;; Carry on looking if this is an
+ ;; identifier (may contain "." in Java)
+ ;; or another "[]" sexp.
+ 'dontknow)
+ (t nil)))))
+
+ (setq pos (point))
+ (if (and after-type-id-pos
+ (goto-char after-type-id-pos)
+ (setq res (c-back-over-member-initializers))
+ (goto-char res)
+ (eq (car (c-beginning-of-decl-1 lim)) 'same))
+ (cons (point) nil) ; Return value.
+
+ (goto-char pos)
+ ;; Checks to do on all sexps before the brace, up to the
+ ;; beginning of the statement.
+ (while (eq braceassignp 'dontknow)
+ (cond ((eq (char-after) ?\;)
+ (setq braceassignp nil))
+ ((and class-key
+ (looking-at class-key))
+ (setq braceassignp nil))
+ ((eq (char-after) ?=)
+ ;; We've seen a =, but must check earlier tokens so
+ ;; that it isn't something that should be ignored.
+ (setq braceassignp 'maybe)
+ (while (and (eq braceassignp 'maybe)
+ (zerop (c-backward-token-2 1 t lim)))
+ (setq braceassignp
+ (cond
+ ;; Check for operator =
+ ((and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix))
+ nil)
+ ;; Check for `<opchar>= in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (or (eq (char-after) ?`)
+ ;; Special case for Pikes
+ ;; `[]=, since '[' is not in
+ ;; the punctuation class.
+ (and (eq (char-after) ?\[)
+ (eq (char-before) ?`))))
+ nil)
+ ((looking-at "\\s.") 'maybe)
+ ;; make sure we're not in a C++ template
+ ;; argument assignment
+ ((and
+ (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (let ((here (point))
+ (pos< (progn
+ (skip-chars-backward "^<>")
+ (point))))
+ (and (eq (char-before) ?<)
+ (not (c-crosses-statement-barrier-p
+ pos< here))
+ (not (c-in-literal))
+ ))))
+ nil)
+ (t t))))))
+ (if (and (eq braceassignp 'dontknow)
+ (/= (c-backward-token-2 1 t lim) 0))
+ (setq braceassignp nil)))
+
+ (cond
+ (braceassignp
+ ;; We've hit the beginning of the aggregate list.
+ (c-beginning-of-statement-1 containing-sexp)
+ (cons (point) inexpr-brace-list))
+ ((and after-type-id-pos
+ (save-excursion
+ (when (eq (char-after) ?\;)
+ (c-forward-token-2 1 t))
+ (setq bufpos (point))
+ (when (looking-at c-opt-<>-sexp-key)
+ (c-forward-token-2)
+ (when (and (eq (char-after) ?<)
+ (c-get-char-property (point) 'syntax-table))
+ (c-go-list-forward nil after-type-id-pos)
+ (c-forward-syntactic-ws)))
+ (and
+ (or (not (looking-at c-class-key))
+ (save-excursion
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (not (eq (point) after-type-id-pos))))
+ (progn
+ (setq res
+ (c-forward-decl-or-cast-1
+ (save-excursion (c-backward-syntactic-ws) (point))
+ nil nil))
+ (and (consp res)
+ (eq (car res) after-type-id-pos))))))
+ (cons bufpos inexpr-brace-list))
+ ((eq (char-after) ?\;)
+ ;; Brace lists can't contain a semicolon, so we're done.
+ ;; (setq containing-sexp nil)
+ nil)
+ ((and (setq macro-start (point))
+ (c-forward-to-cpp-define-body)
+ (eq (point) start))
+ ;; We've a macro whose expansion starts with the '{'.
+ ;; Heuristically, if we have a ';' in it we've not got a
+ ;; brace list, otherwise we have.
+ (let ((macro-end (progn (c-end-of-macro) (point))))
+ (goto-char start)
+ (forward-char)
+ (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t)
+ (eq (char-before) ?\;))
+ nil
+ (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no
+ ; languages where
+ ; `c-opt-inexpr-brace-list-key' is
+ ; non-nil and we have macros.
+ (t t))) ;; The caller can go up one level.
+ )))
+
(defun c-inside-bracelist-p (containing-sexp paren-state)
;; return the buffer position of the beginning of the brace list
;; statement if we're inside a brace list, otherwise return nil.
@@ -9013,13 +10279,9 @@ comment at the start of cc-engine.el for more info."
(c-backward-over-enum-header))
;; this will pick up array/aggregate init lists, even if they are nested.
(save-excursion
- (let ((class-key
- ;; Pike can have class definitions anywhere, so we must
- ;; check for the class key here.
- (and (c-major-mode-is 'pike-mode)
- c-decl-block-key))
- bufpos braceassignp lim next-containing macro-start)
- (while (and (not bufpos)
+ (let ((bufpos t)
+ lim next-containing)
+ (while (and (eq bufpos t)
containing-sexp)
(when paren-state
(if (consp (car paren-state))
@@ -9029,113 +10291,22 @@ comment at the start of cc-engine.el for more info."
(when paren-state
(setq next-containing (car paren-state)
paren-state (cdr paren-state))))
+
(goto-char containing-sexp)
(if (c-looking-at-inexpr-block next-containing next-containing)
;; We're in an in-expression block of some kind. Do not
;; check nesting. We deliberately set the limit to the
;; containing sexp, so that c-looking-at-inexpr-block
;; doesn't check for an identifier before it.
- (setq containing-sexp nil)
- ;; see if the open brace is preceded by = or [...] in
- ;; this statement, but watch out for operator=
- (setq braceassignp 'dontknow)
- (c-backward-token-2 1 t lim)
- ;; Checks to do only on the first sexp before the brace.
- (when (and c-opt-inexpr-brace-list-key
- (eq (char-after) ?\[))
- ;; In Java, an initialization brace list may follow
- ;; directly after "new Foo[]", so check for a "new"
- ;; earlier.
- (while (eq braceassignp 'dontknow)
- (setq braceassignp
- (cond ((/= (c-backward-token-2 1 t lim) 0) nil)
- ((looking-at c-opt-inexpr-brace-list-key) t)
- ((looking-at "\\sw\\|\\s_\\|[.[]")
- ;; Carry on looking if this is an
- ;; identifier (may contain "." in Java)
- ;; or another "[]" sexp.
- 'dontknow)
- (t nil)))))
- ;; Checks to do on all sexps before the brace, up to the
- ;; beginning of the statement.
- (while (eq braceassignp 'dontknow)
- (cond ((eq (char-after) ?\;)
- (setq braceassignp nil))
- ((and class-key
- (looking-at class-key))
- (setq braceassignp nil))
- ((eq (char-after) ?=)
- ;; We've seen a =, but must check earlier tokens so
- ;; that it isn't something that should be ignored.
- (setq braceassignp 'maybe)
- (while (and (eq braceassignp 'maybe)
- (zerop (c-backward-token-2 1 t lim)))
- (setq braceassignp
- (cond
- ;; Check for operator =
- ((and c-opt-op-identifier-prefix
- (looking-at c-opt-op-identifier-prefix))
- nil)
- ;; Check for `<opchar>= in Pike.
- ((and (c-major-mode-is 'pike-mode)
- (or (eq (char-after) ?`)
- ;; Special case for Pikes
- ;; `[]=, since '[' is not in
- ;; the punctuation class.
- (and (eq (char-after) ?\[)
- (eq (char-before) ?`))))
- nil)
- ((looking-at "\\s.") 'maybe)
- ;; make sure we're not in a C++ template
- ;; argument assignment
- ((and
- (c-major-mode-is 'c++-mode)
- (save-excursion
- (let ((here (point))
- (pos< (progn
- (skip-chars-backward "^<>")
- (point))))
- (and (eq (char-before) ?<)
- (not (c-crosses-statement-barrier-p
- pos< here))
- (not (c-in-literal))
- ))))
- nil)
- (t t))))))
- (if (and (eq braceassignp 'dontknow)
- (/= (c-backward-token-2 1 t lim) 0))
- (setq braceassignp nil)))
- (cond
- (braceassignp
- ;; We've hit the beginning of the aggregate list.
- (c-beginning-of-statement-1
- (c-most-enclosing-brace paren-state))
- (setq bufpos (point)))
- ((eq (char-after) ?\;)
- ;; Brace lists can't contain a semicolon, so we're done.
- (setq containing-sexp nil))
- ((and (setq macro-start (point))
- (c-forward-to-cpp-define-body)
- (eq (point) containing-sexp))
- ;; We've a macro whose expansion starts with the '{'.
- ;; Heuristically, if we have a ';' in it we've not got a
- ;; brace list, otherwise we have.
- (let ((macro-end (progn (c-end-of-macro) (point))))
- (goto-char containing-sexp)
- (forward-char)
- (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t)
- (eq (char-before) ?\;))
- (setq bufpos nil
- containing-sexp nil)
- (setq bufpos macro-start))))
- (t
- ;; Go up one level
+ (setq bufpos nil)
+ (when (or (not (eq (char-after) ?{))
+ (eq (setq bufpos (c-looking-at-or-maybe-in-bracelist
+ next-containing lim))
+ t))
(setq containing-sexp next-containing
lim nil
- next-containing nil)))))
-
- bufpos))
- ))
+ next-containing nil))))
+ (and (consp bufpos) (car bufpos))))))
(defun c-looking-at-special-brace-list (&optional lim)
;; If we're looking at the start of a pike-style list, i.e., `({ })',
@@ -9231,12 +10402,27 @@ comment at the start of cc-engine.el for more info."
;; This function might do hidden buffer changes.
(save-excursion
- (let ((res 'maybe) passed-paren
+ (let ((res 'maybe) (passed-bracket-pairs 0) bracket-pos passed-paren
+ haskell-op-pos
(closest-lim (or containing-sexp lim (point-min)))
;; Look at the character after point only as a last resort
;; when we can't disambiguate.
(block-follows (and (eq (char-after) ?{) (point))))
+ ;; Search for a C++11 "->" which suggests a lambda declaration.
+ (when (and (c-major-mode-is 'c++-mode)
+ (setq haskell-op-pos
+ (save-excursion
+ (while
+ (progn
+ (c-syntactic-skip-backward "^;=}>" closest-lim t)
+ (and (eq (char-before) ?>)
+ (c-backward-token-2)
+ (not (looking-at c-haskell-op-re)))))
+ (and (looking-at c-haskell-op-re)
+ (point)))))
+ (goto-char haskell-op-pos))
+
(while (and (eq res 'maybe)
(progn (c-backward-syntactic-ws)
(> (point) closest-lim))
@@ -9274,6 +10460,11 @@ comment at the start of cc-engine.el for more info."
(zerop (c-forward-token-2 1 t)))
(eq (char-after) ?\())))
(cons 'inexpr-class (point))))
+ ((c-keyword-member kw-sym 'c-paren-any-kwds) ; e.g. C++11 "throw" or "noexcept"
+ (setq passed-paren nil)
+ (setq passed-bracket-pairs 0)
+ (setq bracket-pos nil)
+ 'maybe)
((c-keyword-member kw-sym 'c-inexpr-block-kwds)
(when (not passed-paren)
(cons 'inexpr-statement (point))))
@@ -9288,20 +10479,49 @@ comment at the start of cc-engine.el for more info."
(if (looking-at "\\s(")
(if passed-paren
- (if (and (eq passed-paren ?\[)
- (eq (char-after) ?\[))
- ;; Accept several square bracket sexps for
- ;; Java array initializations.
- 'maybe)
- (setq passed-paren (char-after))
+ (cond
+ ((and (eq passed-paren ?\[)
+ (eq (char-after) ?\[)
+ (not (eq (char-after (1+ (point))) ?\[))) ; C++ attribute.
+ ;; Accept several square bracket sexps for
+ ;; Java array initializations.
+ (setq passed-bracket-pairs (1+ passed-bracket-pairs))
+ 'maybe)
+ ((and (eq passed-paren ?\()
+ (eq (char-after) ?\[)
+ (not (eq (char-after (1+ (point))) ?\[))
+ (eq passed-bracket-pairs 0))
+ ;; C++11 lambda function declaration
+ (setq passed-bracket-pairs 1)
+ (setq bracket-pos (point))
+ 'maybe)
+ (t nil))
+ (when (not (looking-at "\\[\\["))
+ (setq passed-paren (char-after))
+ (when (eq passed-paren ?\[)
+ (setq passed-bracket-pairs 1)
+ (setq bracket-pos (point))))
'maybe)
'maybe))))
(if (eq res 'maybe)
- (when (and c-recognize-paren-inexpr-blocks
- block-follows
- containing-sexp
- (eq (char-after containing-sexp) ?\())
+ (cond
+ ((and (c-major-mode-is 'c++-mode)
+ block-follows
+ (eq passed-bracket-pairs 1)
+ (save-excursion
+ (goto-char bracket-pos)
+ (or (<= (point) (or lim (point-min)))
+ (progn
+ (c-backward-token-2 1 nil lim)
+ (and
+ (not (c-on-identifier))
+ (not (looking-at c-opt-op-identifier-prefix)))))))
+ (cons 'inlambda bracket-pos))
+ ((and c-recognize-paren-inexpr-blocks
+ block-follows
+ containing-sexp
+ (eq (char-after containing-sexp) ?\())
(goto-char containing-sexp)
(if (or (save-excursion
(c-backward-syntactic-ws lim)
@@ -9313,9 +10533,21 @@ comment at the start of cc-engine.el for more info."
(and (> (point) (or lim (point-min)))
(c-on-identifier)))
(and c-special-brace-lists
- (c-looking-at-special-brace-list)))
+ (c-looking-at-special-brace-list))
+ (and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (goto-char block-follows)
+ (if (c-go-list-forward)
+ (progn
+ (backward-char)
+ (c-syntactic-skip-backward
+ "^;," block-follows t)
+ (not (eq (char-before) ?\;)))
+ (or (not (c-syntactic-re-search-forward
+ "[;,]" nil t t))
+ (not (eq (char-before) ?\;)))))))
nil
- (cons 'inexpr-statement (point))))
+ (cons 'inexpr-statement (point)))))
res))))
@@ -9341,6 +10573,18 @@ comment at the start of cc-engine.el for more info."
paren-state)
containing-sexp)))))
+(defun c-looking-at-c++-lambda-capture-list ()
+ ;; Return non-nil if we're at the opening "[" of the capture list of a C++
+ ;; lambda function, nil otherwise.
+ (and
+ (eq (char-after) ?\[)
+ (not (eq (char-before) ?\[))
+ (not (eq (char-after (1+ (point))) ?\[))
+ (save-excursion
+ (or (eq (c-backward-token-2 1) 1)
+ (looking-at c-pre-lambda-tokens-re)))
+ (not (c-in-literal))))
+
(defun c-at-macro-vsemi-p (&optional pos)
;; Is there a "virtual semicolon" at POS or point?
;; (See cc-defs.el for full details of "virtual semicolons".)
@@ -9710,10 +10954,10 @@ comment at the start of cc-engine.el for more info."
;; CASE B.2: brace-list-open
((or (consp special-brace-list)
- (save-excursion
- (goto-char beg-of-same-or-containing-stmt)
- (c-syntactic-re-search-forward "=\\([^=]\\|$\\)"
- indent-point t t t)))
+ (consp
+ (c-looking-at-or-maybe-in-bracelist
+ containing-sexp beg-of-same-or-containing-stmt))
+ )
;; The most semantically accurate symbol here is
;; brace-list-open, but we normally report it simply as a
;; statement-cont. The reason is that one normally adjusts
@@ -9746,6 +10990,14 @@ comment at the start of cc-engine.el for more info."
(c-add-stmt-syntax 'defun-open nil t
containing-sexp paren-state))
+ ;; CASE B.5: We have a C++11 "return \n { ..... }" Note that we're
+ ;; not at the "{", currently.
+ ((progn (goto-char indent-point)
+ (backward-sexp)
+ (looking-at c-return-key))
+ (c-add-stmt-syntax 'statement-cont nil t
+ containing-sexp paren-state))
+
;; CASE B.4: Continued statement with block open. The most
;; accurate analysis is perhaps `statement-cont' together with
;; `block-open' but we play DWIM and use `substatement-open'
@@ -9973,8 +11225,8 @@ comment at the start of cc-engine.el for more info."
;; versions, which results in that we get nil from
;; `c-literal-limits' even when `c-in-literal' claims
;; we're inside a comment.
- (setq placeholder (c-literal-limits lim)))
- (c-add-syntax literal (car placeholder)))
+ (setq placeholder (c-literal-start lim)))
+ (c-add-syntax literal placeholder))
;; CASE 3: in a cpp preprocessor macro continuation.
((and (save-excursion
@@ -10245,32 +11497,18 @@ comment at the start of cc-engine.el for more info."
;; CASE 5A.3: brace list open
((save-excursion
- (c-beginning-of-decl-1 lim)
- (while (looking-at c-specifier-key)
- (goto-char (match-end 1))
- (c-forward-syntactic-ws indent-point))
- (setq placeholder (c-point 'boi))
- (or (consp special-brace-list)
- (and (or (save-excursion
- (goto-char indent-point)
- (setq tmpsymbol nil)
- (while (and (> (point) placeholder)
- (zerop (c-backward-token-2 1 t))
- (not (looking-at "=\\([^=]\\|$\\)")))
- (and c-opt-inexpr-brace-list-key
- (not tmpsymbol)
- (looking-at c-opt-inexpr-brace-list-key)
- (setq tmpsymbol 'topmost-intro-cont)))
- (looking-at "=\\([^=]\\|$\\)"))
- (looking-at c-brace-list-key))
- (save-excursion
- (while (and (< (point) indent-point)
- (zerop (c-forward-token-2 1 t))
- (not (memq (char-after) '(?\; ?\()))))
- (not (memq (char-after) '(?\; ?\()))
- ))))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond
+ ((c-backward-over-enum-header)
+ (setq placeholder (c-point 'boi)))
+ ((consp (setq placeholder
+ (c-looking-at-or-maybe-in-bracelist
+ containing-sexp lim)))
+ (setq tmpsymbol (and (cdr placeholder) 'topmost-intro-cont))
+ (setq placeholder (c-point 'boi (car placeholder))))))
(if (and (not c-auto-newline-analysis)
- (c-major-mode-is 'java-mode)
+ ;(c-major-mode-is 'java-mode) ; Not needed anymore (2016-08-30).
(eq tmpsymbol 'topmost-intro-cont))
;; We're in Java and have found that the open brace
;; belongs to a "new Foo[]" initialization list,
@@ -10300,9 +11538,12 @@ comment at the start of cc-engine.el for more info."
(t
(save-excursion
(c-beginning-of-decl-1 lim)
- (while (looking-at c-specifier-key)
- (goto-char (match-end 1))
- (c-forward-syntactic-ws indent-point))
+ (while (cond
+ ((looking-at c-specifier-key)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
(c-add-syntax 'defun-open (c-point 'boi))
;; Bogus to use bol here, but it's the legacy. (Resolved,
;; 2007-11-09)
@@ -10933,9 +12174,12 @@ comment at the start of cc-engine.el for more info."
(c-beginning-of-statement-1
(c-safe-position (1- containing-sexp) paren-state))
(c-forward-token-2 0)
- (while (looking-at c-specifier-key)
- (goto-char (match-end 1))
- (c-forward-syntactic-ws))
+ (while (cond
+ ((looking-at c-specifier-key)
+ (c-forward-keyword-clause 1))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
(c-add-syntax 'brace-list-open (c-point 'boi))))
;; CASE 9B: brace-list-close brace
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 4f6fbb95bb1..f623b9f3332 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -723,6 +723,10 @@ casts and declarations are fontified. Used on level 2 and higher."
(concat ".\\(" c-string-limit-regexp "\\)")
'((c-font-lock-invalid-string)))
+ ;; Fontify C++ raw strings.
+ ,@(when (c-major-mode-is 'c++-mode)
+ '(c-font-lock-raw-strings))
+
;; Fontify keyword constants.
,@(when (c-lang-const c-constant-kwds)
(let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
@@ -895,7 +899,8 @@ casts and declarations are fontified. Used on level 2 and higher."
(c-get-char-property (1- (point)) 'c-type)))))
(when (memq prop '(c-decl-id-start c-decl-type-start))
(c-forward-syntactic-ws limit)
- (c-font-lock-declarators limit t (eq prop 'c-decl-type-start))))
+ (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)
+ (c-bs-at-toplevel-p (point)))))
(setq c-font-lock-context ;; (c-guess-font-lock-context)
(save-excursion
@@ -987,7 +992,7 @@ casts and declarations are fontified. Used on level 2 and higher."
(goto-char pos)))))
nil)
-(defun c-font-lock-declarators (limit list types)
+(defun c-font-lock-declarators (limit list types not-top)
;; Assuming the point is at the start of a declarator in a declaration,
;; fontify the identifier it declares. (If TYPES is set, it does this via
;; the macro `c-fontify-types-and-refs'.)
@@ -997,7 +1002,9 @@ casts and declarations are fontified. Used on level 2 and higher."
;; additionally, mark the commas with c-type property 'c-decl-id-start or
;; 'c-decl-type-start (according to TYPES). Stop at LIMIT.
;;
- ;; If TYPES is non-nil, fontify all identifiers as types.
+ ;; If TYPES is non-nil, fontify all identifiers as types. If NOT-TOP is
+ ;; non-nil, we are not at the top-level ("top-level" includes being directly
+ ;; inside a class or namespace, etc.).
;;
;; Nil is always returned. The function leaves point at the delimiter after
;; the last declarator it processes.
@@ -1021,6 +1028,14 @@ casts and declarations are fontified. Used on level 2 and higher."
(setq next-pos (point)
id-start (car decl-res)
id-face (if (and (eq (char-after) ?\()
+ (or (not (c-major-mode-is 'c++-mode))
+ (not not-top)
+ (car (cddr (cddr decl-res))) ; Id is in
+ ; parens, etc.
+ (save-excursion
+ (forward-char)
+ (c-forward-syntactic-ws)
+ (looking-at "[*&]")))
(not (car (cddr decl-res))) ; brackets-after-id
(or (not (c-major-mode-is 'c++-mode))
(save-excursion
@@ -1162,7 +1177,8 @@ casts and declarations are fontified. Used on level 2 and higher."
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
- (boundp 'parse-sexp-lookup-properties))))
+ (boundp 'parse-sexp-lookup-properties))
+ ))
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
@@ -1194,13 +1210,14 @@ casts and declarations are fontified. Used on level 2 and higher."
c-decl-start-re
(eval c-maybe-decl-faces)
- (lambda (match-pos inside-macro)
+ (lambda (match-pos inside-macro &optional toplev)
;; Note to maintainers: don't use `limit' inside this lambda form;
;; c-find-decl-spots sometimes narrows to less than `limit'.
(setq start-pos (point))
(when
;; The result of the form below is true when we don't recognize a
- ;; declaration or cast.
+ ;; declaration or cast, and we don't recognize a "non-decl",
+ ;; typically a brace list.
(if (or (and (eq (get-text-property (point) 'face)
'font-lock-keyword-face)
(looking-at c-not-decl-init-keywords))
@@ -1216,8 +1233,8 @@ casts and declarations are fontified. Used on level 2 and higher."
;; (e.g. "for (").
(let ((type (and (> match-pos (point-min))
(c-get-char-property (1- match-pos) 'c-type))))
- (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
- (setq context nil
+ (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
+ (setq context (and toplev 'top)
c-restricted-<>-arglists nil))
;; A control flow expression or a decltype
((and (eq (char-before match-pos) ?\()
@@ -1238,6 +1255,37 @@ casts and declarations are fontified. Used on level 2 and higher."
((eq type 'c-decl-arg-start)
(setq context 'decl
c-restricted-<>-arglists nil))
+ ;; We're inside (probably) a brace list.
+ ((eq type 'c-not-decl)
+ (setq context 'not-decl
+ c-restricted-<>-arglists nil))
+ ;; Inside a C++11 lambda function arglist.
+ ((and (c-major-mode-is 'c++-mode)
+ (eq (char-before match-pos) ?\()
+ (save-excursion
+ (goto-char match-pos)
+ (c-backward-token-2)
+ (and
+ (c-safe (goto-char (scan-sexps (point) -1)))
+ (c-looking-at-c++-lambda-capture-list))))
+ (setq context 'decl
+ c-restricted-<>-arglists nil)
+ (c-put-char-property (1- match-pos) 'c-type
+ 'c-decl-arg-start))
+ ;; We're inside a brace list.
+ ((and (eq (char-before match-pos) ?{)
+ (save-excursion
+ (goto-char (1- match-pos))
+ (consp
+ (c-looking-at-or-maybe-in-bracelist))))
+ (setq context 'not-decl
+ c-restricted-<>-arglists nil)
+ (c-put-char-property (1- match-pos) 'c-type
+ 'c-not-decl))
+ ;; We're inside an "ordinary" open brace.
+ ((eq (char-before match-pos) ?{)
+ (setq context (and toplev 'top)
+ c-restricted-<>-arglists nil))
;; Inside an angle bracket arglist.
((or (eq type 'c-<>-arg-sep)
(eq (char-before match-pos) ?<))
@@ -1263,6 +1311,13 @@ casts and declarations are fontified. Used on level 2 and higher."
;; multiline declaration.
(c-put-char-property (1- match-pos)
'c-type 'c-decl-arg-start))
+ ;; Got an open paren preceded by an arith operator.
+ ((and (eq (char-before match-pos) ?\()
+ (save-excursion
+ (and (zerop (c-backward-token-2 2))
+ (looking-at c-arithmetic-op-regexp))))
+ (setq context nil
+ c-restricted-<>-arglists nil))
(t (setq context 'arglist
c-restricted-<>-arglists t))))
@@ -1283,182 +1338,132 @@ casts and declarations are fontified. Used on level 2 and higher."
(c-forward-syntactic-ws))
;; Now analyze the construct.
- (setq decl-or-cast (c-forward-decl-or-cast-1
- match-pos context last-cast-end))
-
- ;; Ensure that c-<>-arg-sep c-type properties are in place on the
- ;; commas separating the arguments inside template/generic <..>s.
- (when (and (eq (char-before match-pos) ?<)
- (> match-pos max-<>-end))
- (save-excursion
- (goto-char match-pos)
- (c-backward-token-2)
- (if (and
- (eq (char-after) ?<)
- (let ((c-restricted-<>-arglists
- (save-excursion
- (c-backward-token-2)
- (and
- (not (looking-at c-opt-<>-sexp-key))
- (progn (c-backward-syntactic-ws)
- (memq (char-before) '(?\( ?,)))
- (not (eq (c-get-char-property (1- (point))
- 'c-type)
- 'c-decl-arg-start))))))
- (c-forward-<>-arglist nil)))
- (setq max-<>-end (point)))))
-
- (cond
- ((eq decl-or-cast 'cast)
- ;; Save the position after the previous cast so we can feed
- ;; it to `c-forward-decl-or-cast-1' in the next round. That
- ;; helps it discover cast chains like "(a) (b) c".
- (setq last-cast-end (point))
- (c-fontify-recorded-types-and-refs)
- nil)
-
- (decl-or-cast
- ;; We've found a declaration.
-
- ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
- ;; under the assumption that we're after the first type decl
- ;; expression in the declaration now. That's not really true;
- ;; we could also be after a parenthesized initializer
- ;; expression in C++, but this is only used as a last resort
- ;; to slant ambiguous expression/declarations, and overall
- ;; it's worth the risk to occasionally fontify an expression
- ;; as a declaration in an initializer expression compared to
- ;; getting ambiguous things in normal function prototypes
- ;; fontified as expressions.
- (if inside-macro
- (when (> (point) max-type-decl-end-before-token)
- (setq max-type-decl-end-before-token (point)))
- (when (> (point) max-type-decl-end)
- (setq max-type-decl-end (point))))
-
- ;; Back up to the type to fontify the declarator(s).
- (goto-char (car decl-or-cast))
-
- (let ((decl-list
- (if context
- ;; Should normally not fontify a list of
- ;; declarators inside an arglist, but the first
- ;; argument in the ';' separated list of a "for"
- ;; statement is an exception.
- (when (eq (char-before match-pos) ?\()
- (save-excursion
- (goto-char (1- match-pos))
- (c-backward-syntactic-ws)
- (and (c-simple-skip-symbol-backward)
- (looking-at c-paren-stmt-key))))
- t)))
-
- ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
- ;; before the first declarator if it's a list.
- ;; `c-font-lock-declarators' handles the rest.
- (when decl-list
- (save-excursion
- (c-backward-syntactic-ws)
- (unless (bobp)
- (c-put-char-property (1- (point)) 'c-type
- (if (cdr decl-or-cast)
- 'c-decl-type-start
- 'c-decl-id-start)))))
-
- (c-font-lock-declarators
- (point-max) decl-list (cdr decl-or-cast)))
-
- ;; A declaration has been successfully identified, so do all the
- ;; fontification of types and refs that've been recorded.
- (c-fontify-recorded-types-and-refs)
- nil)
-
- ;; Restore point, since at this point in the code it has been
- ;; left undefined by c-forward-decl-or-cast-1 above.
- ((progn (goto-char start-pos) nil))
-
- ;; If point is inside a bracelist, there's no point checking it
- ;; being at a declarator.
- ((let ((paren-state (c-parse-state)))
- (setq lbrace (c-cheap-inside-bracelist-p paren-state)))
- ;; Move past this bracelist to prevent an endless loop.
- (goto-char lbrace)
- (unless (c-safe (progn (forward-list) t))
- (goto-char start-pos)
- (c-forward-token-2))
- nil)
-
- ;; If point is just after a ")" which is followed by an
- ;; identifier which isn't a label, or at the matching "(", we're
- ;; at either a macro invocation, a cast, or a
- ;; for/while/etc. statement. The cast case is handled above.
- ;; None of these cases can contain a declarator.
- ((or (and (eq (char-before match-pos) ?\))
- (c-on-identifier)
- (save-excursion (not (c-forward-label))))
- (and (eq (char-after) ?\()
- (save-excursion
- (and
- (progn (c-backward-token-2) (c-on-identifier))
- (save-excursion (not (c-forward-label)))
- (progn (c-backward-token-2)
- (eq (char-after) ?\())))))
- (c-forward-token-2) ; Must prevent looping.
- nil)
-
- ((and (not c-enums-contain-decls)
- ;; An optimization quickly to eliminate scans of long enum
- ;; declarations in the next cond arm.
- (let ((paren-state (c-parse-state)))
- (and
- (numberp (car paren-state))
+ (if (eq context 'not-decl)
+ (progn
+ (setq decl-or-cast nil)
+ (if (c-syntactic-re-search-forward
+ "," (min limit (point-max)) 'at-limit t)
+ (c-put-char-property (1- (point)) 'c-type 'c-not-decl))
+ nil)
+ (setq decl-or-cast
+ (c-forward-decl-or-cast-1
+ match-pos context last-cast-end))
+
+ ;; Ensure that c-<>-arg-sep c-type properties are in place on the
+ ;; commas separating the arguments inside template/generic <..>s.
+ (when (and (eq (char-before match-pos) ?<)
+ (> match-pos max-<>-end))
+ (save-excursion
+ (goto-char match-pos)
+ (c-backward-token-2)
+ (if (and
+ (eq (char-after) ?<)
+ (let ((c-restricted-<>-arglists
+ (save-excursion
+ (c-backward-token-2)
+ (and
+ (not (looking-at c-opt-<>-sexp-key))
+ (progn (c-backward-syntactic-ws)
+ (memq (char-before) '(?\( ?,)))
+ (not (eq (c-get-char-property (1- (point))
+ 'c-type)
+ 'c-decl-arg-start))))))
+ (c-forward-<>-arglist nil)))
+ (setq max-<>-end (point)))))
+
+ (cond
+ ((eq decl-or-cast 'cast)
+ ;; Save the position after the previous cast so we can feed
+ ;; it to `c-forward-decl-or-cast-1' in the next round. That
+ ;; helps it discover cast chains like "(a) (b) c".
+ (setq last-cast-end (point))
+ (c-fontify-recorded-types-and-refs)
+ nil)
+
+ (decl-or-cast
+ ;; We've found a declaration.
+
+ ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
+ ;; under the assumption that we're after the first type decl
+ ;; expression in the declaration now. That's not really true;
+ ;; we could also be after a parenthesized initializer
+ ;; expression in C++, but this is only used as a last resort
+ ;; to slant ambiguous expression/declarations, and overall
+ ;; it's worth the risk to occasionally fontify an expression
+ ;; as a declaration in an initializer expression compared to
+ ;; getting ambiguous things in normal function prototypes
+ ;; fontified as expressions.
+ (if inside-macro
+ (when (> (point) max-type-decl-end-before-token)
+ (setq max-type-decl-end-before-token (point)))
+ (when (> (point) max-type-decl-end)
+ (setq max-type-decl-end (point))))
+
+ ;; Do we have an expression as the second or third clause of
+ ;; a "for" paren expression?
+ (if (save-excursion
+ (and
+ (car (cddr decl-or-cast)) ; maybe-expression flag.
+ (goto-char start-pos)
+ (c-go-up-list-backward)
+ (eq (char-after) ?\()
+ (progn (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))
+ (looking-at c-paren-stmt-key)
+ (progn (goto-char match-pos)
+ (while (and (eq (char-before) ?\))
+ (c-go-list-backward))
+ (c-backward-syntactic-ws))
+ (eq (char-before) ?\;))))
+ ;; We've got an expression in "for" parens. Remove the
+ ;; "type" that would spuriously get fontified.
+ (let ((elt (and (consp c-record-type-identifiers)
+ (assq (cadr (cddr decl-or-cast))
+ c-record-type-identifiers))))
+ (when elt
+ (setq c-record-type-identifiers
+ (c-delq-from-dotted-list
+ elt c-record-type-identifiers)))
+ t)
+ ;; Back up to the type to fontify the declarator(s).
+ (goto-char (car decl-or-cast))
+
+ (let ((decl-list
+ (if (not (memq context '(nil top)))
+ ;; Should normally not fontify a list of
+ ;; declarators inside an arglist, but the first
+ ;; argument in the ';' separated list of a "for"
+ ;; statement is an exception.
+ (when (eq (char-before match-pos) ?\()
+ (save-excursion
+ (goto-char (1- match-pos))
+ (c-backward-syntactic-ws)
+ (and (c-simple-skip-symbol-backward)
+ (looking-at c-paren-stmt-key))))
+ t)))
+
+ ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
+ ;; before the first declarator if it's a list.
+ ;; `c-font-lock-declarators' handles the rest.
+ (when decl-list
(save-excursion
- (goto-char (car paren-state))
- (c-backward-over-enum-header)))))
- (c-forward-token-2)
- nil)
+ (c-backward-syntactic-ws)
+ (unless (bobp)
+ (c-put-char-property (1- (point)) 'c-type
+ (if (cadr decl-or-cast)
+ 'c-decl-type-start
+ 'c-decl-id-start)))))
+
+ (c-font-lock-declarators
+ (min limit (point-max)) decl-list
+ (cadr decl-or-cast) (not toplev)))
+
+ ;; A declaration has been successfully identified, so do all the
+ ;; fontification of types and refs that've been recorded.
+ (c-fontify-recorded-types-and-refs)
+ nil))
- (t
- ;; Are we at a declarator? Try to go back to the declaration
- ;; to check this. If we get there, check whether a "typedef"
- ;; is there, then fontify the declarators accordingly.
- (let ((decl-search-lim (c-determine-limit 1000))
- paren-state bod-res encl-pos is-typedef
- c-recognize-knr-p) ; Strictly speaking, bogus, but it
- ; speeds up lisp.h tremendously.
- (save-excursion
- (if (c-back-over-member-initializers)
- t ; Can't be at a declarator
- (unless (or (eobp)
- (looking-at "\\s(\\|\\s)"))
- (forward-char))
- (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim)))
- (if (and (eq bod-res 'same)
- (save-excursion
- (c-backward-syntactic-ws)
- (eq (char-before) ?\})))
- (c-beginning-of-decl-1 decl-search-lim))
-
- ;; We're now putatively at the declaration.
- (setq paren-state (c-parse-state))
- ;; At top level or inside a "{"?
- (if (or (not (setq encl-pos
- (c-most-enclosing-brace paren-state)))
- (eq (char-after encl-pos) ?\{))
- (progn
- (when (looking-at c-typedef-key) ; "typedef"
- (setq is-typedef t)
- (goto-char (match-end 0))
- (c-forward-syntactic-ws))
- ;; At a real declaration?
- (if (memq (c-forward-type t) '(t known found decltype))
- (progn
- (c-font-lock-declarators (point-max) t is-typedef)
- nil)
- ;; False alarm. Return t to go on to the next check.
- (goto-char start-pos)
- t))
- t)))))))
+ (t t))))
;; It was a false alarm. Check if we're in a label (or other
;; construct with `:' except bitfield) instead.
@@ -1488,6 +1493,22 @@ casts and declarations are fontified. Used on level 2 and higher."
nil)))
+(defun c-font-lock-enum-body (limit)
+ ;; Fontify the identifiers of each enum we find by searching forward.
+ ;;
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ (while (search-forward-regexp c-enum-clause-introduction-re limit t)
+ (when (save-excursion
+ (backward-char)
+ (c-backward-over-enum-header))
+ (c-forward-syntactic-ws)
+ (c-font-lock-declarators limit t nil t)))
+ nil)
+
(defun c-font-lock-enum-tail (limit)
;; Fontify an enum's identifiers when POINT is within the enum's brace
;; block.
@@ -1512,9 +1533,52 @@ casts and declarations are fontified. Used on level 2 and higher."
(c-put-char-property (1- (point)) 'c-type 'c-decl-id-start)
(c-forward-syntactic-ws)
- (c-font-lock-declarators limit t nil)))
+ (c-font-lock-declarators limit t nil t)))
nil)
+(defun c-font-lock-cut-off-declarators (limit)
+ ;; Fontify any declarators "cut off" from their declaring type at the start
+ ;; of the region being fontified.
+ ;;
+ ;; This function will be called from font-lock- for a region bounded by
+ ;; POINT and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; fontification".
+ (let ((decl-search-lim (c-determine-limit 1000))
+ paren-state bod-res is-typedef encl-pos
+ (here (point))
+ c-recognize-knr-p) ; Strictly speaking, bogus, but it
+ ; speeds up lisp.h tremendously.
+ (save-excursion
+ (when (not (c-back-over-member-initializers))
+ (unless (or (eobp)
+ (looking-at "\\s(\\|\\s)"))
+ (forward-char))
+ (c-syntactic-skip-backward "^;{}" decl-search-lim t)
+ (when (eq (char-before) ?})
+ (c-go-list-backward) ; brace block of struct, etc.?
+ (c-syntactic-skip-backward "^;{}" decl-search-lim t))
+ (when (or (bobp)
+ (memq (char-before) '(?\; ?{ ?})))
+ (c-forward-syntactic-ws)
+ ;; We're now putatively at the declaration.
+ (setq paren-state (c-parse-state))
+ ;; At top level or inside a "{"?
+ (if (or (not (setq encl-pos
+ (c-most-enclosing-brace paren-state)))
+ (eq (char-after encl-pos) ?\{))
+ (progn
+ (when (looking-at c-typedef-key) ; "typedef"
+ (setq is-typedef t)
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws))
+ ;; At a real declaration?
+ (if (memq (c-forward-type t) '(t known found decltype))
+ (c-font-lock-declarators
+ limit t is-typedef (not (c-bs-at-toplevel-p here)))))))))
+ nil))
+
(defun c-font-lock-enclosing-decls (limit)
;; Fontify the declarators of (nested) declarations we're in the middle of.
;; This is mainly for when a jit-lock etc. chunk starts inside the brace
@@ -1527,7 +1591,7 @@ casts and declarations are fontified. Used on level 2 and higher."
;; Fontification".
(let* ((paren-state (c-parse-state))
(decl-search-lim (c-determine-limit 1000))
- decl-context in-typedef ps-elt)
+ in-typedef ps-elt)
;; Are we in any nested struct/union/class/etc. braces?
(while paren-state
(setq ps-elt (car paren-state)
@@ -1535,15 +1599,158 @@ casts and declarations are fontified. Used on level 2 and higher."
(when (and (atom ps-elt)
(eq (char-after ps-elt) ?\{))
(goto-char ps-elt)
- (setq decl-context (c-beginning-of-decl-1 decl-search-lim)
- in-typedef (looking-at c-typedef-key))
- (if in-typedef (c-forward-token-2))
- (when (and c-opt-block-decls-with-vars-key
- (looking-at c-opt-block-decls-with-vars-key))
- (goto-char ps-elt)
- (when (c-safe (c-forward-sexp))
- (c-forward-syntactic-ws)
- (c-font-lock-declarators limit t in-typedef)))))))
+ (c-syntactic-skip-backward "^;{}" decl-search-lim)
+ (when (or (bobp)
+ (memq (char-before) '(?\; ?})))
+ (c-forward-syntactic-ws)
+ (setq in-typedef (looking-at c-typedef-key))
+ (if in-typedef (c-forward-token-2))
+ (when (and c-opt-block-decls-with-vars-key
+ (looking-at c-opt-block-decls-with-vars-key))
+ (goto-char ps-elt)
+ (when (c-safe (c-forward-sexp))
+ (c-forward-syntactic-ws)
+ (c-font-lock-declarators limit t in-typedef
+ (not (c-bs-at-toplevel-p (point)))))))))))
+
+(defun c-font-lock-raw-strings (limit)
+ ;; Fontify C++ raw strings.
+ ;;
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ (let* ((state (c-state-semi-pp-to-literal (point)))
+ (string-start (and (eq (cadr state) 'string)
+ (car (cddr state))))
+ (raw-id (and string-start
+ (save-excursion
+ (goto-char string-start)
+ (and (eq (char-before) ?R)
+ (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
+ (match-string-no-properties 1))))))
+ (while (< (point) limit)
+ (if raw-id
+ (progn
+ (if (search-forward-regexp (concat ")\\(" (regexp-quote raw-id) "\\)\"")
+ limit 'limit)
+ (c-put-font-lock-face (match-beginning 1) (point) 'default))
+ (setq raw-id nil))
+
+ (when (search-forward-regexp
+ "R\\(\"\\)\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" limit 'limit)
+ (when
+ (or (and (eobp)
+ (eq (c-get-char-property (1- (point)) 'face)
+ 'font-lock-warning-face))
+ (eq (c-get-char-property (point) 'face) 'font-lock-string-face)
+ (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1))
+ (equal (c-get-char-property (match-beginning 1) 'syntax-table)
+ '(1))))
+ (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table)))
+ (if paren-prop
+ (progn
+ (c-put-font-lock-face (match-beginning 0) (match-end 0)
+ 'font-lock-warning-face)
+ (when
+ (and
+ (equal paren-prop '(15))
+ (not (c-search-forward-char-property 'syntax-table '(15) limit)))
+ (goto-char limit)))
+ (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default)
+ (setq raw-id (match-string-no-properties 2)))))))))
+ nil)
+
+(defun c-font-lock-c++-lambda-captures (limit)
+ ;; Fontify the lambda capture component of C++ lambda declarations.
+ ;;
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ (let (mode capture-default id-start id-end declaration sub-begin sub-end)
+ (while (and (< (point) limit)
+ (search-forward "[" limit t))
+ (when (progn (backward-char)
+ (prog1
+ (c-looking-at-c++-lambda-capture-list)
+ (forward-char)))
+ (c-forward-syntactic-ws)
+ (setq mode (and (memq (char-after) '(?= ?&))
+ (char-after)))
+ ;; Is the first element of the list a bare "=" or "&"?
+ (when mode
+ (forward-char)
+ (c-forward-syntactic-ws)
+ (if (memq (char-after) '(?, ?\]))
+ (progn
+ (setq capture-default mode)
+ (when (eq (char-after) ?,)
+ (forward-char)
+ (c-forward-syntactic-ws)))
+ (c-backward-token-2)))
+
+ ;; Go round the following loop once per captured item. We use "\\s)"
+ ;; rather than "\\]" here to avoid infinite looping in this situation:
+ ;; "unsigned items [] { [ }". The second "[" triggers this function,
+ ;; but if we don't match the "}" with an "\\s)", the
+ ;; `c-syntactic-re-search-forward' at the end of the loop fails to
+ ;; move forward over it, leaving point stuck at the "}".
+ (while (and (not (looking-at "\\s)"))
+ (< (point) limit))
+ (if (eq (char-after) ?&)
+ (progn (setq mode ?&)
+ (forward-char)
+ (c-forward-syntactic-ws))
+ (setq mode ?=))
+ (if (c-on-identifier)
+ (progn
+ (setq id-start (point))
+ (forward-char)
+ (c-end-of-current-token)
+ (setq id-end (point))
+ (c-forward-syntactic-ws)
+
+ (setq declaration (eq (char-after) ?=))
+ (when declaration
+ (forward-char) ; over "="
+ (c-forward-syntactic-ws)
+ (setq sub-begin (point)))
+ (if (or (and (< (point) limit)
+ (c-syntactic-re-search-forward "," limit t t))
+ (and (c-go-up-list-forward nil limit)
+ (eq (char-before) ?\])))
+ (backward-char)
+ (goto-char limit))
+ (when declaration
+ (save-excursion
+ (setq sub-end (point))
+ (goto-char sub-begin)
+ (c-font-lock-c++-lambda-captures sub-end)))
+
+ (c-put-font-lock-face id-start id-end
+ (cond
+ (declaration
+ 'font-lock-variable-name-face)
+ ((and capture-default
+ (eq mode capture-default))
+ 'font-lock-warning-face)
+ ((eq mode ?=) font-lock-constant-face)
+ (t 'font-lock-variable-name-face))))
+ (c-syntactic-re-search-forward "," limit 'bound t))
+
+ (c-forward-syntactic-ws)
+ (when (eq (char-after) ?,)
+ (forward-char)
+ (c-forward-syntactic-ws)))
+
+ (setq capture-default nil)
+ (if (< (point) limit)
+ (forward-char))))) ; over the terminating "]" or other close paren.
+ nil)
+
(c-lang-defconst c-simple-decl-matchers
"Simple font lock matchers for types and declarations. These are used
@@ -1572,7 +1779,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
(eval . (list ,(c-make-font-lock-search-function
'c-known-type-key
'(1 'font-lock-type-face t)
- '((c-font-lock-declarators limit t nil)
+ '((c-font-lock-declarators limit t nil nil)
(save-match-data
(goto-char (match-end 1))
(c-forward-syntactic-ws))
@@ -1594,7 +1801,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
"\\)"))
`(,type-match
'font-lock-type-face t)
- `((c-font-lock-declarators limit t nil)
+ `((c-font-lock-declarators limit t nil nil)
(save-match-data
(goto-char (match-end ,type-match))
(c-forward-syntactic-ws))
@@ -1606,7 +1813,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
(concat "\\<\\("
(regexp-opt (c-lang-const c-typeless-decl-kwds))
"\\)\\>")
- '((c-font-lock-declarators limit t nil)
+ '((c-font-lock-declarators limit t nil nil)
(save-match-data
(goto-char (match-end 1))
(c-forward-syntactic-ws))
@@ -1648,6 +1855,10 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
'c-type 'c-decl-end)))
c-font-lock-objc-methods))
+ ;; Fontify declarators which have been cut off from their declaring
+ ;; types at the start of the region.
+ c-font-lock-cut-off-declarators
+
;; Fontify all declarations, casts and normal labels.
c-font-lock-declarations
@@ -1658,6 +1869,9 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
,@(when (c-lang-const c-recognize-<>-arglists)
`(c-font-lock-<>-arglists))
+ ,@(when (c-major-mode-is 'c++-mode)
+ `(c-font-lock-c++-lambda-captures))
+
;; The first two rules here mostly find occurrences that
;; `c-font-lock-declarations' has found already, but not
;; declarations containing blocks in the type (see note below).
@@ -1699,10 +1913,18 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
(unless (c-skip-comments-and-strings limit)
(c-forward-syntactic-ws)
;; Handle prefix declaration specifiers.
- (when (or (looking-at c-prefix-spec-kwds-re)
- (and (c-major-mode-is 'java-mode)
- (looking-at "@[A-Za-z0-9]+")))
- (c-forward-keyword-clause 1))
+ (while
+ (or
+ (when (or (looking-at c-prefix-spec-kwds-re)
+ (and (c-major-mode-is 'java-mode)
+ (looking-at "@[A-Za-z0-9]+")))
+ (c-forward-keyword-clause 1)
+ t)
+ (when (and c-opt-cpp-prefix
+ (looking-at
+ c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause)
+ t)))
,(if (c-major-mode-is 'c++-mode)
`(when (and (c-forward-type)
(eq (char-after) ?=))
@@ -1814,29 +2036,14 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
generic casts and declarations are fontified. Used on level 2 and
higher."
- t `(,@(when (c-lang-const c-brace-id-list-kwds)
+ t `(,@(when (c-lang-const c-brace-list-decl-kwds)
;; Fontify the remaining identifiers inside an enum list when we start
;; inside it.
`(c-font-lock-enum-tail
;; Fontify the identifiers inside enum lists. (The enum type
;; name is handled by `c-simple-decl-matchers' or
;; `c-complex-decl-matchers' below.
- (,(c-make-font-lock-search-function
- (concat
- "\\<\\("
- (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
- "\\)\\>"
- ;; Disallow various common punctuation chars that can't come
- ;; before the '{' of the enum list, to avoid searching too far.
- "[^][{}();/#=]*"
- "{")
- '((c-font-lock-declarators limit t nil)
- (save-match-data
- (goto-char (match-end 0))
- (c-put-char-property (1- (point)) 'c-type
- 'c-decl-id-start)
- (c-forward-syntactic-ws))
- (goto-char (match-end 0)))))))
+ c-font-lock-enum-body))
;; Fontify labels after goto etc.
,@(when (c-lang-const c-before-label-kwds)
@@ -2229,7 +2436,7 @@ need for `c++-font-lock-extra-types'.")
limit
"[-+]"
nil
- (lambda (match-pos inside-macro)
+ (lambda (match-pos inside-macro &optional top-level)
(forward-char)
(c-font-lock-objc-method))))
nil)
@@ -2401,10 +2608,10 @@ need for `pike-font-lock-extra-types'.")
'font-lock-comment-face)
;; Handle the case when the fontified region starts inside a
;; comment.
- (let ((range (c-literal-limits)))
+ (let ((start (c-literal-start)))
(setq region-beg (point))
- (when range
- (goto-char (car range)))
+ (when start
+ (goto-char start))
(when (looking-at prefix)
(setq comment-beg (point)))))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 6012549dc56..87aeaa4750f 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -474,9 +474,17 @@ so that all identifiers are recognized as words.")
;; The value here may be a list of functions or a single function.
t nil
c++ '(c-extend-region-for-CPP
+; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
+ c-before-change-check-raw-strings
c-before-change-check-<>-operators
- c-invalidate-macro-cache)
- (c objc) '(c-extend-region-for-CPP c-invalidate-macro-cache)
+ c-depropertize-CPP
+ c-before-after-change-digit-quote
+ c-invalidate-macro-cache
+ c-truncate-bs-cache)
+ (c objc) '(c-extend-region-for-CPP
+ c-depropertize-CPP
+ c-invalidate-macro-cache
+ c-truncate-bs-cache)
;; java 'c-before-change-check-<>-operators
awk 'c-awk-record-region-clear-NL)
(c-lang-defvar c-get-state-before-change-functions
@@ -504,15 +512,25 @@ parameters \(point-min) and \(point-max).")
(c-lang-defconst c-before-font-lock-functions
;; For documentation see the following c-lang-defvar of the same name.
;; The value here may be a list of functions or a single function.
- t 'c-change-expand-fl-region
- (c objc) '(c-neutralize-syntax-in-and-mark-CPP
+ t '(c-depropertize-new-text
+ c-change-expand-fl-region)
+ (c objc) '(c-depropertize-new-text
+ c-extend-font-lock-region-for-macros
+ c-neutralize-syntax-in-and-mark-CPP
c-change-expand-fl-region)
- c++ '(c-neutralize-syntax-in-and-mark-CPP
+ c++ '(c-depropertize-new-text
+ c-extend-font-lock-region-for-macros
+; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
+ c-before-after-change-digit-quote
+ c-after-change-re-mark-raw-strings
+ c-neutralize-syntax-in-and-mark-CPP
c-restore-<>-properties
c-change-expand-fl-region)
- java '(c-restore-<>-properties
+ java '(c-depropertize-new-text
+ c-restore-<>-properties
c-change-expand-fl-region)
- awk 'c-awk-extend-and-syntax-tablify-region)
+ awk '(c-depropertize-new-text
+ c-awk-extend-and-syntax-tablify-region))
(c-lang-defvar c-before-font-lock-functions
(let ((fs (c-lang-const c-before-font-lock-functions)))
(if (listp fs)
@@ -619,6 +637,11 @@ This is of the form that fits inside [ ] in a regexp."
objc (concat c-alnum "_$@"))
(c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars))
+(c-lang-defconst c-symbol-char-key
+ "Regexp matching a sequence of at least one identifier character."
+ t (concat "[" (c-lang-const c-symbol-chars) "]+"))
+(c-lang-defvar c-symbol-char-key (c-lang-const c-symbol-char-key))
+
(c-lang-defconst c-symbol-key
"Regexp matching identifiers and keywords (with submatch 0). Assumed
to match if `c-symbol-start' matches on the same position."
@@ -1225,6 +1248,22 @@ operators."
(c-lang-defvar c-assignment-op-regexp
(c-lang-const c-assignment-op-regexp))
+(c-lang-defconst c-arithmetic-operators
+ "List of all arithmetic operators, including \"+=\", etc."
+ ;; Note: in the following, there are too many operators for AWK and IDL.
+ t (append (c-lang-const c-assignment-operators)
+ '("+" "-" "*" "/" "%"
+ "<<" ">>"
+ "<" ">" "<=" ">="
+ "==" "!="
+ "&" "^" "|"
+ "&&" "||")))
+
+(c-lang-defconst c-arithmetic-op-regexp
+ t (c-make-keywords-re nil
+ (c-lang-const c-arithmetic-operators)))
+(c-lang-defvar c-arithmetic-op-regexp (c-lang-const c-arithmetic-op-regexp))
+
(c-lang-defconst c-:$-multichar-token-regexp
;; Regexp matching all tokens ending in ":" which are longer than one char.
;; Currently (2016-01-07) only used in C++ Mode.
@@ -1310,6 +1349,14 @@ operators."
(c-lang-defvar c-stmt-delim-chars-with-comma
(c-lang-const c-stmt-delim-chars-with-comma))
+(c-lang-defconst c-pack-ops
+ "Ops which signal C++11's \"parameter pack\""
+ t nil
+ c++ '("..."))
+(c-lang-defconst c-pack-key
+ t (c-make-keywords-re 'appendable (c-lang-const c-pack-ops)))
+(c-lang-defvar c-pack-key (c-lang-const c-pack-key))
+
(c-lang-defconst c-auto-ops
;; Ops which signal C++11's new auto uses.
t nil
@@ -1325,6 +1372,33 @@ operators."
(c-lang-defconst c-haskell-op-re
t (c-make-keywords-re nil (c-lang-const c-haskell-op)))
(c-lang-defvar c-haskell-op-re (c-lang-const c-haskell-op-re))
+
+(c-lang-defconst c-pre-start-tokens
+ "List of operators following which an apparent declaration \(e.g.
+\"t1 *fn (t2 *b);\") is most likely to be an actual declaration
+\(as opposed to an arithmetic expression)."
+ t '(";" "{" "}"))
+(c-lang-defvar c-pre-start-tokens (c-lang-const c-pre-start-tokens))
+
+(c-lang-defconst c-pre-lambda-tokens
+ "List of tokens which may precede a lambda declaration.
+In C++ this is something like \"[a,b] (foo, bar) -> int { ... };\".
+Currently (2016-08) only used in C++ mode."
+ t (c--set-difference
+ (c--delete-duplicates
+ (append (c-lang-const c-operator-list)
+ (c-lang-const c-other-op-syntax-tokens)))
+ (append
+ '("#" "%:" "??=" "##" "%:%:" "??=??=" "::" "." "->"
+ "]" "<:" ":>" "??(" "??)" "??-" "new" "delete"
+ ")" ".*" "->*" "??'" "??!" "??!??!" "??!=" "??'=")
+ '("<%" "%>" "<:" ":>" "%:" "%:%:" "#" "##" "::" "..."))
+ :test #'string-equal))
+
+(c-lang-defconst c-pre-lambda-tokens-re
+ ;; Regexp matching any token in the list `c-pre-lambda-tokens'.
+ t (regexp-opt (c-lang-const c-pre-lambda-tokens)))
+(c-lang-defvar c-pre-lambda-tokens-re (c-lang-const c-pre-lambda-tokens-re))
;;; Syntactic whitespace.
@@ -1716,6 +1790,16 @@ the appropriate place for that."
"array" "float" "function" "int" "mapping" "mixed" "multiset"
"object" "program" "string" "this_program" "void"))
+(c-lang-defconst c-return-kwds
+ "Keywords which return a value to the calling function."
+ t '("return")
+ idl nil)
+
+(c-lang-defconst c-return-key
+ ;; Adorned regexp matching `c-return-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-return-kwds)))
+(c-lang-defvar c-return-key (c-lang-const c-return-key))
+
(c-lang-defconst c-primitive-type-key
;; An adorned regexp that matches `c-primitive-type-kwds'.
t (c-make-keywords-re t (c-lang-const c-primitive-type-kwds)))
@@ -1778,7 +1862,7 @@ but they don't build a type of themselves. Unlike the keywords on
not the type face."
t nil
c '("const" "restrict" "volatile")
- c++ '("const" "constexpr" "noexcept" "volatile" "throw" "final" "override")
+ c++ '("const" "noexcept" "volatile" "throw")
objc '("const" "volatile"))
(c-lang-defconst c-opt-type-modifier-key
@@ -1807,6 +1891,18 @@ not the type face."
(c-lang-const c-type-modifier-kwds))
:test 'string-equal))
+(c-lang-defconst c-type-decl-suffix-ws-ids-kwds
+ "\"Identifiers\" that when immediately following a declarator have semantic
+effect in the declaration, but are syntactically like whitespace."
+ t nil
+ c++ '("final" "override"))
+
+(c-lang-defconst c-type-decl-suffix-ws-ids-key
+ ;; An adorned regexp matching `c-type-decl-suffix-ws-ids-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-type-decl-suffix-ws-ids-kwds)))
+(c-lang-defvar c-type-decl-suffix-ws-ids-key
+ (c-lang-const c-type-decl-suffix-ws-ids-key))
+
(c-lang-defconst c-class-decl-kwds
"Keywords introducing declarations where the following block (if any)
contains another declaration level that should be considered a class.
@@ -1980,8 +2076,8 @@ If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
will be handled."
t nil
(c c++) '("auto" "extern" "inline" "register" "static")
- c++ (append '("explicit" "friend" "mutable" "template" "thread_local"
- "using" "virtual")
+ c++ (append '("constexpr" "explicit" "friend" "mutable" "template"
+ "thread_local" "using" "virtual")
(c-lang-const c-modifier-kwds))
objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out" "static")
;; FIXME: Some of those below ought to be on `c-other-decl-kwds' instead.
@@ -2249,7 +2345,12 @@ contain type identifiers."
(c c++) '(;; GCC extension.
"__attribute__"
;; MSVC extension.
- "__declspec"))
+ "__declspec")
+ c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept")))
+
+(c-lang-defconst c-paren-nontype-key
+ t (c-make-keywords-re t (c-lang-const c-paren-nontype-kwds)))
+(c-lang-defvar c-paren-nontype-key (c-lang-const c-paren-nontype-key))
(c-lang-defconst c-paren-type-kwds
"Keywords that may be followed by a parenthesis expression containing
@@ -2297,6 +2398,15 @@ assumed to be set if this isn't nil."
t (c-make-keywords-re t (c-lang-const c-<>-sexp-kwds)))
(c-lang-defvar c-opt-<>-sexp-key (c-lang-const c-opt-<>-sexp-key))
+(c-lang-defconst c-inside-<>-type-kwds
+ "Keywords which, used inside a C++ style template arglist, introduce a type."
+ t nil
+ java '("extends" "super"))
+
+(c-lang-defconst c-inside-<>-type-key
+ t (c-make-keywords-re t (c-lang-const c-inside-<>-type-kwds)))
+(c-lang-defvar c-inside-<>-type-key (c-lang-const c-inside-<>-type-key))
+
(c-lang-defconst c-brace-id-list-kwds
"Keywords that may be followed by a brace block containing a comma
separated list of identifier definitions, i.e. like the list of
@@ -2496,6 +2606,41 @@ Note that Java specific rules are currently applied to tell this from
(c-lang-defvar c-opt-inexpr-brace-list-key
(c-lang-const c-opt-inexpr-brace-list-key))
+(c-lang-defconst c-flat-decl-block-kwds
+ ;; Keywords that can introduce another declaration level, i.e. where a
+ ;; following "{" isn't a function block or brace list. Note that, for
+ ;; historical reasons, `c-decl-block-key' is NOT constructed from this lang
+ ;; const.
+ t (c--delete-duplicates
+ (append (c-lang-const c-class-decl-kwds)
+ (c-lang-const c-other-block-decl-kwds)
+ (c-lang-const c-inexpr-class-kwds))
+ :test 'string-equal))
+
+(c-lang-defconst c-brace-stack-thing-key
+ ;; Regexp matching any keyword or operator relevant to the brace stack (see
+ ;; `c-update-brace-stack' in cc-engine.el).
+ t (c-make-keywords-re 'appendable
+ (append
+ (c-lang-const c-flat-decl-block-kwds)
+ (if (c-lang-const c-recognize-<>-arglists)
+ '("{" "}" ";" "," ")" ":" "<")
+ '("{" "}" ";" "," ")" ":")))))
+(c-lang-defvar c-brace-stack-thing-key (c-lang-const c-brace-stack-thing-key))
+
+(c-lang-defconst c-brace-stack-no-semi-key
+ ;; Regexp matching any keyword or operator relevant to the brace stack when
+ ;; a semicolon is not relevant (see `c-update-brace-stack' in
+ ;; cc-engine.el).
+ t (c-make-keywords-re 'appendable
+ (append
+ (c-lang-const c-flat-decl-block-kwds)
+ (if (c-lang-const c-recognize-<>-arglists)
+ '("{" "}" "<")
+ '("{" "}")))))
+(c-lang-defvar c-brace-stack-no-semi-key
+ (c-lang-const c-brace-stack-no-semi-key))
+
(c-lang-defconst c-decl-block-key
;; Regexp matching keywords in any construct that contain another
;; declaration level, i.e. that isn't followed by a function block
@@ -2918,6 +3063,10 @@ Identifier syntax is in effect when this is matched \(see
"\\)"
"\\([^=]\\|$\\)")
c++ (concat "\\("
+ "&&"
+ "\\|"
+ "\\.\\.\\."
+ "\\|"
"[*(&]"
"\\|"
(c-lang-const c-type-decl-prefix-key)
@@ -2935,6 +3084,28 @@ Identifier syntax is in effect when this is matched \(see
(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
'dont-doc)
+(c-lang-defconst c-type-decl-operator-prefix-key
+ "Regexp matching any declarator operator which isn't a keyword
+that might precede the identifier in a declaration, e.g. the
+\"*\" in \"char *argv\". The end of the first submatch is taken
+as the end of the operator. Identifier syntax is in effect when
+this is matched \(see `c-identifier-syntax-table')."
+ t ;; Default to a regexp that never matches.
+ "\\<\\>"
+ ;; Check that there's no "=" afterwards to avoid matching tokens
+ ;; like "*=".
+ (c objc) (concat "\\(\\*\\)"
+ "\\([^=]\\|$\\)")
+ c++ (concat "\\("
+ "\\.\\.\\."
+ "\\|"
+ "\\*"
+ "\\)"
+ "\\([^=]\\|$\\)")
+ pike "\\(\\*\\)\\([^=]\\|$\\)")
+(c-lang-defvar c-type-decl-operator-prefix-key
+ (c-lang-const c-type-decl-operator-prefix-key))
+
(c-lang-defconst c-type-decl-suffix-key
"Regexp matching the declarator operators that might follow after the
identifier in a declaration, e.g. the \"[\" in \"char argv[]\". This
@@ -3064,7 +3235,7 @@ is in effect or not."
(c-lang-defconst c-special-brace-lists
"List of open- and close-chars that makes up a pike-style brace list,
-i.e. for a ([ ]) list there should be a cons (?\\[ . ?\\]) in this
+i.e., for a ([ ]) list there should be a cons (?\\[ . ?\\]) in this
list."
t nil
pike '((?{ . ?}) (?\[ . ?\]) (?< . ?>)))
@@ -3076,6 +3247,13 @@ list."
c t)
(c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p))
+(c-lang-defconst c-pre-id-bracelist-key
+ "A regexp matching tokens which, preceding an identifier, signify a bracelist.
+"
+ t "\\<\\>"
+ c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)")
+(c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key))
+
(c-lang-defconst c-recognize-typeless-decls
"Non-nil means function declarations without return type should be
recognized. That can introduce an ambiguity with parenthesized macro
@@ -3114,6 +3292,24 @@ the invalidity of the putative template construct."
c++ "[<;{},>()]")
(c-lang-defvar c-<>-notable-chars-re (c-lang-const c-<>-notable-chars-re))
+(c-lang-defconst c-enum-clause-introduction-re
+ ;; A regexp loosely matching the start of an enum clause, starting at the
+ ;; keyword itself, and extending up to the "{". It may match text which
+ ;; isn't such a construct; more accurate tests will rule these out when
+ ;; needed.
+ t (if (c-lang-const c-brace-list-decl-kwds)
+ (concat
+ "\\<\\("
+ (c-make-keywords-re nil (c-lang-const c-brace-list-decl-kwds))
+ "\\)\\>"
+ ;; Disallow various common punctuation chars that can't come
+ ;; before the '{' of the enum list, to avoid searching too far.
+ "[^][{};/#=]*"
+ "{")
+ "\\<\\>"))
+(c-lang-defvar c-enum-clause-introduction-re
+ (c-lang-const c-enum-clause-introduction-re))
+
(c-lang-defconst c-enums-contain-decls
"Non-nil means that an enum structure can contain declarations."
t nil
@@ -3213,8 +3409,8 @@ i.e. before \":\". Only used if `c-recognize-colon-labels' is set."
(append (c-lang-const c-label-kwds)
(c-lang-const c-protection-kwds))
:test 'string-equal)))
- ;; Don't allow string literals, except in AWK. Character constants are OK.
- (c objc java pike idl) (concat "\"\\|"
+ ;; Don't allow string literals, except in AWK and Java. Character constants are OK.
+ (c objc pike idl) (concat "\"\\|"
(c-lang-const c-nonlabel-token-key))
;; Also check for open parens in C++, to catch member init lists in
;; constructors. We normally allow it so that macros with arguments
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 53219a9e989..ac4ba05bb56 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -71,6 +71,19 @@
;;
;; http://lists.sourceforge.net/mailman/listinfo/cc-mode-announce
+;; Externally maintained major modes which use CC-mode's engine include:
+;; - cuda-mode
+;; - csharp-mode (https://github.com/josteink/csharp-mode)
+;; - haxe-mode
+;; - d-mode
+;; - dart-mode
+;; - cc-php-js-cs.el
+;; - php-mode
+;; - yang-mode
+;; - math-mode (mathematica)
+;; - unrealscript-mode
+;; - groovy-mode
+
;;; Code:
;; For Emacs < 22.2.
@@ -141,7 +154,18 @@
;; derived-mode-ex.el>.
(defun c-leave-cc-mode-mode ()
- (setq c-buffer-is-cc-mode nil))
+ (when c-buffer-is-cc-mode
+ (save-restriction
+ (widen)
+ (c-save-buffer-state ()
+ (c-clear-char-properties (point-min) (point-max) 'category)
+ (c-clear-char-properties (point-min) (point-max) 'syntax-table)
+ (c-clear-char-properties (point-min) (point-max) 'c-is-sws)
+ (c-clear-char-properties (point-min) (point-max) 'c-in-sws)
+ (c-clear-char-properties (point-min) (point-max) 'c-type)
+ (if (c-major-mode-is 'awk-mode)
+ (c-clear-char-properties (point-min) (point-max) 'c-awk-NL-prop))))
+ (setq c-buffer-is-cc-mode nil)))
(defun c-init-language-vars-for (mode)
"Initialize the language variables for one of the language modes
@@ -468,10 +492,15 @@ preferably use the `c-mode-menu' language constant directly."
(defvar c-just-done-before-change nil)
(make-variable-buffer-local 'c-just-done-before-change)
;; This variable is set to t by `c-before-change' and to nil by
-;; `c-after-change'. It is used to detect a spurious invocation of
-;; `before-change-functions' directly following on from a correct one. This
-;; happens in some Emacsen, for example when `basic-save-buffer' does (insert
-;; ?\n) when `require-final-newline' is non-nil.
+;; `c-after-change'. It is used for two purposes: (i) to detect a spurious
+;; invocation of `before-change-functions' directly following on from a
+;; correct one. This happens in some Emacsen, for example when
+;; `basic-save-buffer' does (insert ?\n) when `require-final-newline' is
+;; non-nil; (ii) to detect when Emacs fails to invoke
+;; `before-change-functions'. This can happen when reverting a buffer - see
+;; bug #24094. It seems these failures happen only in GNU Emacs; XEmacs
+;; seems to maintain the strict alternation of calls to
+;; `before-change-functions' and `after-change-functions'.
(defun c-basic-common-init (mode default-style)
"Do the necessary initialization for the syntax handling routines
@@ -528,6 +557,8 @@ that requires a literal mode spec at compile time."
;; Initialize the cache of brace pairs, and opening braces/brackets/parens.
(c-state-cache-init)
+ ;; Initialize the "brace stack" cache.
+ (c-init-bs-cache)
(when (or c-recognize-<>-arglists
(c-major-mode-is 'awk-mode)
@@ -641,6 +672,14 @@ that requires a literal mode spec at compile time."
(make-variable-buffer-local 'c-new-BEG)
(defvar c-new-END 0)
(make-variable-buffer-local 'c-new-END)
+;; The following two variables record the values of `c-new-BEG' and
+;; `c-new-END' just after `c-new-END' has been adjusted for the length of text
+;; inserted or removed. They may be read by any after-change function (but
+;; should not be altered by one).
+(defvar c-old-BEG 0)
+(make-variable-buffer-local 'c-old-BEG)
+(defvar c-old-END 0)
+(make-variable-buffer-local 'c-old-END)
(defun c-common-init (&optional mode)
"Common initialization for all CC Mode modes.
@@ -674,9 +713,8 @@ compatible with old code; callers should always specify it."
(funcall fn (point-min) (point-max)))
c-get-state-before-change-functions)
(mapc (lambda (fn)
- (if (not (eq fn 'c-restore-<>-properties))
- (funcall fn (point-min) (point-max)
- (- (point-max) (point-min)))))
+ (funcall fn (point-min) (point-max)
+ (- (point-max) (point-min))))
c-before-font-lock-functions))))
(set (make-local-variable 'outline-regexp) "[^#\n\^M]")
@@ -842,14 +880,6 @@ Note that the style variables are always made local to the buffer."
;;; Change hooks, linking with Font Lock and electric-indent-mode.
-;; Buffer local variables recording Beginning/End-of-Macro position before a
-;; change, when a macro straddles, respectively, the BEG or END (or both) of
-;; the change region. Otherwise these have the values BEG/END.
-(defvar c-old-BOM 0)
-(make-variable-buffer-local 'c-old-BOM)
-(defvar c-old-EOM 0)
-(make-variable-buffer-local 'c-old-EOM)
-
(defun c-called-from-text-property-change-p ()
;; Is the primitive which invoked `before-change-functions' or
;; `after-change-functions' one which merely changes text properties? This
@@ -862,9 +892,42 @@ Note that the style variables are always made local to the buffer."
(memq (cadr (backtrace-frame 3))
'(put-text-property remove-list-of-text-properties)))
+(defun c-depropertize-CPP (beg end)
+ ;; Remove the punctuation syntax-table text property from the CPP parts of
+ ;; (c-new-BEG c-new-END).
+ ;;
+ ;; This function is in the C/C++/ObjC values of
+ ;; `c-get-state-before-change-functions' and is called exclusively as a
+ ;; before change function.
+ (c-save-buffer-state (m-beg ss-found)
+ (goto-char c-new-BEG)
+ (while (and (< (point) beg)
+ (search-forward-regexp c-anchored-cpp-prefix beg 'bound))
+ (goto-char (match-beginning 1))
+ (setq m-beg (point))
+ (c-end-of-macro)
+ (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1)))
+
+ (while (and (< (point) end)
+ (setq ss-found
+ (search-forward-regexp c-anchored-cpp-prefix end 'bound)))
+ (goto-char (match-beginning 1))
+ (setq m-beg (point))
+ (c-end-of-macro))
+ (if (and ss-found (> (point) end))
+ (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1)))
+
+ (while (and (< (point) c-new-END)
+ (search-forward-regexp c-anchored-cpp-prefix c-new-END 'bound))
+ (goto-char (match-beginning 1))
+ (setq m-beg (point))
+ (c-end-of-macro)
+ (c-clear-char-property-with-value
+ m-beg (point) 'syntax-table '(1)))))
+
(defun c-extend-region-for-CPP (beg end)
- ;; Set c-old-BOM or c-old-EOM respectively to BEG, END, each extended to the
- ;; beginning/end of any preprocessor construct they may be in.
+ ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of
+ ;; any preprocessor construct they may be in.
;;
;; Point is undefined both before and after this function call; the buffer
;; has already been widened, and match-data saved. The return value is
@@ -873,45 +936,56 @@ Note that the style variables are always made local to the buffer."
;; This function is in the C/C++/ObjC values of
;; `c-get-state-before-change-functions' and is called exclusively as a
;; before change function.
- (goto-char beg)
+ (goto-char c-new-BEG)
(c-beginning-of-macro)
- (setq c-old-BOM (point))
+ (when (< (point) c-new-BEG)
+ (setq c-new-BEG (max (point) (c-determine-limit 500 c-new-BEG))))
- (goto-char end)
+ (goto-char c-new-END)
(when (c-beginning-of-macro)
(c-end-of-macro)
(or (eobp) (forward-char))) ; Over the terminating NL which may be marked
; with a c-cpp-delimiter category property
- (setq c-old-EOM (point)))
-
-(defun c-extend-font-lock-region-for-macros (begg endd &optional old-len)
- ;; Extend the region (BEGG ENDD) to cover all (possibly changed)
- ;; preprocessor macros; return the cons (new-BEG . new-END). OLD-LEN should
- ;; be either the old length parameter when called from an
- ;; after-change-function, or nil otherwise. This defun uses the variables
- ;; c-old-BOM, c-new-BOM.
+ (when (> (point) c-new-END)
+ (setq c-new-END (min (point) (c-determine-+ve-limit 500 c-new-END)))))
+
+(defun c-depropertize-new-text (beg end old-len)
+ ;; Remove from the new text in (BEG END) any and all text properties which
+ ;; might interfere with CC Mode's proper working.
+ ;;
+ ;; This function is called exclusively as an after-change function. It
+ ;; appears in the value (for all languages) of
+ ;; `c-before-font-lock-functions'. The value of point is undefined both on
+ ;; entry and exit, and the return value has no significance. The parameters
+ ;; BEG, END, and OLD-LEN are the standard ones supplied to all after-change
+ ;; functions.
+ (c-save-buffer-state ()
+ (when (> end beg)
+ (c-clear-char-properties beg end 'syntax-table)
+ (c-clear-char-properties beg end 'category)
+ (c-clear-char-properties beg end 'c-is-sws)
+ (c-clear-char-properties beg end 'c-in-sws)
+ (c-clear-char-properties beg end 'c-type)
+ (c-clear-char-properties beg end 'c-awk-NL-prop))))
+
+(defun c-extend-font-lock-region-for-macros (begg endd old-len)
+ ;; Extend the region (c-new-BEG c-new-END) to cover all (possibly changed)
+ ;; preprocessor macros; The return value has no significance.
;;
;; Point is undefined on both entry and exit to this function. The buffer
;; will have been widened on entry.
- (let (limits new-beg new-end)
- (goto-char c-old-BOM) ; already set to old start of macro or begg.
- (setq new-beg
- (min begg
- (if (setq limits (c-state-literal-at (point)))
- (cdr limits) ; go forward out of any string or comment.
- (point))))
-
- (goto-char endd)
- (if (setq limits (c-state-literal-at (point)))
- (goto-char (car limits))) ; go backward out of any string or comment.
- (if (c-beginning-of-macro)
- (c-end-of-macro))
- (setq new-end (max endd
- (if old-len
- (+ (- c-old-EOM old-len) (- endd begg))
- c-old-EOM)
- (point)))
- (cons new-beg new-end)))
+ ;;
+ ;; c-new-BEG has already been extended in `c-extend-region-for-CPP' so we
+ ;; don't need to repeat the exercise here.
+ ;;
+ ;; This function is in the C/C++/ObjC value of `c-before-font-lock-functions'.
+ (goto-char endd)
+ (when (c-beginning-of-macro)
+ (c-end-of-macro)
+ ;; Determine the region, (c-new-BEG c-new-END), which will get font
+ ;; locked. This restricts the region should there be long macros.
+ (setq c-new-END (min (max c-new-END (point))
+ (c-determine-+ve-limit 500 c-new-END)))))
(defun c-neutralize-CPP-line (beg end)
;; BEG and END bound a region, typically a preprocessor line. Put a
@@ -940,19 +1014,14 @@ Note that the style variables are always made local to the buffer."
(t nil)))))))
(defun c-neutralize-syntax-in-and-mark-CPP (begg endd old-len)
- ;; (i) Extend the font lock region to cover all changed preprocessor
- ;; regions; it does this by setting the variables `c-new-BEG' and
- ;; `c-new-END' to the new boundaries.
- ;;
- ;; (ii) "Neutralize" every preprocessor line wholly or partially in the
- ;; extended changed region. "Restore" lines which were CPP lines before the
- ;; change and are no longer so; these can be located from the Buffer local
- ;; variables `c-old-BOM' and `c-old-EOM'.
+ ;; (i) "Neutralize" every preprocessor line wholly or partially in the
+ ;; changed region. "Restore" lines which were CPP lines before the change
+ ;; and are no longer so.
;;
- ;; (iii) Mark every CPP construct by placing a `category' property value
+ ;; (ii) Mark each CPP construct by placing a `category' property value
;; `c-cpp-delimiter' at its start and end. The marked characters are the
;; opening # and usually the terminating EOL, but sometimes the character
- ;; before a comment/string delimiter.
+ ;; before a comment delimiter.
;;
;; That is, set syntax-table properties on characters that would otherwise
;; interact syntactically with those outside the CPP line(s).
@@ -969,16 +1038,9 @@ Note that the style variables are always made local to the buffer."
;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
;;
;; This function might make hidden buffer changes.
- (c-save-buffer-state (new-bounds)
- ;; First determine the region, (c-new-BEG c-new-END), which will get font
- ;; locked. It might need "neutralizing". This region may not start
- ;; inside a string, comment, or macro.
- (setq new-bounds (c-extend-font-lock-region-for-macros
- c-new-BEG c-new-END old-len))
- (setq c-new-BEG (max (car new-bounds) (c-determine-limit 500 begg))
- c-new-END (min (cdr new-bounds) (c-determine-+ve-limit 500 endd)))
- ;; Clear all old relevant properties.
- (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
+ (c-save-buffer-state (limits)
+ ;; Clear 'syntax-table properties "punctuation":
+ ;; (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
;; CPP "comment" markers:
(if (eval-when-compile (memq 'category-properties c-emacs-features));Emacs.
@@ -988,6 +1050,8 @@ Note that the style variables are always made local to the buffer."
;; Add needed properties to each CPP construct in the region.
(goto-char c-new-BEG)
+ (if (setq limits (c-literal-limits)) ; Go past any literal.
+ (goto-char (cdr limits)))
(skip-chars-backward " \t")
(let ((pps-position (point)) pps-state mbeg)
(while (and (< (point) c-new-END)
@@ -1007,7 +1071,7 @@ Note that the style variables are always made local to the buffer."
(nth 4 pps-state)))) ; in a comment?
(goto-char (match-beginning 1))
(setq mbeg (point))
- (if (> (c-syntactic-end-of-macro) mbeg)
+ (if (> (c-no-comment-end-of-macro) mbeg)
(progn
(c-neutralize-CPP-line mbeg (point)) ; "punctuation" properties
(if (eval-when-compile
@@ -1016,6 +1080,102 @@ Note that the style variables are always made local to the buffer."
(forward-line)) ; no infinite loop with, e.g., "#//"
)))))
+(defun c-before-after-change-digit-quote (beg end &optional old-len)
+ ;; This function either removes or applies the punctuation value ('(1)) of
+ ;; the `syntax-table' text property on single quote marks which are
+ ;; separator characters in long integer literals, e.g. "4'294'967'295". It
+ ;; applies to both decimal/octal and hex literals. (FIXME (2016-06-10): it
+ ;; should also apply to binary literals.)
+ ;;
+ ;; In both uses of the function, the `syntax-table' properties are
+ ;; removed/applied only on quote marks which appear to be digit separators.
+ ;;
+ ;; Point is undefined on both entry and exit to this function, and the
+ ;; return value has no significance. The function is called solely as a
+ ;; before-change function (see `c-get-state-before-change-functions') and as
+ ;; an after change function (see `c-before-font-lock-functions', with the
+ ;; parameters BEG, END, and (optionally) OLD-LEN being given the standard
+ ;; values for before/after-change functions.
+ (c-save-buffer-state ((num-begin c-new-BEG) digit-re try-end)
+ (goto-char c-new-END)
+ (when (looking-at "\\(x\\)?[0-9a-fA-F']+")
+ (setq c-new-END (match-end 0)))
+ (goto-char c-new-BEG)
+ (when (looking-at "\\(x?\\)[0-9a-fA-F']")
+ (if (re-search-backward "\\(0x\\)?[0-9a-fA-F]*\\=" nil t)
+ (setq c-new-BEG (point))))
+
+ (while
+ (re-search-forward "[0-9a-fA-F]'[0-9a-fA-F]" c-new-END t)
+ (setq try-end (1- (point)))
+ (re-search-backward "[^0-9a-fA-F']" num-begin t)
+ (setq digit-re
+ (cond
+ ((and (not (bobp)) (eq (char-before) ?0) (memq (char-after) '(?x ?X)))
+ "[0-9a-fA-F]")
+ ((and (eq (char-after (1+ (point))) ?0)
+ (memq (char-after (+ 2 (point))) '(?b ?B)))
+ "[01]")
+ ((memq (char-after (1+ (point))) '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
+ "[0-9]")
+ (t nil)))
+ (when digit-re
+ (cond ((eq (char-after) ?x) (forward-char))
+ ((looking-at ".?0[Bb]") (goto-char (match-end 0)))
+ ((looking-at digit-re))
+ (t (forward-char)))
+ (when (not (c-in-literal))
+ (let ((num-end ; End of valid sequence of digits/quotes.
+ (save-excursion
+ (re-search-forward
+ (concat "\\=\\(" digit-re "+'\\)*" digit-re "+") nil t)
+ (point))))
+ (setq try-end ; End of sequence of digits/quotes
+ (save-excursion
+ (re-search-forward
+ (concat "\\=\\(" digit-re "\\|'\\)+") nil t)
+ (point)))
+ (while (re-search-forward
+ (concat digit-re "\\('\\)" digit-re) num-end t)
+ (if old-len ; i.e. are we in an after-change function?
+ (c-put-char-property (match-beginning 1) 'syntax-table '(1))
+ (c-clear-char-property (match-beginning 1) 'syntax-table))
+ (backward-char)))))
+ (goto-char try-end)
+ (setq num-begin (point)))))
+
+;; The following doesn't seem needed at the moment (2016-08-15).
+;; (defun c-before-after-change-extend-region-for-lambda-capture
+;; (_beg _end &optional _old-len)
+;; ;; In C++ Mode, extend the region (c-new-BEG c-new-END) to cover any lambda
+;; ;; function capture lists we happen to be inside. This function is expected
+;; ;; to be called both as a before-change and after change function.
+;; ;;
+;; ;; Note that these things _might_ be nested, with a capture list looking
+;; ;; like:
+;; ;;
+;; ;; [ ...., &foo = [..](){...}(..), ... ]
+;; ;;
+;; ;; . What a wonderful language is C++. ;-)
+;; (c-save-buffer-state (paren-state pos)
+;; (goto-char c-new-BEG)
+;; (setq paren-state (c-parse-state))
+;; (while (setq pos (c-pull-open-brace paren-state))
+;; (goto-char pos)
+;; (when (c-looking-at-c++-lambda-capture-list)
+;; (setq c-new-BEG (min c-new-BEG pos))
+;; (if (c-go-list-forward)
+;; (setq c-new-END (max c-new-END (point))))))
+
+;; (goto-char c-new-END)
+;; (setq paren-state (c-parse-state))
+;; (while (setq pos (c-pull-open-brace paren-state))
+;; (goto-char pos)
+;; (when (c-looking-at-c++-lambda-capture-list)
+;; (setq c-new-BEG (min c-new-BEG pos))
+;; (if (c-go-list-forward)
+;; (setq c-new-END (max c-new-END (point))))))))
+
(defun c-before-change (beg end)
;; Function to be put on `before-change-functions'. Primarily, this calls
;; the language dependent `c-get-state-before-change-functions'. It is
@@ -1130,10 +1290,22 @@ Note that the style variables are always made local to the buffer."
;; This calls the language variable c-before-font-lock-functions, if non nil.
;; This typically sets `syntax-table' properties.
+ ;; We can sometimes get two consecutive calls to `after-change-functions'
+ ;; without an intervening call to `before-change-functions' when reverting
+ ;; the buffer (see bug #24094). Whatever the cause, assume that the entire
+ ;; buffer has changed.
+ (when (not c-just-done-before-change)
+ (save-restriction
+ (widen)
+ (c-before-change (point-min) (point-max))
+ (setq beg (point-min)
+ end (point-max)
+ old-len (- end beg))))
+
;; (c-new-BEG c-new-END) will be the region to fontify. It may become
;; larger than (beg end).
- ;; (setq c-new-BEG beg c-new-END end)
(setq c-new-END (- (+ c-new-END (- end beg)) old-len))
+ (setq c-old-BEG c-new-BEG c-old-END c-new-END)
(unless (c-called-from-text-property-change-p)
(setq c-just-done-before-change nil)
@@ -1181,28 +1353,41 @@ Note that the style variables are always made local to the buffer."
(defun c-fl-decl-start (pos)
;; If the beginning of the line containing POS is in the middle of a "local"
- ;; declaration (i.e. one which does not start outside of braces enclosing
- ;; POS, such as a struct), return the beginning of that declaration.
- ;; Otherwise return nil. Note that declarations, in this sense, can be
- ;; nested.
+ ;; declaration, return the beginning of that declaration. Otherwise return
+ ;; nil. Note that declarations, in this sense, can be nested. (A local
+ ;; declaration is one which does not start outside of struct braces (and
+ ;; similar) enclosing POS. Brace list braces here are not "similar".
;;
;; This function is called indirectly from font locking stuff - either from
;; c-after-change (to prepare for after-change font-locking) or from font
;; lock context (etc.) fontification.
- (let ((lit-limits (c-literal-limits))
+ (let ((lit-start (c-literal-start))
(new-pos pos)
+ capture-opener
bod-lim bo-decl)
(goto-char (c-point 'bol new-pos))
- (when lit-limits ; Comment or string.
- (goto-char (car lit-limits)))
+ (when lit-start ; Comment or string.
+ (goto-char lit-start))
(setq bod-lim (c-determine-limit 500))
+ ;; In C++ Mode, first check if we are within a (possibly nested) lambda
+ ;; form capture list.
+ (when (c-major-mode-is 'c++-mode)
+ (let ((paren-state (c-parse-state))
+ opener)
+ (save-excursion
+ (while (setq opener (c-pull-open-brace paren-state))
+ (goto-char opener)
+ (if (c-looking-at-c++-lambda-capture-list)
+ (setq capture-opener (point)))))))
+
(while
;; Go to a less nested declaration each time round this loop.
(and
- (eq (car (c-beginning-of-decl-1 bod-lim)) 'same)
+ (c-syntactic-skip-backward "^;{}" bod-lim t)
(> (point) bod-lim)
- (progn (setq bo-decl (point))
+ (progn (c-forward-syntactic-ws)
+ (setq bo-decl (point))
;; Are we looking at a keyword such as "template" or
;; "typedef" which can decorate a type, or the type itself?
(when (or (looking-at c-prefix-spec-kwds-re)
@@ -1219,12 +1404,19 @@ Note that the style variables are always made local to the buffer."
(and (eq (char-before) ?\<)
(eq (c-get-char-property
(1- (point)) 'syntax-table)
- c-<-as-paren-syntax)))))
+ c-<-as-paren-syntax))
+ (and (eq (char-before) ?{)
+ (save-excursion
+ (backward-char)
+ (consp (c-looking-at-or-maybe-in-bracelist))))
+ )))
(not (bobp)))
(backward-char)) ; back over (, [, <.
+ (when (and capture-opener (< capture-opener new-pos))
+ (setq new-pos capture-opener))
(and (/= new-pos pos) new-pos)))
-(defun c-change-expand-fl-region (beg end old-len)
+(defun c-change-expand-fl-region (_beg _end _old-len)
;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock
;; region. This will usually be the smallest sequence of whole lines
;; containing `c-new-BEG' and `c-new-END', but if `c-new-BEG' is in a
@@ -1233,10 +1425,15 @@ Note that the style variables are always made local to the buffer."
;;
;; This is called from an after-change-function, but the parameters BEG END
;; and OLD-LEN are not used.
- (if font-lock-mode
- (setq c-new-BEG
- (or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
- c-new-END (c-point 'bonl c-new-END))))
+ (if font-lock-mode
+ (setq c-new-BEG
+ (or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
+ c-new-END
+ (save-excursion
+ (goto-char c-new-END)
+ (if (bolp)
+ (point)
+ (c-point 'bonl c-new-END))))))
(defun c-context-expand-fl-region (beg end)
;; Return a cons (NEW-BEG . NEW-END), where NEW-BEG is the beginning of a
@@ -1446,7 +1643,8 @@ This function is called from `c-common-init', once per mode initialization."
;;;###autoload (add-to-list 'auto-mode-alist '("\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\'" . c++-mode))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.\\(CC?\\|HH?\\)\\'" . c++-mode))
-;;;###autoload (add-to-list 'auto-mode-alist '("\\.[ch]\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.c\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.h\\'" . c-or-c++-mode))
;; NB: The following two associate yacc and lex files to C Mode, which
;; is not really suitable for those formats. Anyway, afaik there's
@@ -1476,18 +1674,50 @@ initialization, then `c-mode-hook'.
Key bindings:
\\{c-mode-map}"
+ :after-hook (progn (c-make-noise-macro-regexps)
+ (c-make-macro-with-semi-re)
+ (c-update-modeline))
(c-initialize-cc-mode t)
- (set-syntax-table c-mode-syntax-table)
- (setq local-abbrev-table c-mode-abbrev-table
- abbrev-mode t)
- (use-local-map c-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'c-mode)
- (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
(c-common-init 'c-mode)
(easy-menu-add c-c-menu)
(cc-imenu-init cc-imenu-c-generic-expression)
- (c-run-mode-hooks 'c-mode-common-hook 'c-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
+
+(defconst c-or-c++-mode--regexp
+ (eval-when-compile
+ (let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*"))
+ (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\\)>"
+ "\\)")))
+ "A regexp applied to C header files to check if they are really C++.")
+
+;;;###autoload
+(defun c-or-c++-mode ()
+ "Analyse buffer and enable either C or C++ mode.
+
+Some people and projects use .h extension for C++ header files
+which is also the one used for C header files. This makes
+matching on file name insufficient for detecting major mode that
+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'."
+ (if (save-excursion
+ (save-restriction
+ (save-match-data
+ (widen)
+ (goto-char (point-min))
+ (re-search-forward c-or-c++-mode--regexp
+ (+ (point) c-guess-region-max) t))))
+ (c++-mode)
+ (c-mode)))
;; Support for C++
@@ -1531,18 +1761,16 @@ initialization, then `c++-mode-hook'.
Key bindings:
\\{c++-mode-map}"
+ :after-hook (progn (c-make-noise-macro-regexps)
+ (c-make-macro-with-semi-re)
+ (c-update-modeline))
(c-initialize-cc-mode t)
- (set-syntax-table c++-mode-syntax-table)
- (setq local-abbrev-table c++-mode-abbrev-table
- abbrev-mode t)
- (use-local-map c++-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'c++-mode)
- (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
(c-common-init 'c++-mode)
(easy-menu-add c-c++-menu)
(cc-imenu-init cc-imenu-c++-generic-expression)
- (c-run-mode-hooks 'c-mode-common-hook 'c++-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; Support for Objective-C
@@ -1584,18 +1812,16 @@ initialization, then `objc-mode-hook'.
Key bindings:
\\{objc-mode-map}"
+ :after-hook (progn (c-make-noise-macro-regexps)
+ (c-make-macro-with-semi-re)
+ (c-update-modeline))
(c-initialize-cc-mode t)
- (set-syntax-table objc-mode-syntax-table)
- (setq local-abbrev-table objc-mode-abbrev-table
- abbrev-mode t)
- (use-local-map objc-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'objc-mode)
- (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
(c-common-init 'objc-mode)
(easy-menu-add c-objc-menu)
(cc-imenu-init nil 'cc-imenu-objc-function)
- (c-run-mode-hooks 'c-mode-common-hook 'objc-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; Support for Java
@@ -1645,17 +1871,14 @@ initialization, then `java-mode-hook'.
Key bindings:
\\{java-mode-map}"
+ :after-hook (c-update-modeline)
(c-initialize-cc-mode t)
- (set-syntax-table java-mode-syntax-table)
- (setq local-abbrev-table java-mode-abbrev-table
- abbrev-mode t)
- (use-local-map java-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'java-mode)
(c-common-init 'java-mode)
(easy-menu-add c-java-menu)
(cc-imenu-init cc-imenu-java-generic-expression)
- (c-run-mode-hooks 'c-mode-common-hook 'java-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; Support for CORBA's IDL language
@@ -1694,16 +1917,13 @@ initialization, then `idl-mode-hook'.
Key bindings:
\\{idl-mode-map}"
+ :after-hook (c-update-modeline)
(c-initialize-cc-mode t)
- (set-syntax-table idl-mode-syntax-table)
- (setq local-abbrev-table idl-mode-abbrev-table)
- (use-local-map idl-mode-map)
(c-init-language-vars-for 'idl-mode)
(c-common-init 'idl-mode)
(easy-menu-add c-idl-menu)
;;(cc-imenu-init cc-imenu-idl-generic-expression) ;TODO
- (c-run-mode-hooks 'c-mode-common-hook 'idl-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; Support for Pike
@@ -1746,17 +1966,14 @@ initialization, then `pike-mode-hook'.
Key bindings:
\\{pike-mode-map}"
+ :after-hook (c-update-modeline)
(c-initialize-cc-mode t)
- (set-syntax-table pike-mode-syntax-table)
- (setq local-abbrev-table pike-mode-abbrev-table
- abbrev-mode t)
- (use-local-map pike-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'pike-mode)
(c-common-init 'pike-mode)
(easy-menu-add c-pike-menu)
;;(cc-imenu-init cc-imenu-pike-generic-expression) ;TODO
- (c-run-mode-hooks 'c-mode-common-hook 'pike-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; Support for AWK
@@ -1775,9 +1992,9 @@ Key bindings:
(defvar awk-mode-map
(let ((map (c-make-inherited-keymap)))
;; Add bindings which are only useful for awk.
- (define-key map "#" 'self-insert-command)
- (define-key map "/" 'self-insert-command)
- (define-key map "*" 'self-insert-command)
+ (define-key map "#" 'self-insert-command);Overrides electric parent binding.
+ (define-key map "/" 'self-insert-command);Overrides electric parent binding.
+ (define-key map "*" 'self-insert-command);Overrides electric parent binding.
(define-key map "\C-c\C-n" 'undefined) ; #if doesn't exist in awk.
(define-key map "\C-c\C-p" 'undefined)
(define-key map "\C-c\C-u" 'undefined)
@@ -1810,22 +2027,18 @@ initialization, then `awk-mode-hook'.
Key bindings:
\\{awk-mode-map}"
+ :after-hook (c-update-modeline)
;; We need the next line to stop the macro defining
;; `awk-mode-syntax-table'. This would mask the real table which is
;; declared in cc-awk.el and hasn't yet been loaded.
:syntax-table nil
(require 'cc-awk) ; Added 2003/6/10.
(c-initialize-cc-mode t)
- (set-syntax-table awk-mode-syntax-table)
- (setq local-abbrev-table awk-mode-abbrev-table
- abbrev-mode t)
- (use-local-map awk-mode-map)
+ (setq abbrev-mode t)
(c-init-language-vars-for 'awk-mode)
(c-common-init 'awk-mode)
(c-awk-unstick-NL-prop)
-
- (c-run-mode-hooks 'c-mode-common-hook 'awk-mode-hook)
- (c-update-modeline))
+ (c-run-mode-hooks 'c-mode-common-hook))
;; bug reporting
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index b742327c93e..a6a96d15188 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -247,7 +247,7 @@ See `c-offsets-alist'."
;;; User variables
(defcustom c-strict-syntax-p nil
- "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
+ "If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
If the syntactic symbol for a particular line does not match a symbol
in the offsets alist, or if no non-nil offset value can be determined
for a symbol, an error is generated, otherwise no error is reported
@@ -260,12 +260,12 @@ syntactic symbols in `c-offsets-alist'. Please keep it set to nil."
:group 'c)
(defcustom c-echo-syntactic-information-p nil
- "*If non-nil, syntactic info is echoed when the line is indented."
+ "If non-nil, syntactic info is echoed when the line is indented."
:type 'boolean
:group 'c)
(defcustom c-report-syntactic-errors nil
- "*If non-nil, certain syntactic errors are reported with a ding
+ "If non-nil, certain syntactic errors are reported with a ding
and a message, for example when an \"else\" is indented for which
there's no corresponding \"if\".
@@ -277,7 +277,7 @@ anchoring position to indent the line in that case."
:group 'c)
(defcustom-c-stylevar c-basic-offset 4
- "*Amount of basic offset used by + and - symbols in `c-offsets-alist'.
+ "Amount of basic offset used by + and - symbols in `c-offsets-alist'.
Also used as the indentation step when `c-syntactic-indentation' is
nil."
:type 'integer
@@ -286,7 +286,7 @@ nil."
(defcustom c-tab-always-indent t
- "*Controls the operation of the TAB key.
+ "Controls the operation of the TAB key.
If t, hitting TAB always just indents the current line. If nil, hitting
TAB indents the current line if point is at the left margin or in the
line's indentation, otherwise it inserts a `real' tab character \(see
@@ -308,7 +308,7 @@ by the `c-comment-only-line-offset' variable."
:group 'c)
(defcustom c-insert-tab-function 'insert-tab
- "*Function used when inserting a tab for \\[c-indent-command].
+ "Function used when inserting a tab for \\[c-indent-command].
Only used when `c-tab-always-indent' indicates a `real' tab character
should be inserted. Value must be a function taking no arguments.
The default, `insert-tab', inserts either a tab or the equivalent
@@ -317,7 +317,7 @@ number of spaces depending on the value of `indent-tabs-mode'."
:group 'c)
(defcustom c-syntactic-indentation t
- "*Whether the indentation should be controlled by the syntactic context.
+ "Whether the indentation should be controlled by the syntactic context.
If t, the indentation functions indent according to the syntactic
context, using the style settings specified by `c-offsets-alist'.
@@ -333,7 +333,7 @@ e.g. `c-special-indent-hook'."
(put 'c-syntactic-indentation 'safe-local-variable 'booleanp)
(defcustom c-syntactic-indentation-in-macros t
- "*Enable syntactic analysis inside macros.
+ "Enable syntactic analysis inside macros.
If this is nil, all lines inside macro definitions are analyzed as
`cpp-macro-cont'. Otherwise they are analyzed syntactically, just
like normal code, and `cpp-define-intro' is used to create the
@@ -352,7 +352,7 @@ better with the \"do { ... } while \(0)\" trick)."
(put 'c-syntactic-indentation-in-macros 'safe-local-variable 'booleanp)
(defcustom c-defun-tactic 'go-outward
- "*Whether functions are recognized inside, e.g., a class.
+ "Whether functions are recognized inside, e.g., a class.
This is used by `c-beginning-of-defun' and like functions.
Its value is one of:
@@ -367,7 +367,7 @@ Its value is one of:
:group 'c)
(defcustom-c-stylevar c-comment-only-line-offset 0
- "*Extra offset for line which contains only the start of a comment.
+ "Extra offset for line which contains only the start of a comment.
Can contain an integer or a cons cell of the form:
(NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
@@ -391,7 +391,7 @@ default)."
'((anchored-comment . (column . 0))
(end-block . (space . 1))
(cpp-end-block . (space . 2)))
- "*Specifies how \\[indent-for-comment] calculates the comment start column.
+ "Specifies how \\[indent-for-comment] calculates the comment start column.
This is an association list that contains entries of the form:
(LINE-TYPE . INDENT-SPEC)
@@ -465,7 +465,7 @@ in that case, i.e. as if \\[c-indent-command] was used instead."
:group 'c)
(defcustom-c-stylevar c-indent-comments-syntactically-p nil
- "*Specifies how \\[indent-for-comment] should handle comment-only lines.
+ "Specifies how \\[indent-for-comment] should handle comment-only lines.
When this variable is non-nil, comment-only lines are indented
according to syntactic analysis via `c-offsets-alist'. Otherwise, the
comment is indented as if it was preceded by code. Note that this
@@ -488,7 +488,7 @@ comment-only lines."
(if (boundp 'c-comment-continuation-stars)
(symbol-value 'c-comment-continuation-stars)
"* ")
- "*Specifies the line prefix of continued C-style block comments.
+ "Specifies the line prefix of continued C-style block comments.
You should set this variable to the literal string that gets inserted
at the front of continued block style comment lines. This should
either be the empty string, or some characters without preceding
@@ -507,7 +507,7 @@ style comments."
'((pike-mode . "//+!?\\|\\**")
(awk-mode . "#+")
(other . "//+\\|\\**"))
- "*Regexp to match the line prefix inside comments.
+ "Regexp to match the line prefix inside comments.
This regexp is used to recognize the fill prefix inside comments for
correct paragraph filling and other things.
@@ -564,7 +564,7 @@ variable in a mode hook."
'((java-mode . javadoc)
(pike-mode . autodoc)
(c-mode . gtkdoc))
- "*Specifies documentation comment style(s) to recognize.
+ "Specifies documentation comment style(s) to recognize.
This is primarily used to fontify doc comments and the markup within
them, e.g. Javadoc comments.
@@ -634,7 +634,7 @@ afterwards to redo that work."
:group 'c)
(defcustom c-ignore-auto-fill '(string cpp code)
- "*List of contexts in which automatic filling never occurs.
+ "List of contexts in which automatic filling never occurs.
If Auto Fill mode is active, it will be temporarily disabled if point
is in any context on this list. It's e.g. useful to enable Auto Fill
in comments only, but not in strings or normal code. The valid
@@ -654,7 +654,7 @@ contexts are:
:group 'c)
(defcustom-c-stylevar c-cleanup-list '(scope-operator)
- "*List of various C/C++/ObjC constructs to \"clean up\".
+ "List of various C/C++/ObjC constructs to \"clean up\".
The following clean ups only take place when the auto-newline feature
is turned on, as evidenced by the `/la' appearing next to the mode
name:
@@ -751,7 +751,7 @@ involve auto-newline inserted newlines:
(inexpr-class-open after)
(inexpr-class-close before)
(arglist-cont-nonempty))
- "*Controls the insertion of newlines before and after braces
+ "Controls the insertion of newlines before and after braces
when the auto-newline feature is active. This variable contains an
association list with elements of the following form:
\(SYNTACTIC-SYMBOL . ACTION).
@@ -815,7 +815,7 @@ Zero or nil means no limit."
:group 'c)
(defcustom-c-stylevar c-hanging-colons-alist nil
- "*Controls the insertion of newlines before and after certain colons.
+ "Controls the insertion of newlines before and after certain colons.
This variable contains an association list with elements of the
following form: (SYNTACTIC-SYMBOL . ACTION).
@@ -838,7 +838,7 @@ currently not supported for this variable."
(defcustom-c-stylevar c-hanging-semi&comma-criteria
'(c-semi&comma-inside-parenlist)
- "*List of functions that decide whether to insert a newline or not.
+ "List of functions that decide whether to insert a newline or not.
The functions in this list are called, in order, whenever the
auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
string in the mode line), and a semicolon or comma is typed (see
@@ -855,7 +855,7 @@ then no newline is inserted."
:group 'c)
(defcustom-c-stylevar c-backslash-column 48
- "*Minimum alignment column for line continuation backslashes.
+ "Minimum alignment column for line continuation backslashes.
This is used by the functions that automatically insert or align the
line continuation backslashes in multiline macros. If any line in the
macro exceeds this column then the next tab stop from that line is
@@ -865,7 +865,7 @@ used as alignment column instead. See also `c-backslash-max-column'."
;;;###autoload(put 'c-backslash-column 'safe-local-variable 'integerp)
(defcustom-c-stylevar c-backslash-max-column 72
- "*Maximum alignment column for line continuation backslashes.
+ "Maximum alignment column for line continuation backslashes.
This is used by the functions that automatically insert or align the
line continuation backslashes in multiline macros. If any line in the
macro exceeds this column then the backslashes for the other lines
@@ -874,7 +874,7 @@ will be aligned at this column."
:group 'c)
(defcustom c-auto-align-backslashes t
- "*Align automatically inserted line continuation backslashes.
+ "Align automatically inserted line continuation backslashes.
When line continuation backslashes are inserted automatically for line
breaks in multiline macros, e.g. by \\[c-context-line-break], they are
aligned with the other backslashes in the same macro if this flag is
@@ -884,12 +884,12 @@ space."
:group 'c)
(defcustom c-backspace-function 'backward-delete-char-untabify
- "*Function called by `c-electric-backspace' when deleting backwards."
+ "Function called by `c-electric-backspace' when deleting backwards."
:type 'function
:group 'c)
(defcustom c-delete-function 'delete-char
- "*Function called by `c-electric-delete-forward' when deleting forwards."
+ "Function called by `c-electric-delete-forward' when deleting forwards."
:type 'function
:group 'c)
@@ -901,7 +901,7 @@ space."
'((c-mode . t)
(c++-mode . t)
(objc-mode . t))
- "*Controls whether a final newline is ensured when the file is saved.
+ "Controls whether a final newline is ensured when the file is saved.
The value is an association list that for each language mode specifies
the value to give to `require-final-newline' at mode initialization;
see that variable for details about the value. If a language isn't
@@ -931,20 +931,20 @@ present on the association list, CC Mode won't touch
:group 'c)
(defcustom c-electric-pound-behavior nil
- "*List of behaviors for electric pound insertion.
+ "List of behaviors for electric pound insertion.
Only currently supported behavior is `alignleft'."
:type '(set (const alignleft))
:group 'c)
(defcustom c-special-indent-hook nil
- "*Hook for user defined special indentation adjustments.
+ "Hook for user defined special indentation adjustments.
This hook gets called after each line is indented by the mode. It is only
called when `c-syntactic-indentation' is non-nil."
:type 'hook
:group 'c)
(defcustom-c-stylevar c-label-minimum-indentation 1
- "*Minimum indentation for lines inside code blocks.
+ "Minimum indentation for lines inside code blocks.
This variable typically only affects code using the `gnu' style, which
mandates a minimum of one space in front of every line inside code
blocks. Specifically, the function `c-gnu-impose-minimum' on your
@@ -953,7 +953,7 @@ blocks. Specifically, the function `c-gnu-impose-minimum' on your
:group 'c)
(defcustom c-progress-interval 5
- "*Interval used to update progress status during long re-indentation.
+ "Interval used to update progress status during long re-indentation.
If a number, percentage complete gets updated after each interval of
that many seconds. To inhibit all messages during indentation, set
this variable to nil."
@@ -961,7 +961,7 @@ this variable to nil."
:group 'c)
(defcustom c-objc-method-arg-min-delta-to-bracket 2
- "*Minimum number of chars to the opening bracket.
+ "Minimum number of chars to the opening bracket.
Consider this ObjC snippet:
@@ -981,7 +981,7 @@ This behavior can be overridden by customizing the indentation of
:group 'c)
(defcustom c-objc-method-arg-unfinished-offset 4
- "*Offset relative to bracket if first selector is on a new line.
+ "Offset relative to bracket if first selector is on a new line.
[aaaaaaaaa
|<-x->|bbbbbbb: cccccc
@@ -990,7 +990,7 @@ This behavior can be overridden by customizing the indentation of
:group 'c)
(defcustom c-objc-method-parameter-offset 4
- "*Offset for selector parameter on a new line (relative to first selector.
+ "Offset for selector parameter on a new line (relative to first selector.
[aaaaaaa bbbbbbbbbb:
|<-x->|cccccccc
@@ -1001,7 +1001,7 @@ This behavior can be overridden by customizing the indentation of
(defcustom c-default-style '((java-mode . "java") (awk-mode . "awk")
(other . "gnu"))
- "*Style which gets installed by default when a file is visited.
+ "Style which gets installed by default when a file is visited.
The value of this variable can be any style defined in
`c-style-alist', including styles you add. The value can also be an
@@ -1411,7 +1411,7 @@ Here is the current list of valid syntactic element symbols:
do-while-closure else-clause catch-clause inlambda annotation-var-cont))
(defcustom c-style-variables-are-local-p t
- "*Whether style variables should be buffer local by default.
+ "Whether style variables should be buffer local by default.
If non-nil, then all indentation style related variables will be made
buffer local by default. If nil, they will remain global. Variables
are made buffer local when this file is loaded, and once buffer
@@ -1442,54 +1442,54 @@ The list of variables to buffer localize are:
:group 'c)
(defcustom c-mode-hook nil
- "*Hook called by `c-mode'."
+ "Hook called by `c-mode'."
:type 'hook
:group 'c)
(defcustom c++-mode-hook nil
- "*Hook called by `c++-mode'."
+ "Hook called by `c++-mode'."
:type 'hook
:group 'c)
(defcustom objc-mode-hook nil
- "*Hook called by `objc-mode'."
+ "Hook called by `objc-mode'."
:type 'hook
:group 'c)
(defcustom java-mode-hook nil
- "*Hook called by `java-mode'."
+ "Hook called by `java-mode'."
:type 'hook
:group 'c)
(defcustom idl-mode-hook nil
- "*Hook called by `idl-mode'."
+ "Hook called by `idl-mode'."
:type 'hook
:group 'c)
(defcustom pike-mode-hook nil
- "*Hook called by `pike-mode'."
+ "Hook called by `pike-mode'."
:type 'hook
:group 'c)
(defcustom awk-mode-hook nil
- "*Hook called by `awk-mode'."
+ "Hook called by `awk-mode'."
:type 'hook
:group 'c)
(defcustom c-mode-common-hook nil
- "*Hook called by all CC Mode modes for common initializations."
+ "Hook called by all CC Mode modes for common initializations."
:type 'hook
:group 'c)
(defcustom c-initialization-hook nil
- "*Hook called when the CC Mode package gets initialized.
+ "Hook called when the CC Mode package gets initialized.
This hook is only run once per Emacs session and can be used as a
`load-hook' or in place of using `eval-after-load'."
:type 'hook
:group 'c)
(defcustom c-enable-xemacs-performance-kludge-p nil
- "*Enables a XEmacs only hack that may improve speed for some coding styles.
+ "Enables a XEmacs only hack that may improve speed for some coding styles.
For styles that hang top-level opening braces (as is common with JDK
Java coding styles) this can improve performance between 3 and 60
times for core indentation functions (e.g. `c-parse-state'). For
@@ -1499,8 +1499,8 @@ This variable only has effect in XEmacs."
:type 'boolean
:group 'c)
-(defvar c-old-style-variable-behavior nil
- "*Enables the old style variable behavior when non-nil.
+(defcustom c-old-style-variable-behavior nil
+ "Enables the old style variable behavior when non-nil.
Normally the values of the style variables will override the style
settings specified by the variables `c-default-style' and
@@ -1513,7 +1513,9 @@ It's believed that despite this change, the new behavior will still
produce the same results for most old CC Mode configurations, since
all style variables are per default set in a special non-override
state. Set this variable only if your configuration has stopped
-working due to this change.")
+working due to this change."
+ :type 'boolean
+ :group 'c)
(define-widget 'c-extra-types-widget 'radio
"Internal CC Mode widget for the `*-font-lock-extra-types' variables."
@@ -1632,12 +1634,53 @@ names)."))
:type 'c-extra-types-widget
:group 'c)
-
-;; Non-customizable variables, still part of the interface to CC Mode
-;; The following two are preparations for Emacs 25.2 (2016-05-09):
+(defvar c-noise-macro-with-parens-name-re "\\<\\>")
+(defvar c-noise-macro-name-re "\\<\\>")
+
+(defcustom c-noise-macro-names nil
+ "A list of names of macros which expand to nothing, or compiler extensions
+like \"????\" which are syntactic noise. Such a macro/extension is complete in
+itself, never having parentheses. All these names must be syntactically valid
+identifiers.
+
+If you change this variable's value, call the function
+`c-make-noise-macro-regexps' to set the necessary internal variables (or do
+this implicitly by reinitializing C/C++/Objc Mode on any buffer)."
+ :type '(repeat :tag "List of names" string)
+ :group 'c)
(put 'c-noise-macro-names 'safe-local-variable #'c-string-list-p)
+
+(defcustom c-noise-macro-with-parens-names nil
+ "A list of names of macros \(or compiler extensions like \"__attribute__\")
+which optionally have arguments in parentheses, and which expand to nothing.
+These are recognized by CC Mode only in declarations."
+ :type '(regexp :tag "List of names (possibly empty)" string)
+ :group 'c)
(put 'c-noise-macro-with-parens-names 'safe-local-variable #'c-string-list-p)
+(defun c-make-noise-macro-regexps ()
+ ;; Convert `c-noise-macro-names' and `c-noise-macro-with-parens-names' into
+ ;; `c-noise-macro-name-re' and `c-noise-macro-with-parens-name-re'.
+ (setq c-noise-macro-with-parens-name-re
+ (cond ((null c-noise-macro-with-parens-names) "\\<\\>")
+ ((consp c-noise-macro-with-parens-names)
+ (concat (regexp-opt c-noise-macro-with-parens-names t)
+ "\\([^[:alnum:]_$]\\|$\\)"))
+ ((stringp c-noise-macro-with-parens-names)
+ (copy-sequence c-noise-macro-with-parens-names))
+ (t (error "c-make-noise-macro-regexps: \
+c-noise-macro-with-parens-names is invalid: %s" c-noise-macro-with-parens-names))))
+ (setq c-noise-macro-name-re
+ (cond ((null c-noise-macro-names) "\\<\\>")
+ ((consp c-noise-macro-names)
+ (concat (regexp-opt c-noise-macro-names t)
+ "\\([^[:alnum:]_$]\\|$\\)"))
+ ((stringp c-noise-macro-names)
+ (copy-sequence c-noise-macro-names))
+ (t (error "c-make-noise-macro-regexps: \
+c-noise-macro-names is invalid: %s" c-noise-macro-names)))))
+
+;; Non-customizable variables, still part of the interface to CC Mode
(defvar c-macro-with-semi-re nil
;; Regular expression which matches a (#define'd) symbol whose expansion
;; ends with a semicolon.
@@ -1659,10 +1702,7 @@ the regular expression must match only valid identifiers.
If you change this variable's value, call the function
`c-make-macros-with-semi-re' to set the necessary internal
-variables.
-
-Note that currently \(2008-11-04) this variable is a prototype,
-and is likely to disappear or change its form soon.")
+variables.")
(make-variable-buffer-local 'c-macro-names-with-semicolon)
(put 'c-macro-names-with-semicolon 'safe-local-variable
#'c-string-or-string-list-p)
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index e62e017aa0a..d35388e98d7 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -130,7 +130,7 @@ and a string describing how the process finished.")
(defvar compilation-num-errors-found)
;; If you make any changes to `compilation-error-regexp-alist-alist',
-;; be sure to run the ERT test in test/automated/compile-tests.el.
+;; be sure to run the ERT test in test/lisp/progmodes/compile-tests.el.
;; emacs -batch -l compile-tests.el -f ert-run-tests-batch-and-exit
(defvar compilation-error-regexp-alist-alist
@@ -161,6 +161,13 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
\\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([ \n]Warning\\(?: [0-9]+\\)?:\\)?\\)"
2 (3 . 4) (5 . 6) (7))
+ (cmake
+ "^CMake \\(?:Error\\|\\(Warning\\)\\) at \\(.*\\):\\([1-9][0-9]*\\) ([^)]+):$"
+ 2 3 nil (1))
+ (cmake-info
+ "^ \\(?: \\*\\)?\\(.*\\):\\([1-9][0-9]*\\) ([^)]+)$"
+ 1 2 nil 0)
+
(comma
"^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\
\\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4))
@@ -223,6 +230,13 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
nil 1 nil 2 0
(2 (compilation-face '(3))))
+ (clang-include
+ ,(rx bol "In file included from "
+ (group (+ (not (any ?\n ?:)))) ?:
+ (group (+ (any (?0 . ?9)))) ?:
+ eol)
+ 1 2 nil 0)
+
(gcc-include
"^\\(?:In file included \\| \\|\t\\)from \
\\([0-9]*[^0-9\n]\\(?:[^\n :]\\| [^-/\n]\\|:[^ \n]\\)*?\\):\
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index d5bf68fc5f4..f4cb478e028 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -4,7 +4,7 @@
;; Author: Ilya Zakharevich
;; Bob Olson
-;; Maintainer: Ilya Zakharevich <ilyaz@cpan.org>
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: languages, Perl
;; This file is part of GNU Emacs.
@@ -202,7 +202,7 @@
(defcustom cperl-extra-newline-before-brace nil
- "*Non-nil means that if, elsif, while, until, else, for, foreach
+ "Non-nil means that if, elsif, while, until, else, for, foreach
and do constructs look like:
if ()
@@ -218,13 +218,13 @@ instead of:
(defcustom cperl-extra-newline-before-brace-multiline
cperl-extra-newline-before-brace
- "*Non-nil means the same as `cperl-extra-newline-before-brace', but
+ "Non-nil means the same as `cperl-extra-newline-before-brace', but
for constructs with multiline if/unless/while/until/for/foreach condition."
:type 'boolean
:group 'cperl-autoinsert-details)
(defcustom cperl-indent-level 2
- "*Indentation of CPerl statements with respect to containing block."
+ "Indentation of CPerl statements with respect to containing block."
:type 'integer
:group 'cperl-indentation-details)
@@ -242,52 +242,52 @@ for constructs with multiline if/unless/while/until/for/foreach condition."
;;;###autoload(put 'cperl-merge-trailing-else 'safe-local-variable 'booleanp)
(defcustom cperl-lineup-step nil
- "*`cperl-lineup' will always lineup at multiple of this number.
+ "`cperl-lineup' will always lineup at multiple of this number.
If nil, the value of `cperl-indent-level' will be used."
:type '(choice (const nil) integer)
:group 'cperl-indentation-details)
(defcustom cperl-brace-imaginary-offset 0
- "*Imagined indentation of a Perl open brace that actually follows a statement.
+ "Imagined indentation of a Perl open brace that actually follows a statement.
An open brace following other text is treated as if it were this far
to the right of the start of its line."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context."
+ "Extra indentation for braces, compared with other text in same context."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-label-offset -2
- "*Offset of CPerl label lines relative to usual indentation."
+ "Offset of CPerl label lines relative to usual indentation."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-min-label-indent 1
- "*Minimal offset of CPerl label lines."
+ "Minimal offset of CPerl label lines."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-continued-statement-offset 2
- "*Extra indent for lines not starting new statements."
+ "Extra indent for lines not starting new statements."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-continued-brace-offset 0
- "*Extra indent for substatements that start with open-braces.
+ "Extra indent for substatements that start with open-braces.
This is in addition to cperl-continued-statement-offset."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-close-paren-offset -1
- "*Extra indent for substatements that start with close-parenthesis."
+ "Extra indent for substatements that start with close-parenthesis."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-indent-wrt-brace t
- "*Non-nil means indent statements in if/etc block relative brace, not if/etc.
+ "Non-nil means indent statements in if/etc block relative brace, not if/etc.
Versions 5.2 ... 5.20 behaved as if this were nil."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-auto-newline nil
- "*Non-nil means automatically newline before and after braces,
+ "Non-nil means automatically newline before and after braces,
and after colons and semicolons, inserted in CPerl code. The following
\\[cperl-electric-backspace] will remove the inserted whitespace.
Insertion after colons requires both this variable and
@@ -296,43 +296,43 @@ Insertion after colons requires both this variable and
:group 'cperl-autoinsert-details)
(defcustom cperl-autoindent-on-semi nil
- "*Non-nil means automatically indent after insertion of (semi)colon.
+ "Non-nil means automatically indent after insertion of (semi)colon.
Active if `cperl-auto-newline' is false."
:type 'boolean
:group 'cperl-autoinsert-details)
(defcustom cperl-auto-newline-after-colon nil
- "*Non-nil means automatically newline even after colons.
+ "Non-nil means automatically newline even after colons.
Subject to `cperl-auto-newline' setting."
:type 'boolean
:group 'cperl-autoinsert-details)
(defcustom cperl-tab-always-indent t
- "*Non-nil means TAB in CPerl mode should always reindent the current line,
+ "Non-nil means TAB in CPerl mode should always reindent the current line,
regardless of where in the line point is when the TAB command is used."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-font-lock nil
- "*Non-nil (and non-null) means CPerl buffers will use `font-lock-mode'.
+ "Non-nil (and non-null) means CPerl buffers will use `font-lock-mode'.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-electric-lbrace-space nil
- "*Non-nil (and non-null) means { after $ should be preceded by ` '.
+ "Non-nil (and non-null) means { after $ should be preceded by ` '.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-electric-parens-string "({[]})<"
- "*String of parentheses that should be electric in CPerl.
+ "String of parentheses that should be electric in CPerl.
Closing ones are electric only if the region is highlighted."
:type 'string
:group 'cperl-affected-by-hairy)
(defcustom cperl-electric-parens nil
- "*Non-nil (and non-null) means parentheses should be electric in CPerl.
+ "Non-nil (and non-null) means parentheses should be electric in CPerl.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
@@ -345,20 +345,20 @@ Can be overwritten by `cperl-hairy' if nil."
transient-mark-mode)
(and (boundp 'zmacs-regions) ; For XEmacs
zmacs-regions)))
- "*Not-nil means that electric parens look for active mark.
+ "Not-nil means that electric parens look for active mark.
Default is yes if there is visual feedback on mark."
:type 'boolean
:group 'cperl-autoinsert-details)
(defcustom cperl-electric-linefeed nil
- "*If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy.
+ "If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy.
In any case these two mean plain and hairy linefeeds together.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-electric-keywords nil
- "*Not-nil (and non-null) means keywords are electric in CPerl.
+ "Not-nil (and non-null) means keywords are electric in CPerl.
Can be overwritten by `cperl-hairy' if nil.
Uses `abbrev-mode' to do the expansion. If you want to use your
@@ -372,12 +372,12 @@ that begin with \"cperl-electric\".
:group 'cperl-affected-by-hairy)
(defcustom cperl-electric-backspace-untabify t
- "*Not-nil means electric-backspace will untabify in CPerl."
+ "Not-nil means electric-backspace will untabify in CPerl."
:type 'boolean
:group 'cperl-autoinsert-details)
(defcustom cperl-hairy nil
- "*Not-nil means most of the bells and whistles are enabled in CPerl.
+ "Not-nil means most of the bells and whistles are enabled in CPerl.
Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
`cperl-electric-parens', `cperl-electric-linefeed', `cperl-electric-keywords',
`cperl-info-on-command-no-prompt', `cperl-clobber-lisp-bindings',
@@ -386,22 +386,22 @@ Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
:group 'cperl-affected-by-hairy)
(defcustom cperl-comment-column 32
- "*Column to put comments in CPerl (use \\[cperl-indent] to lineup with code)."
+ "Column to put comments in CPerl (use \\[cperl-indent] to lineup with code)."
:type 'integer
:group 'cperl-indentation-details)
(defcustom cperl-indent-comment-at-column-0 nil
- "*Non-nil means that comment started at column 0 should be indentable."
+ "Non-nil means that comment started at column 0 should be indentable."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-vc-sccs-header '("($sccs) = ('%W\ %' =~ /(\\d+(\\.\\d+)+)/) ;")
- "*Special version of `vc-sccs-header' that is used in CPerl mode buffers."
+ "Special version of `vc-sccs-header' that is used in CPerl mode buffers."
:type '(repeat string)
:group 'cperl)
(defcustom cperl-vc-rcs-header '("($rcs) = (' $Id\ $ ' =~ /(\\d+(\\.\\d+)+)/);")
- "*Special version of `vc-rcs-header' that is used in CPerl mode buffers."
+ "Special version of `vc-rcs-header' that is used in CPerl mode buffers."
:type '(repeat string)
:group 'cperl)
@@ -418,43 +418,43 @@ Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
;; (boundp 'interpreter-mode-alist)
;; (assoc "miniperl" interpreter-mode-alist)
;; (assoc "\\.\\([pP][Llm]\\|al\\)$" auto-mode-alist)))
-;; "*Whether to install us into `interpreter-' and `extension' mode lists."
+;; "Whether to install us into `interpreter-' and `extension' mode lists."
;; :type 'boolean
;; :group 'cperl)
(defcustom cperl-info-on-command-no-prompt nil
- "*Not-nil (and non-null) means not to prompt on C-h f.
+ "Not-nil (and non-null) means not to prompt on C-h f.
The opposite behavior is always available if prefixed with C-c.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-clobber-lisp-bindings nil
- "*Not-nil (and non-null) means not overwrite C-h f.
+ "Not-nil (and non-null) means not overwrite C-h f.
The function is available on \\[cperl-info-on-command], \\[cperl-get-help].
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-lazy-help-time nil
- "*Not-nil (and non-null) means to show lazy help after given idle time.
+ "Not-nil (and non-null) means to show lazy help after given idle time.
Can be overwritten by `cperl-hairy' to be 5 sec if nil."
:type '(choice (const null) (const nil) integer)
:group 'cperl-affected-by-hairy)
(defcustom cperl-pod-face 'font-lock-comment-face
- "*Face for POD highlighting."
+ "Face for POD highlighting."
:type 'face
:group 'cperl-faces)
(defcustom cperl-pod-head-face 'font-lock-variable-name-face
- "*Face for POD highlighting.
+ "Face for POD highlighting.
Font for POD headers."
:type 'face
:group 'cperl-faces)
(defcustom cperl-here-face 'font-lock-string-face
- "*Face for here-docs highlighting."
+ "Face for here-docs highlighting."
:type 'face
:group 'cperl-faces)
@@ -462,23 +462,23 @@ Font for POD headers."
(defvar cperl-singly-quote-face (featurep 'xemacs))
(defcustom cperl-invalid-face 'underline
- "*Face for highlighting trailing whitespace."
+ "Face for highlighting trailing whitespace."
:type 'face
:version "21.1"
:group 'cperl-faces)
(defcustom cperl-pod-here-fontify '(featurep 'font-lock)
- "*Not-nil after evaluation means to highlight POD and here-docs sections."
+ "Not-nil after evaluation means to highlight POD and here-docs sections."
:type 'boolean
:group 'cperl-faces)
(defcustom cperl-fontify-m-as-s t
- "*Not-nil means highlight 1arg regular expressions operators same as 2arg."
+ "Not-nil means highlight 1arg regular expressions operators same as 2arg."
:type 'boolean
:group 'cperl-faces)
(defcustom cperl-highlight-variables-indiscriminately nil
- "*Non-nil means perform additional highlighting on variables.
+ "Non-nil means perform additional highlighting on variables.
Currently only changes how scalar variables are highlighted.
Note that that variable is only read at initialization time for
the variable `cperl-font-lock-keywords-2', so changing it after you've
@@ -487,125 +487,125 @@ entered CPerl mode the first time will have no effect."
:group 'cperl)
(defcustom cperl-pod-here-scan t
- "*Not-nil means look for POD and here-docs sections during startup.
+ "Not-nil means look for POD and here-docs sections during startup.
You can always make lookup from menu or using \\[cperl-find-pods-heres]."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-regexp-scan t
- "*Not-nil means make marking of regular expression more thorough.
+ "Not-nil means make marking of regular expression more thorough.
Effective only with `cperl-pod-here-scan'."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-hook-after-change t
- "*Not-nil means install hook to know which regions of buffer are changed.
+ "Not-nil means install hook to know which regions of buffer are changed.
May significantly speed up delayed fontification. Changes take effect
after reload."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-imenu-addback nil
- "*Not-nil means add backreferences to generated `imenu's.
+ "Not-nil means add backreferences to generated `imenu's.
May require patched `imenu' and `imenu-go'. Obsolete."
:type 'boolean
:group 'cperl-help-system)
(defcustom cperl-max-help-size 66
- "*Non-nil means shrink-wrapping of info-buffer allowed up to these percents."
+ "Non-nil means shrink-wrapping of info-buffer allowed up to these percents."
:type '(choice integer (const nil))
:group 'cperl-help-system)
(defcustom cperl-shrink-wrap-info-frame t
- "*Non-nil means shrink-wrapping of info-buffer-frame allowed."
+ "Non-nil means shrink-wrapping of info-buffer-frame allowed."
:type 'boolean
:group 'cperl-help-system)
(defcustom cperl-info-page "perl"
- "*Name of the info page containing perl docs.
+ "Name of the info page containing perl docs.
Older version of this page was called `perl5', newer `perl'."
:type 'string
:group 'cperl-help-system)
(defcustom cperl-use-syntax-table-text-property
(boundp 'parse-sexp-lookup-properties)
- "*Non-nil means CPerl sets up and uses `syntax-table' text property."
+ "Non-nil means CPerl sets up and uses `syntax-table' text property."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-use-syntax-table-text-property-for-tags
cperl-use-syntax-table-text-property
- "*Non-nil means: set up and use `syntax-table' text property generating TAGS."
+ "Non-nil means: set up and use `syntax-table' text property generating TAGS."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-scan-files-regexp "\\.\\([pP][Llm]\\|xs\\)$"
- "*Regexp to match files to scan when generating TAGS."
+ "Regexp to match files to scan when generating TAGS."
:type 'regexp
:group 'cperl)
(defcustom cperl-noscan-files-regexp
"/\\(\\.\\.?\\|SCCS\\|RCS\\|CVS\\|blib\\)$"
- "*Regexp to match files/dirs to skip when generating TAGS."
+ "Regexp to match files/dirs to skip when generating TAGS."
:type 'regexp
:group 'cperl)
(defcustom cperl-regexp-indent-step nil
- "*Indentation used when beautifying regexps.
+ "Indentation used when beautifying regexps.
If nil, the value of `cperl-indent-level' will be used."
:type '(choice integer (const nil))
:group 'cperl-indentation-details)
(defcustom cperl-indent-left-aligned-comments t
- "*Non-nil means that the comment starting in leftmost column should indent."
+ "Non-nil means that the comment starting in leftmost column should indent."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-under-as-char nil
- "*Non-nil means that the _ (underline) should be treated as word char."
+ "Non-nil means that the _ (underline) should be treated as word char."
:type 'boolean
:group 'cperl)
(make-obsolete-variable 'cperl-under-as-char 'superword-mode "24.4")
(defcustom cperl-extra-perl-args ""
- "*Extra arguments to use when starting Perl.
+ "Extra arguments to use when starting Perl.
Currently used with `cperl-check-syntax' only."
:type 'string
:group 'cperl)
(defcustom cperl-message-electric-keyword t
- "*Non-nil means that the `cperl-electric-keyword' prints a help message."
+ "Non-nil means that the `cperl-electric-keyword' prints a help message."
:type 'boolean
:group 'cperl-help-system)
(defcustom cperl-indent-region-fix-constructs 1
- "*Amount of space to insert between `}' and `else' or `elsif'
+ "Amount of space to insert between `}' and `else' or `elsif'
in `cperl-indent-region'. Set to nil to leave as is. Values other
than 1 and nil will probably not work."
:type '(choice (const nil) (const 1))
:group 'cperl-indentation-details)
(defcustom cperl-break-one-line-blocks-when-indent t
- "*Non-nil means that one-line if/unless/while/until/for/foreach BLOCKs
+ "Non-nil means that one-line if/unless/while/until/for/foreach BLOCKs
need to be reformatted into multiline ones when indenting a region."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-fix-hanging-brace-when-indent t
- "*Non-nil means that BLOCK-end `}' may be put on a separate line
+ "Non-nil means that BLOCK-end `}' may be put on a separate line
when indenting a region.
Braces followed by else/elsif/while/until are excepted."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-merge-trailing-else t
- "*Non-nil means that BLOCK-end `}' followed by else/elsif/continue
+ "Non-nil means that BLOCK-end `}' followed by else/elsif/continue
may be merged to be on the same line when indenting a region."
:type 'boolean
:group 'cperl-indentation-details)
(defcustom cperl-indent-parens-as-block nil
- "*Non-nil means that non-block ()-, {}- and []-groups are indented as blocks,
+ "Non-nil means that non-block ()-, {}- and []-groups are indented as blocks,
but for trailing \",\" inside the group, which won't increase indentation.
One should tune up `cperl-close-paren-offset' as well."
:type 'boolean
@@ -614,20 +614,20 @@ One should tune up `cperl-close-paren-offset' as well."
(defcustom cperl-syntaxify-by-font-lock
(and cperl-can-font-lock
(boundp 'parse-sexp-lookup-properties))
- "*Non-nil means that CPerl uses the `font-lock' routines for syntaxification."
+ "Non-nil means that CPerl uses the `font-lock' routines for syntaxification."
:type '(choice (const message) boolean)
:group 'cperl-speed)
(defcustom cperl-syntaxify-unwind
t
- "*Non-nil means that CPerl unwinds to a start of a long construction
+ "Non-nil means that CPerl unwinds to a start of a long construction
when syntaxifying a chunk of buffer."
:type 'boolean
:group 'cperl-speed)
(defcustom cperl-syntaxify-for-menu
t
- "*Non-nil means that CPerl syntaxifies up to the point before showing menu.
+ "Non-nil means that CPerl syntaxifies up to the point before showing menu.
This way enabling/disabling of menu items is more correct."
:type 'boolean
:group 'cperl-speed)
@@ -1126,7 +1126,28 @@ versions of Emacs."
;; expansion manually. Any other suggestions?
(require 'cl))
-(defvar cperl-mode-abbrev-table nil
+(define-abbrev-table 'cperl-mode-abbrev-table
+ '(
+ ("if" "if" cperl-electric-keyword :system t)
+ ("elsif" "elsif" cperl-electric-keyword :system t)
+ ("while" "while" cperl-electric-keyword :system t)
+ ("until" "until" cperl-electric-keyword :system t)
+ ("unless" "unless" cperl-electric-keyword :system t)
+ ("else" "else" cperl-electric-else :system t)
+ ("continue" "continue" cperl-electric-else :system t)
+ ("for" "for" cperl-electric-keyword :system t)
+ ("foreach" "foreach" cperl-electric-keyword :system t)
+ ("formy" "formy" cperl-electric-keyword :system t)
+ ("foreachmy" "foreachmy" cperl-electric-keyword :system t)
+ ("do" "do" cperl-electric-keyword :system t)
+ ("=pod" "=pod" cperl-electric-pod :system t)
+ ("=over" "=over" cperl-electric-pod :system t)
+ ("=head1" "=head1" cperl-electric-pod :system t)
+ ("=head2" "=head2" cperl-electric-pod :system t)
+ ("pod" "pod" cperl-electric-pod :system t)
+ ("over" "over" cperl-electric-pod :system t)
+ ("head1" "head1" cperl-electric-pod :system t)
+ ("head2" "head2" cperl-electric-pod :system t))
"Abbrev table in use in CPerl mode buffers.")
(add-hook 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-")))
@@ -1708,29 +1729,6 @@ or as help on variables `cperl-tips', `cperl-problems',
(cperl-define-key "\C-hf" 'cperl-info-on-current-command [(control h) f])
(cperl-define-key "\C-c\C-hf" 'cperl-info-on-command
[(control c) (control h) f])))
- (let ((prev-a-c abbrevs-changed))
- (define-abbrev-table 'cperl-mode-abbrev-table '(
- ("if" "if" cperl-electric-keyword 0)
- ("elsif" "elsif" cperl-electric-keyword 0)
- ("while" "while" cperl-electric-keyword 0)
- ("until" "until" cperl-electric-keyword 0)
- ("unless" "unless" cperl-electric-keyword 0)
- ("else" "else" cperl-electric-else 0)
- ("continue" "continue" cperl-electric-else 0)
- ("for" "for" cperl-electric-keyword 0)
- ("foreach" "foreach" cperl-electric-keyword 0)
- ("formy" "formy" cperl-electric-keyword 0)
- ("foreachmy" "foreachmy" cperl-electric-keyword 0)
- ("do" "do" cperl-electric-keyword 0)
- ("=pod" "=pod" cperl-electric-pod 0)
- ("=over" "=over" cperl-electric-pod 0)
- ("=head1" "=head1" cperl-electric-pod 0)
- ("=head2" "=head2" cperl-electric-pod 0)
- ("pod" "pod" cperl-electric-pod 0)
- ("over" "over" cperl-electric-pod 0)
- ("head1" "head1" cperl-electric-pod 0)
- ("head2" "head2" cperl-electric-pod 0)))
- (setq abbrevs-changed prev-a-c))
(setq local-abbrev-table cperl-mode-abbrev-table)
(if (cperl-val 'cperl-electric-keywords)
(abbrev-mode 1))
@@ -8578,7 +8576,7 @@ the appropriate statement modifier."
(cperl-perldoc (cperl-word-at-point)))
(defcustom pod2man-program "pod2man"
- "*File name for `pod2man'."
+ "File name for `pod2man'."
:type 'file
:group 'cperl)
diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el
index e17d15b8a28..e35a76e38cd 100644
--- a/lisp/progmodes/cpp.el
+++ b/lisp/progmodes/cpp.el
@@ -104,6 +104,14 @@ Each entry is a list with the following elements:
(const :tag "Both branches writable" both))))
:group 'cpp)
+(defcustom cpp-message-min-time-interval 1.0
+ "Minimum time interval in seconds for `cpp-progress-message' messages.
+If nil, `cpp-progress-message' prints no progress messages."
+ :type '(choice (const :tag "Disable progress messages" nil)
+ float)
+ :group 'cpp
+ :version "26.1")
+
(defvar cpp-overlay-list nil)
;; List of cpp overlays active in the current buffer.
(make-variable-buffer-local 'cpp-overlay-list)
@@ -278,7 +286,7 @@ A prefix arg suppresses display of that buffer."
(cpp-parse-close from to))
(t
(cpp-parse-error "Parser error"))))))))
- (message "Parsing...done"))
+ (cpp-progress-message "Parsing...done"))
(if cpp-state-stack
(save-excursion
(goto-char (nth 3 (car cpp-state-stack)))
@@ -819,16 +827,21 @@ BRANCH should be either nil (false branch), t (true branch) or `both'."
;;; Utilities:
-(defvar cpp-progress-time 0)
-;; Last time we issued a progress message.
+(defvar cpp-progress-time 0
+ "Last time `cpp-progress-message' issued a progress message.")
(defun cpp-progress-message (&rest args)
- ;; Report progress at most once a second. Take same ARGS as `message'.
- (let ((time (nth 1 (current-time))))
- (if (= time cpp-progress-time)
- ()
- (setq cpp-progress-time time)
- (apply 'message args))))
+ "Report progress by printing messages used by \"cpp-\" functions.
+
+Print messages at most once every `cpp-message-min-time-interval' seconds.
+If that option is nil, don't prints messages.
+ARGS are the same as for `message'."
+ (when cpp-message-min-time-interval
+ (let ((time (current-time)))
+ (when (>= (float-time (time-subtract time cpp-progress-time))
+ cpp-message-min-time-interval)
+ (setq cpp-progress-time time)
+ (apply 'message args)))))
(provide 'cpp)
diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el
index 05352432618..a8229df4aeb 100644
--- a/lisp/progmodes/ebnf2ps.el
+++ b/lisp/progmodes/ebnf2ps.el
@@ -1191,7 +1191,7 @@ Elements of ALIST that are not conses are ignored."
"Translate an EBNF to a syntactic chart on PostScript."
:prefix "ebnf-"
:version "20"
- :group 'wp
+ :group 'text
:group 'postscript)
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index ffb6fad6da7..53a0f66439b 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -245,11 +245,8 @@ Blank lines separate paragraphs. Semicolons start comments.
;; Font-locking support.
(defun elisp--font-lock-flush-elisp-buffers (&optional file)
- ;; FIXME: Aren't we only ever called from after-load-functions?
- ;; Don't flush during load unless called from after-load-functions.
- ;; In that case, FILE is non-nil. It's somehow strange that
- ;; load-in-progress is t when an after-load-function is called since
- ;; that should run *after* the load...
+ ;; We're only ever called from after-load-functions, load-in-progress can
+ ;; still be t in case of nested loads.
(when (or (not load-in-progress) file)
;; FIXME: If the loaded file did not define any macros, there shouldn't
;; be any need to font-lock-flush all the Elisp buffers.
@@ -721,7 +718,10 @@ non-nil result supercedes the xrefs produced by
(let* ((info (cl--generic-method-info method));; qual-string combined-args doconly
(specializers (cl--generic-method-specializers method))
(non-default nil)
- (met-name (cons symbol specializers))
+ (met-name (cl--generic-load-hist-format
+ symbol
+ (cl--generic-method-qualifiers method)
+ specializers))
(file (find-lisp-object-file-name met-name 'cl-defmethod)))
(dolist (item specializers)
;; default method has all 't' in specializers
@@ -1061,6 +1061,17 @@ If CHAR is not a character, return nil."
((or (eq (following-char) ?\')
(eq (preceding-char) ?\'))
(setq left-quote ?\`)))
+
+ ;; When after a named character literal, skip over the entire
+ ;; literal, not only its last word.
+ (when (= (preceding-char) ?})
+ (let ((begin (save-excursion
+ (backward-char)
+ (skip-syntax-backward "w-")
+ (backward-char 3)
+ (when (looking-at-p "\\\\N{") (point)))))
+ (when begin (goto-char begin))))
+
(forward-sexp -1)
;; If we were after `?\e' (or similar case),
;; use the whole thing, not just the `e'.
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 0361adf5719..8d635cb6d4d 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -33,8 +33,9 @@
;;;###autoload
(defvar tags-file-name nil
"File name of tags table.
-To switch to a new tags table, setting this variable is sufficient.
-If you set this variable, do not also set `tags-table-list'.
+To switch to a new tags table, do not set this variable; instead,
+invoke `visit-tags-table', which is the only reliable way of
+setting the value of this variable, whether buffer-local or global.
Use the `etags' program to make a tags table file.")
;; Make M-x set-variable tags-file-name like M-x visit-tags-table.
;;;###autoload (put 'tags-file-name 'variable-interactive (purecopy "fVisit tags table: "))
@@ -288,7 +289,8 @@ FILE should be the name of a file created with the `etags' program.
A directory name is ok too; it means file TAGS in that directory.
Normally \\[visit-tags-table] sets the global value of `tags-file-name'.
-With a prefix arg, set the buffer-local value instead.
+With a prefix arg, set the buffer-local value instead. When called
+from Lisp, if the optional arg LOCAL is non-nil, set the local value.
When you find a tag with \\[find-tag], the buffer it finds the tag
in is given a local value of this variable which is the name of the tags
file the tag was in."
@@ -304,19 +306,28 @@ file the tag was in."
;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
;; initialize a buffer for FILE and set tags-file-name to the
;; fully-expanded name.
- (let ((tags-file-name file))
+ (let ((tags-file-name file)
+ (cbuf (current-buffer)))
(save-excursion
(or (visit-tags-table-buffer file)
- (signal 'file-error (list "Visiting tags table"
- "No such file or directory"
- file)))
- ;; Set FILE to the expanded name.
- (setq file tags-file-name)))
+ (signal 'file-missing (list "Visiting tags table"
+ "No such file or directory"
+ file)))
+ ;; Set FILE to the expanded name. Do that in the buffer we
+ ;; started from, because visit-tags-table-buffer switches
+ ;; buffers after updating tags-file-name, so if tags-file-name
+ ;; is local in the buffer we started, that value is only visible
+ ;; in that buffer.
+ (setq file (with-current-buffer cbuf tags-file-name))))
(if local
- ;; Set the local value of tags-file-name.
- (set (make-local-variable 'tags-file-name) file)
+ (progn
+ ;; Force recomputation of tags-completion-table.
+ (setq-local tags-completion-table nil)
+ ;; Set the local value of tags-file-name.
+ (setq-local tags-file-name file))
;; Set the global value of tags-file-name.
- (setq-default tags-file-name file)))
+ (setq-default tags-file-name file)
+ (setq tags-completion-table nil)))
(defun tags-table-check-computed-list ()
"Compute `tags-table-computed-list' from `tags-table-list' if necessary."
@@ -540,17 +551,21 @@ Returns nil when out of tables."
(setq tags-file-name (car tags-table-list-pointer))))
;;;###autoload
-(defun visit-tags-table-buffer (&optional cont)
+(defun visit-tags-table-buffer (&optional cont cbuf)
"Select the buffer containing the current tags table.
-If optional arg is a string, visit that file as a tags table.
-If optional arg is t, visit the next table in `tags-table-list'.
-If optional arg is the atom `same', don't look for a new table;
+Optional arg CONT specifies which tags table to visit.
+If CONT is a string, visit that file as a tags table.
+If CONT is t, visit the next table in `tags-table-list'.
+If CONT is the atom `same', don't look for a new table;
just select the buffer visiting `tags-file-name'.
-If arg is nil or absent, choose a first buffer from information in
+If CONT is nil or absent, choose a first buffer from information in
`tags-file-name', `tags-table-list', `tags-table-list-pointer'.
+Optional second arg CBUF, if non-nil, specifies the initial buffer,
+which is important if that buffer has a local value of `tags-file-name'.
Returns t if it visits a tags table, or nil if there are no more in the list."
;; Set tags-file-name to the tags table file we want to visit.
+ (if cbuf (set-buffer cbuf))
(cond ((eq cont 'same)
;; Use the ambient value of tags-file-name.
(or tags-file-name
@@ -752,28 +767,33 @@ Assumes the tags table is the current buffer."
(or tags-included-tables
(setq tags-included-tables (funcall tags-included-tables-function))))
-(defun tags-completion-table ()
- "Build `tags-completion-table' on demand.
+(defun tags-completion-table (&optional buf)
+ "Build `tags-completion-table' on demand for a buffer's tags tables.
+Optional argument BUF specifies the buffer for which to build
+\`tags-completion-table', and defaults to the current buffer.
The tags included in the completion table are those in the current
-tags table and its (recursively) included tags tables."
- (or tags-completion-table
- ;; No cached value for this buffer.
- (condition-case ()
- (let (tables cont)
- (message "Making tags completion table for %s..." buffer-file-name)
- (save-excursion
- ;; Iterate over the current list of tags tables.
- (while (visit-tags-table-buffer cont)
- ;; Find possible completions in this table.
- (push (funcall tags-completion-table-function) tables)
- (setq cont t)))
- (message "Making tags completion table for %s...done"
- buffer-file-name)
- ;; Cache the result in a buffer-local variable.
- (setq tags-completion-table
- (nreverse (delete-dups (apply #'nconc tables)))))
- (quit (message "Tags completion table construction aborted.")
- (setq tags-completion-table nil)))))
+tags table for BUF and its (recursively) included tags tables."
+ (if (not buf) (setq buf (current-buffer)))
+ (with-current-buffer buf
+ (or tags-completion-table
+ ;; No cached value for this buffer.
+ (condition-case ()
+ (let (tables cont)
+ (message "Making tags completion table for %s..."
+ buffer-file-name)
+ (save-excursion
+ ;; Iterate over the current list of tags tables.
+ (while (visit-tags-table-buffer cont buf)
+ ;; Find possible completions in this table.
+ (push (funcall tags-completion-table-function) tables)
+ (setq cont t)))
+ (message "Making tags completion table for %s...done"
+ buffer-file-name)
+ ;; Cache the result in a variable.
+ (setq tags-completion-table
+ (nreverse (delete-dups (apply #'nconc tables)))))
+ (quit (message "Tags completion table construction aborted.")
+ (setq tags-completion-table nil))))))
;;;###autoload
(defun tags-lazy-completion-table ()
@@ -784,7 +804,9 @@ tags table and its (recursively) included tags tables."
;; If we need to ask for the tag table, allow that.
(let ((enable-recursive-minibuffers t))
(visit-tags-table-buffer))
- (complete-with-action action (tags-completion-table) string pred))))))
+ (complete-with-action action
+ (tags-completion-table buf)
+ string pred))))))
;;;###autoload (defun tags-completion-at-point-function ()
;;;###autoload (if (or tags-table-list tags-file-name)
@@ -1084,6 +1106,7 @@ error message."
(case-fold-search (if (memq tags-case-fold-search '(nil t))
tags-case-fold-search
case-fold-search))
+ (cbuf (current-buffer))
)
(save-excursion
@@ -1104,8 +1127,7 @@ error message."
(catch 'qualified-match-found
;; Iterate over the list of tags tables.
- (while (or first-table
- (visit-tags-table-buffer t))
+ (while (or first-table (visit-tags-table-buffer t cbuf))
(and first-search first-table
;; Start at beginning of tags file.
@@ -1707,25 +1729,26 @@ if the file was newly read in, the value is the filename."
((eq initialize t)
;; Initialize the list from the tags table.
(save-excursion
- ;; Visit the tags table buffer to get its list of files.
- (visit-tags-table-buffer)
- ;; Copy the list so we can setcdr below, and expand the file
- ;; names while we are at it, in this buffer's default directory.
- (setq next-file-list (mapcar 'expand-file-name (tags-table-files)))
- ;; Iterate over all the tags table files, collecting
- ;; a complete list of referenced file names.
- (while (visit-tags-table-buffer t)
- ;; Find the tail of the working list and chain on the new
- ;; sublist for this tags table.
- (let ((tail next-file-list))
- (while (cdr tail)
- (setq tail (cdr tail)))
- ;; Use a copy so the next loop iteration will not modify the
- ;; list later returned by (tags-table-files).
- (if tail
- (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
- (setq next-file-list (mapcar 'expand-file-name
- (tags-table-files))))))))
+ (let ((cbuf (current-buffer)))
+ ;; Visit the tags table buffer to get its list of files.
+ (visit-tags-table-buffer)
+ ;; Copy the list so we can setcdr below, and expand the file
+ ;; names while we are at it, in this buffer's default directory.
+ (setq next-file-list (mapcar 'expand-file-name (tags-table-files)))
+ ;; Iterate over all the tags table files, collecting
+ ;; a complete list of referenced file names.
+ (while (visit-tags-table-buffer t cbuf)
+ ;; Find the tail of the working list and chain on the new
+ ;; sublist for this tags table.
+ (let ((tail next-file-list))
+ (while (cdr tail)
+ (setq tail (cdr tail)))
+ ;; Use a copy so the next loop iteration will not modify the
+ ;; list later returned by (tags-table-files).
+ (if tail
+ (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
+ (setq next-file-list (mapcar 'expand-file-name
+ (tags-table-files)))))))))
(t
;; Initialize the list by evalling the argument.
(setq next-file-list (eval initialize))))
@@ -1921,8 +1944,9 @@ directory specification."
(princ (substitute-command-keys "':\n\n"))
(save-excursion
(let ((first-time t)
- (gotany nil))
- (while (visit-tags-table-buffer (not first-time))
+ (gotany nil)
+ (cbuf (current-buffer)))
+ (while (visit-tags-table-buffer (not first-time) cbuf)
(setq first-time nil)
(if (funcall list-tags-function file)
(setq gotany t)))
@@ -1945,8 +1969,9 @@ directory specification."
(tags-with-face 'highlight (princ regexp))
(princ (substitute-command-keys "':\n\n"))
(save-excursion
- (let ((first-time t))
- (while (visit-tags-table-buffer (not first-time))
+ (let ((first-time t)
+ (cbuf (current-buffer)))
+ (while (visit-tags-table-buffer (not first-time) cbuf)
(setq first-time nil)
(funcall tags-apropos-function regexp))))
(etags-tags-apropos-additional regexp))
@@ -2107,9 +2132,10 @@ for \\[find-tag] (which see)."
(marks (make-hash-table :test 'equal))
(case-fold-search (if (memq tags-case-fold-search '(nil t))
tags-case-fold-search
- case-fold-search)))
+ case-fold-search))
+ (cbuf (current-buffer)))
(save-excursion
- (while (visit-tags-table-buffer (not first-time))
+ (while (visit-tags-table-buffer (not first-time) cbuf)
(setq first-time nil)
(dolist (order-fun (cond (regexp? find-tag-regexp-tag-order)
(t etags-xref-find-definitions-tag-order)))
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 11605bcf3a3..e488c196fef 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -102,6 +102,8 @@ See `flymake-error-bitmap' and `flymake-warning-bitmap'."
"Enables/disables GUI warnings."
:group 'flymake
:type 'boolean)
+(make-obsolete-variable 'flymake-gui-warnings-enabled
+ "it no longer has any effect." "26.1")
(defcustom flymake-start-syntax-check-on-find-file t
"Start syntax check on find file."
@@ -1072,6 +1074,7 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
"flymake-proc" (current-buffer) cmd args))))
(set-process-sentinel process 'flymake-process-sentinel)
(set-process-filter process 'flymake-process-filter)
+ (set-process-query-on-exit-flag process nil)
(push process flymake-processes)
(setq flymake-is-running t)
@@ -1189,15 +1192,17 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
(setq flymake-mode-line mode-line)
(force-mode-line-update)))
-(defun flymake-display-warning (warning)
- "Display a warning to user."
- (message-box warning))
+;; Nothing in flymake uses this at all any more, so this is just for
+;; third-party compatibility.
+(define-obsolete-function-alias 'flymake-display-warning 'message-box "26.1")
(defun flymake-report-fatal-status (status warning)
"Display a warning and switch flymake mode off."
- (when flymake-gui-warnings-enabled
- (flymake-display-warning (format "Flymake: %s. Flymake will be switched OFF" warning))
- )
+ ;; This first message was always shown by default, and flymake-log
+ ;; does nothing by default, hence the use of message.
+ ;; Another option is display-warning.
+ (if (< flymake-log-level 0)
+ (message "Flymake: %s. Flymake will be switched OFF" warning))
(flymake-mode 0)
(flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s"
(buffer-name) status warning))
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index a625e26ed61..a30669d6bde 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1976,6 +1976,7 @@ is running."
(not gdb-non-stop))
gud-running)
(and gdb-gud-control-all-threads
+ (not (null gdb-running-threads-count))
(> gdb-running-threads-count 0))))
;; GUD displays the selected GDB frame. This might might not be the current
@@ -2492,7 +2493,9 @@ current thread and update GDB buffers."
;; Reason is available with target-async only
(let* ((result (gdb-json-string output-field))
(reason (bindat-get-field result 'reason))
- (thread-id (bindat-get-field result 'thread-id)))
+ (thread-id (bindat-get-field result 'thread-id))
+ (retval (bindat-get-field result 'return-value))
+ (varnum (bindat-get-field result 'gdb-result-var)))
;; -data-list-register-names needs to be issued for any stopped
;; thread
@@ -2518,6 +2521,15 @@ current thread and update GDB buffers."
(if (string-equal reason "exited-normally")
(setq gdb-active-process nil))
+ (when (and retval varnum
+ ;; When the user typed CLI commands, GDB/MI helpfully
+ ;; includes the "Value returned" response in the "~"
+ ;; record; here we avoid displaying it twice.
+ (not (string-match "^Value returned is " gdb-filter-output)))
+ (setq gdb-filter-output
+ (concat gdb-filter-output
+ (format "Value returned is %s = %s\n" varnum retval))))
+
;; Select new current thread.
;; Don't switch if we have no reasons selected
@@ -2650,8 +2662,15 @@ responses.
If FIX-LIST is non-nil, \"FIX-LIST={..}\" is replaced with
\"FIX-LIST=[..]\" prior to parsing. This is used to fix broken
-break-info output when it contains breakpoint script field
-incompatible with GDB/MI output syntax."
+incompatible with GDB/MI output syntax.
+
+If `default-directory' is remote, full file names are adapted accordingly."
(save-excursion
+ (let ((remote (file-remote-p default-directory)))
+ (when remote
+ (goto-char (point-min))
+ (while (re-search-forward "[\\[,]fullname=\"\\(.+\\)\"" nil t)
+ (replace-match (concat remote "\\1") nil nil nil 1))))
(goto-char (point-min))
(when fix-key
(save-excursion
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index 91ede84a400..22d4f2abd98 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -227,6 +227,22 @@ to determine whether cdr should not be excluded."
(const :tag "No ignored files" nil))
:group 'grep)
+(defcustom grep-save-buffers 'ask
+ "If non-nil, save buffers before running the grep commands.
+If `ask', ask before saving. If a function, call it with no arguments
+with each buffer current, as a predicate to determine whether that
+buffer should be saved or not. E.g., one can set this to
+ (lambda ()
+ (string-prefix-p my-grep-root (file-truename (buffer-file-name))))
+to limit saving to files located under `my-grep-root'."
+ :version "26.1"
+ :type '(choice
+ (const :tag "Ask before saving" ask)
+ (const :tag "Don't save buffers" nil)
+ function
+ (other :tag "Save all buffers" t))
+ :group 'grep)
+
(defcustom grep-error-screen-columns nil
"If non-nil, column numbers in grep hits are screen columns.
See `compilation-error-screen-columns'"
@@ -527,7 +543,9 @@ This function is called from `compilation-filter-hook'."
(let* ((host-id
(intern (or (file-remote-p default-directory) "localhost")))
(host-defaults (assq host-id grep-host-defaults-alist))
- (defaults (assq nil grep-host-defaults-alist)))
+ (defaults (assq nil grep-host-defaults-alist))
+ (quot-braces (shell-quote-argument "{}"))
+ (quot-scolon (shell-quote-argument ";")))
;; There are different defaults on different hosts. They must be
;; computed for every host once.
(dolist (setting '(grep-command grep-template
@@ -621,9 +639,8 @@ This function is called from `compilation-filter-hook'."
"")))
(cons
(if (eq grep-find-use-xargs 'exec-plus)
- (format "%s %s{} +" cmd0 null)
- (format "%s {} %s%s" cmd0 null
- (shell-quote-argument ";")))
+ (format "%s %s%s +" cmd0 null quot-braces)
+ (format "%s %s %s%s" cmd0 quot-braces null quot-scolon))
(1+ (length cmd0)))))
(t
(format "%s . -type f -print | \"%s\" %s"
@@ -639,12 +656,11 @@ This function is called from `compilation-filter-hook'."
(format "%s <D> <X> -type f <F> -print0 | \"%s\" -0 %s"
find-program xargs-program gcmd))
((eq grep-find-use-xargs 'exec)
- (format "%s <D> <X> -type f <F> -exec %s {} %s%s"
- find-program gcmd null
- (shell-quote-argument ";")))
+ (format "%s <D> <X> -type f <F> -exec %s %s %s%s"
+ find-program gcmd quot-braces null quot-scolon))
((eq grep-find-use-xargs 'exec-plus)
- (format "%s <D> <X> -type f <F> -exec %s %s{} +"
- find-program gcmd null))
+ (format "%s <D> <X> -type f <F> -exec %s %s%s +"
+ find-program gcmd null quot-braces))
(t
(format "%s <D> <X> -type f <F> -print | \"%s\" %s"
find-program xargs-program gcmd))))))))
@@ -728,6 +744,12 @@ This function is called from `compilation-filter-hook'."
grep-error-screen-columns)
(add-hook 'compilation-filter-hook 'grep-filter nil t))
+(defun grep--save-buffers ()
+ (when grep-save-buffers
+ (save-some-buffers (and (not (eq grep-save-buffers 'ask))
+ (not (functionp grep-save-buffers)))
+ (and (functionp grep-save-buffers)
+ grep-save-buffers))))
;;;###autoload
(defun grep (command-args)
@@ -759,6 +781,7 @@ list is empty)."
'grep-history
(if current-prefix-arg nil default))))))
+ (grep--save-buffers)
;; Setting process-setup-function makes exit-message-function work
;; even when async processes aren't supported.
(compilation-start (if (and grep-use-null-device null-device)
@@ -952,6 +975,7 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
(let ((default-directory dir))
;; Setting process-setup-function makes exit-message-function work
;; even when async processes aren't supported.
+ (grep--save-buffers)
(compilation-start (if (and grep-use-null-device null-device)
(concat command " " null-device)
command)
@@ -1014,6 +1038,7 @@ to specify a command to run."
(read-from-minibuffer "Confirm: "
command nil nil 'grep-find-history))
(add-to-history 'grep-find-history command))
+ (grep--save-buffers)
(let ((default-directory dir))
(compilation-start command 'grep-mode))
;; Set default-directory if we started rgrep in the *grep* buffer.
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index f67fe3dd055..1301758ea12 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -1188,36 +1188,30 @@ containing the executable being debugged."
;; correct line number, but life's too short.
;; d.love@dl.ac.uk (Dave Love) can be blamed for this
-(defvar gud-irix-p
- (and (string-match "^mips-[^-]*-irix" system-configuration)
- (not (string-match "irix[6-9]\\.[1-9]" system-configuration)))
+(defvar gud-irix-p nil
"Non-nil to assume the interface appropriate for IRIX dbx.
This works in IRIX 4, 5 and 6, but `gud-dbx-use-stopformat-p' provides
a better solution in 6.1 upwards.")
-(defvar gud-dbx-use-stopformat-p
- (string-match "irix[6-9]\\.[1-9]" system-configuration)
+(defvar gud-dbx-use-stopformat-p nil
"Non-nil to use the dbx feature present at least from Irix 6.1
whereby $stopformat=1 produces an output format compatible with
`gud-dbx-marker-filter'.")
-;; [Irix dbx seems to be a moving target. The dbx output changed
+;; [Irix dbx seemed to be a moving target. The dbx output changed
;; subtly sometime between OS v4.0.5 and v5.2 so that, for instance,
;; the output from `up' is no longer spotted by gud (and it's probably
;; not distinctive enough to try to match it -- use C-<, C->
;; exclusively) . For 5.3 and 6.0, the $curline variable changed to
;; `long long'(why?!), so the printf stuff needed changing. The line
;; number was cast to `long' as a compromise between the new `long
-;; long' and the original `int'. This is reported not to work in 6.2,
+;; long' and the original `int'. This was reported not to work in 6.2,
;; so it's changed back to int -- don't make your sources too long.
-;; From Irix6.1 (but not 6.0?) dbx supports an undocumented feature
+;; From Irix6.1 (but not 6.0?) dbx supported an undocumented feature
;; whereby `set $stopformat=1' reportedly produces output compatible
;; with `gud-dbx-marker-filter', which we prefer.
;; The process filter is also somewhat
;; unreliable, sometimes not spotting the markers; I don't know
-;; whether there's anything that can be done about that. It would be
-;; much better if SGI could be persuaded to (re?)instate the MIPS
-;; -emacs flag for gdb-like output (which ought to be possible as most
-;; of the communication I've had over it has been from sgi.com).]
+;; whether there's anything that can be done about that.]
;; this filter is influenced by the xdb one rather than the gdb one
(defun gud-irixdbx-marker-filter (string)
@@ -1959,10 +1953,10 @@ the source code display in sync with the debugging session.")
PATH gives the directories in which to search for files with
extension EXTN. Normally EXTN is given as the regular expression
\"\\.java$\" ."
- (apply 'nconc (mapcar (lambda (d)
- (when (file-directory-p d)
- (directory-files d t extn nil)))
- path)))
+ (mapcan (lambda (d)
+ (when (file-directory-p d)
+ (directory-files d t extn nil)))
+ path))
;; Move point past whitespace.
(defun gud-jdb-skip-whitespace ()
@@ -2573,9 +2567,6 @@ comint mode, which see."
:group 'gud
:type 'boolean)
-(declare-function tramp-file-name-localname "tramp" (vec))
-(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
-
;; Perform initializations common to all debuggers.
;; The first arg is the specified command line,
;; which starts with the program to debug.
@@ -2630,13 +2621,8 @@ comint mode, which see."
(let ((w args))
(while (and w (not (eq (car w) t)))
(setq w (cdr w)))
- (if w
- (setcar w
- (if (file-remote-p file)
- ;; Tramp has already been loaded if we are here.
- (setq file (tramp-file-name-localname
- (tramp-dissect-file-name file)))
- file))))
+ ;; Tramp has already been loaded if we are here.
+ (if w (setcar w (setq file (file-local-name file)))))
(apply 'make-comint (concat "gud" filepart) program nil
(if massage-args (funcall massage-args file args) args))
;; Since comint clobbered the mode, we don't set it until now.
@@ -2864,8 +2850,7 @@ Obeying it means displaying in another window the specified file and line."
(frame (or gud-last-frame gud-last-last-frame))
(buffer-file-name-localized
(and (buffer-file-name)
- (or (file-remote-p (buffer-file-name) 'localname)
- (buffer-file-name))))
+ (file-local-name (buffer-file-name))))
result)
(while (and str
(let ((case-fold-search nil))
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index eb5bb4bbfbd..b34ea1c4ae1 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -1114,8 +1114,8 @@ preprocessing token"
result)))
(defun hif-delimit (lis atom)
- (nconc (cl-mapcan (lambda (l) (list l atom))
- (butlast lis))
+ (nconc (mapcan (lambda (l) (list l atom))
+ (butlast lis))
(last lis)))
;; Perform token replacement:
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index ead2308dc3f..0e4e67018ed 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -351,6 +351,10 @@ Use the command `hs-minor-mode' to toggle or set this variable.")
(define-key map "\C-c@\C-\M-s" 'hs-show-all)
(define-key map "\C-c@\C-l" 'hs-hide-level)
(define-key map "\C-c@\C-c" 'hs-toggle-hiding)
+ (define-key map "\C-c@\C-a" 'hs-show-all)
+ (define-key map "\C-c@\C-t" 'hs-hide-all)
+ (define-key map "\C-c@\C-d" 'hs-hide-block)
+ (define-key map "\C-c@\C-e" 'hs-toggle-hiding)
(define-key map [(shift mouse-2)] 'hs-mouse-toggle-hiding)
map)
"Keymap for hideshow minor mode.")
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 6102f8b298f..e3f64a8f327 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -62,7 +62,7 @@
(defvar moz-repl-name)
(defvar ido-cur-list)
(defvar electric-layout-rules)
-(declare-function ido-mode "ido")
+(declare-function ido-mode "ido" (&optional arg))
(declare-function inferior-moz-process "ext:mozrepl" ())
;;; Constants
@@ -1722,7 +1722,8 @@ This performs fontification according to `js--class-styles'."
(eval-when-compile (append "=({[,:;" '(nil))))))
(put-text-property (match-beginning 1) (match-end 1)
'syntax-table (string-to-syntax "\"/"))
- (js-syntax-propertize-regexp end))))))
+ (js-syntax-propertize-regexp end)))))
+ ("\\`\\(#\\)!" (1 "< b")))
(point) end))
(defconst js--prettify-symbols-alist
@@ -2254,7 +2255,7 @@ i.e., customize JSX element indentation with `sgml-basic-offset',
"Fill the paragraph with `c-fill-paragraph'."
(interactive "*P")
(let ((js--filling-paragraph t)
- (fill-paragraph-function 'c-fill-paragraph))
+ (fill-paragraph-function #'c-fill-paragraph))
(c-fill-paragraph justify)))
;;; Type database and Imenu
@@ -3501,6 +3502,7 @@ browser, respectively."
(unwind-protect
+ ;; FIXME: Don't impose IDO on the user.
(setq selected-tab-cname
(let ((ido-minibuffer-setup-hook
(cons #'setup-hook ido-minibuffer-setup-hook)))
@@ -3723,9 +3725,9 @@ If one hasn't been set, or if it's stale, prompt for a new one."
(define-derived-mode js-mode prog-mode "JavaScript"
"Major mode for editing JavaScript."
:group 'js
- (setq-local indent-line-function 'js-indent-line)
- (setq-local beginning-of-defun-function 'js-beginning-of-defun)
- (setq-local end-of-defun-function 'js-end-of-defun)
+ (setq-local indent-line-function #'js-indent-line)
+ (setq-local beginning-of-defun-function #'js-beginning-of-defun)
+ (setq-local end-of-defun-function #'js-end-of-defun)
(setq-local open-paren-in-column-0-is-defun-start nil)
(setq-local font-lock-defaults (list js--font-lock-keywords))
(setq-local syntax-propertize-function #'js-syntax-propertize)
@@ -3738,7 +3740,7 @@ If one hasn't been set, or if it's stale, prompt for a new one."
;; Comments
(setq-local comment-start "// ")
(setq-local comment-end "")
- (setq-local fill-paragraph-function 'js-c-fill-paragraph)
+ (setq-local fill-paragraph-function #'js-c-fill-paragraph)
;; Parse cache
(add-hook 'before-change-functions #'js--flush-caches t t)
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index 01ee6e839f2..5cda7bb219c 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -103,7 +103,6 @@
(t (:reverse-video t)))
"Face to use for highlighting leading spaces in Font-Lock mode."
:group 'makefile)
-(define-obsolete-face-alias 'makefile-space-face 'makefile-space "22.1")
(defface makefile-targets
;; This needs to go along both with foreground and background colors (i.e. shell)
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index e8ff210f7cd..ac9ba630c4e 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -34,31 +34,6 @@
;;; Code:
(require 'comint)
-;;; For emacs < 24.3.
-(require 'newcomment)
-(eval-and-compile
- (unless (fboundp 'user-error)
- (defalias 'user-error 'error))
- (unless (fboundp 'delete-consecutive-dups)
- (defalias 'delete-consecutive-dups 'delete-dups))
- (unless (fboundp 'completion-table-with-cache)
- (defun completion-table-with-cache (fun &optional ignore-case)
- ;; See eg bug#11906.
- (let* (last-arg last-result
- (new-fun
- (lambda (arg)
- (if (and last-arg (string-prefix-p last-arg arg ignore-case))
- last-result
- (prog1
- (setq last-result (funcall fun arg))
- (setq last-arg arg))))))
- (completion-table-dynamic new-fun)))))
-(eval-when-compile
- (unless (fboundp 'setq-local)
- (defmacro setq-local (var val)
- "Set variable VAR to value VAL in current buffer."
- (list 'set (list 'make-local-variable (list 'quote var)) val))))
-
(defgroup octave nil
"Editing Octave code."
:link '(custom-manual "(octave-mode)Top")
@@ -605,13 +580,8 @@ Key bindings:
(setq-local fill-nobreak-predicate
(lambda () (eq (octave-in-string-p) ?')))
- (with-no-warnings
- (if (fboundp 'add-function) ; new in 24.4
- (add-function :around (local 'comment-line-break-function)
- #'octave--indent-new-comment-line)
- (setq-local comment-line-break-function
- (apply-partially #'octave--indent-new-comment-line
- #'comment-indent-new-line))))
+ (add-function :around (local 'comment-line-break-function)
+ #'octave--indent-new-comment-line)
(setq font-lock-defaults '(octave-font-lock-keywords))
@@ -908,9 +878,6 @@ startup file, `~/.emacs-octave'."
(inferior-octave-completion-table)
'comint-completion-file-name-table))))))
-(define-obsolete-function-alias 'inferior-octave-complete
- 'completion-at-point "24.1")
-
(defun inferior-octave-dynamic-list-input-ring ()
"List the buffer's input history in a help buffer."
;; We cannot use `comint-dynamic-list-input-ring', because it replaces
@@ -1060,8 +1027,7 @@ directory and makes this the current buffer's default directory."
(skip-syntax-backward "-(")
(thing-at-point 'symbol)))))
(completing-read
- (format (if def "Function (default %s): "
- "Function: ") def)
+ (format (if def "Function (default %s): " "Function: ") def)
(inferior-octave-completion-table)
nil nil nil nil def)))
@@ -1448,9 +1414,6 @@ The block marked is the one that contains point or follows point."
(inferior-octave-completion-table))
octave-reserved-words)))))
-(define-obsolete-function-alias 'octave-complete-symbol
- 'completion-at-point "24.1")
-
(defun octave-add-log-current-defun ()
"A function for `add-log-current-defun-function' (which see)."
(save-excursion
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index 2ce40802e7c..8f66f1c9541 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -49,6 +49,53 @@
map)
"Keymap used for programming modes.")
+(defvar prog-indentation-context nil
+ "When non-nil, provides context for indenting embedded code chunks.
+
+There are languages where part of the code is actually written in
+a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists
+of plain C code. This variable enables the major mode of the
+main language to use the indentation engine of the sub-mode for
+lines in code chunks written in the sub-mode's language.
+
+When a major mode of such a main language decides to delegate the
+indentation of a line/region to the indentation engine of the sub
+mode, it should bind this variable to non-nil around the call.
+
+The non-nil value should be a list of the form:
+
+ (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS)
+
+FIRST-COLUMN is the column the indentation engine of the sub-mode
+should use for top-level language constructs inside the code
+chunk (instead of 0).
+
+START and END specify the region of the code chunk. END can be
+nil, which stands for the value of `point-max'. The function
+`prog-widen' uses this to restore restrictions imposed by the
+sub-mode's indentation engine.
+
+PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of
+the sub-mode with the virtual context of the code chunk. Valid
+values are:
+
+ - A string containing text which the indentation engine can
+ consider as standing in front of the code chunk. To cache the
+ string's calculated syntactic information for repeated calls
+ with the same string, the sub-mode can add text-properties to
+ the string.
+
+ A typical use case is for grammars with code chunks which are
+ to be indented like function bodies -- the string would contain
+ the corresponding function preamble.
+
+ - A function, to be called with the start position of the current
+ chunk. It should return either the region of the previous chunk
+ as (PREV-START . PREV-END), or nil if there is no previous chunk.
+
+ A typical use case are literate programming sources -- the
+ function would successively return the previous code chunks.")
+
(defun prog-indent-sexp (&optional defun)
"Indent the expression after point.
When interactively called with prefix, indent the enclosing defun
@@ -62,6 +109,27 @@ instead."
(end (progn (forward-sexp 1) (point))))
(indent-region start end nil))))
+(defun prog-first-column ()
+ "Return the indentation column normally used for top-level constructs."
+ (or (car prog-indentation-context) 0))
+
+(defun prog-widen ()
+ "Remove restrictions (narrowing) from current code chunk or buffer.
+This function should be used instead of `widen' in any function used
+by the indentation engine to make it respect the value of
+`prog-indentation-context'.
+
+This function (like `widen') is useful inside a
+`save-restriction' to make the indentation correctly work when
+narrowing is in effect."
+ (let ((chunk (cadr prog-indentation-context)))
+ (if chunk
+ ;; No call to `widen' is necessary here, as narrow-to-region
+ ;; changes (not just narrows) the existing restrictions
+ (narrow-to-region (car chunk) (or (cdr chunk) (point-max)))
+ (widen))))
+
+
(defvar-local prettify-symbols-alist nil
"Alist of symbol prettifications.
Each element looks like (SYMBOL . CHARACTER), where the symbol
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 295c6ee1db7..c234cca3ff9 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -271,6 +271,9 @@
(require 'easymenu)
(require 'align)
+(eval-when-compile
+ (or (fboundp 'use-region-p)
+ (defsubst use-region-p () (region-exists-p))))
(defgroup prolog nil
"Editing and running Prolog and Mercury files."
@@ -1271,7 +1274,7 @@ Actually this is just customized `prolog-mode'."
(comint-send-string proc (string last-command-event))
(call-interactively 'self-insert-command))))
-(declare-function 'compilation-shell-minor-mode "compile" (&optional arg))
+(declare-function compilation-shell-minor-mode "compile" (&optional arg))
(defvar compilation-error-regexp-alist)
(define-derived-mode prolog-inferior-mode comint-mode "Inferior Prolog"
@@ -3329,12 +3332,6 @@ PREFIX is the prefix of the search regexp."
;; prolog buffer)
;;-------------------------------------------------------------------
-(unless (fboundp 'region-exists-p)
- (defun region-exists-p ()
- "Non-nil if the mark is set. Lobotomized version for Emacsen that do not provide their own."
- (mark)))
-
-
;; GNU Emacs ignores `easy-menu-add' so the order in which the menus
;; are defined _is_ important!
@@ -3368,7 +3365,7 @@ PREFIX is the prefix of the search regexp."
:included (not (eq prolog-system 'mercury))]
["Consult buffer" prolog-consult-buffer
:included (not (eq prolog-system 'mercury))]
- ["Consult region" prolog-consult-region :active (region-exists-p)
+ ["Consult region" prolog-consult-region :active (use-region-p)
:included (not (eq prolog-system 'mercury))]
["Consult predicate" prolog-consult-predicate
:included (not (eq prolog-system 'mercury))]
@@ -3380,7 +3377,7 @@ PREFIX is the prefix of the search regexp."
:included (eq prolog-system 'sicstus)]
["Compile buffer" prolog-compile-buffer
:included (eq prolog-system 'sicstus)]
- ["Compile region" prolog-compile-region :active (region-exists-p)
+ ["Compile region" prolog-compile-region :active (use-region-p)
:included (eq prolog-system 'sicstus)]
["Compile predicate" prolog-compile-predicate
:included (eq prolog-system 'sicstus)]
@@ -3418,11 +3415,11 @@ PREFIX is the prefix of the search regexp."
prolog-edit-menu-insert-move prolog-mode-map
"Commands for Prolog code manipulation."
'("Prolog"
- ["Comment region" comment-region (region-exists-p)]
- ["Uncomment region" prolog-uncomment-region (region-exists-p)]
+ ["Comment region" comment-region (use-region-p)]
+ ["Uncomment region" prolog-uncomment-region (use-region-p)]
["Add comment/move to comment" indent-for-comment t]
["Convert variables in region to '_'" prolog-variables-to-anonymous
- :active (region-exists-p) :included (not (eq prolog-system 'mercury))]
+ :active (use-region-p) :included (not (eq prolog-system 'mercury))]
"---"
["Insert predicate template" prolog-insert-predicate-template t]
["Insert next clause head" prolog-insert-next-clause t]
@@ -3435,10 +3432,10 @@ PREFIX is the prefix of the search regexp."
["End of predicate" prolog-end-of-predicate t]
"---"
["Indent line" indent-according-to-mode t]
- ["Indent region" indent-region (region-exists-p)]
+ ["Indent region" indent-region (use-region-p)]
["Indent predicate" prolog-indent-predicate t]
["Indent buffer" prolog-indent-buffer t]
- ["Align region" align (region-exists-p)]
+ ["Align region" align (use-region-p)]
"---"
["Mark clause" prolog-mark-clause t]
["Mark predicate" prolog-mark-predicate t]
diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el
index 86dd20a43ba..7e2b7fdf79f 100644
--- a/lisp/progmodes/ps-mode.el
+++ b/lisp/progmodes/ps-mode.el
@@ -113,7 +113,7 @@ When the figure is finished these values should be replaced."
(defcustom ps-mode-print-function
(lambda ()
(let ((lpr-switches nil)
- (lpr-command (if (memq system-type '(usg-unix-v hpux irix))
+ (lpr-command (if (memq system-type '(usg-unix-v hpux))
"lp" "lpr")))
(lpr-buffer)))
"Lisp function to print current buffer as PostScript."
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index f9956e1599f..68e19ef5b3b 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4,7 +4,7 @@
;; Author: Fabián E. Gallina <fgallina@gnu.org>
;; URL: https://github.com/fgallina/python.el
-;; Version: 0.25.1
+;; Version: 0.25.2
;; Package-Requires: ((emacs "24.1") (cl-lib "1.0"))
;; Maintainer: emacs-devel@gnu.org
;; Created: Jul 2010
@@ -283,6 +283,18 @@
:version "24.3"
:link '(emacs-commentary-link "python"))
+
+;;; 24.x Compat
+
+
+(unless (fboundp 'prog-widen)
+ (defun prog-widen ()
+ (widen)))
+
+(unless (fboundp 'prog-first-column)
+ (defun prog-first-column ()
+ 0))
+
;;; Bindings
@@ -318,6 +330,7 @@
;; Some util commands
(define-key map "\C-c\C-v" 'python-check)
(define-key map "\C-c\C-f" 'python-eldoc-at-point)
+ (define-key map "\C-c\C-d" 'python-describe-at-point)
;; Utilities
(substitute-key-definition 'complete-symbol 'completion-at-point
map global-map)
@@ -549,23 +562,32 @@ The type returned can be `comment', `string' or `paren'."
;; Builtin Exceptions
(,(rx symbol-start
(or
+ ;; Python 2 and 3:
"ArithmeticError" "AssertionError" "AttributeError" "BaseException"
- "DeprecationWarning" "EOFError" "EnvironmentError" "Exception"
- "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError"
- "ImportError" "ImportWarning" "IndexError" "KeyError"
- "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
- "NotImplementedError" "OSError" "OverflowError"
- "PendingDeprecationWarning" "ReferenceError" "RuntimeError"
- "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning"
- "SystemError" "SystemExit" "TypeError" "UnboundLocalError"
- "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
- "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError"
- "ValueError" "Warning" "WindowsError" "ZeroDivisionError"
+ "BufferError" "BytesWarning" "DeprecationWarning" "EOFError"
+ "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning"
+ "GeneratorExit" "IOError" "ImportError" "ImportWarning"
+ "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt"
+ "LookupError" "MemoryError" "NameError" "NotImplementedError"
+ "OSError" "OverflowError" "PendingDeprecationWarning"
+ "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration"
+ "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError"
+ "TypeError" "UnboundLocalError" "UnicodeDecodeError"
+ "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError"
+ "UnicodeWarning" "UserWarning" "ValueError" "Warning"
+ "ZeroDivisionError"
;; Python 2:
"StandardError"
;; Python 3:
- "BufferError" "BytesWarning" "IndentationError" "ResourceWarning"
- "TabError")
+ "BlockingIOError" "BrokenPipeError" "ChildProcessError"
+ "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError"
+ "ConnectionResetError" "FileExistsError" "FileNotFoundError"
+ "InterruptedError" "IsADirectoryError" "NotADirectoryError"
+ "PermissionError" "ProcessLookupError" "RecursionError"
+ "ResourceWarning" "StopAsyncIteration" "TimeoutError"
+ ;; OS specific
+ "VMSError" "WindowsError"
+ )
symbol-end) . font-lock-type-face)
;; Builtins
(,(rx symbol-start
@@ -759,7 +781,7 @@ work on `python-indent-calculate-indentation' instead."
(interactive)
(save-excursion
(save-restriction
- (widen)
+ (prog-widen)
(goto-char (point-min))
(let ((block-end))
(while (and (not block-end)
@@ -858,7 +880,7 @@ keyword
- Point is on a line starting a dedenter block.
- START is the position where the dedenter block starts."
(save-restriction
- (widen)
+ (prog-widen)
(let ((ppss (save-excursion
(beginning-of-line)
(syntax-ppss))))
@@ -1005,10 +1027,10 @@ current context or a list of integers. The latter case is only
happening for :at-dedenter-block-start context since the
possibilities can be narrowed to specific indentation points."
(save-restriction
- (widen)
+ (prog-widen)
(save-excursion
(pcase (python-indent-context)
- (`(:no-indent . ,_) 0)
+ (`(:no-indent . ,_) (prog-first-column)) ; usually 0
(`(,(or :after-line
:after-comment
:inside-string
@@ -1046,7 +1068,7 @@ possibilities can be narrowed to specific indentation points."
(let ((opening-block-start-points
(python-info-dedenter-opening-block-positions)))
(if (not opening-block-start-points)
- 0 ; if not found default to first column
+ (prog-first-column) ; if not found default to first column
(mapcar (lambda (pos)
(save-excursion
(goto-char pos)
@@ -1064,7 +1086,7 @@ integers. Levels are returned in ascending order, and in the
case INDENTATION is a list, this order is enforced."
(if (listp indentation)
(sort (copy-sequence indentation) #'<)
- (nconc (number-sequence 0 (1- indentation)
+ (nconc (number-sequence (prog-first-column) (1- indentation)
python-indent-offset)
(list indentation))))
@@ -1089,7 +1111,7 @@ minimum."
(python-indent--previous-level levels (current-indentation))
(if levels
(apply #'max levels)
- 0))))
+ (prog-first-column)))))
(defun python-indent-line (&optional previous)
"Internal implementation of `python-indent-line-function'.
@@ -2042,8 +2064,8 @@ virtualenv."
(defun python-shell-calculate-pythonpath ()
"Calculate the PYTHONPATH using `python-shell-extra-pythonpaths'."
(let ((pythonpath
- (tramp-compat-split-string
- (or (getenv "PYTHONPATH") "") path-separator)))
+ (split-string
+ (or (getenv "PYTHONPATH") "") path-separator 'omit)))
(python-shell--add-to-path-with-priority
pythonpath python-shell-extra-pythonpaths)
(mapconcat 'identity pythonpath path-separator)))
@@ -2114,7 +2136,7 @@ appends `python-shell-remote-exec-path' instead of `exec-path'."
(md5 tramp-end-of-output)))
unset vars item)
(while env
- (setq item (tramp-compat-split-string (car env) "="))
+ (setq item (split-string (car env) "=" 'omit))
(setcdr item (mapconcat 'identity (cdr item) "="))
(if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
(push (format "%s %s" (car item) (cdr item)) vars)
@@ -2357,7 +2379,9 @@ the `buffer-name'."
(defun python-shell-calculate-command ()
"Calculate the string used to execute the inferior Python process."
(format "%s %s"
- (shell-quote-argument python-shell-interpreter)
+ ;; `python-shell-make-comint' expects to be able to
+ ;; `split-string-and-unquote' the result of this function.
+ (combine-and-quote-strings (list python-shell-interpreter))
python-shell-interpreter-args))
(define-obsolete-function-alias
@@ -3128,13 +3152,10 @@ t when called interactively."
(insert-file-contents
(or temp-file-name file-name))
(python-info-encoding)))
- (file-name (expand-file-name
- (or (file-remote-p file-name 'localname)
- file-name)))
+ (file-name (expand-file-name (file-local-name file-name)))
(temp-file-name (when temp-file-name
(expand-file-name
- (or (file-remote-p temp-file-name 'localname)
- temp-file-name)))))
+ (file-local-name temp-file-name)))))
(python-shell-send-string
(format
(concat
@@ -4018,14 +4039,14 @@ be added to `python-mode-skeleton-abbrev-table'."
"Abbrev table for Python mode."
:parents (list python-mode-skeleton-abbrev-table))
-(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
+(defmacro python-define-auxiliary-skeleton (name &optional doc &rest skel)
"Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
The skeleton will be bound to python-skeleton-NAME."
(declare (indent 2))
(let* ((name (symbol-name name))
(function-name (intern (concat "python-skeleton--" name)))
- (msg (format-message
- "Add `%s' clause? " name)))
+ (msg (funcall (if (fboundp 'format-message) #'format-message #'format)
+ "Add `%s' clause? " name)))
(when (not skel)
(setq skel
`(< ,(format "%s:" name) \n \n
@@ -4038,11 +4059,11 @@ The skeleton will be bound to python-skeleton-NAME."
(signal 'quit t))
,@skel)))
-(python-define-auxiliary-skeleton else nil)
+(python-define-auxiliary-skeleton else)
-(python-define-auxiliary-skeleton except nil)
+(python-define-auxiliary-skeleton except)
-(python-define-auxiliary-skeleton finally nil)
+(python-define-auxiliary-skeleton finally)
(python-skeleton-define if nil
"Condition: "
@@ -4346,6 +4367,11 @@ Interactively, prompt for symbol."
nil nil symbol))))
(message (python-eldoc--get-doc-at-point symbol)))
+(defun python-describe-at-point (symbol process)
+ (interactive (list (python-info-current-symbol)
+ (python-shell-get-process)))
+ (comint-send-string process (concat "help('" symbol "')\n")))
+
;;; Hideshow
@@ -4513,7 +4539,7 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun.
This function can be used as the value of `add-log-current-defun-function'
since it returns nil if point is not inside a defun."
(save-restriction
- (widen)
+ (prog-widen)
(save-excursion
(end-of-line 1)
(let ((names)
@@ -4696,7 +4722,7 @@ likely an invalid python file."
(let ((point (python-info-dedenter-opening-block-position)))
(when point
(save-restriction
- (widen)
+ (prog-widen)
(message "Closes %s" (save-excursion
(goto-char point)
(buffer-substring
@@ -4717,7 +4743,7 @@ statement."
With optional argument LINE-NUMBER, check that line instead."
(save-excursion
(save-restriction
- (widen)
+ (prog-widen)
(when line-number
(python-util-goto-line line-number))
(while (and (not (eobp))
@@ -4733,7 +4759,7 @@ With optional argument LINE-NUMBER, check that line instead."
Optional argument LINE-NUMBER forces the line number to check against."
(save-excursion
(save-restriction
- (widen)
+ (prog-widen)
(when line-number
(python-util-goto-line line-number))
(when (python-info-line-ends-backslash-p)
@@ -4750,7 +4776,7 @@ When current line is continuation of another return the point
where the continued line ends."
(save-excursion
(save-restriction
- (widen)
+ (prog-widen)
(let* ((context-type (progn
(back-to-indentation)
(python-syntax-context-type)))
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 866aa14e7b6..036d071f10b 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1799,9 +1799,9 @@ If the result is do-end block, it will always be multiline."
(content
(buffer-substring-no-properties (1+ min) (1- max))))
(setq content
- (if (equal string-quote "\"")
- (replace-regexp-in-string "\\\\\"" "\"" (replace-regexp-in-string "\\([^\\\\]\\)'" "\\1\\\\'" content))
- (replace-regexp-in-string "\\\\'" "'" (replace-regexp-in-string "\\([^\\\\]\\)\"" "\\1\\\\\"" content))))
+ (if (equal string-quote "'")
+ (replace-regexp-in-string "\\\\\"" "\"" (replace-regexp-in-string "\\(\\`\\|[^\\\\]\\)'" "\\1\\\\'" content))
+ (replace-regexp-in-string "\\\\'" "'" (replace-regexp-in-string "\\(\\`\\|[^\\\\]\\)\"" "\\1\\\\\"" content))))
(let ((orig-point (point)))
(delete-region min max)
(insert
diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
index bfb7bd3b9f4..0dcf9b47b84 100644
--- a/lisp/progmodes/scheme.el
+++ b/lisp/progmodes/scheme.el
@@ -54,7 +54,7 @@
(defvar scheme-mode-syntax-table
(let ((st (make-syntax-table))
- (i 0))
+ (i 0))
;; Symbol constituents
;; We used to treat chars 128-256 as symbol-constituent, but they
;; should be valid word constituents (Bug#8843). Note that valid
@@ -116,11 +116,11 @@
(defvar scheme-imenu-generic-expression
'((nil
- "^(define\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)*\\s-+(?\\(\\sw+\\)" 4)
- ("Types"
- "^(define-class\\s-+(?\\(\\sw+\\)" 1)
- ("Macros"
- "^(\\(defmacro\\|define-macro\\|define-syntax\\)\\s-+(?\\(\\sw+\\)" 2))
+ "^(define\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)*\\s-+(?\\(\\sw+\\)" 4)
+ ("Types"
+ "^(define-class\\s-+(?\\(\\sw+\\)" 1)
+ ("Macros"
+ "^(\\(defmacro\\|define-macro\\|define-syntax\\)\\s-+(?\\(\\sw+\\)" 2))
"Imenu generic expression for Scheme mode. See `imenu-generic-expression'.")
(defun scheme-mode-variables ()
@@ -151,18 +151,19 @@
(setq-local imenu-syntax-alist '(("+-*/.<>=?!$%_&~^:" . "w")))
(setq-local syntax-propertize-function #'scheme-syntax-propertize)
(setq font-lock-defaults
- '((scheme-font-lock-keywords
- scheme-font-lock-keywords-1 scheme-font-lock-keywords-2)
- nil t (("+-*/.<>=!?$%_&~^:" . "w") (?#. "w 14"))
- beginning-of-defun
- (font-lock-mark-block-function . mark-defun)))
+ '((scheme-font-lock-keywords
+ scheme-font-lock-keywords-1 scheme-font-lock-keywords-2)
+ nil t (("+-*/.<>=!?$%_&~^:" . "w") (?#. "w 14"))
+ beginning-of-defun
+ (font-lock-mark-block-function . mark-defun)))
+ (setq-local prettify-symbols-alist lisp-prettify-symbols-alist)
(setq-local lisp-doc-string-elt-property 'scheme-doc-string-elt))
(defvar scheme-mode-line-process "")
(defvar scheme-mode-map
(let ((smap (make-sparse-keymap))
- (map (make-sparse-keymap "Scheme")))
+ (map (make-sparse-keymap "Scheme")))
(set-keymap-parent smap lisp-mode-shared-map)
(define-key smap [menu-bar scheme] (cons "Scheme" map))
(define-key map [run-scheme] '("Run Inferior Scheme" . run-scheme))
@@ -270,25 +271,25 @@ See `run-hooks'."
;; Declarations. Hannes Haug <hannes.haug@student.uni-tuebingen.de> says
;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS.
(list (concat "(\\(define\\*?\\("
- ;; Function names.
- "\\(\\|-public\\|-method\\|-generic\\(-procedure\\)?\\)\\|"
- ;; Macro names, as variable names. A bit dubious, this.
- "\\(-syntax\\|-macro\\)\\|"
- ;; Class names.
- "-class"
+ ;; Function names.
+ "\\(\\|-public\\|-method\\|-generic\\(-procedure\\)?\\)\\|"
+ ;; Macro names, as variable names. A bit dubious, this.
+ "\\(-syntax\\|-macro\\)\\|"
+ ;; Class names.
+ "-class"
;; Guile modules.
"\\|-module"
- "\\)\\)\\>"
- ;; Any whitespace and declared object.
- ;; The "(*" is for curried definitions, e.g.,
- ;; (define ((sum a) b) (+ a b))
- "[ \t]*(*"
- "\\(\\sw+\\)?")
- '(1 font-lock-keyword-face)
- '(6 (cond ((match-beginning 3) font-lock-function-name-face)
- ((match-beginning 5) font-lock-variable-name-face)
- (t font-lock-type-face))
- nil t))
+ "\\)\\)\\>"
+ ;; Any whitespace and declared object.
+ ;; The "(*" is for curried definitions, e.g.,
+ ;; (define ((sum a) b) (+ a b))
+ "[ \t]*(*"
+ "\\(\\sw+\\)?")
+ '(1 font-lock-keyword-face)
+ '(6 (cond ((match-beginning 3) font-lock-function-name-face)
+ ((match-beginning 5) font-lock-variable-name-face)
+ (t font-lock-type-face))
+ nil t))
))
"Subdued expressions to highlight in Scheme modes.")
@@ -300,21 +301,30 @@ See `run-hooks'."
;; Control structures.
(cons
(concat
- "(" (regexp-opt
- '("begin" "call-with-current-continuation" "call/cc"
- "call-with-input-file" "call-with-output-file" "case" "cond"
- "do" "else" "for-each" "if" "lambda" "λ"
- "let" "let*" "let-syntax" "letrec" "letrec-syntax"
- ;; R6RS library subforms.
- "export" "import"
- ;; SRFI 11 usage comes up often enough.
- "let-values" "let*-values"
- ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
- "and" "or" "delay" "force"
- ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
- ;;"quasiquote" "quote" "unquote" "unquote-splicing"
- "map" "syntax" "syntax-rules") t)
- "\\>") 1)
+ "(" (regexp-opt
+ '("begin" "call-with-current-continuation" "call/cc"
+ "call-with-input-file" "call-with-output-file" "case" "cond"
+ "do" "else" "for-each" "if" "lambda" "λ"
+ "let" "let*" "let-syntax" "letrec" "letrec-syntax"
+ ;; R6RS library subforms.
+ "export" "import"
+ ;; SRFI 11 usage comes up often enough.
+ "let-values" "let*-values"
+ ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
+ "and" "or" "delay" "force"
+ ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
+ ;;"quasiquote" "quote" "unquote" "unquote-splicing"
+ "map" "syntax" "syntax-rules"
+ ;; For R7RS
+ "when" "unless" "letrec*" "include" "include-ci" "cond-expand"
+ "delay-force" "parameterize" "guard" "case-lambda"
+ "syntax-error" "only" "except" "prefix" "rename" "define-values"
+ "define-record-type" "define-library"
+ "include-library-declarations"
+ ;; SRFI-8
+ "receive"
+ ) t)
+ "\\>") 1)
;;
;; It wouldn't be Scheme w/o named-let.
'("(let\\s-+\\(\\sw+\\)"
@@ -327,8 +337,8 @@ See `run-hooks'."
'("\\<#?:\\sw+\\>" . font-lock-builtin-face)
;; R6RS library declarations.
'("(\\(\\<library\\>\\)\\s-*(?\\(\\sw+\\)?"
- (1 font-lock-keyword-face)
- (2 font-lock-type-face))
+ (1 font-lock-keyword-face)
+ (2 font-lock-type-face))
)))
"Gaudy expressions to highlight in Scheme modes.")
@@ -393,9 +403,9 @@ that variable's value is a string."
(not buffer-read-only)
(insert dsssl-sgml-declaration))
(setq font-lock-defaults '(dsssl-font-lock-keywords
- nil t (("+-*/.<>=?$%_&~^:" . "w"))
- beginning-of-defun
- (font-lock-mark-block-function . mark-defun)))
+ nil t (("+-*/.<>=?$%_&~^:" . "w"))
+ beginning-of-defun
+ (font-lock-mark-block-function . mark-defun)))
(setq-local add-log-current-defun-function #'lisp-current-defun-name)
(setq-local imenu-case-fold-search nil)
(setq imenu-generic-expression dsssl-imenu-generic-expression)
@@ -415,22 +425,22 @@ that variable's value is a string."
(eval-when-compile
(list
;; Similar to Scheme
- (list "(\\(define\\(-\\w+\\)?\\)\\>[ ]*\\((?\\)\\(\\sw+\\)\\>"
- '(1 font-lock-keyword-face)
- '(4 font-lock-function-name-face))
+ (list "(\\(define\\(-\\w+\\)?\\)\\>[ \t]*\\((?\\)\\(\\sw+\\)\\>"
+ '(1 font-lock-keyword-face)
+ '(4 font-lock-function-name-face))
(cons
(concat "(\\("
- ;; (make-regexp '("case" "cond" "else" "if" "lambda"
- ;; "let" "let*" "letrec" "and" "or" "map" "with-mode"))
- "and\\|c\\(ase\\|ond\\)\\|else\\|if\\|"
- "l\\(ambda\\|et\\(\\|*\\|rec\\)\\)\\|map\\|or\\|with-mode"
- "\\)\\>")
+ ;; (make-regexp '("case" "cond" "else" "if" "lambda"
+ ;; "let" "let*" "letrec" "and" "or" "map" "with-mode"))
+ "and\\|c\\(ase\\|ond\\)\\|else\\|if\\|"
+ "l\\(ambda\\|et\\(\\|*\\|rec\\)\\)\\|map\\|or\\|with-mode"
+ "\\)\\>")
1)
;; DSSSL syntax
- '("(\\(element\\|mode\\|declare-\\w+\\)\\>[ ]*\\(\\sw+\\)"
+ '("(\\(element\\|mode\\|declare-\\w+\\)\\>[ \t]*\\(\\sw+\\)"
(1 font-lock-keyword-face)
(2 font-lock-type-face))
- '("(\\(element\\)\\>[ ]*(\\(\\S)+\\))"
+ '("(\\(element\\)\\>[ \t]*(\\(\\S)+\\))"
(1 font-lock-keyword-face)
(2 font-lock-type-face))
'("\\<\\sw+:\\>" . font-lock-constant-face) ; trailing `:' c.f. scheme
@@ -467,7 +477,7 @@ indentation."
(progn (goto-char calculate-lisp-indent-last-sexp)
(beginning-of-line)
(parse-partial-sexp (point)
- calculate-lisp-indent-last-sexp 0 t)))
+ calculate-lisp-indent-last-sexp 0 t)))
;; Indent under the list or under the first sexp on the same
;; line as calculate-lisp-indent-last-sexp. Note that first
;; thing on that line has to be complete sexp since we are
@@ -475,20 +485,20 @@ indentation."
(backward-prefix-chars)
(current-column))
(let ((function (buffer-substring (point)
- (progn (forward-sexp 1) (point))))
- method)
- (setq method (or (get (intern-soft function) 'scheme-indent-function)
- (get (intern-soft function) 'scheme-indent-hook)))
- (cond ((or (eq method 'defun)
- (and (null method)
- (> (length function) 3)
- (string-match "\\`def" function)))
- (lisp-indent-defform state indent-point))
- ((integerp method)
- (lisp-indent-specform method state
- indent-point normal-indent))
- (method
- (funcall method state indent-point normal-indent)))))))
+ (progn (forward-sexp 1) (point))))
+ method)
+ (setq method (or (get (intern-soft function) 'scheme-indent-function)
+ (get (intern-soft function) 'scheme-indent-hook)))
+ (cond ((or (eq method 'defun)
+ (and (null method)
+ (> (length function) 3)
+ (string-match "\\`def" function)))
+ (lisp-indent-defform state indent-point))
+ ((integerp method)
+ (lisp-indent-specform method state
+ indent-point normal-indent))
+ (method
+ (funcall method state indent-point normal-indent)))))))
;;; Let is different in Scheme
@@ -546,6 +556,18 @@ indentation."
(put 'call-with-values 'scheme-indent-function 1) ; r5rs?
(put 'dynamic-wind 'scheme-indent-function 3) ; r5rs?
+;; R7RS
+(put 'when 'scheme-indent-function 1)
+(put 'unless 'scheme-indent-function 1)
+(put 'letrec* 'scheme-indent-function 1)
+(put 'parameterize 'scheme-indent-function 1)
+(put 'define-values 'scheme-indent-function 1)
+(put 'define-record-type 'scheme-indent-function 1) ;; is 1 correct?
+(put 'define-library 'scheme-indent-function 1)
+
+;; SRFI-8
+(put 'receive 'scheme-indent-function 2)
+
;;;; MIT Scheme specific indentation.
(if scheme-mit-dialect
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 96d29a339cb..da0819e1071 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -925,8 +925,6 @@ See `sh-feature'.")
(:weight bold)))
"Face to show quoted execs like \\=`blabla\\=`."
:group 'sh-indentation)
-(define-obsolete-face-alias 'sh-heredoc-face 'sh-heredoc "22.1")
-(defvar sh-heredoc-face 'sh-heredoc)
(defface sh-escaped-newline '((t :inherit font-lock-string-face))
"Face used for (non-escaped) backslash at end of a line in Shell-script mode."
@@ -1207,7 +1205,7 @@ subshells can nest."
(if q
(if (characterp q)
(if (eq q ?\`) 'sh-quoted-exec font-lock-string-face)
- sh-heredoc-face)
+ 'sh-heredoc)
font-lock-comment-face)))
(defgroup sh-indentation nil
@@ -1662,7 +1660,12 @@ with your script for an edit-interpret-debug cycle."
(setq-local skeleton-filter-function 'sh-feature)
(setq-local skeleton-newline-indent-rigidly t)
(setq-local defun-prompt-regexp
- (concat "^\\(function[ \t]\\|[[:alnum:]]+[ \t]+()[ \t]+\\)"))
+ (concat
+ "^\\("
+ "\\(function[ \t]\\)?[ \t]*[[:alnum:]]+[ \t]*([ \t]*)"
+ "\\|"
+ "function[ \t]+[[:alnum:]]+[ \t]*\\(([ \t]*)\\)?"
+ "\\)[ \t]*"))
(setq-local add-log-current-defun-function #'sh-current-defun-name)
(add-hook 'completion-at-point-functions
#'sh-completion-at-point-function nil t)
@@ -1680,6 +1683,7 @@ with your script for an edit-interpret-debug cycle."
((string-match "[.]bash\\>" buffer-file-name) "bash")
((string-match "[.]ksh\\>" buffer-file-name) "ksh")
((string-match "[.]t?csh\\(rc\\)?\\>" buffer-file-name) "csh")
+ ((string-match "[.]zsh\\(rc\\|env\\)?\\>" buffer-file-name) "zsh")
((equal (file-name-nondirectory buffer-file-name) ".profile") "sh")
(t sh-shell-file))
nil nil)
@@ -2430,8 +2434,8 @@ whose value is the shell name (don't quote it)."
(funcall mksym "rules")
:forward-token (funcall mksym "forward-token")
:backward-token (funcall mksym "backward-token")))
+ (setq-local parse-sexp-lookup-properties t)
(unless sh-use-smie
- (setq-local parse-sexp-lookup-properties t)
(setq-local sh-kw-alist (sh-feature sh-kw))
(let ((regexp (sh-feature sh-kws-for-done)))
(if regexp
@@ -2900,7 +2904,7 @@ STRING This is ignored for the purposes of calculating
;;(This function never returns just t.)
(cond
((or (nth 3 (syntax-ppss (point)))
- (eq (get-text-property (point) 'face) sh-heredoc-face))
+ (eq (get-text-property (point) 'face) 'sh-heredoc))
;; String continuation -- don't indent
(setq result t)
(setq have-result t))
@@ -3106,8 +3110,7 @@ we go to the end of the previous line and do not check for continuations."
(forward-comment (- (point-max)))
(unless end (beginning-of-line))
(when (and (not (bobp))
- (equal (get-text-property (1- (point)) 'face)
- sh-heredoc-face))
+ (eq (get-text-property (1- (point)) 'face) 'sh-heredoc))
(let ((p1 (previous-single-property-change (1- (point)) 'face)))
(when p1
(goto-char p1)
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index cea159ef3b4..d6c9516c43e 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -462,9 +462,9 @@ file. Since that is a plaintext file, this could be dangerous."
:list-all ("\\d+" . "\\dS+")
:list-table ("\\d+ %s" . "\\dS+ %s")
:completion-object sql-postgres-completion-object
- :prompt-regexp "^\\w*=[#>] "
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
:prompt-length 5
- :prompt-cont-regexp "^\\w*[-(][#>] "
+ :prompt-cont-regexp "^[[:alnum:]_]*[-(][#>] "
:input-filter sql-remove-tabs-filter
:terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g"))
@@ -514,9 +514,9 @@ file. Since that is a plaintext file, this could be dangerous."
:sqli-comint-func sql-comint-vertica
:list-all ("\\d" . "\\dS")
:list-table "\\d %s"
- :prompt-regexp "^\\w*=[#>] "
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
:prompt-length 5
- :prompt-cont-regexp "^\\w*[-(][#>] ")
+ :prompt-cont-regexp "^[[:alnum:]_]*[-(][#>] ")
)
"An alist of product specific configuration settings.
@@ -1072,14 +1072,26 @@ add your name with a \"-U\" prefix (such as \"-Umark\") to the list."
:version "20.8"
:group 'SQL)
-(defcustom sql-postgres-login-params `((user :default ,(user-login-name))
- (database :default ,(user-login-name))
- server)
+(defcustom sql-postgres-login-params
+ `((user :default ,(user-login-name))
+ (database :default ,(user-login-name)
+ :completion ,(completion-table-dynamic
+ (lambda (_) (sql-postgres-list-databases))))
+ server)
"List of login parameters needed to connect to Postgres."
:type 'sql-login-params
:version "24.1"
:group 'SQL)
+(defun sql-postgres-list-databases ()
+ "Return a list of available PostgreSQL databases."
+ (when (executable-find sql-postgres-program)
+ (let ((res '()))
+ (dolist (row (process-lines sql-postgres-program "-ltX"))
+ (when (string-match "^ \\([[:alnum:]-_]+\\) +|.*" row)
+ (push (match-string 1 row) res)))
+ (nreverse res))))
+
;; Customization for Interbase
(defcustom sql-interbase-program "isql"
@@ -1340,7 +1352,7 @@ Based on `comint-mode-map'.")
;; double quotes (") don't delimit strings
(modify-syntax-entry ?\" "." table)
;; Make these all punctuation
- (mapc #'(lambda (c) (modify-syntax-entry c "." table))
+ (mapc (lambda (c) (modify-syntax-entry c "." table))
(string-to-list "!#$%&+,.:;<=>?@\\|"))
table)
"Syntax table used in `sql-mode' and `sql-interactive-mode'.")
@@ -2441,7 +2453,7 @@ highlighting rules in SQL mode.")
(let ((init (or (and initial (symbol-name initial)) "ansi")))
(intern (completing-read
prompt
- (mapcar #'(lambda (info) (symbol-name (car info)))
+ (mapcar (lambda (info) (symbol-name (car info)))
sql-product-alist)
nil 'require-match
init 'sql-product-history init))))
@@ -2476,7 +2488,7 @@ configuration."
;; after this product's name.
(let ((next-item)
(down-display (downcase display)))
- (map-keymap #'(lambda (k b)
+ (map-keymap (lambda (k b)
(when (and (not next-item)
(string-lessp down-display
(downcase (cadr b))))
@@ -2582,7 +2594,7 @@ also be configured."
(font-lock-mode-internal t))
(add-hook 'font-lock-mode-hook
- #'(lambda ()
+ (lambda ()
;; Provide defaults for new font-lock faces.
(defvar font-lock-builtin-face
(if (boundp 'font-lock-preprocessor-face)
@@ -2631,7 +2643,7 @@ adds a fontification pattern to fontify identifiers ending in
"Iterate through login parameters and return a list of results."
(delq nil
(mapcar
- #'(lambda (param)
+ (lambda (param)
(let ((token (or (car-safe param) param))
(plist (cdr-safe param)))
(funcall body token plist)))
@@ -2643,7 +2655,7 @@ adds a fontification pattern to fontify identifiers ending in
(defun sql-product-syntax-table ()
(let ((table (copy-syntax-table sql-mode-syntax-table)))
- (mapc #'(lambda (entry)
+ (mapc (lambda (entry)
(modify-syntax-entry (car entry) (cdr entry) table))
(sql-get-product-feature sql-product :syntax-alist))
table))
@@ -2652,7 +2664,7 @@ adds a fontification pattern to fontify identifiers ending in
(append
;; Change all symbol character to word characters
(mapcar
- #'(lambda (entry) (if (string= (substring (cdr entry) 0 1) "_")
+ (lambda (entry) (if (string= (substring (cdr entry) 0 1) "_")
(cons (car entry)
(concat "w" (substring (cdr entry) 1)))
entry))
@@ -3025,7 +3037,7 @@ In order to qualify, the SQLi buffer must be alive, be in
buf)
;; Look thru each buffer
(car (apply #'append
- (mapcar #'(lambda (b)
+ (mapcar (lambda (b)
(and (sql-buffer-live-p b prod connection)
(list (buffer-name b))))
(buffer-list)))))))
@@ -3112,7 +3124,7 @@ server/database name."
(apply #'append nil
(sql-for-each-login
(sql-get-product-feature sql-product :sqli-login)
- #'(lambda (token plist)
+ (lambda (token plist)
(pcase token
(`user
(unless (string= "" sql-user)
@@ -3278,12 +3290,12 @@ Allows the suppression of continuation prompts.")
((functionp filter)
(setq string (funcall filter string)))
((listp filter)
- (mapc #'(lambda (f) (setq string (funcall f string))) filter))
+ (mapc (lambda (f) (setq string (funcall f string))) filter))
(t nil))
;; Count how many newlines in the string
(setq sql-output-newline-count
- (apply #'+ (mapcar #'(lambda (ch)
+ (apply #'+ (mapcar (lambda (ch)
(if (eq ch ?\n) 1 0)) string)))
;; Send the string
@@ -3510,7 +3522,7 @@ list of SQLi command strings."
(when visible
(message "Executing SQL command..."))
(if (consp command)
- (mapc #'(lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior))
+ (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior))
command)
(sql-redirect-one sqlbuf command outbuf save-prior))
(when visible
@@ -3594,7 +3606,7 @@ for each match."
(match-string regexp-groups))
;; list of numbers; return the specified matches only
((consp regexp-groups)
- (mapcar #'(lambda (c)
+ (mapcar (lambda (c)
(cond
((numberp c) (match-string c))
((stringp c) (match-substitute-replacement c))
@@ -3624,7 +3636,7 @@ strings are formatted with ARG and executed.
If the results are empty the OUTBUF is deleted, otherwise the
buffer is popped into a view window."
(mapc
- #'(lambda (c)
+ (lambda (c)
(cond
((stringp c)
(sql-redirect sqlbuf (if arg (format c arg) c) outbuf) t)
@@ -4009,7 +4021,7 @@ Sentinels will always get the two parameters PROCESS and EVENT."
"Read a connection name."
(let ((completion-ignore-case t))
(completing-read prompt
- (mapcar #'(lambda (c) (car c))
+ (mapcar (lambda (c) (car c))
sql-connection-alist)
nil t initial 'sql-connection-history default)))
@@ -4040,6 +4052,12 @@ is specified in the connection settings."
(if connect-set
;; Set the desired parameters
(let (param-var login-params set-params rem-params)
+ ;; Set the parameters and start the interactive session
+ (mapc
+ (lambda (vv)
+ (set-default (car vv) (eval (cadr vv))))
+ (cdr connect-set))
+ (setq-default sql-connection connection)
;; :sqli-login params variable
(setq param-var
@@ -4052,7 +4070,7 @@ is specified in the connection settings."
;; Params in the connection
(setq set-params
(mapcar
- #'(lambda (v)
+ (lambda (v)
(pcase (car v)
(`sql-user 'user)
(`sql-password 'password)
@@ -4065,17 +4083,10 @@ is specified in the connection settings."
;; the remaining params (w/o the connection params)
(setq rem-params
(sql-for-each-login login-params
- #'(lambda (token plist)
+ (lambda (token plist)
(unless (member token set-params)
(if plist (cons token plist) token)))))
- ;; Set the parameters and start the interactive session
- (mapc
- #'(lambda (vv)
- (set-default (car vv) (eval (cadr vv))))
- (cdr connect-set))
- (setq-default sql-connection connection)
-
;; Start the SQLi session with revised list of login parameters
(eval `(let ((,param-var ',rem-params))
(sql-product-interactive ',sql-product ',new-name))))
@@ -4125,7 +4136,7 @@ optionally is saved to the user's init file."
(cons name
(sql-for-each-login
`(product ,@login)
- #'(lambda (token _plist)
+ (lambda (token _plist)
(pcase token
(`product `(sql-product ',product))
(`user `(sql-user ,user))
@@ -4144,7 +4155,7 @@ optionally is saved to the user's init file."
"Generate menu entries for using each connection."
(append
(mapcar
- #'(lambda (conn)
+ (lambda (conn)
(vector
(format "Connection <%s>\t%s" (car conn)
(let ((sql-user "") (sql-database "")
@@ -4428,7 +4439,7 @@ The default comes from `process-coding-system-alist' and
;; Remove any settings that haven't changed
(mapc
- #'(lambda (one-cur-setting)
+ (lambda (one-cur-setting)
(setq saved-settings (delete one-cur-setting saved-settings)))
(sql-oracle-save-settings sqlbuf))
@@ -4946,7 +4957,7 @@ Try to set `comint-output-filter-functions' like this:
(sql-redirect sqlbuf "\\a"))
;; Return the list of table names (public schema name can be omitted)
- (mapcar #'(lambda (tbl)
+ (mapcar (lambda (tbl)
(if (string= (car tbl) "public")
(format "\"%s\"" (cadr tbl))
(format "\"%s\".\"%s\"" (car tbl) (cadr tbl))))
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 1765614495d..48ee55500f8 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -123,7 +123,7 @@
;;
;; This variable will always hold the version number of the mode
-(defconst verilog-mode-version "2015-09-18-314cf1d-vpo-GNU"
+(defconst verilog-mode-version "2016-11-14-26d3540-vpo-GNU"
"Version of this Verilog mode.")
(defconst verilog-mode-release-emacs t
"If non-nil, this version of Verilog mode was released with Emacs itself.")
@@ -230,10 +230,9 @@ STRING should be given if the last search was by `string-match' on STRING."
`(customize ,var))
)
- (unless (boundp 'inhibit-point-motion-hooks)
- (defvar inhibit-point-motion-hooks nil))
- (unless (boundp 'deactivate-mark)
- (defvar deactivate-mark nil))
+ (defvar inhibit-modification-hooks)
+ (defvar inhibit-point-motion-hooks)
+ (defvar deactivate-mark)
)
;;
;; OK, do this stuff if we are NOT XEmacs:
@@ -327,6 +326,14 @@ wherever possible, since it is slow."
(not (null pos)))))))
(eval-and-compile
+ (cond
+ ((fboundp 'restore-buffer-modified-p)
+ ;; Faster, as does not update mode line when nothing changes
+ (defalias 'verilog-restore-buffer-modified-p 'restore-buffer-modified-p))
+ (t
+ (defalias 'verilog-restore-buffer-modified-p 'set-buffer-modified-p))))
+
+(eval-and-compile
;; Both xemacs and emacs
(condition-case nil
(require 'diff) ; diff-command and diff-switches
@@ -342,6 +349,11 @@ wherever possible, since it is slow."
(condition-case nil
(unless (fboundp 'prog-mode)
(define-derived-mode prog-mode fundamental-mode "Prog"))
+ (error nil))
+ ;; Added in Emacs 25.1
+ (condition-case nil
+ (unless (fboundp 'forward-word-strictly)
+ (defalias 'forward-word-strictly 'forward-word))
(error nil)))
(eval-when-compile
@@ -741,6 +753,13 @@ mode is experimental."
:type 'boolean)
(put 'verilog-auto-declare-nettype 'safe-local-variable `stringp)
+(defcustom verilog-auto-wire-comment t
+ "Non-nil indicates to insert to/from comments with `verilog-auto-wire' etc."
+ :version "25.1"
+ :group 'verilog-mode-actions
+ :type 'boolean)
+(put 'verilog-auto-wire-comment 'safe-local-variable `verilog-booleanp)
+
(defcustom verilog-auto-wire-type nil
"Non-nil specifies the data type to use with `verilog-auto-wire' etc.
Set this to \"logic\" for SystemVerilog code, or use `verilog-auto-logic'."
@@ -827,6 +846,10 @@ Function takes three arguments, the original buffer, the
difference buffer, and the point in original buffer with the
first difference.")
+(defvar verilog-diff-ignore-regexp nil
+ "Non-nil specifies regexp which `verilog-diff-auto' will ignore.
+This is typically nil.")
+
;;; Compile support:
;;
@@ -1115,32 +1138,67 @@ be replaced, and will remain symbolic.
For example, imagine a submodule uses parameters to declare the size of its
inputs. This is then used by an upper module:
- module InstModule (o,i);
- parameter WIDTH;
- input [WIDTH-1:0] i;
- endmodule
+ module InstModule (o,i);
+ parameter WIDTH;
+ input [WIDTH-1:0] i;
+ parameter type OUT_t;
+ output OUT_t o;
+ endmodule
- module ExampInst;
- InstModule
- #(.PARAM(10))
- instName
- (/*AUTOINST*/
- .i (i[PARAM-1:0]));
+ module ExampInst;
+ /*AUTOOUTPUT*/
+ // Beginning of automatic outputs
+ output OUT_t o;
+ // End of automatics
+
+ InstModule
+ #(.WIDTH(10),
+ ,.OUT_t(upper_t))
+ instName
+ (/*AUTOINST*/
+ .i (i[WIDTH-1:0]),
+ .o (o));
-Note even though PARAM=10, the AUTOINST has left the parameter as a
-symbolic name. If `verilog-auto-inst-param-value' is set, this will
+Note even though WIDTH=10, the AUTOINST has left the parameter as
+a symbolic name. Likewise the OUT_t is preserved as the name
+from the instantiated module.
+
+If `verilog-auto-inst-param-value' is set, this will
instead expand to:
module ExampInst;
- InstModule
- #(.PARAM(10))
- instName
- (/*AUTOINST*/
- .i (i[9:0]));"
+ /*AUTOOUTPUT*/
+ // Beginning of automatic outputs
+ output upper_t o;
+ // End of automatics
+
+ InstModule
+ #(.WIDTH(10),
+ ,.OUT_t(upper_t))
+ instName
+ (/*AUTOINST*/
+ .i (i[9:0]),
+ .o (o));
+
+Note that the instantiation now has \"i[9:0]\" as the WIDTH
+was expanded. Likewise the data type of \"o\" in the AUTOOUTPUT
+is now upper_t, from the OUT_t parameter override.
+This second expansion of parameter types can be overridden with
+`verilog-auto-inst-param-value-type'."
:group 'verilog-mode-auto
:type 'boolean)
(put 'verilog-auto-inst-param-value 'safe-local-variable 'verilog-booleanp)
+(defcustom verilog-auto-inst-param-value-type t
+ "Non-nil means expand parameter type in instantiations.
+If nil, leave parameter types as symbolic names.
+
+See `verilog-auto-inst-param-value'."
+ :version "25.1"
+ :group 'verilog-mode-auto
+ :type 'boolean)
+(put 'verilog-auto-inst-param-value-type 'safe-local-variable 'verilog-booleanp)
+
(defcustom verilog-auto-inst-sort nil
"Non-nil means AUTOINST signals will be sorted, not in declaration order.
Also affects AUTOINSTPARAM. Declaration order is the default for
@@ -1310,8 +1368,13 @@ See also `verilog-case-fold'."
:type 'hook)
(defvar verilog-imenu-generic-expression
- '((nil "^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 4)
- ("*Vars*" "^\\s-*\\(reg\\|wire\\)\\s-+\\(\\|\\[[^]]+\\]\\s-+\\)\\([A-Za-z0-9_]+\\)" 3))
+ '((nil "^\\s-*\\(?:m\\(?:odule\\|acromodule\\)\\|p\\(?:rimitive\\|rogram\\|ackage\\)\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 1)
+ ("*Variables*" "^\\s-*\\(reg\\|wire\\|logic\\)\\s-+\\(\\|\\[[^]]+\\]\\s-+\\)\\([A-Za-z0-9_]+\\)" 3)
+ ("*Classes*" "^\\s-*\\(?:\\(?:virtual\\|interface\\)\\s-+\\)?class\\s-+\\([A-Za-z_][A-Za-z0-9_]+\\)" 1)
+ ("*Tasks*" "^\\s-*\\(?:\\(?:static\\|pure\\|virtual\\|local\\|protected\\)\\s-+\\)*task\\s-+\\(?:\\(?:static\\|automatic\\)\\s-+\\)?\\([A-Za-z_][A-Za-z0-9_:]+\\)" 1)
+ ("*Functions*" "^\\s-*\\(?:\\(?:static\\|pure\\|virtual\\|local\\|protected\\)\\s-+\\)*function\\s-+\\(?:\\(?:static\\|automatic\\)\\s-+\\)?\\(?:\\w+\\s-+\\)?\\([A-Za-z_][A-Za-z0-9_:]+\\)" 1)
+ ("*Interfaces*" "^\\s-*interface\\s-+\\([a-zA-Z_0-9]+\\)" 1)
+ ("*Types*" "^\\s-*typedef\\s-+.*\\s-+\\([a-zA-Z_0-9]+\\)\\s-*;" 1))
"Imenu expression for Verilog mode. See `imenu-generic-expression'.")
;;
@@ -1353,8 +1416,10 @@ If set will become buffer local.")
(define-key map "\M-\C-b" 'electric-verilog-backward-sexp)
(define-key map "\M-\C-f" 'electric-verilog-forward-sexp)
(define-key map "\M-\r" `electric-verilog-terminate-and-indent)
- (define-key map "\M-\t" 'verilog-complete-word)
- (define-key map "\M-?" 'verilog-show-completions)
+ (define-key map "\M-\t" (if (fboundp 'completion-at-point)
+ 'completion-at-point 'verilog-complete-word))
+ (define-key map "\M-?" (if (fboundp 'completion-help-at-point)
+ 'completion-help-at-point 'verilog-show-completions))
;; Note \C-c and letter are reserved for users
(define-key map "\C-c`" 'verilog-lint-off)
(define-key map "\C-c*" 'verilog-delete-auto-star-implicit)
@@ -1363,7 +1428,7 @@ If set will become buffer local.")
(define-key map "\C-c\C-i" 'verilog-pretty-declarations)
(define-key map "\C-c=" 'verilog-pretty-expr)
(define-key map "\C-c\C-b" 'verilog-submit-bug-report)
- (define-key map "\M-*" 'verilog-star-comment)
+ (define-key map "\C-c/" 'verilog-star-comment)
(define-key map "\C-c\C-c" 'verilog-comment-region)
(define-key map "\C-c\C-u" 'verilog-uncomment-region)
(when (featurep 'xemacs)
@@ -1385,7 +1450,7 @@ If set will become buffer local.")
(easy-menu-define
verilog-menu verilog-mode-map "Menu for Verilog mode"
(verilog-easy-menu-filter
- '("Verilog"
+ `("Verilog"
("Choose Compilation Action"
["None"
(progn
@@ -1477,7 +1542,8 @@ If set will become buffer local.")
:help "Take a signal vector on the current line and expand it to multiple lines"]
["Insert begin-end block" verilog-insert-block
:help "Insert begin ... end"]
- ["Complete word" verilog-complete-word
+ ["Complete word" ,(if (fboundp 'completion-at-point)
+ 'completion-at-point 'verilog-complete-word)
:help "Complete word at point"]
"----"
["Recompute AUTOs" verilog-auto
@@ -1740,7 +1806,7 @@ so there may be a large up front penalty for the first search."
(let (pt)
(while (and (not pt)
(re-search-forward regexp bound noerror))
- (if (verilog-inside-comment-or-string-p)
+ (if (verilog-inside-comment-or-string-p (match-beginning 0))
(re-search-forward "[/\"\n]" nil t) ; Only way a comment or quote can end
(setq pt (match-end 0))))
pt))
@@ -1754,7 +1820,7 @@ so there may be a large up front penalty for the first search."
(let (pt)
(while (and (not pt)
(re-search-backward regexp bound noerror))
- (if (verilog-inside-comment-or-string-p)
+ (if (verilog-inside-comment-or-string-p (match-beginning 0))
(re-search-backward "[/\"]" nil t) ; Only way a comment or quote can begin
(setq pt (match-beginning 0))))
pt))
@@ -2540,15 +2606,15 @@ find the errors."
"\\|\\(\\<table\\>\\)" ;7
"\\|\\(\\<specify\\>\\)" ;8
"\\|\\(\\<function\\>\\)" ;9
- "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<function\\>\\)" ;10
- "\\|\\(\\<task\\>\\)" ;14
- "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<task\\>\\)" ;15
- "\\|\\(\\<generate\\>\\)" ;18
- "\\|\\(\\<covergroup\\>\\)" ;16 20
- "\\|\\(\\(\\(\\<cover\\>\\s-+\\)\\|\\(\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)" ;17 21
- "\\|\\(\\<\\(rand\\)?sequence\\>\\)" ;21 25
- "\\|\\(\\<clocking\\>\\)" ;22 27
- "\\|\\(\\<`[ou]vm_[a-z_]+_begin\\>\\)" ;28
+ "\\|\\(\\(?:\\<\\(?:virtual\\|protected\\|static\\)\\>\\s-+\\)*\\<function\\>\\)" ;10
+ "\\|\\(\\<task\\>\\)" ;11
+ "\\|\\(\\(?:\\<\\(?:virtual\\|protected\\|static\\)\\>\\s-+\\)*\\<task\\>\\)" ;12
+ "\\|\\(\\<generate\\>\\)" ;13
+ "\\|\\(\\<covergroup\\>\\)" ;14
+ "\\|\\(\\(?:\\(?:\\<cover\\>\\s-+\\)\\|\\(?:\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)" ;15
+ "\\|\\(\\<\\(?:rand\\)?sequence\\>\\)" ;16
+ "\\|\\(\\<clocking\\>\\)" ;17
+ "\\|\\(\\<`[ou]vm_[a-z_]+_begin\\>\\)" ;18
"\\|\\(\\<`vmm_[a-z_]+_member_begin\\>\\)"
;;
))
@@ -2791,10 +2857,12 @@ find the errors."
"\\(\\<\\(import\\|export\\)\\>\\s-+\"DPI\\(-C\\)?\"\\s-+\\(\\<\\(context\\|pure\\)\\>\\s-+\\)?\\([A-Za-z_][A-Za-z0-9_]*\\s-*=\\s-*\\)?\\<\\(function\\|task\\)\\>\\)"
))
+(defconst verilog-default-clocking-re "\\<default\\s-+clocking\\>")
(defconst verilog-disable-fork-re "\\(disable\\|wait\\)\\s-+fork\\>")
-(defconst verilog-extended-case-re "\\(\\(unique0?\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
+(defconst verilog-extended-case-re "\\(\\(unique0?\\s-+\\|priority\\s-+\\)?case[xz]?\\|randcase\\)")
(defconst verilog-extended-complete-re
- (concat "\\(\\(\\<extern\\s-+\\|\\<\\(\\<\\(pure\\|context\\)\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)\\)"
+ ;; verilog-beg-of-statement also looks backward one token to extend this match
+ (concat "\\(\\(\\<extern\\s-+\\|\\<\\(\\<\\(pure\\|context\\)\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\|\\<static\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)\\)"
"\\|\\(\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)\\)"
"\\|\\(\\(\\<\\(import\\|export\\)\\>\\s-+\\)?\\(\"DPI\\(-C\\)?\"\\s-+\\)?\\(\\<\\(pure\\|context\\)\\>\\s-+\\)?\\([A-Za-z_][A-Za-z0-9_]*\\s-*=\\s-*\\)?\\(function\\>\\|task\\>\\)\\)"
"\\|" verilog-extended-case-re ))
@@ -2937,8 +3005,6 @@ find the errors."
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
- ;; FIXME: This goes against Emacs conventions. Use "_" syntax instead and
- ;; then use regexps with things like "\\_<...\\_>".
(modify-syntax-entry ?` "w" table) ; ` is part of definition symbols in Verilog
(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?\' "." table)
@@ -3017,7 +3083,7 @@ See also `verilog-font-lock-extra-types'.")
"Font lock mode face used to highlight AMS keywords."
:group 'font-lock-highlighting-faces)
-(defvar verilog-font-grouping-keywords-face
+(defvar verilog-font-lock-grouping-keywords-face
'verilog-font-lock-grouping-keywords-face
"Font to use for Verilog Grouping Keywords (such as begin..end).")
(defface verilog-font-lock-grouping-keywords-face
@@ -3225,56 +3291,63 @@ A change is considered significant if it affects the buffer text
in any way that isn't completely restored again. Any
user-visible changes to the buffer must not be within a
`verilog-save-buffer-state'."
- ;; From c-save-buffer-state
- `(let* ((modified (buffer-modified-p))
- (buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-point-motion-hooks t)
- (verilog-no-change-functions t)
- before-change-functions
- after-change-functions
- deactivate-mark
- buffer-file-name ; Prevent primitives checking
- buffer-file-truename) ; for file modification
- (unwind-protect
- (progn ,@body)
- (and (not modified)
- (buffer-modified-p)
- (set-buffer-modified-p nil)))))
+ `(let ((inhibit-point-motion-hooks t)
+ (verilog-no-change-functions t))
+ ,(if (fboundp 'with-silent-modifications)
+ `(with-silent-modifications ,@body)
+ ;; Backward compatible version of with-silent-modifications
+ `(let* ((modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t)
+ ;; XEmacs ignores inhibit-modification-hooks.
+ before-change-functions after-change-functions
+ deactivate-mark
+ buffer-file-name ; Prevent primitives checking
+ buffer-file-truename) ; for file modification
+ (unwind-protect
+ (progn ,@body)
+ (and (not modified)
+ (buffer-modified-p)
+ (verilog-restore-buffer-modified-p nil)))))))
-(defmacro verilog-save-no-change-functions (&rest body)
- "Execute BODY forms, disabling all change hooks in BODY.
-For insignificant changes, see instead `verilog-save-buffer-state'."
- `(let* ((inhibit-point-motion-hooks t)
- (verilog-no-change-functions t)
- before-change-functions
- after-change-functions)
- (progn ,@body)))
(defvar verilog-save-font-mod-hooked nil
- "Local variable when inside a `verilog-save-font-mods' block.")
+ "Local variable when inside a `verilog-save-font-no-change-functions' block.")
(make-variable-buffer-local 'verilog-save-font-mod-hooked)
-(defmacro verilog-save-font-mods (&rest body)
- "Execute BODY forms, disabling text modifications to allow performing BODY.
+(defmacro verilog-save-font-no-change-functions (&rest body)
+ "Execute BODY forms, disabling all change hooks in BODY.
Includes temporary disabling of `font-lock' to restore the buffer
to full text form for parsing. Additional actions may be specified with
-`verilog-before-save-font-hook' and `verilog-after-save-font-hook'."
- ;; Before version 20, match-string with font-lock returns a
- ;; vector that is not equal to the string. IE if on "input"
- ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
- `(let* ((hooked (unless verilog-save-font-mod-hooked
- (verilog-run-hooks 'verilog-before-save-font-hook)
- t))
- (verilog-save-font-mod-hooked t)
- (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode)
- (font-lock-mode 0)
- t)))
- (unwind-protect
- (progn ,@body)
- ;; Unwind forms
- (when fontlocked (font-lock-mode t))
- (when hooked (verilog-run-hooks 'verilog-after-save-font-hook)))))
+`verilog-before-save-font-hook' and `verilog-after-save-font-hook'.
+For insignificant changes, see instead `verilog-save-buffer-state'."
+ `(if verilog-save-font-mod-hooked ; Short-circuit a recursive call
+ (progn ,@body)
+ ;; Before version 20, match-string with font-lock returns a
+ ;; vector that is not equal to the string. IE if on "input"
+ ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
+ ;; Therefore we must remove and restore font-lock mode
+ (verilog-run-hooks 'verilog-before-save-font-hook)
+ (let* ((verilog-save-font-mod-hooked (- (point-max) (point-min)))
+ ;; Significant speed savings with no font-lock properties
+ (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode)
+ (font-lock-mode 0)
+ t)))
+ (run-hook-with-args 'before-change-functions (point-min) (point-max))
+ (unwind-protect
+ ;; Must inhibit and restore hooks before restoring font-lock
+ (let* ((inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ (verilog-no-change-functions t)
+ ;; XEmacs and pre-Emacs 21 ignore inhibit-modification-hooks.
+ before-change-functions after-change-functions)
+ (progn ,@body))
+ ;; Unwind forms
+ (run-hook-with-args 'after-change-functions (point-min) (point-max)
+ verilog-save-font-mod-hooked) ; old length
+ (when fontlocked (font-lock-mode t))
+ (verilog-run-hooks 'verilog-after-save-font-hook)))))
;;
;; Comment detection and caching
@@ -3558,28 +3631,28 @@ Use filename, if current buffer being edited shorten to just buffer name."
;; Search forward for matching endfunction
(setq reg "\\<endfunction\\>" )
(setq nest 'no))
- ((match-end 14)
+ ((match-end 11)
;; Search forward for matching endtask
(setq reg "\\<endtask\\>" )
(setq nest 'no))
- ((match-end 15)
+ ((match-end 12)
;; Search forward for matching endtask
(setq reg "\\<endtask\\>" )
(setq nest 'no))
- ((match-end 19)
+ ((match-end 12)
;; Search forward for matching endgenerate
(setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
- ((match-end 20)
+ ((match-end 13)
;; Search forward for matching endgroup
(setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
- ((match-end 21)
+ ((match-end 14)
;; Search forward for matching endproperty
(setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
- ((match-end 25)
+ ((match-end 15)
;; Search forward for matching endsequence
(setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" )
(setq md 3)) ; 3 to get to endsequence in the reg above
- ((match-end 27)
+ ((match-end 17)
;; Search forward for matching endclocking
(setq reg "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)" )))
(if (and reg
@@ -3736,7 +3809,7 @@ AUTO expansion functions are, in part:
Some other functions are:
- \\[verilog-complete-word] Complete word with appropriate possibilities.
+ \\[completion-at-point] Complete word with appropriate possibilities.
\\[verilog-mark-defun] Mark function.
\\[verilog-beg-of-defun] Move to beginning of current function.
\\[verilog-end-of-defun] Move to end of current function.
@@ -3850,10 +3923,35 @@ Key bindings specific to `verilog-mode-map' are:
verilog-forward-sexp-function)
hs-special-modes-alist))))
+ (add-hook 'completion-at-point-functions
+ #'verilog-completion-at-point nil 'local)
+
;; Stuff for autos
(add-hook 'write-contents-hooks 'verilog-auto-save-check nil 'local)
;; verilog-mode-hook call added by define-derived-mode
)
+
+;;; Integration with the speedbar
+;;
+
+;; Avoid problems with XEmacs byte-compiles.
+;; For GNU Emacs, the eval-after-load will handle if it isn't loaded yet.
+(when (eval-when-compile (fboundp 'declare-function))
+ (declare-function speedbar-add-supported-extension "speedbar" (extension)))
+
+(defun verilog-speedbar-initialize ()
+ "Initialize speedbar to understand `verilog-mode'."
+ ;; Set Verilog file extensions (extracted from `auto-mode-alist')
+ (let ((mode-alist auto-mode-alist))
+ (while mode-alist
+ (when (eq (cdar mode-alist) 'verilog-mode)
+ (speedbar-add-supported-extension (caar mode-alist)))
+ (setq mode-alist (cdr mode-alist)))))
+
+;; If the speedbar is loaded, execute initialization instructions right away,
+;; otherwise add the initialization instructions to the speedbar loader.
+(eval-after-load "speedbar" '(verilog-speedbar-initialize))
+
;;; Electric functions:
;;
@@ -4521,7 +4619,7 @@ Limit search to point LIM."
(progn
(if
(verilog-re-search-backward
- "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
+ "\\<\\(randcase\\|case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
(progn
(cond
((match-end 1)
@@ -5647,13 +5745,17 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
(goto-char here)
(throw 'nesting 'block)))))
- ((match-end 27) ; *sigh* might be a clocking declaration
+ ((match-end 17) ; *sigh* might be a clocking declaration
(let ((here (point)))
- (if (verilog-in-paren)
- t ; this is a normal statement
- (progn ; or is fork, starts a new block
- (goto-char here)
- (throw 'nesting 'block)))))
+ (cond ((verilog-in-paren)
+ t) ; this is a normal statement
+ ((save-excursion
+ (verilog-beg-of-statement)
+ (looking-at verilog-default-clocking-re))
+ t) ; default clocking, normal statement
+ (t
+ (goto-char here) ; or is clocking, starts a new block
+ (throw 'nesting 'block)))))
;; need to consider typedef struct here...
((looking-at "\\<class\\|struct\\|function\\|task\\>")
@@ -5781,7 +5883,7 @@ Jump from end to matching begin, from endcase to matching case, and so on."
"\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))
((looking-at "\\<endtask\\>")
;; 2: Search back for matching task
- (setq reg "\\(\\<task\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<task\\>\\)")
+ (setq reg "\\(\\<task\\>\\)\\|\\(\\(\\<\\(virtual\\|protected\\|static\\)\\>\\s-+\\)+\\<task\\>\\)")
(setq nesting 'no))
((looking-at "\\<endcase\\>")
(catch 'nesting
@@ -5803,7 +5905,7 @@ Jump from end to matching begin, from endcase to matching case, and so on."
(setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
((looking-at "\\<endfunction\\>")
;; 8: Search back for matching function
- (setq reg "\\(\\<function\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<function\\>\\)")
+ (setq reg "\\(\\<function\\>\\)\\|\\(\\(\\<\\(virtual\\|protected\\|static\\)\\>\\s-+\\)+\\<function\\>\\)")
(setq nesting 'no))
;;(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
((looking-at "\\<endgenerate\\>")
@@ -6255,7 +6357,7 @@ Return >0 for nested struct."
(let ((p (point)))
(and
(equal (char-after) ?\{)
- (forward-list)
+ (ignore-errors (forward-list))
(progn (backward-char 1)
(verilog-backward-ws&directives)
(and
@@ -7102,6 +7204,9 @@ Region is defined by B and EDPOS."
Repeated use of \\[verilog-complete-word] will show you all of them.
Normally, when there is more than one possible completion,
it displays a list of all possible completions.")
+(when (boundp 'completion-cycle-threshold)
+ (make-obsolete-variable
+ 'verilog-toggle-completions 'completion-cycle-threshold "26.1"))
(defvar verilog-type-keywords
@@ -7384,21 +7489,33 @@ exact match, nil otherwise."
(defvar verilog-last-word-shown nil)
(defvar verilog-last-completions nil)
+(defun verilog-completion-at-point ()
+ "Used as an element of `completion-at-point-functions'.
+\(See also `verilog-type-keywords' and
+`verilog-separator-keywords'.)"
+ (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
+ (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
+ (verilog-str (buffer-substring b e))
+ ;; The following variable is used in verilog-completion
+ (verilog-buffer-to-use (current-buffer))
+ (allcomp (if (and verilog-toggle-completions
+ (string= verilog-last-word-shown verilog-str))
+ verilog-last-completions
+ (all-completions verilog-str 'verilog-completion))))
+ (list b e allcomp)))
+
(defun verilog-complete-word ()
"Complete word at current point.
\(See also `verilog-toggle-completions', `verilog-type-keywords',
and `verilog-separator-keywords'.)"
- ;; FIXME: Provide completion-at-point-function.
+ ;; NOTE: This is just a fallback for Emacs versions lacking
+ ;; `completion-at-point'.
(interactive)
- (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
- (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
+ (let* ((comp-info (verilog-completion-at-point))
+ (b (nth 0 comp-info))
+ (e (nth 1 comp-info))
(verilog-str (buffer-substring b e))
- ;; The following variable is used in verilog-completion
- (verilog-buffer-to-use (current-buffer))
- (allcomp (if (and verilog-toggle-completions
- (string= verilog-last-word-shown verilog-str))
- verilog-last-completions
- (all-completions verilog-str 'verilog-completion)))
+ (allcomp (nth 2 comp-info))
(match (if verilog-toggle-completions
"" (try-completion
verilog-str (mapcar (lambda (elm)
@@ -7446,23 +7563,15 @@ and `verilog-separator-keywords'.)"
(defun verilog-show-completions ()
"Show all possible completions at current point."
+ ;; NOTE: This is just a fallback for Emacs versions lacking
+ ;; `completion-help-at-point'.
(interactive)
- (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
- (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
- (verilog-str (buffer-substring b e))
- ;; The following variable is used in verilog-completion
- (verilog-buffer-to-use (current-buffer))
- (allcomp (if (and verilog-toggle-completions
- (string= verilog-last-word-shown verilog-str))
- verilog-last-completions
- (all-completions verilog-str 'verilog-completion))))
- ;; Show possible completions in a temporary buffer.
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list allcomp))
- ;; Wait for a key press. Then delete *Completion* window
- (momentary-string-display "" (point))
- (delete-window (get-buffer-window (get-buffer "*Completions*")))))
-
+ ;; Show possible completions in a temporary buffer.
+ (with-output-to-temp-buffer "*Completions*"
+ (display-completion-list (nth 2 (verilog-completion-at-point))))
+ ;; Wait for a key press. Then delete *Completion* window
+ (momentary-string-display "" (point))
+ (delete-window (get-buffer-window (get-buffer "*Completions*"))))
(defun verilog-get-default-symbol ()
"Return symbol around current point as a string."
@@ -7786,7 +7895,7 @@ See also `verilog-sk-header' for an alternative format."
(if (verilog-sig-multidim sig)
(let ((str "") (args (verilog-sig-multidim sig)))
(while args
- (setq str (concat str (car args)))
+ (setq str (concat (car args) str))
(setq args (cdr args)))
str)))
(defsubst verilog-sig-modport (sig)
@@ -8074,7 +8183,7 @@ Duplicate signals are also removed. For example A[2] and A[1] become A[2:1]."
(when (and sv-busstring
(not (equal sv-busstring (verilog-sig-bits sig))))
(when nil ; Debugging
- (message (concat "Warning, can't merge into single bus %s%s"
+ (message (concat "Warning, can't merge into single bus `%s%s'"
", the AUTOs may be wrong")
sv-name bus))
(setq buswarn ", Couldn't Merge"))
@@ -8307,7 +8416,8 @@ Return an array of [outputs inouts inputs wire reg assign const]."
in-modport in-clocking in-ign-to-semi ptype ign-prop
sigs-in sigs-out sigs-inout sigs-var sigs-assign sigs-const
sigs-gparam sigs-intf sigs-modports
- vec expect-signal keywd newsig rvalue enum io signed typedefed multidim
+ vec expect-signal keywd last-keywd newsig rvalue enum io
+ signed typedefed multidim
modport
varstack tmp)
;;(if dbg (setq dbg (concat dbg (format "\n\nverilog-read-decls START PT %s END %s\n" (point) end-mod-point))))
@@ -8377,18 +8487,19 @@ Return an array of [outputs inouts inputs wire reg assign const]."
(setcar (cdr (cdr (cdr newsig)))
(if (verilog-sig-memory newsig)
(concat (verilog-sig-memory newsig) (match-string 1))
- (match-string 1))))
+ (match-string-no-properties 1))))
(vec ; Multidimensional
(setq multidim (cons vec multidim))
(setq vec (verilog-string-replace-matches
- "\\s-+" "" nil nil (match-string 1))))
+ "\\s-+" "" nil nil (match-string-no-properties 1))))
(t ; Bit width
(setq vec (verilog-string-replace-matches
- "\\s-+" "" nil nil (match-string 1))))))
+ "\\s-+" "" nil nil (match-string-no-properties 1))))))
;; Normal or escaped identifier -- note we remember the \ if escaped
((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
(goto-char (match-end 0))
- (setq keywd (match-string 1))
+ (setq last-keywd keywd
+ keywd (match-string-no-properties 1))
(when (string-match "^\\\\" (match-string 1))
(setq keywd (concat keywd " "))) ; Escaped ID needs space at end
;; Add any :: package names to same identifier
@@ -8453,7 +8564,8 @@ Return an array of [outputs inouts inputs wire reg assign const]."
(setq functask (1- functask)))
((equal keywd "modport")
(setq in-modport t))
- ((equal keywd "clocking")
+ ((and (equal keywd "clocking")
+ (not (equal last-keywd "default")))
(setq in-clocking t))
((equal keywd "import")
(if v2kargs-ok ; import in module header, not a modport import
@@ -8573,21 +8685,31 @@ Return an array of [outputs inouts inputs wire reg assign const]."
(defvar sigs-out-unk)
(defvar sigs-temp)
;; These are known to be from other packages and may not be defined
- (defvar diff-command nil)
+ (defvar diff-command)
;; There are known to be from newer versions of Emacs
- (defvar create-lockfiles))
-
-(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim)
+ (defvar create-lockfiles)
+ (defvar which-func-modes))
+
+(defun verilog-read-sub-decls-type (par-values portdata)
+ "For `verilog-read-sub-decls-line', decode a signal type."
+ (let* ((type (verilog-sig-type portdata))
+ (pvassoc (assoc type par-values)))
+ (cond ((member type '("wire" "reg")) nil)
+ (pvassoc (nth 1 pvassoc))
+ (t type))))
+
+(defun verilog-read-sub-decls-sig (submoddecls par-values comment port sig vec multidim mem)
"For `verilog-read-sub-decls-line', add a signal."
;; sig eq t to indicate .name syntax
;;(message "vrsds: %s(%S)" port sig)
(let ((dotname (eq sig t))
- portdata)
+ portdata)
(when sig
(setq port (verilog-symbol-detick-denumber port))
(setq sig (if dotname port (verilog-symbol-detick-denumber sig)))
(if vec (setq vec (verilog-symbol-detick-denumber vec)))
(if multidim (setq multidim (mapcar `verilog-symbol-detick-denumber multidim)))
+ (if mem (setq mem (verilog-symbol-detick-denumber mem)))
(unless (or (not sig)
(equal sig "")) ; Ignore .foo(1'b1) assignments
(cond ((or (setq portdata (assoc port (verilog-decls-get-inouts submoddecls)))
@@ -8597,11 +8719,10 @@ Return an array of [outputs inouts inputs wire reg assign const]."
sig
(if dotname (verilog-sig-bits portdata) vec)
(concat "To/From " comment)
- (verilog-sig-memory portdata)
+ mem
nil
(verilog-sig-signed portdata)
- (unless (member (verilog-sig-type portdata) '("wire" "reg"))
- (verilog-sig-type portdata))
+ (verilog-read-sub-decls-type par-values portdata)
multidim nil)
sigs-inout)))
((or (setq portdata (assoc port (verilog-decls-get-outputs submoddecls)))
@@ -8611,7 +8732,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
sig
(if dotname (verilog-sig-bits portdata) vec)
(concat "From " comment)
- (verilog-sig-memory portdata)
+ mem
nil
(verilog-sig-signed portdata)
;; Though ok in SV, in V2K code, propagating the
@@ -8619,8 +8740,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
;; Also for backwards compatibility we don't propagate
;; "input wire" upwards.
;; See also `verilog-signals-edit-wire-reg'.
- (unless (member (verilog-sig-type portdata) '("wire" "reg"))
- (verilog-sig-type portdata))
+ (verilog-read-sub-decls-type par-values portdata)
multidim nil)
sigs-out)))
((or (setq portdata (assoc port (verilog-decls-get-inputs submoddecls)))
@@ -8630,11 +8750,10 @@ Return an array of [outputs inouts inputs wire reg assign const]."
sig
(if dotname (verilog-sig-bits portdata) vec)
(concat "To " comment)
- (verilog-sig-memory portdata)
+ mem
nil
(verilog-sig-signed portdata)
- (unless (member (verilog-sig-type portdata) '("wire" "reg"))
- (verilog-sig-type portdata))
+ (verilog-read-sub-decls-type par-values portdata)
multidim nil)
sigs-in)))
((setq portdata (assoc port (verilog-decls-get-interfaces submoddecls)))
@@ -8643,10 +8762,10 @@ Return an array of [outputs inouts inputs wire reg assign const]."
sig
(if dotname (verilog-sig-bits portdata) vec)
(concat "To/From " comment)
- (verilog-sig-memory portdata)
+ mem
nil
(verilog-sig-signed portdata)
- (verilog-sig-type portdata)
+ (verilog-read-sub-decls-type par-values portdata)
multidim nil)
sigs-intf)))
((setq portdata (and verilog-read-sub-decls-in-interfaced
@@ -8656,20 +8775,20 @@ Return an array of [outputs inouts inputs wire reg assign const]."
sig
(if dotname (verilog-sig-bits portdata) vec)
(concat "To/From " comment)
- (verilog-sig-memory portdata)
+ mem
nil
(verilog-sig-signed portdata)
- (verilog-sig-type portdata)
+ (verilog-read-sub-decls-type par-values portdata)
multidim nil)
sigs-intf)))
;; (t -- warning pin isn't defined.) ; Leave for lint tool
)))))
-(defun verilog-read-sub-decls-expr (submoddecls comment port expr)
+(defun verilog-read-sub-decls-expr (submoddecls par-values comment port expr)
"For `verilog-read-sub-decls-line', parse a subexpression and add signals."
;;(message "vrsde: `%s'" expr)
;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port
- (setq expr (verilog-string-replace-matches "/\\*\\(\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
+ (setq expr (verilog-string-replace-matches "/\\*\\(\\.?\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
;; Remove front operators
(setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
;;
@@ -8681,9 +8800,9 @@ Return an array of [outputs inouts inputs wire reg assign const]."
(let ((mlst (split-string (match-string 1 expr) "[{},]"))
mstr)
(while (setq mstr (pop mlst))
- (verilog-read-sub-decls-expr submoddecls comment port mstr)))))
+ (verilog-read-sub-decls-expr submoddecls par-values comment port mstr)))))
(t
- (let (sig vec multidim)
+ (let (sig vec multidim mem)
;; Remove leading reduction operators, etc
(setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
;;(message "vrsde-ptop: `%s'" expr)
@@ -8703,12 +8822,17 @@ Return an array of [outputs inouts inputs wire reg assign const]."
(when vec (setq multidim (cons vec multidim)))
(setq vec (match-string 1 expr)
expr (substring expr (match-end 0))))
+ ;; Find .[unpacked_memory] or .[unpacked][unpacked]...
+ (while (string-match "^\\s-*\\.\\(\\(\\[[^]]+\\]\\)+\\)" expr)
+ ;;(message "vrsde-m: `%s'" (match-string 1 expr))
+ (setq mem (match-string 1 expr)
+ expr (substring expr (match-end 0))))
;; If found signal, and nothing unrecognized, add the signal
;;(message "vrsde-rem: `%s'" expr)
(when (and sig (string-match "^\\s-*$" expr))
- (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))))))
+ (verilog-read-sub-decls-sig submoddecls par-values comment port sig vec multidim mem))))))
-(defun verilog-read-sub-decls-line (submoddecls comment)
+(defun verilog-read-sub-decls-line (submoddecls par-values comment)
"For `verilog-read-sub-decls', read lines of port defs until none match.
Inserts the list of signals found, using submodi to look up each port."
(let (done port)
@@ -8717,23 +8841,23 @@ Inserts the list of signals found, using submodi to look up each port."
(while (not done)
;; Get port name
(cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
- (setq port (match-string 1))
+ (setq port (match-string-no-properties 1))
(goto-char (match-end 0)))
;; .\escaped (
((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*(\\s-*")
- (setq port (concat (match-string 1) " ")) ; escaped id's need trailing space
+ (setq port (concat (match-string-no-properties 1) " ")) ; escaped id's need trailing space
(goto-char (match-end 0)))
;; .name
((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*[,)/]")
(verilog-read-sub-decls-sig
- submoddecls comment (match-string 1) t ; sig==t for .name
- nil nil) ; vec multidim
+ submoddecls par-values comment (match-string-no-properties 1) t ; sig==t for .name
+ nil nil nil) ; vec multidim mem
(setq port nil))
;; .\escaped_name
((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*[,)/]")
(verilog-read-sub-decls-sig
- submoddecls comment (concat (match-string 1) " ") t ; sig==t for .name
- nil nil) ; vec multidim
+ submoddecls par-values comment (concat (match-string-no-properties 1) " ") t ; sig==t for .name
+ nil nil nil) ; vec multidim mem
(setq port nil))
;; random
((looking-at "\\s-*\\.[^(]*(")
@@ -8747,28 +8871,29 @@ Inserts the list of signals found, using submodi to look up each port."
(when port
(cond ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
(verilog-read-sub-decls-sig
- submoddecls comment port
- (verilog-string-remove-spaces (match-string 1)) ; sig
- nil nil)) ; vec multidim
+ submoddecls par-values comment port
+ (verilog-string-remove-spaces (match-string-no-properties 1)) ; sig
+ nil nil nil)) ; vec multidim mem
;;
((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
(verilog-read-sub-decls-sig
- submoddecls comment port
- (verilog-string-remove-spaces (match-string 1)) ; sig
- (match-string 2) nil)) ; vec multidim
+ submoddecls par-values comment port
+ (verilog-string-remove-spaces (match-string-no-properties 1)) ; sig
+ (match-string-no-properties 2) nil nil)) ; vec multidim mem
;; Fastpath was above looking-at's.
;; For something more complicated invoke a parser
((looking-at "[^)]+")
(verilog-read-sub-decls-expr
- submoddecls comment port
- (buffer-substring
+ submoddecls par-values comment port
+ (buffer-substring-no-properties
(point) (1- (progn (search-backward "(") ; start at (
(verilog-forward-sexp-ign-cmt 1)
(point)))))))) ; expr
;;
(forward-line 1)))))
+;;(verilog-read-sub-decls-line (verilog-subdecls-new nil nil nil nil nil) nil "Cmt")
-(defun verilog-read-sub-decls-gate (submoddecls comment submod end-inst-point)
+(defun verilog-read-sub-decls-gate (submoddecls par-values comment submod end-inst-point)
"For `verilog-read-sub-decls', read lines of UDP gate decl until none match.
Inserts the list of signals found."
(save-excursion
@@ -8792,7 +8917,7 @@ Inserts the list of signals found."
(setq verilog-read-sub-decls-gate-ios (or (car iolist) "input")
iolist (cdr iolist))
(verilog-read-sub-decls-expr
- submoddecls comment "primitive_port"
+ submoddecls par-values comment "primitive_port"
(match-string 0)))
(t
(forward-char 1)
@@ -8818,13 +8943,16 @@ Outputs comments above subcell signals, for example:
.in (in));"
(save-excursion
(let ((end-mod-point (verilog-get-end-of-defun))
- st-point end-inst-point
+ st-point end-inst-point par-values
;; below 3 modified by verilog-read-sub-decls-line
sigs-out sigs-inout sigs-in sigs-intf sigs-intfd)
(verilog-beg-of-defun-quick)
(while (verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-mod-point t)
(save-excursion
(goto-char (match-beginning 0))
+ (setq par-values (and verilog-auto-inst-param-value
+ verilog-auto-inst-param-value-type
+ (verilog-read-inst-param-value)))
(unless (verilog-inside-comment-or-string-p)
;; Attempt to snarf a comment
(let* ((submod (verilog-read-inst-module))
@@ -8842,7 +8970,7 @@ Outputs comments above subcell signals, for example:
(point))
st-point (point))
(forward-char 1)
- (verilog-read-sub-decls-gate submoddecls comment submod end-inst-point))
+ (verilog-read-sub-decls-gate submoddecls par-values comment submod end-inst-point))
;; Non-primitive
(t
(when (setq submodi (verilog-modi-lookup submod t))
@@ -8856,19 +8984,19 @@ Outputs comments above subcell signals, for example:
;; However I want it to be runnable even on user's manually added signals
(let ((verilog-read-sub-decls-in-interfaced t))
(while (re-search-forward "\\s *(?\\s *// Interfaced" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment))) ; Modifies sigs-ifd
+ (verilog-read-sub-decls-line submoddecls par-values comment))) ; Modifies sigs-ifd
(goto-char st-point)
(while (re-search-forward "\\s *(?\\s *// Interfaces" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ; Modifies sigs-out
+ (verilog-read-sub-decls-line submoddecls par-values comment)) ; Modifies sigs-out
(goto-char st-point)
(while (re-search-forward "\\s *(?\\s *// Outputs" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ; Modifies sigs-out
+ (verilog-read-sub-decls-line submoddecls par-values comment)) ; Modifies sigs-out
(goto-char st-point)
(while (re-search-forward "\\s *(?\\s *// Inouts" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ; Modifies sigs-inout
+ (verilog-read-sub-decls-line submoddecls par-values comment)) ; Modifies sigs-inout
(goto-char st-point)
(while (re-search-forward "\\s *(?\\s *// Inputs" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ; Modifies sigs-in
+ (verilog-read-sub-decls-line submoddecls par-values comment)) ; Modifies sigs-in
)))))))
;; Combine duplicate bits
;;(setq rr (vector sigs-out sigs-inout sigs-in))
@@ -8993,7 +9121,8 @@ IGNORE-NEXT is true to ignore next token, fake from inside case statement."
;;(if dbg (setq dbg (concat dbg (format "\tif-check-else-other %s\n" keywd))))
(setq gotend t))
;; Final statement?
- ((and exit-keywd (equal keywd exit-keywd))
+ ((and exit-keywd (and (equal keywd exit-keywd)
+ (not (looking-at "::"))))
(setq gotend t)
(forward-char (length keywd)))
;; Standard tokens...
@@ -9009,7 +9138,9 @@ IGNORE-NEXT is true to ignore next token, fake from inside case statement."
(goto-char (match-end 0))
(forward-char 1)))
((equal keywd ":") ; Case statement, begin/end label, x?y:z
- (cond ((equal "endcase" exit-keywd) ; case x: y=z; statement next
+ (cond ((looking-at "::")
+ (forward-char 1)) ; Another forward-char below
+ ((equal "endcase" exit-keywd) ; case x: y=z; statement next
(setq ignore-next nil rvalue nil))
((equal "?" exit-keywd) ; x?y:z rvalue
) ; NOP
@@ -9056,7 +9187,7 @@ IGNORE-NEXT is true to ignore next token, fake from inside case statement."
;;(if dbg (setq dbg (concat dbg (format "\tgot-end %s\n" exit-keywd))))
(setq ignore-next nil rvalue semi-rvalue)
(if (not exit-keywd) (setq end-else-check t)))
- ((member keywd '("case" "casex" "casez"))
+ ((member keywd '("case" "casex" "casez" "randcase"))
(skip-syntax-forward "w_")
(verilog-read-always-signals-recurse "endcase" t nil)
(setq ignore-next nil rvalue semi-rvalue)
@@ -9104,7 +9235,7 @@ IGNORE-NEXT is true to ignore next token, fake from inside case statement."
(verilog-read-always-signals-recurse nil nil nil)
(setq sigs-out-i (append sigs-out-i sigs-out-unk)
sigs-out-unk nil)
- ;;(if dbg (with-current-buffer (get-buffer-create "*vl-dbg*")) (delete-region (point-min) (point-max)) (insert dbg) (setq dbg ""))
+ ;;(if dbg (with-current-buffer (get-buffer-create "*vl-dbg*") (delete-region (point-min) (point-max)) (insert dbg) (setq dbg "")))
;; Return what was found
(verilog-alw-new sigs-out-d sigs-out-i sigs-temp sigs-in))))
@@ -9282,29 +9413,43 @@ Optionally associate it with the specified enumeration ENUMNAME."
If the filename is provided, `verilog-library-flags' will be used to
resolve it. If optional RECURSE is non-nil, recurse through \\=`includes.
-Parameters must be simple assignments to constants, or have their own
-\"parameter\" label rather than a list of parameters. Thus:
+Localparams must be simple assignments to constants, or have their own
+\"localparam\" label rather than a list of localparams. Thus:
- parameter X = 5, Y = 10; // Ok
- parameter X = {1\\='b1, 2\\='h2}; // Ok
- parameter X = {1\\='b1, 2\\='h2}, Y = 10; // Bad, make into 2 parameter lines
+ localparam X = 5, Y = 10; // Ok
+ localparam X = {1\\='b1, 2\\='h2}; // Ok
+ localparam X = {1\\='b1, 2\\='h2}, Y = 10; // Bad, make into 2 localparam lines
Defines must be simple text substitutions, one on a line, starting
at the beginning of the line. Any ifdefs or multiline comments around the
define are ignored.
-Defines are stored inside Emacs variables using the name vh-{definename}.
+Defines are stored inside Emacs variables using the name
+vh-{definename}.
+
+Localparams define what symbols are constants so that AUTOSENSE
+will not include them in sensitivity lists. However any
+parameters in the include file are not considered ports in the
+including file, thus will not appear in AUTOINSTPARAM lists for a
+parent module..
-This function is useful for setting vh-* variables. The file variables
-feature can be used to set defines that `verilog-mode' can see; put at the
-*END* of your file something like:
+The file variables feature can be used to set defines that
+`verilog-mode' can see; put at the *END* of your file something
+like:
// Local Variables:
// vh-macro:\"macro_definition\"
// End:
If macros are defined earlier in the same file and you want their values,
-you can read them automatically (provided `enable-local-eval' is on):
+you can read them automatically with:
+
+ // Local Variables:
+ // verilog-auto-read-includes:t
+ // End:
+
+Or a more specific alternative example, which requires having
+`enable-local-eval' non-nil:
// Local Variables:
// eval:(verilog-read-defines)
@@ -9372,6 +9517,13 @@ file.
It is often useful put at the *END* of your file something like:
// Local Variables:
+ // verilog-auto-read-includes:t
+ // End:
+
+Or the equivalent longer version, which requires having
+`enable-local-eval' non-nil:
+
+ // Local Variables:
// eval:(verilog-read-defines)
// eval:(verilog-read-includes)
// End:
@@ -9793,9 +9945,14 @@ Uses the CURRENT filename, `verilog-library-extensions',
`verilog-library-directories' and `verilog-library-files'
variables to build the path."
;; Return search locations for it
- (append (list current) ; first, current buffer
- (verilog-library-filenames module current t)
- verilog-library-files)) ; finally, any libraries
+ (append (list current) ; first, current buffer
+ (verilog-library-filenames module current t)
+ ;; Finally any libraries; fixed up if using e.g. tramp
+ (mapcar (lambda (fname)
+ (if (file-name-absolute-p fname)
+ (concat (file-remote-p current) fname)
+ fname))
+ verilog-library-files)))
;;
;; Module Information
@@ -9894,7 +10051,7 @@ Return modi if successful, else print message unless IGNORE-ERROR is true."
(or mif ignore-error
(error
(concat
- "%s: Can't locate %s module definition%s"
+ "%s: Can't locate `%s' module definition%s"
"\n Check the verilog-library-directories variable."
"\n I looked in (if not listed, doesn't exist):\n\t%s")
(verilog-point-text) module
@@ -9959,9 +10116,9 @@ Cache the output of function so next call may have faster access."
(t
;; Read from file
;; Clear then restore any highlighting to make emacs19 happy
- (let (func-returns)
- (verilog-save-font-mods
- (setq func-returns (funcall function)))
+ (let ((func-returns
+ (verilog-save-font-no-change-functions
+ (funcall function))))
;; Cache for next time
(setq verilog-modi-cache-list
(cons (list (list modi function)
@@ -10003,7 +10160,7 @@ Report errors unless optional IGNORE-ERROR."
(let* ((realname (verilog-symbol-detick name t))
(modport (assoc name (verilog-decls-get-modports (verilog-modi-get-decls modi)))))
(or modport ignore-error
- (error "%s: Can't locate %s modport definition%s"
+ (error "%s: Can't locate `%s' modport definition%s"
(verilog-point-text) name
(if (not (equal name realname))
(concat " (Expanded macro to " realname ")")
@@ -10193,7 +10350,7 @@ When MODI is non-null, also add to modi-cache, for tracking."
((equal direction "parameter")
(verilog-modi-cache-add-gparams modi sigs))
(t
- (error "Unsupported verilog-insert-definition direction: %s" direction))))
+ (error "Unsupported verilog-insert-definition direction: `%s'" direction))))
(or dont-sort
(setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
(while sigs
@@ -10215,8 +10372,9 @@ When MODI is non-null, also add to modi-cache, for tracking."
direction))
indent-pt)
(insert (if v2k "," ";"))
- (if (or (not (verilog-sig-comment sig))
- (equal "" (verilog-sig-comment sig)))
+ (if (or (not verilog-auto-wire-comment)
+ (not (verilog-sig-comment sig))
+ (equal "" (verilog-sig-comment sig)))
(insert "\n")
(indent-to (max 48 (+ indent-pt 40)))
(verilog-insert "// " (verilog-sig-comment sig) "\n"))
@@ -10224,7 +10382,7 @@ When MODI is non-null, also add to modi-cache, for tracking."
(eval-when-compile
(if (not (boundp 'indent-pt))
- (defvar indent-pt nil "Local used by insert-indent")))
+ (defvar indent-pt nil "Local used by `verilog-insert-indent'.")))
(defun verilog-insert-indent (&rest stuff)
"Indent to position stored in local `indent-pt' variable, then insert STUFF.
@@ -10510,6 +10668,41 @@ removed."
(re-search-backward ",")
(delete-char 1))))))
+(defun verilog-delete-auto-buffer ()
+ "Perform `verilog-delete-auto' on the current buffer.
+Intended for internal use inside a `verilog-save-font-no-change-functions' block."
+ ;; Allow user to customize
+ (verilog-run-hooks 'verilog-before-delete-auto-hook)
+
+ ;; Remove those that have multi-line insertions, possibly with parameters
+ ;; We allow anything beginning with AUTO, so that users can add their own
+ ;; patterns
+ (verilog-auto-re-search-do
+ (concat "/\\*AUTO[A-Za-z0-9_]+"
+ ;; Optional parens or quoted parameter or .* for (((...)))
+ "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
+ "\\*/")
+ 'verilog-delete-autos-lined)
+ ;; Remove those that are in parenthesis
+ (verilog-auto-re-search-do
+ (concat "/\\*"
+ (eval-when-compile
+ (verilog-regexp-words
+ `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
+ "AUTOSENSE")))
+ "\\*/")
+ 'verilog-delete-to-paren)
+ ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
+ (verilog-auto-re-search-do "\\.\\*"
+ 'verilog-delete-auto-star-all)
+ ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
+ (goto-char (point-min))
+ (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
+ (replace-match ""))
+
+ ;; Final customize
+ (verilog-run-hooks 'verilog-delete-auto-hook))
+
(defun verilog-delete-auto ()
"Delete the automatic outputs, regs, and wires created by \\[verilog-auto].
Use \\[verilog-auto] to re-insert the updated AUTOs.
@@ -10520,39 +10713,10 @@ called before and after this function, respectively."
(save-excursion
(if (buffer-file-name)
(find-file-noselect (buffer-file-name))) ; To check we have latest version
- (verilog-save-no-change-functions
+ (verilog-save-font-no-change-functions
(verilog-save-scan-cache
- ;; Allow user to customize
- (verilog-run-hooks 'verilog-before-delete-auto-hook)
-
- ;; Remove those that have multi-line insertions, possibly with parameters
- ;; We allow anything beginning with AUTO, so that users can add their own
- ;; patterns
- (verilog-auto-re-search-do
- (concat "/\\*AUTO[A-Za-z0-9_]+"
- ;; Optional parens or quoted parameter or .* for (((...)))
- "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
- "\\*/")
- 'verilog-delete-autos-lined)
- ;; Remove those that are in parenthesis
- (verilog-auto-re-search-do
- (concat "/\\*"
- (eval-when-compile
- (verilog-regexp-words
- `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
- "AUTOSENSE")))
- "\\*/")
- 'verilog-delete-to-paren)
- ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
- (verilog-auto-re-search-do "\\.\\*"
- 'verilog-delete-auto-star-all)
- ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
- (goto-char (point-min))
- (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
- (replace-match ""))
+ (verilog-delete-auto-buffer)))))
- ;; Final customize
- (verilog-run-hooks 'verilog-delete-auto-hook)))))
;;; Auto inject:
;;
@@ -10679,10 +10843,11 @@ Typing \\[verilog-inject-auto] will make this into:
;; Auto diff:
;;
-(defun verilog-diff-buffers-p (b1 b2 &optional whitespace)
+(defun verilog-diff-buffers-p (b1 b2 &optional whitespace regexp)
"Return nil if buffers B1 and B2 have same contents.
Else, return point in B1 that first mismatches.
-If optional WHITESPACE true, ignore whitespace."
+If optional WHITESPACE true, ignore whitespace.
+If optional REGEXP, ignore differences matching it."
(save-excursion
(let* ((case-fold-search nil) ; compare-buffer-substrings cares
(p1 (with-current-buffer b1 (goto-char (point-min))))
@@ -10703,6 +10868,15 @@ If optional WHITESPACE true, ignore whitespace."
(goto-char p2)
(skip-chars-forward " \t\n\r\f\v")
(setq p2 (point))))
+ (when regexp
+ (with-current-buffer b1
+ (goto-char p1)
+ (when (looking-at regexp)
+ (setq p1 (match-end 0))))
+ (with-current-buffer b2
+ (goto-char p2)
+ (when (looking-at regexp)
+ (setq p2 (match-end 0)))))
(setq size (min (- maxp1 p1) (- maxp2 p2)))
(setq progress (compare-buffer-substrings b2 p2 (+ size p2)
b1 p1 (+ size p1)))
@@ -10723,7 +10897,7 @@ Ignores WHITESPACE if t, and writes output to stdout if SHOW."
;; call `diff' as `diff' has different calling semantics on different
;; versions of Emacs.
(if (not (file-exists-p f1))
- (message "Buffer %s has no associated file on disc" (buffer-name b2))
+ (message "Buffer `%s' has no associated file on disk" (buffer-name b2))
(with-temp-buffer "*Verilog-Diff*"
(let ((outbuf (current-buffer))
(f2 (make-temp-file "vm-diff-auto-")))
@@ -10750,9 +10924,9 @@ Ignores WHITESPACE if t, and writes output to stdout if SHOW."
Differences are between buffers B1 and B2, starting at point
DIFFPT. This function is called via `verilog-diff-function'."
(let ((name1 (with-current-buffer b1 (buffer-file-name))))
- (verilog-warn "%s:%d: Difference in AUTO expansion found"
- name1 (with-current-buffer b1
- (count-lines (point-min) diffpt)))
+ (verilog-warn-error "%s:%d: Difference in AUTO expansion found"
+ name1 (with-current-buffer b1
+ (count-lines (point-min) diffpt)))
(cond (noninteractive
(verilog-diff-file-with-buffer name1 b2 t t))
(t
@@ -10791,7 +10965,7 @@ or `diff' in batch mode."
;; Restore name if unwind
(with-current-buffer b1 (setq buffer-file-name name1)))))
;;
- (setq diffpt (verilog-diff-buffers-p b1 b2 t))
+ (setq diffpt (verilog-diff-buffers-p b1 b2 t verilog-diff-ignore-regexp))
(cond ((not diffpt)
(unless noninteractive (message "AUTO expansion identical"))
(kill-buffer newname)) ; Nice to cleanup after oneself
@@ -11054,6 +11228,7 @@ If PAR-VALUES replace final strings with these parameter values."
(vl-name (verilog-sig-name port-st))
(vl-width (verilog-sig-width port-st))
(vl-modport (verilog-sig-modport port-st))
+ (vl-memory (verilog-sig-memory port-st))
(vl-mbits (if (verilog-sig-multidim port-st)
(verilog-sig-multidim-string port-st) ""))
(vl-bits (if (or verilog-auto-inst-vector
@@ -11078,15 +11253,25 @@ If PAR-VALUES replace final strings with these parameter values."
(concat "\\<" (nth 0 (car check-values)) "\\>")
(concat "(" (nth 1 (car check-values)) ")")
t t vl-mbits)
+ vl-memory (when vl-memory
+ (verilog-string-replace-matches
+ (concat "\\<" (nth 0 (car check-values)) "\\>")
+ (concat "(" (nth 1 (car check-values)) ")")
+ t t vl-memory))
check-values (cdr check-values)))
(setq vl-bits (verilog-simplify-range-expression vl-bits)
vl-mbits (verilog-simplify-range-expression vl-mbits)
+ vl-memory (when vl-memory (verilog-simplify-range-expression vl-memory))
vl-width (verilog-make-width-expression vl-bits))) ; Not in the loop for speed
;; Default net value if not found
- (setq dflt-bits (if (and (verilog-sig-bits port-st)
- (or (verilog-sig-multidim port-st)
- (verilog-sig-memory port-st)))
- (concat "/*" vl-mbits vl-bits "*/")
+ (setq dflt-bits (if (or (and (verilog-sig-bits port-st)
+ (verilog-sig-multidim port-st))
+ (verilog-sig-memory port-st))
+ (concat "/*" vl-mbits vl-bits
+ ;; .[ used to separate packed from unpacked
+ (if vl-memory "." "")
+ (if vl-memory vl-memory "")
+ "*/")
(concat vl-bits))
tpl-net (concat port
(if (and vl-modport
@@ -11157,7 +11342,7 @@ If PAR-VALUES replace final strings with these parameter values."
(for-star
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
verilog-auto-inst-column))
- (verilog-insert " // Implicit .\*\n")) ;For some reason the . or * must be escaped...
+ (verilog-insert " // Implicit .*\n"))
(t
(insert "\n")))))
;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
@@ -12958,7 +13143,7 @@ Typing \\[verilog-auto] will make this into:
(verilog-read-signals
(save-excursion
(verilog-re-search-backward-quick
- "\\(@\\|\\<\\(begin\\|if\\|case\\|always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t)
+ "\\(@\\|\\<\\(begin\\|if\\|case[xz]?\\|always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t)
(point))
(point)))))
(save-excursion
@@ -13316,13 +13501,16 @@ Typing \\[verilog-auto] will make this into:
(sig-list-all (verilog-decls-get-iovars moddecls))
;;
(undecode-sig (or (assoc undecode-name sig-list-all)
- (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name)))
+ (error "%s: Signal `%s' not found in design"
+ (verilog-point-text) undecode-name)))
(undecode-enum (or (verilog-sig-enum undecode-sig)
- (error "%s: Signal %s does not have an enum tag" (verilog-point-text) undecode-name)))
+ (error "%s: Signal `%s' does not have an enum tag"
+ (verilog-point-text) undecode-name)))
;;
(enum-sigs (verilog-signals-not-in
(or (verilog-signals-matching-enum sig-list-consts undecode-enum)
- (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum))
+ (error "%s: No state definitions for `%s'"
+ (verilog-point-text) undecode-enum))
nil))
;;
(one-hot (or
@@ -13518,120 +13706,115 @@ Wilson Snyder (wsnyder@wsnyder.org)."
(unless noninteractive (message "Updating AUTOs..."))
(if (fboundp 'dinotrace-unannotate-all)
(dinotrace-unannotate-all))
- (verilog-save-font-mods
+ ;; Disable change hooks for speed
+ ;; This let can't be part of above let; must restore
+ ;; after-change-functions before font-lock resumes
+ (verilog-save-font-no-change-functions
(let ((oldbuf (if (not (buffer-modified-p))
- (buffer-string)))
- (case-fold-search verilog-case-fold)
- ;; Cache directories; we don't write new files, so can't change
- (verilog-dir-cache-preserving t)
- ;; Cache current module
- (verilog-modi-cache-current-enable t)
- (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
- verilog-modi-cache-current)
- (unwind-protect
- ;; Disable change hooks for speed
- ;; This let can't be part of above let; must restore
- ;; after-change-functions before font-lock resumes
- (verilog-save-no-change-functions
- (verilog-save-scan-cache
- (save-excursion
- ;; Wipe cache; otherwise if we AUTOed a block above this one,
- ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
- (setq verilog-modi-cache-list nil)
- ;; Local state
- (verilog-read-auto-template-init)
- ;; If we're not in verilog-mode, change syntax table so parsing works right
- (unless (eq major-mode `verilog-mode) (verilog-mode))
- ;; Allow user to customize
- (verilog-run-hooks 'verilog-before-auto-hook)
- ;; Try to save the user from needing to revert-file to reread file local-variables
- (verilog-auto-reeval-locals)
- (verilog-read-auto-lisp-present)
- (verilog-read-auto-lisp (point-min) (point-max))
- (verilog-getopt-flags)
- ;; From here on out, we can cache anything we read from disk
- (verilog-preserve-dir-cache
- ;; These two may seem obvious to do always, but on large includes it can be way too slow
- (when verilog-auto-read-includes
- (verilog-read-includes)
- (verilog-read-defines nil nil t))
- ;; Setup variables due to SystemVerilog expansion
- (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic-setup)
- ;; This particular ordering is important
- ;; INST: Lower modules correct, no internal dependencies, FIRST
- (verilog-preserve-modi-cache
- ;; Clear existing autos else we'll be screwed by existing ones
- (verilog-delete-auto)
- ;; Injection if appropriate
- (when inject
- (verilog-inject-inst)
- (verilog-inject-sense)
- (verilog-inject-arg))
- ;;
- ;; Do user inserts first, so their code can insert AUTOs
- (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
- 'verilog-auto-insert-lisp)
- ;; Expand instances before need the signals the instances input/output
- (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
- (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
- (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
- ;; Doesn't matter when done, but combine it with a common changer
- (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
- (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
- ;; Must be done before autoin/out as creates a reg
- (verilog-auto-re-search-do "/\\*AUTOASCIIENUM(.*?)\\*/" 'verilog-auto-ascii-enum)
- ;;
- ;; first in/outs from other files
- (verilog-auto-re-search-do "/\\*AUTOINOUTMODPORT(.*?)\\*/" 'verilog-auto-inout-modport)
- (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE(.*?)\\*/" 'verilog-auto-inout-module)
- (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP(.*?)\\*/" 'verilog-auto-inout-comp)
- (verilog-auto-re-search-do "/\\*AUTOINOUTIN(.*?)\\*/" 'verilog-auto-inout-in)
- (verilog-auto-re-search-do "/\\*AUTOINOUTPARAM(.*?)\\*/" 'verilog-auto-inout-param)
- ;; next in/outs which need previous sucked inputs first
- (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((.*?)\\)?\\*/" 'verilog-auto-output)
- (verilog-auto-re-search-do "/\\*AUTOINPUT\\((.*?)\\)?\\*/" 'verilog-auto-input)
- (verilog-auto-re-search-do "/\\*AUTOINOUT\\((.*?)\\)?\\*/" 'verilog-auto-inout)
- ;; Then tie off those in/outs
- (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
- ;; These can be anywhere after AUTOINSERTLISP
- (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((.*?)\\)?\\*/" 'verilog-auto-undef)
- ;; Wires/regs must be after inputs/outputs
- (verilog-auto-re-search-do "/\\*AUTOASSIGNMODPORT(.*?)\\*/" 'verilog-auto-assign-modport)
- (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
- (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
- (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
- (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
- ;; outputevery needs AUTOOUTPUTs done first
- (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\((.*?)\\)?\\*/" 'verilog-auto-output-every)
- ;; After we've created all new variables
- (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
- ;; Must be after all inputs outputs are generated
- (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
- ;; User inserts
- (verilog-auto-re-search-do "/\\*AUTOINSERTLAST(.*?)\\*/" 'verilog-auto-insert-last)
- ;; Fix line numbers (comments only)
- (when verilog-auto-inst-template-numbers
- (verilog-auto-templated-rel))
- (when verilog-auto-template-warn-unused
- (verilog-auto-template-lint))))
- ;;
- (verilog-run-hooks 'verilog-auto-hook)
- ;;
- (when verilog-auto-delete-trailing-whitespace
- (verilog-delete-trailing-whitespace))
- ;;
- (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
- ;;
- ;; If end result is same as when started, clear modified flag
- (cond ((and oldbuf (equal oldbuf (buffer-string)))
- (set-buffer-modified-p nil)
- (unless noninteractive (message "Updating AUTOs...done (no changes)")))
- (t (unless noninteractive (message "Updating AUTOs...done"))))
- ;; End of after-change protection
- )))
- ;; Unwind forms
- ;; Currently handled in verilog-save-font-mods
- ))))
+ (buffer-string)))
+ (case-fold-search verilog-case-fold)
+ ;; Cache directories; we don't write new files, so can't change
+ (verilog-dir-cache-preserving t)
+ ;; Cache current module
+ (verilog-modi-cache-current-enable t)
+ (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
+ verilog-modi-cache-current)
+ (verilog-save-scan-cache
+ (save-excursion
+ ;; Wipe cache; otherwise if we AUTOed a block above this one,
+ ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
+ (setq verilog-modi-cache-list nil)
+ ;; Local state
+ (verilog-read-auto-template-init)
+ ;; If we're not in verilog-mode, change syntax table so parsing works right
+ (unless (eq major-mode `verilog-mode) (verilog-mode))
+ ;; Allow user to customize
+ (verilog-run-hooks 'verilog-before-auto-hook)
+ ;; Try to save the user from needing to revert-file to reread file local-variables
+ (verilog-auto-reeval-locals)
+ (verilog-read-auto-lisp-present)
+ (verilog-read-auto-lisp (point-min) (point-max))
+ (verilog-getopt-flags)
+ ;; From here on out, we can cache anything we read from disk
+ (verilog-preserve-dir-cache
+ ;; These two may seem obvious to do always, but on large includes it can be way too slow
+ (when verilog-auto-read-includes
+ (verilog-read-includes)
+ (verilog-read-defines nil nil t))
+ ;; Setup variables due to SystemVerilog expansion
+ (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic-setup)
+ ;; This particular ordering is important
+ ;; INST: Lower modules correct, no internal dependencies, FIRST
+ (verilog-preserve-modi-cache
+ ;; Clear existing autos else we'll be screwed by existing ones
+ (verilog-delete-auto-buffer)
+ ;; Injection if appropriate
+ (when inject
+ (verilog-inject-inst)
+ (verilog-inject-sense)
+ (verilog-inject-arg))
+ ;;
+ ;; Do user inserts first, so their code can insert AUTOs
+ (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
+ 'verilog-auto-insert-lisp)
+ ;; Expand instances before need the signals the instances input/output
+ (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
+ (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
+ (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
+ ;; Doesn't matter when done, but combine it with a common changer
+ (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
+ (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
+ ;; Must be done before autoin/out as creates a reg
+ (verilog-auto-re-search-do "/\\*AUTOASCIIENUM(.*?)\\*/" 'verilog-auto-ascii-enum)
+ ;;
+ ;; first in/outs from other files
+ (verilog-auto-re-search-do "/\\*AUTOINOUTMODPORT(.*?)\\*/" 'verilog-auto-inout-modport)
+ (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE(.*?)\\*/" 'verilog-auto-inout-module)
+ (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP(.*?)\\*/" 'verilog-auto-inout-comp)
+ (verilog-auto-re-search-do "/\\*AUTOINOUTIN(.*?)\\*/" 'verilog-auto-inout-in)
+ (verilog-auto-re-search-do "/\\*AUTOINOUTPARAM(.*?)\\*/" 'verilog-auto-inout-param)
+ ;; next in/outs which need previous sucked inputs first
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((.*?)\\)?\\*/" 'verilog-auto-output)
+ (verilog-auto-re-search-do "/\\*AUTOINPUT\\((.*?)\\)?\\*/" 'verilog-auto-input)
+ (verilog-auto-re-search-do "/\\*AUTOINOUT\\((.*?)\\)?\\*/" 'verilog-auto-inout)
+ ;; Then tie off those in/outs
+ (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
+ ;; These can be anywhere after AUTOINSERTLISP
+ (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((.*?)\\)?\\*/" 'verilog-auto-undef)
+ ;; Wires/regs must be after inputs/outputs
+ (verilog-auto-re-search-do "/\\*AUTOASSIGNMODPORT(.*?)\\*/" 'verilog-auto-assign-modport)
+ (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
+ (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
+ (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
+ (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
+ ;; outputevery needs AUTOOUTPUTs done first
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\((.*?)\\)?\\*/" 'verilog-auto-output-every)
+ ;; After we've created all new variables
+ (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
+ ;; Must be after all inputs outputs are generated
+ (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
+ ;; User inserts
+ (verilog-auto-re-search-do "/\\*AUTOINSERTLAST(.*?)\\*/" 'verilog-auto-insert-last)
+ ;; Fix line numbers (comments only)
+ (when verilog-auto-inst-template-numbers
+ (verilog-auto-templated-rel))
+ (when verilog-auto-template-warn-unused
+ (verilog-auto-template-lint))))
+ ;;
+ (verilog-run-hooks 'verilog-auto-hook)
+ ;;
+ (when verilog-auto-delete-trailing-whitespace
+ (verilog-delete-trailing-whitespace))
+ ;;
+ (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
+ ;;
+ ;; If end result is same as when started, clear modified flag
+ (cond ((and oldbuf (equal oldbuf (buffer-string)))
+ (verilog-restore-buffer-modified-p nil)
+ (unless noninteractive (message "Updating AUTOs...done (no changes)")))
+ (t (unless noninteractive (message "Updating AUTOs...done"))))
+ ;; End of save-cache
+ )))))
;;; Skeletons:
;;
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index c2ea4546f88..41513340e12 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -1,4 +1,4 @@
-;;; which-func.el --- print current function in mode line
+;;; which-func.el --- print current function in mode line -*- lexical-binding:t -*-
;; Copyright (C) 1994, 1997-1998, 2001-2017 Free Software Foundation,
;; Inc.
@@ -80,7 +80,6 @@
"List of major modes for which Which Function mode should be used.
For other modes it is disabled. If this is equal to t,
then Which Function mode is enabled in any major mode that supports it."
- :group 'which-func
:version "24.3" ; explicit list -> t
:type '(choice (const :tag "All modes" t)
(repeat (symbol :tag "Major mode"))))
@@ -91,13 +90,11 @@ This means that Which Function mode won't really do anything
until you use Imenu, in these modes. Note that files
larger than `which-func-maxout' behave in this way too;
Which Function mode doesn't do anything until you use Imenu."
- :group 'which-func
:type '(repeat (symbol :tag "Major mode")))
(defcustom which-func-maxout 500000
"Don't automatically compute the Imenu menu if buffer is this big or bigger.
Zero means compute the Imenu menu regardless of size."
- :group 'which-func
:type 'integer)
(defvar which-func-keymap
@@ -137,8 +134,7 @@ Zero means compute the Imenu menu regardless of size."
:foreground "Blue1")
(t
:foreground "LightSkyBlue"))
- "Face used to highlight mode line function names."
- :group 'which-func)
+ "Face used to highlight mode line function names.")
(defcustom which-func-format
`("["
@@ -152,7 +148,6 @@ mouse-3: go to end")
"]")
"Format for displaying the function in the mode line."
:version "24.2" ; added mouse-face; 24point2 is correct
- :group 'which-func
:type 'sexp)
;;;###autoload (put 'which-func-format 'risky-local-variable t)
@@ -193,14 +188,16 @@ This makes a difference only if `which-function-mode' is non-nil.")
(add-hook 'find-file-hook 'which-func-ff-hook t)
+(defun which-func-try-to-enable ()
+ (unless (or (not which-function-mode)
+ (local-variable-p 'which-func-mode))
+ (setq which-func-mode (or (eq which-func-modes t)
+ (member major-mode which-func-modes)))))
+
(defun which-func-ff-hook ()
"File find hook for Which Function mode.
It creates the Imenu index for the buffer, if necessary."
- (unless (local-variable-p 'which-func-mode)
- (setq which-func-mode
- (and which-function-mode
- (or (eq which-func-modes t)
- (member major-mode which-func-modes)))))
+ (which-func-try-to-enable)
(condition-case err
(if (and which-func-mode
@@ -239,6 +236,13 @@ It creates the Imenu index for the buffer, if necessary."
(defvar which-func-update-timer nil)
+(unless (or (assq 'which-func-mode mode-line-misc-info)
+ (assq 'which-function-mode mode-line-misc-info))
+ (add-to-list 'mode-line-misc-info
+ '(which-function-mode ;Only display if mode is enabled.
+ (which-func-mode ;Only display if buffer supports it.
+ ("" which-func-format " ")))))
+
;; This is the name people would normally expect.
;;;###autoload
(define-minor-mode which-function-mode
@@ -254,17 +258,12 @@ in certain major modes."
(when (timerp which-func-update-timer)
(cancel-timer which-func-update-timer))
(setq which-func-update-timer nil)
- (if which-function-mode
- ;;Turn it on
- (progn
- (setq which-func-update-timer
- (run-with-idle-timer idle-update-delay t #'which-func-update))
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (unless (local-variable-p 'which-func-mode)
- (setq which-func-mode
- (or (eq which-func-modes t)
- (member major-mode which-func-modes)))))))))
+ (when which-function-mode
+ ;;Turn it on.
+ (setq which-func-update-timer
+ (run-with-idle-timer idle-update-delay t #'which-func-update))
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf (which-func-try-to-enable)))))
(defvar which-function-imenu-failed nil
"Locally t in a buffer if `imenu--make-index-alist' found nothing there.")