;;; cc-mode.el --- major mode for editing C and similar languages
-;; Copyright (C) 1985, 1987, 1992-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2016 Free Software Foundation, Inc.
;; Authors: 2003- Alan Mackenzie
;; 1998- Martin Stjernholm
(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1
-;; We set these variables during mode init, yet we don't require
+;; We set this variable during mode init, yet we don't require
;; font-lock.
(cc-bytecomp-defvar font-lock-defaults)
-(cc-bytecomp-defvar font-lock-syntactic-keywords)
;; Menu support for both XEmacs and Emacs. If you don't have easymenu
;; with your version of Emacs, you are incompatible!
and the line breaking/filling code. Intended to be used by other
packages that embed CC Mode.
-MODE is the CC Mode flavor to set up, e.g. 'c-mode or 'java-mode.
+MODE is the CC Mode flavor to set up, e.g. `c-mode' or `java-mode'.
DEFAULT-STYLE tells which indentation style to install. It has the
same format as `c-default-style'.
(set (make-local-variable 'comment-line-break-function)
'c-indent-new-comment-line)
+ ;; Prevent time-wasting activity on C-y.
+ (when (boundp 'yank-handled-properties)
+ (make-local-variable 'yank-handled-properties)
+ (let ((yank-cat-handler (assq 'category yank-handled-properties)))
+ (when yank-cat-handler
+ (setq yank-handled-properties (remq yank-cat-handler
+ yank-handled-properties)))))
+
;; For the benefit of adaptive file, which otherwise mis-fills.
(setq fill-paragraph-handle-comment nil)
(font-lock-mode 1)))
;; Buffer local variables defining the region to be fontified by a font lock
-;; after-change function. They are set in c-after-change to
-;; after-change-functions' BEG and END, and may be modified by functions in
+;; after-change function. They are initialized in c-before-change to
+;; before-change-functions' BEG and END. `c-new-END' is amended in
+;; c-after-change with after-change-functions' BEG, END, and OLD-LEN. These
+;; variables may be modified by any before/after-change function, in
+;; particular by functions in `c-get-state-before-change-functions' and
;; `c-before-font-lock-functions'.
(defvar c-new-BEG 0)
(make-variable-buffer-local 'c-new-BEG)
customary in CC Mode modes but which aren't strictly necessary for CC
Mode to operate correctly.
-MODE is the symbol for the mode to initialize, like 'c-mode. See
+MODE is the symbol for the mode to initialize, like `c-mode'. See
`c-basic-common-init' for details. It's only optional to be
compatible with old code; callers should always specify it."
(setq c-new-BEG (point-min))
(setq c-new-END (point-max))
(save-excursion
- (mapc (lambda (fn)
- (funcall fn (point-min) (point-max)))
- c-get-state-before-change-functions)
- (mapc (lambda (fn)
- (funcall fn (point-min) (point-max)
- (- (point-max) (point-min))))
- c-before-font-lock-functions)))
+ (let (before-change-functions after-change-functions)
+ (mapc (lambda (fn)
+ (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)))))
+ c-before-font-lock-functions))))
(set (make-local-variable 'outline-regexp) "[^#\n\^M]")
(set (make-local-variable 'outline-level) 'c-outline-level)
(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
+ ;; function must be called directly from a member of one of the above hooks.
+ ;;
+ ;; In the following call, frame 0 is `backtrace-frame', frame 1 is
+ ;; `c-called-from-text-property-change-p', frame 2 is
+ ;; `c-before/after-change', frame 3 is the primitive invoking the change
+ ;; hook.
+ (memq (cadr (backtrace-frame 3))
+ '(put-text-property remove-list-of-text-properties)))
+
(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.
(unless
(or (save-excursion
(goto-char (match-beginning 0))
- (c-beginning-of-macro))
+ (let ((here (point)))
+ (and (save-match-data (c-beginning-of-macro))
+ (< (point) here))))
(progn
(setq pps-state
(parse-partial-sexp pps-position (point) nil nil pps-state)
;; it/them from the cache. Don't worry about being inside a string
;; or a comment - "wrongly" removing a symbol from `c-found-types'
;; isn't critical.
- (unless c-just-done-before-change ; Guard against a spurious second
- ; invocation of before-change-functions.
+ (unless (or (c-called-from-text-property-change-p)
+ c-just-done-before-change) ; guard against a spurious second
+ ; invocation of before-change-functions.
(setq c-just-done-before-change t)
+ ;; (c-new-BEG c-new-END) will be the region to fontify.
+ (setq c-new-BEG beg c-new-END end)
(setq c-maybe-stale-found-type nil)
(save-restriction
(save-match-data
(buffer-substring-no-properties beg end)))))))
(if c-get-state-before-change-functions
- (let (open-paren-in-column-0-is-defun-start)
- (mapc (lambda (fn)
- (funcall fn beg end))
- c-get-state-before-change-functions)))
+ (mapc (lambda (fn)
+ (funcall fn beg end))
+ c-get-state-before-change-functions))
)))
;; The following must be done here rather than in `c-after-change' because
;; newly inserted parens would foul up the invalidation algorithm.
;; This calls the language variable c-before-font-lock-functions, if non nil.
;; This typically sets `syntax-table' properties.
- (setq c-just-done-before-change nil)
- (c-save-buffer-state (case-fold-search open-paren-in-column-0-is-defun-start)
- ;; When `combine-after-change-calls' is used we might get calls
- ;; with regions outside the current narrowing. This has been
- ;; observed in Emacs 20.7.
- (save-restriction
- (save-match-data ; c-recognize-<>-arglists changes match-data
- (widen)
-
- (when (> end (point-max))
- ;; Some emacsen might return positions past the end. This has been
- ;; observed in Emacs 20.7 when rereading a buffer changed on disk
- ;; (haven't been able to minimize it, but Emacs 21.3 appears to
- ;; work).
- (setq end (point-max))
- (when (> beg end)
- (setq beg end)))
-
- ;; C-y is capable of spuriously converting category properties
- ;; c-</>-as-paren-syntax and c-cpp-delimiter into hard syntax-table
- ;; properties. Remove these when it happens.
- (when (eval-when-compile (memq 'category-properties c-emacs-features))
- (c-clear-char-property-with-value beg end 'syntax-table
- c-<-as-paren-syntax)
- (c-clear-char-property-with-value beg end 'syntax-table
- c->-as-paren-syntax)
- (c-clear-char-property-with-value beg end 'syntax-table nil))
-
- (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
- (c-invalidate-sws-region-after beg end)
- ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
- (c-invalidate-find-decl-cache beg)
-
- (when c-recognize-<>-arglists
- (c-after-change-check-<>-operators beg end))
-
- ;; (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-in-after-change-fontification t)
- (save-excursion
- (mapc (lambda (fn)
- (funcall fn beg end old-len))
- c-before-font-lock-functions))))))
+ ;; (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))
+
+ (unless (c-called-from-text-property-change-p)
+ (setq c-just-done-before-change nil)
+ (c-save-buffer-state (case-fold-search)
+ ;; When `combine-after-change-calls' is used we might get calls
+ ;; with regions outside the current narrowing. This has been
+ ;; observed in Emacs 20.7.
+ (save-restriction
+ (save-match-data ; c-recognize-<>-arglists changes match-data
+ (widen)
+
+ (when (> end (point-max))
+ ;; Some emacsen might return positions past the end. This has been
+ ;; observed in Emacs 20.7 when rereading a buffer changed on disk
+ ;; (haven't been able to minimize it, but Emacs 21.3 appears to
+ ;; work).
+ (setq end (point-max))
+ (when (> beg end)
+ (setq beg end)))
+
+ ;; C-y is capable of spuriously converting category properties
+ ;; c-</>-as-paren-syntax and c-cpp-delimiter into hard syntax-table
+ ;; properties. Remove these when it happens.
+ (when (eval-when-compile (memq 'category-properties c-emacs-features))
+ (c-save-buffer-state ()
+ (c-clear-char-property-with-value beg end 'syntax-table
+ c-<-as-paren-syntax)
+ (c-clear-char-property-with-value beg end 'syntax-table
+ c->-as-paren-syntax)
+ (c-clear-char-property-with-value beg end 'syntax-table nil)))
+
+ (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
+ (c-invalidate-sws-region-after beg end)
+ ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
+ (c-invalidate-find-decl-cache beg)
+
+ (when c-recognize-<>-arglists
+ (c-after-change-check-<>-operators beg end))
+
+ (setq c-in-after-change-fontification t)
+ (save-excursion
+ (mapc (lambda (fn)
+ (funcall fn beg end old-len))
+ c-before-font-lock-functions)))))))
(defun c-fl-decl-start (pos)
;; If the beginning of the line containing POS is in the middle of a "local"
;; Go to a less nested declaration each time round this loop.
(and
(eq (car (c-beginning-of-decl-1 bod-lim)) 'same)
+ (> (point) bod-lim)
(progn (setq bo-decl (point))
;; Are we looking at a keyword such as "template" or
;; "typedef" which can decorate a type, or the type itself?
(save-restriction
(widen)
(save-excursion
- (let ((new-beg beg) (new-end end) new-region)
+ (let ((new-beg beg) (new-end end)
+ (new-region (cons beg end)))
(mapc (lambda (fn)
(setq new-region (funcall fn new-beg new-end))
(setq new-beg (car new-region) new-end (cdr new-region)))
;;
;;
;; void myfunc(T* p) {}
- ;;
+ ;;
;; Type a space in the first blank line, and the fontification of the next
;; line was fouled up by context fontification.
- (let (new-beg new-end new-region case-fold-search
- open-paren-in-column-0-is-defun-start)
+ (let (new-beg new-end new-region case-fold-search)
(if (and c-in-after-change-fontification
(< beg c-new-END) (> end c-new-BEG))
;; Region and the latest after-change fontification region overlap.
(defun c-after-font-lock-init ()
;; Put on `font-lock-mode-hook'. This function ensures our after-change
;; function will get executed before the font-lock one.
- (remove-hook 'after-change-functions 'c-after-change t)
- (add-hook 'after-change-functions 'c-after-change nil t))
+ (when (memq #'c-after-change after-change-functions)
+ (remove-hook 'after-change-functions #'c-after-change t)
+ (add-hook 'after-change-functions #'c-after-change nil t)))
(defun c-font-lock-init ()
"Set up the font-lock variables for using the font-lock support in CC Mode.
(font-lock-mark-block-function
. c-mark-function)))
+ ;; Prevent `font-lock-default-fontify-region' extending the region it will
+ ;; fontify to whole lines by removing `font-lock-extend-region-wholelines'
+ ;; from `font-lock-extend-region-functions'. (Emacs only). This fixes
+ ;; Emacs bug #19669.
+ (when (boundp 'font-lock-extend-region-functions)
+ (setq font-lock-extend-region-functions
+ (delq 'font-lock-extend-region-wholelines
+ font-lock-extend-region-functions)))
+
(make-local-variable 'font-lock-fontify-region-function)
(setq font-lock-fontify-region-function 'c-font-lock-fontify-region)
(add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
;; Emacs 22 and later.
-(defun c-extend-after-change-region (_beg _end _old-len)
+(defun c-extend-after-change-region (beg end _old-len)
"Extend the region to be fontified, if necessary."
;; Note: the parameter OLD-LEN is ignored here. This somewhat indirect
;; implementation exists because it is minimally different from the
(when (eq font-lock-support-mode 'jit-lock-mode)
(save-restriction
(widen)
- (if (< c-new-BEG beg)
- (put-text-property c-new-BEG beg 'fontified nil))
- (if (> c-new-END end)
- (put-text-property end c-new-END 'fontified nil))))
+ (c-save-buffer-state () ; Protect the undo-list from put-text-property.
+ (if (< c-new-BEG beg)
+ (put-text-property c-new-BEG beg 'fontified nil))
+ (if (> c-new-END end)
+ (put-text-property end c-new-END 'fontified nil)))))
(cons c-new-BEG c-new-END))
;; Emacs < 22 and XEmacs
;;;###autoload
(define-derived-mode c-mode prog-mode "C"
- "Major mode for editing K&R and ANSI C code.
+ "Major mode for editing C code.
+
To submit a problem report, enter `\\[c-submit-bug-report]' from a
c-mode buffer. This automatically sets up a mail buffer with version
information already added. You just need to add a description of the
;; bug reporting
(defconst c-mode-help-address
- "bug-cc-mode@gnu.org"
+ "submit@debbugs.gnu.org"
"Address(es) for CC Mode bug reports.")
(defun c-version ()
(defvar reporter-prompt-for-summary-p)
(defvar reporter-dont-compact-list)
+;; This could be "emacs,cc-mode" in the version included in Emacs.
+(defconst c-mode-bug-package "cc-mode"
+ "The package to use in the bug submission.")
+
+;; reporter-submit-bug-report requires sendmail.
+(declare-function mail-position-on-field "sendmail" (field &optional soft))
+
(defun c-submit-bug-report ()
"Submit via mail a bug report on CC Mode."
(interactive)
vars)
(lambda ()
(run-hooks 'c-prepare-bug-report-hook)
+ (save-excursion
+ (or (mail-position-on-field "X-Debbugs-Package")
+ (insert c-mode-bug-package)))
(insert (format "Buffer Style: %s\nc-emacs-features: %s\n"
style c-features)))))))
\f
(cc-provide 'cc-mode)
-;;; Local Variables:
-;;; indent-tabs-mode: t
-;;; tab-width: 8
-;;; End:
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
;;; cc-mode.el ends here