;;; cc-mode.el --- major mode for editing C and similar languages
;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
;; Free Software Foundation, Inc.
;; Authors: 2003- Alan Mackenzie
;; 1998- Martin Stjernholm
;; 1992-1999 Barry A. Warsaw
-;; 1987 Dave Detlefs and Stewart Clamen
+;; 1987 Dave Detlefs
+;; 1987 Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: bug-cc-mode@gnu.org
;; Created: a long, long, time ago. adapted from the original c-mode.el
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program; see the file COPYING. If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
+;; For Emacs < 22.2.
+(eval-and-compile
+ (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
(eval-when-compile
(let ((load-path
(if (and (boundp 'byte-compile-dest-file)
;; Autoload directive for emacsen that doesn't have an older CC Mode
;; version in the dist.
-(autoload 'c-subword-mode "cc-subword"
+(autoload 'subword-mode "subword"
"Mode enabling subword movement and editing keys." t)
;; Load cc-fonts first after font-lock is loaded, since it isn't
;; function is called from top-level forms that are evaluated
;; while cc-bytecomp is active when one does M-x eval-buffer.
(cond
- ;; XEmacs
- ((cc-bytecomp-fboundp 'set-keymap-parents)
- (set-keymap-parents map c-mode-base-map))
;; Emacs
((cc-bytecomp-fboundp 'set-keymap-parent)
(set-keymap-parent map c-mode-base-map))
+ ;; XEmacs
+ ((cc-bytecomp-fboundp 'set-keymap-parents)
+ (set-keymap-parents map c-mode-base-map))
;; incompatible
(t (error "CC Mode is incompatible with this version of Emacs")))
map))
;; RMS says don't make these the default.
;; (April 2006): RMS has now approved these commands as defaults.
- (define-key c-mode-base-map "\e\C-a" 'c-beginning-of-defun)
- (define-key c-mode-base-map "\e\C-e" 'c-end-of-defun)
+ (unless (memq 'argumentative-bod-function c-emacs-features)
+ (define-key c-mode-base-map "\e\C-a" 'c-beginning-of-defun)
+ (define-key c-mode-base-map "\e\C-e" 'c-end-of-defun))
(define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional)
(define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional)
;; conflicts with OOBR
;;(define-key c-mode-base-map "\C-c\C-v" 'c-version)
;; (define-key c-mode-base-map "\C-c\C-y" 'c-toggle-hungry-state) Commented out by ACM, 2005-11-22.
- (define-key c-mode-base-map "\C-c\C-w" 'c-subword-mode)
+ (define-key c-mode-base-map "\C-c\C-w" 'subword-mode)
)
;; We don't require the outline package, but we configure it a bit anyway.
(make-local-variable 'lookup-syntax-properties)
(setq lookup-syntax-properties t)))
- ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky
+ ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
;; property on each character.
(when (boundp 'text-property-default-nonsticky)
(make-local-variable 'text-property-default-nonsticky)
- (let ((elem (assq 'syntax-table text-property-default-nonsticky)))
- (if elem
- (setcdr elem t)
- (setq text-property-default-nonsticky
- (cons '(syntax-table . t)
- text-property-default-nonsticky))))
- (setq text-property-default-nonsticky
- (cons '(c-type . t)
- text-property-default-nonsticky)))
+ (mapc (lambda (tprop)
+ (unless (assq tprop text-property-default-nonsticky)
+ (setq text-property-default-nonsticky
+ (cons `(,tprop . t) text-property-default-nonsticky))))
+ '(syntax-table category c-type)))
;; In Emacs 21 and later it's possible to turn off the ad-hoc
;; heuristic that open parens in column 0 are defun starters. Since
(make-local-hook 'after-change-functions)
(add-hook 'after-change-functions 'c-after-change nil t)
(set (make-local-variable 'font-lock-extend-after-change-region-function)
- 'c-extend-after-change-region)) ; Currently (2008-04), only used by AWK.
+ 'c-extend-after-change-region)) ; Currently (2009-05) used by all
+ ; lanaguages with #define (C, C++,; ObjC), and by AWK.
(defun c-setup-doc-comment-style ()
"Initialize the variables that depend on the value of `c-doc-comment-style'."
(and (cdr rfn)
(setq require-final-newline mode-require-final-newline)))))
+(defun c-before-hack-hook ()
+ "Set the CC Mode style and \"offsets\" when in the buffer's local variables.
+They are set only when, respectively, the pseudo variables
+`c-file-style' and `c-file-offsets' are present in the list.
+
+This function is called from the hook `before-hack-local-variables-hook'."
+ (when c-buffer-is-cc-mode
+ (let ((mode-cons (assq 'mode file-local-variables-alist))
+ (stile (cdr (assq 'c-file-style file-local-variables-alist)))
+ (offsets (cdr (assq 'c-file-offsets file-local-variables-alist))))
+ (when mode-cons
+ (hack-one-local-variable (car mode-cons) (cdr mode-cons))
+ (setq file-local-variables-alist
+ (delq mode-cons file-local-variables-alist)))
+ (when stile
+ (or (stringp stile) (error "c-file-style is not a string"))
+ (c-set-style stile))
+ (when offsets
+ (mapc
+ (lambda (langentry)
+ (let ((langelem (car langentry))
+ (offset (cdr langentry)))
+ (c-set-offset langelem offset)))
+ offsets)))))
+
(defun c-remove-any-local-eval-or-mode-variables ()
;; If the buffer specifies `mode' or `eval' in its File Local Variable list
;; or on the first line, remove all occurrences. See
(when c-buffer-is-cc-mode
(if (or c-file-style c-file-offsets)
(c-make-styles-buffer-local t))
- (and c-file-style
- (c-set-style c-file-style))
+ (when c-file-style
+ (or (stringp c-file-style)
+ (error "c-file-style is not a string"))
+ (c-set-style c-file-style))
+
(and c-file-offsets
(mapc
(lambda (langentry)
(hack-local-variables))
nil))))
-(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
+(if (boundp 'before-hack-local-variables-hook)
+ (add-hook 'before-hack-local-variables-hook 'c-before-hack-hook)
+ (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
(defmacro c-run-mode-hooks (&rest hooks)
;; Emacs 21.1 has introduced a system with delayed mode hooks that
(setq c-old-EOM (point)))
(defun c-neutralize-CPP-line (beg end)
- ;; BEG and END bound a preprocessor line. Put a "punctuation" syntax-table
- ;; property on syntactically obtrusive characters, ones which would interact
- ;; syntactically with stuff outside the CPP line.
+ ;; BEG and END bound a region, typically a preprocessor line. Put a
+ ;; "punctuation" syntax-table property on syntactically obtrusive
+ ;; characters, ones which would interact syntactically with stuff outside
+ ;; this region.
;;
;; These are unmatched string delimiters, or unmatched
;; parens/brackets/braces. An unclosed comment is regarded as valid, NOT
;; obtrusive.
- (let (s)
- (while
- (progn
- (setq s (parse-partial-sexp beg end -1))
- (cond
- ((< (nth 0 s) 0) ; found an unmated ),},]
- (c-put-char-property (1- (point)) 'syntax-table '(1))
- t)
- ((nth 3 s) ; In a string
- (c-put-char-property (nth 8 s) 'syntax-table '(1))
- t)
- ((> (nth 0 s) 0) ; In a (,{,[
- (c-put-char-property (nth 1 s) 'syntax-table '(1))
- t)
- (t nil))))))
-
-(defun c-neutralize-syntax-in-CPP (begg endd old-len)
- ;; "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; these can be located from the Buffer local variables
- ;; c-old-[EB]OM.
+ (save-excursion
+ (let (s)
+ (while
+ (progn
+ (setq s (parse-partial-sexp beg end -1))
+ (cond
+ ((< (nth 0 s) 0) ; found an unmated ),},]
+ (c-put-char-property (1- (point)) 'syntax-table '(1))
+ t)
+ ((nth 3 s) ; In a string
+ (c-put-char-property (nth 8 s) 'syntax-table '(1))
+ t)
+ ((> (nth 0 s) 0) ; In a (,{,[
+ (c-put-char-property (nth 1 s) 'syntax-table '(1))
+ t)
+ (t nil)))))))
+
+(defun c-extend-and-neutralize-syntax-in-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'.
;;
;; That is, set syntax-table properties on characters that would otherwise
;; interact syntactically with those outside the CPP line(s).
;;
;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
;;
- ;; This function might do invisible changes.
- (c-save-buffer-state (limits mbeg+1 beg end)
- ;; First calculate the region, possibly to be extended.
- (setq beg (min begg c-old-BOM))
+ ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
+ ;;
+ ;; This function might make hidden buffer changes.
+ (c-save-buffer-state (limits mbeg+1)
+ ;; 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.
+ (goto-char c-old-BOM) ; already set to old start of macro or begg.
+ (setq c-new-BEG
+ (if (setq limits (c-literal-limits))
+ (cdr limits) ; go forward out of any string or comment.
+ (point)))
+
(goto-char endd)
- (when (c-beginning-of-macro)
- (c-end-of-macro))
- (setq end (max (+ (- c-old-EOM old-len) (- endd begg))
+ (if (setq limits (c-literal-limits))
+ (goto-char (car limits))) ; go backward out of any string or comment.
+ (if (c-beginning-of-macro)
+ (c-end-of-macro))
+ (setq c-new-END (max (+ (- c-old-EOM old-len) (- endd begg))
(point)))
- ;; Clear all old punctuation properties
- (c-clear-char-property-with-value beg end 'syntax-table '(1))
-
- (goto-char beg)
- (while (and (< (point) end)
- (search-forward-regexp c-anchored-cpp-prefix end t))
- ;; If we've found a "#" inside a string/comment, ignore it.
- (if (setq limits (c-literal-limits))
- (goto-char (cdr limits))
- (setq mbeg+1 (point))
- (c-end-of-macro) ; Do we need to go forward 1 char here? No!
- (c-neutralize-CPP-line mbeg+1 (point))))))
+
+ ;; Clear any existing punctuation properties.
+ (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
+
+ ;; Add needed properties to each CPP construct in the region.
+ (goto-char c-new-BEG)
+ (let ((pps-position c-new-BEG) pps-state)
+ (while (and (< (point) c-new-END)
+ (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
+ ;; If we've found a "#" inside a string/comment, ignore it.
+ (setq pps-state
+ (parse-partial-sexp pps-position (point) nil nil pps-state)
+ pps-position (point))
+ (unless (or (nth 3 pps-state) ; in a string?
+ (nth 4 pps-state)) ; in a comment?
+ (setq mbeg+1 (point))
+ (c-end-of-macro) ; Do we need to go forward 1 char here? No!
+ (c-neutralize-CPP-line mbeg+1 (point))
+ (setq pps-position (point))))))) ; no need to update pps-state.
(defun c-before-change (beg end)
;; Function to be put on `before-change-function'. Primarily, this calls
(buffer-substring-no-properties type-pos term-pos)
(buffer-substring-no-properties 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)
(if c-get-state-before-change-function
nil nil
,c-identifier-syntax-modifications
c-beginning-of-syntax
- (font-lock-lines-before . 1)
(font-lock-mark-block-function
. c-mark-function)))
;; font-lock-extend-after-change-region-function, is forced to use advice
;; instead.
;;
- ;; Of the seven CC Mode languages, currently (2008-04) only AWK Mode makes
- ;; non-null use of this function.
+ ;; Of the seven CC Mode languages, currently (2009-05) only C, C++, Objc
+ ;; (the languages with #define) and AWK Mode make non-null use of this
+ ;; function.
(cons c-new-BEG c-new-END))
\f
;; which could cause it to clobber user settings. Later emacsen have
;; an append option, but it's not safe to use.
-;; The the extension ".C" is associated to C++ while the lowercase
-;; variant goes to C. On case insensitive file systems, this means
+;; The extension ".C" is associated with C++ while the lowercase
+;; variant goes with C. On case insensitive file systems, this means
;; that ".c" files also might open C++ mode if the C++ entry comes
;; first on `auto-mode-alist'. Thus we try to ensure that ".C" comes
;; after ".c", and since `add-to-list' adds the entry first we have to
;;;###autoload (add-to-list 'auto-mode-alist '("\\.y\\(acc\\)?\\'" . c-mode))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.lex\\'" . c-mode))
+;; Preprocessed files generated by C and C++ compilers.
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.i\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.ii\\'" . c++-mode))
+
+
;;;###autoload
(defun c-mode ()
"Major mode for editing K&R and ANSI C code.
(easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands"
(cons "AWK" (c-lang-const c-mode-menu awk)))
+;; (require 'cc-awk) brings these in.
+(defvar awk-mode-syntax-table)
+(declare-function c-awk-unstick-NL-prop "cc-awk" ())
+
(defun awk-mode ()
"Major mode for editing AWK code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an