X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/48395495d6f6602f666c11d0b38f6600b629ccfc..a1f221bd82eb4393ccba83a361b435a4992b532a:/lisp/progmodes/cc-mode.el diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index d88fe702c5..738870b727 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1,6 +1,6 @@ ;;; 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 @@ -99,10 +99,9 @@ (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! @@ -479,7 +478,7 @@ preferably use the `c-mode-menu' language constant directly." 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'. @@ -511,6 +510,14 @@ that requires a literal mode spec at compile time." (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) @@ -624,8 +631,11 @@ that requires a literal mode spec at compile time." (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) @@ -639,7 +649,7 @@ In addition to the work done by `c-basic-common-init' and 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." @@ -659,13 +669,15 @@ 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) @@ -838,6 +850,18 @@ Note that the style variables are always made local to the buffer." (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. @@ -972,7 +996,9 @@ Note that the style variables are always made local to the buffer." (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) @@ -1006,9 +1032,12 @@ Note that the style variables are always made local to the buffer." ;; 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 @@ -1074,10 +1103,9 @@ Note that the style variables are always made local to the buffer." (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. @@ -1102,51 +1130,54 @@ 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. - (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" @@ -1170,6 +1201,7 @@ Note that the style variables are always made local to the buffer." ;; 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? @@ -1220,7 +1252,8 @@ Note that the style variables are always made local to the buffer." (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))) @@ -1238,11 +1271,10 @@ Note that the style variables are always made local to the buffer." ;; ;; ;; 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. @@ -1280,8 +1312,9 @@ Note that the style variables are always made local to the buffer." (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. @@ -1303,12 +1336,13 @@ This function is called from `c-common-init', once per mode initialization." . c-mark-function))) ;; Prevent `font-lock-default-fontify-region' extending the region it will - ;; fontify to whole lines by removing `font-lock-extend-region-whole-lines' - ;; (and, coincidentally, `font-lock-extend-region-multiline' (which we do - ;; not need)) from `font-lock-extend-region-functions'. (Emacs only). This - ;; fixes Emacs bug #19669. + ;; 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 nil)) + (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) @@ -1318,7 +1352,7 @@ This function is called from `c-common-init', once per mode initialization." (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 @@ -1332,10 +1366,11 @@ This function is called from `c-common-init', once per mode initialization." (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 @@ -1427,7 +1462,8 @@ This function is called from `c-common-init', once per mode initialization." ;;;###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 @@ -1795,7 +1831,7 @@ Key bindings: ;; 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 () @@ -1812,6 +1848,13 @@ Key bindings: (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) @@ -1875,14 +1918,17 @@ Key bindings: 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))))))) (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