Source

cc-mode / cc-langs.el

Diff from to

cc-langs.el

 ;;; cc-langs.el --- specific language support for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2000 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    2000- Martin Stjernholm
+;;	       1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+(eval-when-compile
+  (let ((load-path
+	 (if (and (boundp 'byte-compile-current-file)
+		  (stringp byte-compile-current-file))
+	     (cons (file-name-directory byte-compile-current-file)
+		   load-path)
+	   load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-styles)
+
+;; Pull in some other packages.
+(eval-when-compile
+  (condition-case nil
+      ;; Not required and only needed during compilation to shut up
+      ;; the compiler.
+      (require 'outline)
+    (error nil)))
+;; menu support for both XEmacs and Emacs.  If you don't have easymenu
+;; with your version of Emacs, you are incompatible!
+(require 'easymenu)
 
 
-(eval-when-compile
-  (require 'cc-defs))
+(defvar c-buffer-is-cc-mode nil
+  "Non-nil for all buffers with a `major-mode' derived from CC Mode.
+Otherwise, this variable is nil. I.e. this variable is non-nil for
+`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode',
+`pike-mode', and any other non-CC Mode mode that calls
+`c-initialize-cc-mode' (e.g. `awk-mode').")
+(make-variable-buffer-local 'c-buffer-is-cc-mode)
+(put 'c-buffer-is-cc-mode 'permanent-local t)
 
+
 ;; Regular expressions and other values which must be parameterized on
 ;; a per-language basis.
 
 ;; keywords introducing class definitions.  language specific
 (defconst c-C-class-key "\\(struct\\|union\\)")
 (defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
-(defconst c-IDL-class-key "\\(class\\|struct\\|union\\|interface\\)")
+(defconst c-IDL-class-key "\\(interface\\|struct\\|union\\|valuetype\\)")
 (defconst c-C-extra-toplevel-key "\\(extern\\)")
 (defconst c-C++-extra-toplevel-key "\\(extern\\|namespace\\)")
 (defconst c-IDL-extra-toplevel-key "\\(module\\)")
 (defvar c-extra-toplevel-key c-C-extra-toplevel-key)
 (make-variable-buffer-local 'c-extra-toplevel-key)
 
+;; Keywords that can introduce bitfields in the languages that supports that.
+(defconst c-C-bitfield-key "\\(char\\|int\\|long\\|signed\\|unsigned\\)")
+
+(defvar c-bitfield-key nil)
+(make-variable-buffer-local 'c-bitfield-key)
+
 
 ;; regexp describing access protection clauses.  language specific
 (defvar c-access-key nil)
 (make-variable-buffer-local 'c-access-key)
 (defconst c-C++-access-key (concat c-protection-key "[ \t]*:"))
+(defconst c-IDL-access-key nil)
 (defconst c-ObjC-access-key (concat "@" c-protection-key))
 (defconst c-Java-access-key nil)
 (defconst c-Pike-access-key nil)
 ;; keywords introducing conditional blocks
 (defconst c-C-conditional-key nil)
 (defconst c-C++-conditional-key nil)
+(defconst c-IDL-conditional-key nil)
+(defconst c-ObjC-conditional-key nil)
 (defconst c-Java-conditional-key nil)
 (defconst c-Pike-conditional-key nil)
 
       (back    "\\)\\b[^_]"))
   (setq c-C-conditional-key (concat front all-kws back)
 	c-C++-conditional-key (concat front all-kws exc-kws back)
+	;; c-IDL-conditional-key is nil.
+	c-ObjC-conditional-key c-C-conditional-key
 	c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)
 	c-Pike-conditional-key (concat front all-kws "\\|foreach" back)))
 
 
 ;; comment starter definitions for various languages.  language specific
 (defconst c-C++-comment-start-regexp "/[/*]")
+(defconst c-C-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-IDL-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-ObjC-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-Pike-comment-start-regexp c-C++-comment-start-regexp)
 ;; We need to match all 3 Java style comments
 ;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
 (defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)")
 (defconst c-Java-defun-prompt-regexp
   "^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*")
 
-;; Regexp describing Javadoc markup that always starts paragraphs.
+;; Regexp describing regexp to append to paragraph-start
+(defvar c-append-paragraph-start "$")
+(make-variable-buffer-local 'c-append-paragraph-start)
 (defconst c-Java-javadoc-paragraph-start
-  "@\\(author\\|exception\\|param\\|return\\|see\\|version\\)")
+  (concat "\\("
+	  "@\\(author\\|deprecated\\|exception\\|param\\|return\\|"
+	  "s\\(e\\(e\\|rial\\(\\|Data\\|Field\\)\\)\\|ince\\)\\|"
+	  "throws\\|version\\)"
+	  "\\|$\\)"))
 
 ;; Regexp that starts lambda constructs.
 (defvar c-lambda-key nil)
 (defvar c-inexpr-class-key nil)
 (make-variable-buffer-local 'c-inexpr-class-key)
 (defconst c-Java-inexpr-class-key "\\<new\\>")
+(defconst c-Pike-inexpr-class-key "\\<class\\>")
 
 ;; List of open- and close-chars that makes up a pike-style brace
 ;; list, ie for a `([�])' list there should be a cons (?\[ . ?\]) in
   ;; Common initializations for all modes.
   ;; these variables should always be buffer local; they do not affect
   ;; indentation style.
-  (make-local-variable 'paragraph-start)
-  (make-local-variable 'paragraph-separate)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
   (make-local-variable 'require-final-newline)
   (make-local-variable 'parse-sexp-ignore-comments)
   (make-local-variable 'indent-line-function)
   (make-local-variable 'indent-region-function)
+  (make-local-variable 'outline-regexp)
+  (make-local-variable 'outline-level)
+  (make-local-variable 'normal-auto-fill-function)
   (make-local-variable 'comment-start)
   (make-local-variable 'comment-end)
   (make-local-variable 'comment-column)
   (make-local-variable 'comment-start-skip)
   (make-local-variable 'comment-multi-line)
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-ignore-fill-prefix)
+  (make-local-variable 'adaptive-fill-mode)
   (make-local-variable 'adaptive-fill-regexp)
-  (make-local-variable 'adaptive-fill-mode)
   (make-local-variable 'imenu-generic-expression) ;set in the mode functions
   ;; X/Emacs 20 only
   (and (boundp 'comment-line-break-function)
-       (make-local-variable 'comment-line-break-function))
-  ;; Emacs 19.30 and beyond only, AFAIK
-  (if (boundp 'fill-paragraph-function)
-      (progn
-	(make-local-variable 'fill-paragraph-function)
-	(setq fill-paragraph-function 'c-fill-paragraph)))
+       (progn
+	 (make-local-variable 'comment-line-break-function)
+	 (setq comment-line-break-function
+	       'c-indent-new-comment-line)))
   ;; now set their values
-  (setq paragraph-start (concat page-delimiter "\\|$")
-	paragraph-separate paragraph-start
-	paragraph-ignore-fill-prefix t
-	require-final-newline t
+  (setq require-final-newline t
 	parse-sexp-ignore-comments t
 	indent-line-function 'c-indent-line
 	indent-region-function 'c-indent-region
 	outline-regexp "[^#\n\^M]"
 	outline-level 'c-outline-level
+	normal-auto-fill-function 'c-do-auto-fill
 	comment-column 32
-	comment-start-skip "/\\*+ *\\|// *"
-	comment-multi-line nil
-	comment-line-break-function 'c-comment-line-break-function
-	adaptive-fill-regexp nil
-	adaptive-fill-mode nil)
+	comment-start-skip "/\\*+ *\\|//+ *"
+	comment-multi-line t)
+  ;; now set the mode style based on c-default-style
+  (let ((style (if (stringp c-default-style)
+		   (if (c-major-mode-is 'java-mode)
+		       "java"
+		     c-default-style)
+		 (or (cdr (assq major-mode c-default-style))
+		     (cdr (assq 'other c-default-style))
+		     "gnu"))))
+    ;; Override style variables if `c-old-style-variable-behavior' is
+    ;; set.  Also override if we are using global style variables,
+    ;; have already initialized a style once, and are switching to a
+    ;; different style.  (It's doubtful whether this is desirable, but
+    ;; the whole situation with nonlocal style variables is a bit
+    ;; awkward.  It's at least the most compatible way with the old
+    ;; style init procedure.)
+    (c-set-style style (not (or c-old-style-variable-behavior
+				(and (not c-style-variables-are-local-p)
+				     c-indentation-style
+				     (not (string-equal c-indentation-style
+							style)))))))
+  ;; Fix things up for paragraph recognition and filling inside
+  ;; comments by using c-comment-prefix-regexp in the relevant places.
+  ;; We use adaptive filling for this to make it possible to use
+  ;; filladapt or some other fancy package.
+  (let ((comment-line-prefix
+	 (concat "[ \t]*\\(" c-comment-prefix-regexp "\\)?[ \t]*")))
+    (setq paragraph-start (concat comment-line-prefix
+				  c-append-paragraph-start
+				  "\\|"
+				  page-delimiter)
+	  paragraph-separate (concat comment-line-prefix "$"
+				     "\\|"
+				     page-delimiter)
+	  paragraph-ignore-fill-prefix t
+	  adaptive-fill-mode t
+	  adaptive-fill-regexp
+	  (concat comment-line-prefix
+		  (if adaptive-fill-regexp
+		      (concat "\\(" adaptive-fill-regexp "\\)")
+		    "")))
+    (when (boundp 'adaptive-fill-first-line-regexp)
+      ;; XEmacs (20.x) adaptive fill mode doesn't have this.
+      (make-local-variable 'adaptive-fill-first-line-regexp)
+      (setq adaptive-fill-first-line-regexp
+	    (concat "\\`" comment-line-prefix
+		    ;; Maybe we should incorporate the old value here,
+		    ;; but then we have to do all sorts of kludges to
+		    ;; deal with the \` and \' it probably contains.
+		    "\\'"))))
   ;; we have to do something special for c-offsets-alist so that the
   ;; buffer local value has its own alist structure.
   (setq c-offsets-alist (copy-alist c-offsets-alist))
       (setq minor-mode-alist
 	    (cons '(c-auto-hungry-string c-auto-hungry-string)
 		  minor-mode-alist)))
-  ;; now set the mode style based on c-default-style
-  (c-set-style (if (stringp c-default-style)
-		   (if (c-major-mode-is 'java-mode)
-		       "java"
-		     c-default-style)
-		 (or (cdr (assq major-mode c-default-style))
-		     (cdr (assq 'other c-default-style))
-		     "gnu")))
   )
 
 
   ;; backward-kill-word.
   (define-key c-mode-base-map [(control meta h)] 'c-mark-function)
   (define-key c-mode-base-map "\e\C-q"    'c-indent-exp)
-  (define-key c-mode-base-map "\ea"       'c-beginning-of-statement)
-  (define-key c-mode-base-map "\ee"       'c-end-of-statement)
+  (substitute-key-definition 'backward-sentence
+			     'c-beginning-of-statement
+			     c-mode-base-map global-map)
+  (substitute-key-definition 'forward-sentence
+			     'c-end-of-statement
+			     c-mode-base-map global-map)
+  (substitute-key-definition 'indent-new-comment-line
+			     'c-indent-new-comment-line
+			     c-mode-base-map global-map)
   ;; RMS says don't make these the default.
 ;;  (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)
   (define-key c-mode-base-map "\C-c\C-u"  'c-up-conditional)
-  (define-key c-mode-base-map "\t"        'c-indent-command)
+  (substitute-key-definition 'indent-for-tab-command
+			     'c-indent-command
+			     c-mode-base-map global-map)
+  ;; It doesn't suffice to put c-fill-paragraph on
+  ;; fill-paragraph-function due to the way it works.
+  (substitute-key-definition 'fill-paragraph 'c-fill-paragraph
+			     c-mode-base-map global-map)
+  ;; In XEmacs the default fill function is called
+  ;; fill-paragraph-or-region.
+  (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
+			     c-mode-base-map global-map)
   ;; Caution!  Enter here at your own risk.  We are trying to support
   ;; several behaviors and it gets disgusting. :-(
   ;;
-  ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
-  ;; backwards deletion behavior to DEL, which both Delete and
-  ;; Backspace get translated to.  There's no way to separate this
-  ;; behavior in a clean way, so deal with it!  Besides, it's been
-  ;; this way since the dawn of BOCM.
-  (if (not (boundp 'delete-key-deletes-forward))
-      (define-key c-mode-base-map "\177" 'c-electric-backspace)
-    ;; However, XEmacs 20 actually achieved enlightenment.  It is
-    ;; possible to sanely define both backward and forward deletion
-    ;; behavior under X separately (TTYs are forever beyond hope, but
-    ;; who cares?  XEmacs 20 does the right thing with these too).
-    (define-key c-mode-base-map [delete]    'c-electric-delete)
-    (define-key c-mode-base-map [backspace] 'c-electric-backspace))
+  (if (boundp 'delete-key-deletes-forward)
+      (progn
+	;; In XEmacs 20 it is possible to sanely define both backward
+	;; and forward deletion behavior under X separately (TTYs are
+	;; forever beyond hope, but who cares?  XEmacs 20 does the
+	;; right thing with these too).
+	(define-key c-mode-base-map [delete]    'c-electric-delete)
+	(define-key c-mode-base-map [backspace] 'c-electric-backspace))
+    ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
+    ;; backwards deletion behavior to DEL, which both Delete and
+    ;; Backspace get translated to.  There's no way to separate this
+    ;; behavior in a clean way, so deal with it!  Besides, it's been
+    ;; this way since the dawn of BOCM.
+    (define-key c-mode-base-map "\177" 'c-electric-backspace))
   ;; these are new keybindings, with no counterpart to BOCM
   (define-key c-mode-base-map ","         'c-electric-semi&comma)
   (define-key c-mode-base-map "*"         'c-electric-star)
   ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
   )
 
-;; menu support for both XEmacs and Emacs.  If you don't have easymenu
-;; with your version of Emacs, you are incompatible!
-(require 'easymenu)
-
 (defvar c-c-menu nil)
 (defvar c-c++-menu nil)
 (defvar c-objc-menu nil)
   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
   )
 
+(defvar c++-template-syntax-table nil
+  "A variant of `c++-mode-syntax-table' that defines `<' and `>' as
+parenthesis characters.  Used temporarily when template argument lists
+are parsed.")
+(if c++-template-syntax-table
+    ()
+  (setq c++-template-syntax-table
+	(copy-syntax-table c++-mode-syntax-table))
+  (modify-syntax-entry ?< "(>" c++-template-syntax-table)
+  (modify-syntax-entry ?> ")<" c++-template-syntax-table))
+
 (easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
 		  (c-mode-menu "C++"))