Initial revision

This commit is contained in:
Richard M. Stallman 1997-07-10 07:54:06 +00:00
parent 883e21bd33
commit 785eecbbba
10 changed files with 5805 additions and 0 deletions

392
lisp/progmodes/cc-align.el Normal file
View file

@ -0,0 +1,392 @@
;;; cc-align.el --- custom indentation functions for CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
(eval-when-compile
(require 'cc-defs)
(require 'cc-vars)
(require 'cc-engine)
(require 'cc-langs))
;; Standard indentation line-ups
(defun c-lineup-arglist (langelem)
;; lineup the current arglist line with the arglist appearing just
;; after the containing paren which starts the arglist.
(save-excursion
(let* ((containing-sexp
(save-excursion
;; arglist-cont-nonempty gives relpos ==
;; to boi of containing-sexp paren. This
;; is good when offset is +, but bad
;; when it is c-lineup-arglist, so we
;; have to special case a kludge here.
(if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
(progn
(beginning-of-line)
(backward-up-list 1)
(skip-chars-forward " \t" (c-point 'eol)))
(goto-char (cdr langelem)))
(point)))
(langelem-col (c-langelem-col langelem t)))
(if (save-excursion
(beginning-of-line)
(looking-at "[ \t]*)"))
(progn (goto-char (match-end 0))
(forward-sexp -1)
(forward-char 1)
(c-forward-syntactic-ws)
(- (current-column) langelem-col))
(goto-char containing-sexp)
(or (eolp)
(not (memq (char-after) '(?{ ?\( )))
(let ((eol (c-point 'eol))
(here (progn
(forward-char 1)
(skip-chars-forward " \t")
(point))))
(c-forward-syntactic-ws)
(if (< (point) eol)
(goto-char here))))
(- (current-column) langelem-col)
))))
(defun c-lineup-arglist-intro-after-paren (langelem)
;; lineup an arglist-intro line to just after the open paren
(save-excursion
(let ((langelem-col (c-langelem-col langelem t))
(ce-curcol (save-excursion
(beginning-of-line)
(backward-up-list 1)
(skip-chars-forward " \t" (c-point 'eol))
(current-column))))
(- ce-curcol langelem-col -1))))
(defun c-lineup-arglist-close-under-paren (langelem)
;; lineup an arglist-intro line to just after the open paren
(save-excursion
(let ((langelem-col (c-langelem-col langelem t))
(ce-curcol (save-excursion
(beginning-of-line)
(backward-up-list 1)
(current-column))))
(- ce-curcol langelem-col))))
(defun c-lineup-streamop (langelem)
;; lineup stream operators
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(re-search-forward "<<\\|>>" (c-point 'eol) 'move)
(goto-char (match-beginning 0))
(- (current-column) langelem-col))))
(defun c-lineup-multi-inher (langelem)
;; line up multiple inheritance lines
(save-excursion
(let ((eol (c-point 'eol))
(here (point))
(langelem-col (c-langelem-col langelem)))
(skip-chars-forward "^:" eol)
(skip-chars-forward " \t:" eol)
(if (or (eolp)
(looking-at c-comment-start-regexp))
(c-forward-syntactic-ws here))
(- (current-column) langelem-col)
)))
(defun c-lineup-java-inher (langelem)
;; line up Java implements and extends continuations
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(forward-word 1)
(if (looking-at "[ \t]*$")
langelem-col
(c-forward-syntactic-ws)
(- (current-column) langelem-col)))))
(defun c-lineup-java-throws (langelem)
;; lineup func-decl-cont's in Java which are continuations of throws
;; declarations. If `throws' starts the previous line, line up to
;; just after that keyword. If not, lineup under the previous line.
(save-excursion
(let ((iopl (c-point 'iopl))
(langelem-col (c-langelem-col langelem t))
(extra 0))
(back-to-indentation)
(cond
((looking-at "throws[ \t\n]")
(goto-char (cdr langelem))
(setq extra c-basic-offset))
((and (goto-char iopl)
(looking-at "throws[ \t\n]"))
(forward-word 1)
(skip-chars-forward " \t")
(when (eolp)
(back-to-indentation)
(setq extra c-basic-offset)))
(t (goto-char iopl)))
(+ (- (current-column) langelem-col) extra))))
(defun c-lineup-C-comments (langelem)
;; line up C block comment continuation lines
(save-excursion
(let ((here (point))
(stars (progn (back-to-indentation)
(skip-chars-forward "*")))
(langelem-col (c-langelem-col langelem)))
(back-to-indentation)
(if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
(progn
(if (not (looking-at "[*]+"))
(progn
;; we now have to figure out where this comment begins.
(goto-char here)
(back-to-indentation)
(if (looking-at "[*]+/")
(progn (goto-char (match-end 0))
(forward-comment -1))
(goto-char (cdr langelem))
(back-to-indentation))))
(- (current-column) langelem-col))
(if (zerop stars)
(progn
(skip-chars-forward " \t")
(- (current-column) langelem-col))
;; how many stars on comment opening line? if greater than
;; on current line, align left. if less than or equal,
;; align right. this should also pick up Javadoc style
;; comments.
(if (> (length (match-string 1)) stars)
(progn
(back-to-indentation)
(- (current-column) -1 langelem-col))
(- (current-column) stars langelem-col))
)))))
(defun c-lineup-comment (langelem)
;; support old behavior for comment indentation. we look at
;; c-comment-only-line-offset to decide how to indent comment
;; only-lines
(save-excursion
(back-to-indentation)
;; this highly kludgiforous flag prevents the mapcar over
;; c-syntactic-context from entering an infinite loop
(let ((recurse-prevention-flag (boundp 'recurse-prevention-flag)))
(cond
;; CASE 1: preserve comment-column
(recurse-prevention-flag 0)
((= (current-column) comment-column)
;; we have to subtract out all other indentation
(- comment-column (apply '+ (mapcar 'c-get-offset
c-syntactic-context))))
;; indent as specified by c-comment-only-line-offset
((not (bolp))
(or (car-safe c-comment-only-line-offset)
c-comment-only-line-offset))
(t
(or (cdr-safe c-comment-only-line-offset)
(car-safe c-comment-only-line-offset)
-1000)) ;jam it against the left side
))))
(defun c-lineup-runin-statements (langelem)
;; line up statements in coding standards which place the first
;; statement on the same line as the block opening brace.
(if (eq (char-after (cdr langelem)) ?{)
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(forward-char 1)
(skip-chars-forward " \t")
(- (current-column) langelem-col)))
0))
(defun c-lineup-math (langelem)
;; line up math statement-cont after the equals
(save-excursion
(let ((equalp (save-excursion
(goto-char (c-point 'boi))
(skip-chars-forward "^=" (c-point 'eol))
(and (eq (char-after) ?=)
(- (point) (c-point 'boi)))))
(langelem-col (c-langelem-col langelem))
donep)
(while (and (not donep)
(< (point) (c-point 'eol)))
(skip-chars-forward "^=" (c-point 'eol))
(if (c-in-literal (cdr langelem))
(forward-char 1)
(setq donep t)))
(if (not (eq (char-after) ?=))
;; there's no equal sign on the line
c-basic-offset
;; calculate indentation column after equals and ws, unless
;; our line contains an equals sign
(if (not equalp)
(progn
(forward-char 1)
(skip-chars-forward " \t")
(setq equalp 0)))
(- (current-column) equalp langelem-col))
)))
(defun c-lineup-ObjC-method-call (langelem)
;; Line up methods args as elisp-mode does with function args: go to
;; the position right after the message receiver, and if you are at
;; (eolp) indent the current line by a constant offset from the
;; opening bracket; otherwise we are looking at the first character
;; of the first method call argument, so lineup the current line
;; with it.
(save-excursion
(let* ((extra (save-excursion
(back-to-indentation)
(c-backward-syntactic-ws (cdr langelem))
(if (eq (char-before) ?:)
(- c-basic-offset)
0)))
(open-bracket-pos (cdr langelem))
(open-bracket-col (progn
(goto-char open-bracket-pos)
(current-column)))
(target-col (progn
(forward-char)
(forward-sexp)
(skip-chars-forward " \t")
(if (eolp)
(+ open-bracket-col c-basic-offset)
(current-column))))
)
(- target-col open-bracket-col extra))))
(defun c-lineup-ObjC-method-args (langelem)
;; Line up the colons that separate args. This is done trying to
;; align colons vertically.
(save-excursion
(let* ((here (c-point 'boi))
(curcol (progn (goto-char here) (current-column)))
(eol (c-point 'eol))
(relpos (cdr langelem))
(first-col-column (progn
(goto-char relpos)
(skip-chars-forward "^:" eol)
(and (eq (char-after) ?:)
(current-column)))))
(if (not first-col-column)
c-basic-offset
(goto-char here)
(skip-chars-forward "^:" eol)
(if (eq (char-after) ?:)
(+ curcol (- first-col-column (current-column)))
c-basic-offset)))))
(defun c-lineup-ObjC-method-args-2 (langelem)
;; Line up the colons that separate args. This is done trying to
;; align the colon on the current line with the previous one.
(save-excursion
(let* ((here (c-point 'boi))
(curcol (progn (goto-char here) (current-column)))
(eol (c-point 'eol))
(relpos (cdr langelem))
(prev-col-column (progn
(skip-chars-backward "^:" relpos)
(and (eq (char-before) ?:)
(- (current-column) 1)))))
(if (not prev-col-column)
c-basic-offset
(goto-char here)
(skip-chars-forward "^:" eol)
(if (eq (char-after) ?:)
(+ curcol (- prev-col-column (current-column)))
c-basic-offset)))))
(defun c-snug-do-while (syntax pos)
"Dynamically calculate brace hanginess for do-while statements.
Using this function, `while' clauses that end a `do-while' block will
remain on the same line as the brace that closes that block.
See `c-hanging-braces-alist' for how to utilize this function as an
ACTION associated with `block-close' syntax."
(save-excursion
(let (langelem)
(if (and (eq syntax 'block-close)
(setq langelem (assq 'block-close c-syntactic-context))
(progn (goto-char (cdr langelem))
(if (eq (char-after) ?{)
(c-safe (forward-sexp -1)))
(looking-at "\\<do\\>[^_]")))
'(before)
'(before after)))))
(defun c-gnu-impose-minimum ()
"Imposes a minimum indentation for lines inside a top-level construct.
The variable `c-label-minimum-indentation' specifies the minimum
indentation amount."
(let ((non-top-levels '(defun-block-intro statement statement-cont
statement-block-intro statement-case-intro
statement-case-open substatement substatement-open
case-label label do-while-closure else-clause
))
(syntax c-syntactic-context)
langelem)
(while syntax
(setq langelem (car (car syntax))
syntax (cdr syntax))
;; don't adjust comment-only lines
(cond ((eq langelem 'comment-intro)
(setq syntax nil))
((memq langelem non-top-levels)
(save-excursion
(setq syntax nil)
(back-to-indentation)
(if (zerop (current-column))
(insert (make-string c-label-minimum-indentation 32)))
))
))))
;; Useful for c-hanging-semi&comma-criteria
(defun c-semi&comma-inside-parenlist ()
"Determine if a newline should be added after a semicolon.
If a comma was inserted, no determination is made. If a semicolon was
inserted inside a parenthesis list, no newline is added otherwise a
newline is added. In either case, checking is stopped. This supports
exactly the old newline insertion behavior."
;; newline only after semicolon, but only if that semicolon is not
;; inside a parenthesis list (e.g. a for loop statement)
(if (not (eq last-command-char ?\;))
nil ; continue checking
(if (condition-case nil
(save-excursion
(up-list -1)
(not (eq (char-after) ?\()))
(error t))
t
'stop)))
(provide 'cc-align)
;;; cc-align.el ends here

1369
lisp/progmodes/cc-cmds.el Normal file

File diff suppressed because it is too large Load diff

149
lisp/progmodes/cc-compat.el Normal file
View file

@ -0,0 +1,149 @@
;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Author: 1994-1997 Barry A. Warsaw
;; Maintainer: cc-mode-help@python.org
;; Created: August 1994, split from cc-mode.el
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;;
;; Boring old c-mode.el (BOCM) is confusion and brain melt. cc-mode.el
;; is clarity of thought and purity of chi. If you are still unwilling
;; to accept enlightenment, this might help, or it may prolong your
;; agony.
;;
;; To use, add the following to your c-mode-hook:
;;
;; (require 'cc-compat)
;; (c-set-style "BOCM")
;;; Code:
(eval-when-compile
(require 'cc-styles)
(require 'cc-engine))
;; In case c-mode.el isn't loaded
(defvar c-indent-level 2
"*Indentation of C statements with respect to containing block.")
(defvar c-brace-imaginary-offset 0
"*Imagined indentation of a C open brace that actually follows a statement.")
(defvar c-brace-offset 0
"*Extra indentation for braces, compared with other text in same context.")
(defvar c-argdecl-indent 5
"*Indentation level of declarations of C function arguments.")
(defvar c-label-offset -2
"*Offset of C label lines and case statements relative to usual indentation.")
(defvar c-continued-statement-offset 2
"*Extra indent for lines not starting new statements.")
(defvar c-continued-brace-offset 0
"*Extra indent for substatements that start with open-braces.
This is in addition to c-continued-statement-offset.")
;; these offsets are taken by brute force testing c-mode.el, since
;; there's no logic to what it does.
(let* ((offsets '(c-offsets-alist .
((defun-block-intro . cc-block-intro-offset)
(statement-block-intro . cc-block-intro-offset)
(defun-open . 0)
(class-open . 0)
(inline-open . c-brace-offset)
(block-open . c-brace-offset)
(block-close . cc-block-close-offset)
(brace-list-open . c-brace-offset)
(substatement-open . cc-substatement-open-offset)
(substatement . c-continued-statement-offset)
(knr-argdecl-intro . c-argdecl-indent)
(case-label . c-label-offset)
(access-label . c-label-offset)
(label . c-label-offset)
))))
(c-add-style "BOCM" offsets))
(defun cc-block-intro-offset (langelem)
;; taken directly from calculate-c-indent confusion
(save-excursion
(c-backward-syntactic-ws)
(if (eq (char-before) ?{)
(forward-char -1)
(goto-char (cdr langelem)))
(let* ((curcol (save-excursion
(goto-char (cdr langelem))
(current-column)))
(bocm-lossage
;; If no previous statement, indent it relative to line
;; brace is on. For open brace in column zero, don't let
;; statement start there too. If c-indent-level is zero,
;; use c-brace-offset + c-continued-statement-offset
;; instead. For open-braces not the first thing in a line,
;; add in c-brace-imaginary-offset.
(+ (if (and (bolp) (zerop c-indent-level))
(+ c-brace-offset c-continued-statement-offset)
c-indent-level)
;; Move back over whitespace before the openbrace. If
;; openbrace is not first nonwhite thing on the line,
;; add the c-brace-imaginary-offset.
(progn (skip-chars-backward " \t")
(if (bolp) 0 c-brace-imaginary-offset))
;; If the openbrace is preceded by a parenthesized exp,
;; move to the beginning of that; possibly a different
;; line
(progn
(if (eq (char-before) ?\))
(forward-sexp -1))
;; Get initial indentation of the line we are on.
(current-indentation)))))
(- bocm-lossage curcol))))
(defun cc-block-close-offset (langelem)
(save-excursion
(let* ((here (point))
bracep
(curcol (progn
(goto-char (cdr langelem))
(current-column)))
(bocm-lossage (progn
(goto-char (cdr langelem))
(if (eq (char-after) ?{)
(setq bracep t)
(goto-char here)
(beginning-of-line)
(backward-up-list 1)
(forward-char 1)
(c-forward-syntactic-ws))
(current-column))))
(- bocm-lossage curcol
(if bracep 0 c-indent-level)))))
(defun cc-substatement-open-offset (langelem)
(+ c-continued-statement-offset c-continued-brace-offset))
(provide 'cc-compat)
;;; cc-compat.el ends here

185
lisp/progmodes/cc-defs.el Normal file
View file

@ -0,0 +1,185 @@
;;; cc-defs.el --- definitions for CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;; Figure out what features this Emacs has
(defconst c-emacs-features
(let ((infodock-p (boundp 'infodock-version))
(comments
;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags.
;; Emacs 19 uses a 1-bit flag. We will have to set up our
;; syntax tables differently to handle this.
(let ((table (copy-syntax-table))
entry)
(modify-syntax-entry ?a ". 12345678" table)
(cond
;; XEmacs 19, and beyond Emacs 19.34
((arrayp table)
(setq entry (aref table ?a))
;; In Emacs, table entries are cons cells
(if (consp entry) (setq entry (car entry))))
;; XEmacs 20
((fboundp 'get-char-table) (setq entry (get-char-table ?a table)))
;; before and including Emacs 19.34
((and (fboundp 'char-table-p)
(char-table-p table))
(setq entry (car (char-table-range table [?a]))))
;; incompatible
(t (error "CC Mode is incompatible with this version of Emacs")))
(if (= (logand (lsh entry -16) 255) 255)
'8-bit
'1-bit))))
(if infodock-p
(list comments 'infodock)
(list comments)))
"A list of features extant in the Emacs you are using.
There are many flavors of Emacs out there, each with different
features supporting those needed by CC Mode. Here's the current
supported list, along with the values for this variable:
XEmacs 19: (8-bit)
XEmacs 20: (8-bit)
Emacs 19: (1-bit)
Infodock (based on XEmacs) has an additional symbol on this list:
'infodock.")
(defsubst c-point (position)
;; Returns the value of point at certain commonly referenced POSITIONs.
;; POSITION can be one of the following symbols:
;;
;; bol -- beginning of line
;; eol -- end of line
;; bod -- beginning of defun
;; boi -- back to indentation
;; ionl -- indentation of next line
;; iopl -- indentation of previous line
;; bonl -- beginning of next line
;; bopl -- beginning of previous line
;;
;; This function does not modify point or mark.
(let ((here (point)))
(cond
((eq position 'bol) (beginning-of-line))
((eq position 'eol) (end-of-line))
((eq position 'bod)
(beginning-of-defun)
;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at
;; the open brace.
(and defun-prompt-regexp
(looking-at defun-prompt-regexp)
(goto-char (match-end 0)))
)
((eq position 'boi) (back-to-indentation))
((eq position 'bonl) (forward-line 1))
((eq position 'bopl) (forward-line -1))
((eq position 'iopl)
(forward-line -1)
(back-to-indentation))
((eq position 'ionl)
(forward-line 1)
(back-to-indentation))
(t (error "unknown buffer position requested: %s" position))
)
(prog1
(point)
(goto-char here))))
(defmacro c-safe (&rest body)
;; safely execute BODY, return nil if an error occurred
(` (condition-case nil
(progn (,@ body))
(error nil))))
(defmacro c-add-syntax (symbol &optional relpos)
;; a simple macro to append the syntax in symbol to the syntax list.
;; try to increase performance by using this macro
(` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
(defsubst c-auto-newline ()
;; if auto-newline feature is turned on, insert a newline character
;; and return t, otherwise return nil.
(and c-auto-newline
(not (c-in-literal))
(not (newline))))
(defsubst c-intersect-lists (list alist)
;; return the element of ALIST that matches the first element found
;; in LIST. Uses assq.
(let (match)
(while (and list
(not (setq match (assq (car list) alist))))
(setq list (cdr list)))
match))
(defsubst c-lookup-lists (list alist1 alist2)
;; first, find the first entry from LIST that is present in ALIST1,
;; then find the entry in ALIST2 for that entry.
(assq (car (c-intersect-lists list alist1)) alist2))
(defsubst c-langelem-col (langelem &optional preserve-point)
;; convenience routine to return the column of langelem's relpos.
;; Leaves point at the relpos unless preserve-point is non-nil.
(let ((here (point)))
(goto-char (cdr langelem))
(prog1 (current-column)
(if preserve-point
(goto-char here))
)))
(defsubst c-update-modeline ()
;; set the c-auto-hungry-string for the correct designation on the modeline
(setq c-auto-hungry-string
(if c-auto-newline
(if c-hungry-delete-key "/ah" "/a")
(if c-hungry-delete-key "/h" nil)))
(force-mode-line-update))
(defsubst c-keep-region-active ()
;; Do whatever is necessary to keep the region active in XEmacs.
;; Ignore byte-compiler warnings you might see. This is not needed
;; for Emacs.
(and (boundp 'zmacs-region-stays)
(setq zmacs-region-stays t)))
(defsubst c-load-all ()
;; make sure all necessary components of CC Mode are loaded in.
(require 'cc-vars)
(require 'cc-engine)
(require 'cc-langs)
(require 'cc-menus)
(require 'cc-align)
(require 'cc-styles)
(require 'cc-cmds))
(provide 'cc-defs)
;;; cc-defs.el ends here

1704
lisp/progmodes/cc-engine.el Normal file

File diff suppressed because it is too large Load diff

551
lisp/progmodes/cc-langs.el Normal file
View file

@ -0,0 +1,551 @@
;;; cc-langs.el --- specific language support for CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;; Regular expressions and other values which must be parameterized on
;; a per-language basis.
;; Keywords defining protection levels
(defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>")
;; Regex describing a `symbol' in all languages We cannot use just
;; `word' syntax class since `_' cannot be in word class. Putting
;; underscore in word class breaks forward word movement behavior that
;; users are familiar with.
(defconst c-symbol-key "\\(\\w\\|\\s_\\)+")
;; keywords introducing class definitions. language specific
(defconst c-C-class-key "\\(struct\\|union\\)")
(defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
(defconst c-ObjC-class-key
(concat
"@\\(interface\\|implementation\\)\\s +"
c-symbol-key ;name of the class
"\\(\\s *:\\s *" c-symbol-key "\\)?" ;maybe followed by the superclass
"\\(\\s *<[^>]+>\\)?" ;and maybe the adopted protocols list
))
(defconst c-Java-class-key
(concat
"\\(" c-protection-key "\\s +\\)?"
"\\(interface\\|class\\)\\s +"
c-symbol-key ;name of the class
"\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass
;;"\\(\\s *implements *[^{]+{\\)?" ;maybe the adopted protocols list
))
(defvar c-class-key c-C-class-key)
(make-variable-buffer-local 'c-class-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-ObjC-access-key (concat "@" c-protection-key))
(defconst c-Java-access-key nil)
;; keywords introducing conditional blocks
(defconst c-C-conditional-key nil)
(defconst c-C++-conditional-key nil)
(defconst c-Java-conditional-key nil)
(let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch")
(exc-kws "\\|try\\|catch")
(thr-kws "\\|finally\\|synchronized")
(front "\\b\\(")
(back "\\)\\b[^_]"))
(setq c-C-conditional-key (concat front all-kws back)
c-C++-conditional-key (concat front all-kws exc-kws back)
c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)))
(defvar c-conditional-key c-C-conditional-key)
(make-variable-buffer-local 'c-conditional-key)
;; keywords describing method definition introductions
(defvar c-method-key nil)
(make-variable-buffer-local 'c-method-key)
(defconst c-ObjC-method-key
(concat
"^\\s *[+-]\\s *"
"\\(([^)]*)\\)?" ; return type
;; \\s- in objc syntax table does not include \n
;; since it is considered the end of //-comments.
"[ \t\n]*" c-symbol-key))
(defconst c-Java-method-key
(concat
"^\\s *[+-]\\s *"
"\\(([^)]*)\\)?" ; return type
;; \\s- in java syntax table does not include \n
;; since it is considered the end of //-comments.
"[ \t\n]*" c-symbol-key))
;; comment starter definitions for various languages. language specific
(defconst c-C-comment-start-regexp "/[*]")
(defconst 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 "/\\(/\\|[*][*]?\\)")
(defvar c-comment-start-regexp c-C-comment-start-regexp)
(make-variable-buffer-local 'c-comment-start-regexp)
;; Regexp describing a switch's case or default label for all languages
(defconst c-switch-label-key "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):")
;; Regexp describing any label.
(defconst c-label-key (concat c-symbol-key ":\\([^:]\\|$\\)"))
;; Regexp describing class inheritance declarations. TBD: this should
;; be language specific, and only makes sense for C++
(defconst c-inher-key
(concat "\\(\\<static\\>\\s +\\)?"
c-C++-class-key "[ \t]+" c-symbol-key
"\\([ \t]*:[ \t]*\\)\\s *[^;]"))
;; Regexp describing C++ base classes in a derived class definition.
;; TBD: this should be language specific, and only makes sense for C++
(defvar c-baseclass-key
(concat
":?[ \t]*\\(virtual[ \t]+\\)?\\("
c-protection-key "[ \t]+\\)" c-symbol-key))
(make-variable-buffer-local 'c-baseclass-key)
;; Regexp describing friend declarations in C++ classes.
(defconst c-C++-friend-key
"friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
;; Regexp describing Java inheritance and throws clauses.
(defconst c-Java-special-key "\\(implements\\|extends\\|throws\\)[^_]")
;; Regexp describing the beginning of a Java top-level definition.
(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-*")
;; internal state variables
;; Internal state of hungry delete key feature
(defvar c-hungry-delete-key nil)
(make-variable-buffer-local 'c-hungry-delete-key)
;; Internal state of auto newline feature.
(defvar c-auto-newline nil)
(make-variable-buffer-local 'c-auto-newline)
;; Internal auto-newline/hungry-delete designation string for mode line.
(defvar c-auto-hungry-string nil)
(make-variable-buffer-local 'c-auto-hungry-string)
;; Buffer local language-specific comment style flag.
(defvar c-double-slash-is-comments-p nil)
(make-variable-buffer-local 'c-double-slash-is-comments-p)
;; Non-nil means K&R style argument declarations are valid.
(defvar c-recognize-knr-p t)
(make-variable-buffer-local 'c-recognize-knr-p)
(defun c-use-java-style ()
"Institutes `java' indentation style.
For use with the variable `java-mode-hook'."
(c-set-style "java"))
(defvar c-styles-are-initialized nil)
(defun c-common-init ()
;; Common initializations for all modes.
(if c-styles-are-initialized
nil
(require 'cc-styles)
(c-initialize-builtin-style)
(if c-style-variables-are-local-p
(c-make-styles-buffer-local))
(setq c-styles-are-initialized t))
;; 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 '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 'adaptive-fill-regexp)
(make-local-variable 'imenu-generic-expression) ;set in the mode functions
;; 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)))
;; now set their values
(setq paragraph-start (concat page-delimiter "\\|$")
paragraph-separate paragraph-start
paragraph-ignore-fill-prefix t
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
comment-column 32
comment-start-skip "/\\*+ *\\|// *"
adaptive-fill-regexp nil)
;; 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))
;; setup the comment indent variable in a Emacs version portable way
;; ignore any byte compiler warnings you might get here
(make-local-variable 'comment-indent-function)
(setq comment-indent-function 'c-comment-indent)
;; add menus to menubar
(easy-menu-add (c-mode-menu mode-name))
;; put auto-hungry designators onto minor-mode-alist, but only once
(or (assq 'c-auto-hungry-string minor-mode-alist)
(setq minor-mode-alist
(cons '(c-auto-hungry-string c-auto-hungry-string)
minor-mode-alist))))
(defun c-postprocess-file-styles ()
"Function that post processes relevant file local variables.
Currently, this function simply applies any style and offset settings
found in the file's Local Variable list. It first applies any style
setting found in `c-file-style', then it applies any offset settings
it finds in `c-file-offsets'."
;; apply file styles and offsets
(and c-file-style
(c-set-style c-file-style))
(and c-file-offsets
(mapcar
(function
(lambda (langentry)
(let ((langelem (car langentry))
(offset (cdr langentry)))
(c-set-offset langelem offset)
)))
c-file-offsets)))
(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
;; Common routines
(defsubst c-make-inherited-keymap ()
(let ((map (make-sparse-keymap)))
(cond
;; XEmacs 19 & 20
((fboundp 'set-keymap-parents)
(set-keymap-parents map c-mode-base-map))
;; Emacs 19
((fboundp 'set-keymap-parent)
(set-keymap-parent map c-mode-base-map))
;; incompatible
(t (error "CC Mode is incompatible with this version of Emacs")))
map))
(defun c-populate-syntax-table (table)
;; Populate the syntax TABLE
;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
(modify-syntax-entry ?_ "_" table)
(modify-syntax-entry ?\\ "\\" table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?% "." table)
(modify-syntax-entry ?< "." table)
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
(modify-syntax-entry ?\' "\"" table))
(defun c-setup-dual-comments (table)
;; Set up TABLE to handle block and line style comments
(cond
;; XEmacs 19 & 20
((memq '8-bit c-emacs-features)
(modify-syntax-entry ?/ ". 1456" table)
(modify-syntax-entry ?* ". 23" table)
(modify-syntax-entry ?\n "> b" table)
;; Give CR the same syntax as newline, for selective-display
(modify-syntax-entry ?\^m "> b" table))
;; Emacs 19
((memq '1-bit c-emacs-features)
(modify-syntax-entry ?/ ". 124b" table)
(modify-syntax-entry ?* ". 23" table)
(modify-syntax-entry ?\n "> b" table)
;; Give CR the same syntax as newline, for selective-display
(modify-syntax-entry ?\^m "> b" table))
;; incompatible
(t (error "CC Mode is incompatible with this version of Emacs"))
))
(defvar c-mode-base-map ()
"Keymap shared by all CC Mode related modes.")
(if c-mode-base-map
nil
;; TBD: should we even worry about naming this keymap. My vote: no,
;; because Emacs and XEmacs do it differently.
(setq c-mode-base-map (make-sparse-keymap))
;; put standard keybindings into MAP
;; the following mappings correspond more or less directly to BOCM
(define-key c-mode-base-map "{" 'c-electric-brace)
(define-key c-mode-base-map "}" 'c-electric-brace)
(define-key c-mode-base-map ";" 'c-electric-semi&comma)
(define-key c-mode-base-map "#" 'c-electric-pound)
(define-key c-mode-base-map ":" 'c-electric-colon)
;; Lucid Emacs 19.9 defined these two, the second of which was
;; commented out...
;; (define-key c-mode-base-map "\e{" 'c-insert-braces)
;; Commented out electric square brackets because nobody likes them.
;; (define-key c-mode-base-map "[" 'c-insert-brackets)
(define-key c-mode-base-map "\C-c\C-m" '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)
(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)
;; 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))
;; 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-q" 'c-indent-defun)
(define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
(define-key c-mode-base-map "\C-c\C-a" 'c-toggle-auto-state)
(define-key c-mode-base-map "\C-c\C-b" 'c-submit-bug-report)
(define-key c-mode-base-map "\C-c\C-c" 'comment-region)
(define-key c-mode-base-map "\C-c\C-d" 'c-toggle-hungry-state)
(define-key c-mode-base-map "\C-c\C-e" 'c-macro-expand)
(define-key c-mode-base-map "\C-c\C-o" 'c-set-offset)
(define-key c-mode-base-map "\C-c\C-s" 'c-show-syntactic-information)
(define-key c-mode-base-map "\C-c\C-t" 'c-toggle-auto-hungry-state)
(define-key c-mode-base-map "\C-c." 'c-set-style)
;; conflicts with OOBR
;;(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)
(defvar c-java-menu nil)
(defun c-mode-menu (modestr)
(let ((m
'(["Comment Out Region" comment-region (mark)]
["Macro Expand Region" c-macro-expand (mark)]
["Backslashify" c-backslash-region (mark)]
["Indent Expression" c-indent-exp
(memq (char-after) '(?\( ?\[ ?\{))]
["Indent Line" c-indent-command t]
["Fill Comment Paragraph" c-fill-paragraph t]
["Up Conditional" c-up-conditional t]
["Backward Conditional" c-backward-conditional t]
["Forward Conditional" c-forward-conditional t]
["Backward Statement" c-beginning-of-statement t]
["Forward Statement" c-end-of-statement t]
)))
(cons modestr m)))
;; Support for C
(defvar c-mode-abbrev-table nil
"Abbrev table in use in c-mode buffers.")
(define-abbrev-table 'c-mode-abbrev-table ())
(defvar c-mode-map ()
"Keymap used in c-mode buffers.")
(if c-mode-map
nil
(setq c-mode-map (c-make-inherited-keymap))
;; add bindings which are only useful for C
)
;;;###autoload
(defvar c-mode-syntax-table nil
"Syntax table used in c-mode buffers.")
(if c-mode-syntax-table
()
(setq c-mode-syntax-table (make-syntax-table))
(c-populate-syntax-table c-mode-syntax-table)
;; add extra comment syntax
(modify-syntax-entry ?/ ". 14" c-mode-syntax-table)
(modify-syntax-entry ?* ". 23" c-mode-syntax-table))
(defun c-enable-//-in-c-mode ()
"Enables // as a comment delimiter in `c-mode'.
ANSI C currently does *not* allow this, although many C compilers
support optional C++ style comments. To use, call this function from
your `.emacs' file before you visit any C files. The changes are
global and affect all future `c-mode' buffers."
(c-setup-dual-comments c-mode-syntax-table)
(setq-default c-C-comment-start-regexp c-C++-comment-start-regexp))
(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
(c-mode-menu "C"))
;; Support for C++
(defvar c++-mode-abbrev-table nil
"Abbrev table in use in c++-mode buffers.")
(define-abbrev-table 'c++-mode-abbrev-table ())
(defvar c++-mode-map ()
"Keymap used in c++-mode buffers.")
(if c++-mode-map
nil
(setq c++-mode-map (c-make-inherited-keymap))
;; add bindings which are only useful for C++
(define-key c++-mode-map "\C-c:" 'c-scope-operator)
(define-key c++-mode-map "/" 'c-electric-slash)
(define-key c++-mode-map "<" 'c-electric-lt-gt)
(define-key c++-mode-map ">" 'c-electric-lt-gt))
(defvar c++-mode-syntax-table nil
"Syntax table used in c++-mode buffers.")
(if c++-mode-syntax-table
()
(setq c++-mode-syntax-table (make-syntax-table))
(c-populate-syntax-table c++-mode-syntax-table)
;; add extra comment syntax
(c-setup-dual-comments c++-mode-syntax-table)
;; TBD: does it make sense for colon to be symbol class in C++?
;; I'm not so sure, since c-label-key is busted on lines like:
;; Foo::bar( i );
;; maybe c-label-key should be fixed instead of commenting this out,
;; but it also bothers me that this only seems appropriate for C++
;; and not C.
;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
)
(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
(c-mode-menu "C++"))
;; Support for Objective-C
(defvar objc-mode-abbrev-table nil
"Abbrev table in use in objc-mode buffers.")
(define-abbrev-table 'objc-mode-abbrev-table ())
(defvar objc-mode-map ()
"Keymap used in objc-mode buffers.")
(if objc-mode-map
nil
(setq objc-mode-map (c-make-inherited-keymap))
;; add bindings which are only useful for Objective-C
(define-key objc-mode-map "/" 'c-electric-slash))
(defvar objc-mode-syntax-table nil
"Syntax table used in objc-mode buffers.")
(if objc-mode-syntax-table
()
(setq objc-mode-syntax-table (make-syntax-table))
(c-populate-syntax-table objc-mode-syntax-table)
;; add extra comment syntax
(c-setup-dual-comments objc-mode-syntax-table)
;; everyone gets these
(modify-syntax-entry ?@ "_" objc-mode-syntax-table)
)
(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
(c-mode-menu "ObjC"))
;; Support for Java
(defvar java-mode-abbrev-table nil
"Abbrev table in use in java-mode buffers.")
(define-abbrev-table 'java-mode-abbrev-table ())
(defvar java-mode-map ()
"Keymap used in java-mode buffers.")
(if java-mode-map
nil
(setq java-mode-map (c-make-inherited-keymap))
;; add bindings which are only useful for Java
(define-key java-mode-map "/" 'c-electric-slash))
(defvar java-mode-syntax-table nil
"Syntax table used in java-mode buffers.")
(if java-mode-syntax-table
()
(setq java-mode-syntax-table (make-syntax-table))
(c-populate-syntax-table java-mode-syntax-table)
;; add extra comment syntax
(c-setup-dual-comments java-mode-syntax-table)
;; everyone gets these
(modify-syntax-entry ?@ "_" java-mode-syntax-table)
)
(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
(c-mode-menu "Java"))
(provide 'cc-langs)
;;; cc-langs.el ends here

103
lisp/progmodes/cc-menus.el Normal file
View file

@ -0,0 +1,103 @@
;;; cc-menus.el --- imenu support for CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;; imenu integration
(defvar cc-imenu-c++-generic-expression
(`
((nil
(,
(concat
"^" ; beginning of line is required
"\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
"\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
"\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
"\\(" ; last type spec including */&
"[a-zA-Z0-9_:]+"
"\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either ptr/ref sign or ws
"\\)?" ; if there is a last type spec
"\\(" ; name, take into the imenu entry
"[a-zA-Z0-9_:~]+" ; member func, ctor or dtor...
; (may not contain * because then
; "a::operator char*" would
; become "char*"!)
"\\|"
"\\([a-zA-Z0-9_:~]*::\\)?operator"
"[^a-zA-Z1-9_][^(]*" ; ...or operator
" \\)"
"[ \t]*([^)]*)[ \t\n]*[^ ;]" ; require something other than
; a `;' after the (...) to
; avoid prototypes. Can't
; catch cases with () inside
; the parentheses surrounding
; the parameters. e.g.:
; "int foo(int a=bar()) {...}"
)) 6)
("Class"
(, (concat
"^" ; beginning of line is required
"\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
"class[ \t]+"
"\\([a-zA-Z0-9_]+\\)" ; the string we want to get
"[ \t]*[:{]"
)) 2)))
"Imenu generic expression for C++ mode. See `imenu-generic-expression'.")
(defvar cc-imenu-c-generic-expression
cc-imenu-c++-generic-expression
"Imenu generic expression for C mode. See `imenu-generic-expression'.")
;(defvar cc-imenu-objc-generic-expression
; ())
; Please contribute one!
(defvar cc-imenu-java-generic-expression
(`
((nil
(,
(concat
"^\\([ \t]\\)*"
"\\([A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be
"\\([A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right?
"\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
"\\([ \t]\\)"
"\\([A-Za-z0-9_-]+\\)" ; the string we want to get
"\\([ \t]*\\)+("
"\\([a-zA-Z,_1-9\n \t]*[[]?[]]?\\)*" ; arguments
")[ \t]*"
"[^;(]"
"[,a-zA-Z_1-9\n \t]*{"
)) 6)))
"Imenu generic expression for Java mode. See `imenu-generic-expression'.")
(provide 'cc-menus)
;;; cc-menus.el ends here

344
lisp/progmodes/cc-mode.el Normal file
View file

@ -0,0 +1,344 @@
;;; cc-mode.el --- major mode for editing C, C++, Objective-C, and Java code
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: a long, long, time ago. adapted from the original c-mode.el
;; Version: 5.12
;; Keywords: c languages oop
;; NOTE: Read the commentary below for the right way to submit bug reports!
;; NOTE: See the accompanying texinfo manual for details on using this mode!
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; This package provides GNU Emacs major modes for editing C, C++,
;; Objective-C, and Java code. As of the latest Emacs and XEmacs
;; releases, it is the default package for editing these languages.
;; This package is called "CC Mode", and should be spelled exactly
;; this way. It supports K&R and ANSI C, ANSI C++, Objective-C, and
;; Java, with a consistent indentation model across all modes. This
;; indentation model is intuitive and very flexible, so that almost
;; any desired style of indentation can be supported. Installation,
;; usage, and programming details are contained in an accompanying
;; texinfo manual.
;; CC Mode's immediate ancestors were, c++-mode.el, cplus-md.el, and
;; cplus-md1.el..
;; NOTE: This mode does not perform font-locking (a.k.a syntactic
;; coloring, keyword highlighting, etc.) for any of the supported
;; modes. Typically this is done by a package called font-lock.el
;; which I do *not* maintain. You should contact the Emacs
;; maintainers for questions about coloring or highlighting in any
;; language mode.
;; To submit bug reports, type "C-c C-b". These will be sent to
;; bug-gnu-emacs@prep.ai.mit.edu as well as cc-mode-help@python.org,
;; and I'll read about them there (the former is mirrored as the
;; Usenet newsgroup gnu.emacs.bug). Questions can sent to
;; help-gnu-emacs@prep.ai.mit.edu (mirrored as gnu.emacs.help) and/or
;; cc-mode-help@python.org. Please do not send bugs or questions to
;; my personal account.
;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
;; the cross-Emacsen support. GNU Emacs 19 (from the FSF), GNU XEmacs
;; 19 (formerly Lucid Emacs), and GNU Emacs 18 all do things
;; differently and there's no way to shut the byte-compiler up at the
;; necessary granularity. Let me say this again: YOU CAN IGNORE ALL
;; BYTE-COMPILER WARNINGS (you'd be surprised at how many people don't
;; follow this advice :-).
;; Many, many thanks go out to all the folks on the beta test list.
;; Without their patience, testing, insight, code contributions, and
;; encouragement CC Mode would be a far inferior package.
;; You can get the latest version of CC Mode, including PostScript
;; documentation and separate individual files from:
;;
;; http://www.python.org/ftp/emacs/
;; Or if you don't have access to the World Wide Web, through
;; anonymous ftp from:
;;
;; ftp://ftp.python.org/pub/emacs
;;; Code:
(eval-when-compile
(require 'cc-menus))
(require 'cc-defs)
;;;###autoload
(defun c-mode ()
"Major mode for editing K&R and ANSI 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
problem, including a reproducible test case and send the message.
To see what version of CC Mode you are running, enter `\\[c-version]'.
The hook variable `c-mode-hook' is run with no args, if that value is
bound and has a non-nil value. Also the hook `c-mode-common-hook' is
run first.
Key bindings:
\\{c-mode-map}"
(interactive)
(c-load-all)
(kill-all-local-variables)
(set-syntax-table c-mode-syntax-table)
(setq major-mode 'c-mode
mode-name "C"
local-abbrev-table c-mode-abbrev-table)
(use-local-map c-mode-map)
(c-common-init)
(setq comment-start "/* "
comment-end " */"
comment-multi-line t
c-conditional-key c-C-conditional-key
c-class-key c-C-class-key
c-baseclass-key nil
c-comment-start-regexp c-C-comment-start-regexp
imenu-generic-expression cc-imenu-c-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'c-mode-hook)
(c-update-modeline))
;;;###autoload
(defun c++-mode ()
"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 problem, including a reproducible test case, and send the
message.
To see what version of CC Mode you are running, enter `\\[c-version]'.
The hook variable `c++-mode-hook' is run with no args, if that
variable is bound and has a non-nil value. Also the hook
`c-mode-common-hook' is run first.
Key bindings:
\\{c++-mode-map}"
(interactive)
(c-load-all)
(kill-all-local-variables)
(set-syntax-table c++-mode-syntax-table)
(setq major-mode 'c++-mode
mode-name "C++"
local-abbrev-table c++-mode-abbrev-table)
(use-local-map c++-mode-map)
(c-common-init)
(setq comment-start "// "
comment-end ""
comment-multi-line nil
c-conditional-key c-C++-conditional-key
c-comment-start-regexp c-C++-comment-start-regexp
c-class-key c-C++-class-key
c-access-key c-C++-access-key
c-double-slash-is-comments-p t
c-recognize-knr-p nil
imenu-generic-expression cc-imenu-c++-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'c++-mode-hook)
(c-update-modeline))
;;;###autoload
(defun objc-mode ()
"Major mode for editing Objective C code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
objc-mode buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
To see what version of CC Mode you are running, enter `\\[c-version]'.
The hook variable `objc-mode-hook' is run with no args, if that value
is bound and has a non-nil value. Also the hook `c-mode-common-hook'
is run first.
Key bindings:
\\{objc-mode-map}"
(interactive)
(c-load-all)
(kill-all-local-variables)
(set-syntax-table objc-mode-syntax-table)
(setq major-mode 'objc-mode
mode-name "ObjC"
local-abbrev-table objc-mode-abbrev-table)
(use-local-map objc-mode-map)
(c-common-init)
(setq comment-start "// "
comment-end ""
comment-multi-line nil
c-conditional-key c-C-conditional-key
c-comment-start-regexp c-C++-comment-start-regexp
c-class-key c-ObjC-class-key
c-baseclass-key nil
c-access-key c-ObjC-access-key
c-double-slash-is-comments-p t
c-method-key c-ObjC-method-key)
(run-hooks 'c-mode-common-hook)
(run-hooks 'objc-mode-hook)
(c-update-modeline))
;;;###autoload
(defun java-mode ()
"Major mode for editing Java code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
java-mode buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case and send the
message.
To see what version of CC Mode you are running, enter `\\[c-version]'.
The hook variable `java-mode-hook' is run with no args, if that value
is bound and has a non-nil value. Also the common hook
`c-mode-common-hook' is run first. Note that this mode automatically
sets the \"java\" style before calling any hooks so be careful if you
set styles in `c-mode-common-hook'.
Key bindings:
\\{java-mode-map}"
(interactive)
(c-load-all)
(kill-all-local-variables)
(set-syntax-table java-mode-syntax-table)
(setq major-mode 'java-mode
mode-name "Java"
local-abbrev-table java-mode-abbrev-table)
(use-local-map java-mode-map)
(c-common-init)
(setq comment-start "// "
comment-end ""
comment-multi-line nil
c-conditional-key c-Java-conditional-key
c-comment-start-regexp c-Java-comment-start-regexp
c-class-key c-Java-class-key
c-method-key c-Java-method-key
c-double-slash-is-comments-p t
c-baseclass-key nil
c-recognize-knr-p nil
c-access-key c-Java-access-key
;defun-prompt-regexp c-Java-defun-prompt-regexp
imenu-generic-expression cc-imenu-java-generic-expression
)
(c-set-style "java")
(run-hooks 'c-mode-common-hook)
(run-hooks 'java-mode-hook)
(c-update-modeline))
;; defuns for submitting bug reports
(defconst c-version "5.12"
"CC Mode version number.")
(defconst c-mode-help-address
"bug-gnu-emacs@prep.ai.mit.edu, cc-mode-help@python.org"
"Address for CC Mode bug reports.")
(defun c-version ()
"Echo the current version of CC Mode in the minibuffer."
(interactive)
(message "Using CC Mode version %s" c-version)
(c-keep-region-active))
;; Get reporter-submit-bug-report when byte-compiling
(eval-when-compile
(require 'reporter))
(defun c-submit-bug-report ()
"Submit via mail a bug report on CC Mode."
(interactive)
(require 'cc-vars)
;; load in reporter
(let ((reporter-prompt-for-summary-p t)
(reporter-dont-compact-list '(c-offsets-alist))
(style c-indentation-style)
(hook c-special-indent-hook)
(c-features c-emacs-features))
(and
(if (y-or-n-p "Do you want to submit a report on CC Mode? ")
t (message "") nil)
(require 'reporter)
(reporter-submit-bug-report
c-mode-help-address
(concat "CC Mode " c-version " ("
(cond ((eq major-mode 'c++-mode) "C++")
((eq major-mode 'c-mode) "C")
((eq major-mode 'objc-mode) "ObjC")
((eq major-mode 'java-mode) "Java")
)
")")
(let ((vars (list
;; report only the vars that affect indentation
'c-basic-offset
'c-offsets-alist
'c-cleanup-list
'c-comment-only-line-offset
'c-backslash-column
'c-delete-function
'c-electric-pound-behavior
'c-hanging-braces-alist
'c-hanging-colons-alist
'c-hanging-comment-starter-p
'c-hanging-comment-ender-p
'c-indent-comments-syntactically-p
'c-tab-always-indent
'c-recognize-knr-p
'c-label-minimum-indentation
'defun-prompt-regexp
'tab-width
)))
(if (not (boundp 'defun-prompt-regexp))
(delq 'defun-prompt-regexp vars)
vars))
(function
(lambda ()
(insert
"Buffer Style: " style "\n\n"
(if hook
(concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
"c-special-indent-hook is set to '"
(format "%s" hook)
".\nPerhaps this is your problem?\n"
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
"\n")
(format "c-emacs-features: %s\n" c-features)
)))
nil
"Dear Barry,"
))))
(provide 'cc-mode)
;;; cc-mode.el ends here

617
lisp/progmodes/cc-styles.el Normal file
View file

@ -0,0 +1,617 @@
;;; cc-styles.el --- support for styles in CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
(defconst c-style-alist
'(("gnu"
(c-basic-offset . 2)
(c-comment-only-line-offset . (0 . 0))
(c-offsets-alist . ((statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . +)
(label . 0)
(statement-case-open . +)
(statement-cont . +)
(arglist-intro . c-lineup-arglist-intro-after-paren)
(arglist-close . c-lineup-arglist)
))
(c-special-indent-hook . c-gnu-impose-minimum)
)
("k&r"
(c-basic-offset . 5)
(c-comment-only-line-offset . 0)
(c-offsets-alist . ((statement-block-intro . +)
(knr-argdecl-intro . 0)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
))
)
("bsd"
(c-basic-offset . 4)
(c-comment-only-line-offset . 0)
(c-offsets-alist . ((statement-block-intro . +)
(knr-argdecl-intro . +)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
))
)
("stroustrup"
(c-basic-offset . 4)
(c-comment-only-line-offset . 0)
(c-offsets-alist . ((statement-block-intro . +)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
))
)
("whitesmith"
(c-basic-offset . 4)
(c-comment-only-line-offset . 0)
(c-offsets-alist . ((statement-block-intro . +)
(knr-argdecl-intro . +)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
))
)
("ellemtel"
(c-basic-offset . 3)
(c-comment-only-line-offset . 0)
(c-hanging-braces-alist . ((substatement-open before after)))
(c-offsets-alist . ((topmost-intro . 0)
(topmost-intro-cont . 0)
(substatement . +)
(substatement-open . 0)
(case-label . +)
(access-label . -)
(inclass . ++)
(inline-open . 0)
))
)
("linux"
(c-basic-offset . 8)
(c-comment-only-line-offset . 0)
(c-hanging-braces-alist . ((brace-list-open)
(substatement-open after)
(block-close . c-snug-do-while)))
(c-cleanup-list . (brace-else-brace))
(c-offsets-alist . ((statement-block-intro . +)
(knr-argdecl-intro . 0)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
))
)
("python"
(indent-tabs-mode . t)
(fill-column . 72)
(c-basic-offset . 8)
(c-offsets-alist . ((substatement-open . 0)
))
(c-hanging-braces-alist . ((brace-list-open)
(brace-list-intro)
(brace-list-close)
(substatement-open after)
(block-close . c-snug-do-while)
))
)
("java"
(c-basic-offset . 2)
(c-comment-only-line-offset . (0 . 0))
(c-offsets-alist . ((topmost-intro-cont . +)
(statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . +)
(label . 0)
(statement-case-open . +)
(statement-cont . +)
(arglist-intro . c-lineup-arglist-intro-after-paren)
(arglist-close . c-lineup-arglist)
(access-label . 0)
(inher-cont . c-lineup-java-inher)
(func-decl-cont . c-lineup-java-throws)
))
)
)
"Styles of indentation.
Elements of this alist are of the form:
(STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
where STYLE-STRING is a short descriptive string used to select a
style, VARIABLE is any Emacs variable, and VALUE is the intended value
for that variable when using the selected style.
Optional BASE-STYLE if present, is a string and must follow
STYLE-STRING. BASE-STYLE names a style that this style inherits from.
By default, all styles inherit from the \"cc-mode\" style, which is
computed at run time. Style loops generate errors.
Two variables are treated specially. When VARIABLE is
`c-offsets-alist', the VALUE is a list containing elements of the
form:
(SYNTACTIC-SYMBOL . OFFSET)
as described in `c-offsets-alist'. These are passed directly to
`c-set-offset' so there is no need to set every syntactic symbol in
your style, only those that are different from the default.
When VARIABLE is `c-special-indent-hook', its VALUE is added to
`c-special-indent-hook' using `add-hook'. If VALUE is a list, each
element of the list is added with `add-hook'.
Do not change this variable directly. Use the function `c-add-style'
to add new styles or modify existing styles (it is not a good idea to
modify existing styles -- you should create a new style that inherits
the existing style.")
;; Functions that manipulate styles
(defun c-set-style-1 (conscell)
;; Set the style for one variable
(let ((attr (car conscell))
(val (cdr conscell)))
(cond
;; first special variable
((eq attr 'c-offsets-alist)
(mapcar
(function
(lambda (langentry)
(let ((langelem (car langentry))
(offset (cdr langentry)))
(c-set-offset langelem offset)
)))
val))
;; second special variable
((eq attr 'c-special-indent-hook)
(if (listp val)
(while val
(add-hook 'c-special-indent-hook (car val))
(setq val (cdr val)))
(add-hook 'c-special-indent-hook val)))
;; all other variables
(t (set attr val)))
))
(defun c-set-style-2 (style basestyles)
;; Recursively set the base style. If no base style is given, the
;; default base style is "cc-mode" and the recursion stops. Be sure
;; to detect loops.
(if (not (string-equal style "cc-mode"))
(let ((base (if (stringp (car basestyles))
(downcase (car basestyles))
"cc-mode")))
(if (memq base basestyles)
(error "Style loop detected: %s in %s" base basestyles))
(c-set-style-2 base (cons base basestyles))))
(let ((vars (cdr (or (assoc (downcase style) c-style-alist)
(assoc (upcase style) c-style-alist)
(assoc style c-style-alist)
(error "Undefined style: %s" style)))))
(mapcar 'c-set-style-1 vars)))
(defvar c-set-style-history nil)
;;;###autoload
(defun c-set-style (stylename)
"Set CC Mode variables to use one of several different indentation styles.
STYLENAME is a string representing the desired style from the list of
styles described in the variable `c-style-alist'. See that variable
for details of setting up styles.
The variable `c-indentation-style' always contains the buffer's current
style name."
(interactive (list (let ((completion-ignore-case t)
(prompt (format "Which %s indentation style? "
mode-name)))
(completing-read prompt c-style-alist nil t
(cons c-indentation-style 0)
'c-set-style-history))))
(c-set-style-2 stylename nil)
(setq c-indentation-style stylename)
(c-keep-region-active))
;;;###autoload
(defun c-add-style (style descrip &optional set-p)
"Adds a style to `c-style-alist', or updates an existing one.
STYLE is a string identifying the style to add or update. DESCRIP is
an association list describing the style and must be of the form:
([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
See the variable `c-style-alist' for the semantics of BASESTYLE,
VARIABLE and VALUE. This function also sets the current style to
STYLE using `c-set-style' if the optional SET-P flag is non-nil."
(interactive
(let ((stylename (completing-read "Style to add: " c-style-alist
nil nil nil 'c-set-style-history))
(description (eval-minibuffer "Style description: ")))
(list stylename description
(y-or-n-p "Set the style too? "))))
(setq style (downcase style))
(let ((s (assoc style c-style-alist)))
(if s
(setcdr s (copy-alist descrip)) ; replace
(setq c-style-alist (cons (cons style descrip) c-style-alist))))
(and set-p (c-set-style style)))
(defconst c-offsets-alist
'((string . -1000)
(c . c-lineup-C-comments)
(defun-open . 0)
(defun-close . 0)
(defun-block-intro . +)
(class-open . 0)
(class-close . 0)
(inline-open . +)
(inline-close . 0)
(func-decl-cont . +)
(knr-argdecl-intro . +)
(knr-argdecl . 0)
(topmost-intro . 0)
(topmost-intro-cont . 0)
(member-init-intro . +)
(member-init-cont . 0)
(inher-intro . +)
(inher-cont . c-lineup-multi-inher)
(block-open . 0)
(block-close . 0)
(brace-list-open . 0)
(brace-list-close . 0)
(brace-list-intro . +)
(brace-list-entry . 0)
(statement . 0)
;; some people might prefer
;;(statement . c-lineup-runin-statements)
(statement-cont . +)
;; some people might prefer
;;(statement-cont . c-lineup-math)
(statement-block-intro . +)
(statement-case-intro . +)
(statement-case-open . 0)
(substatement . +)
(substatement-open . +)
(case-label . 0)
(access-label . -)
(label . 2)
(do-while-closure . 0)
(else-clause . 0)
(comment-intro . c-lineup-comment)
(arglist-intro . +)
(arglist-cont . 0)
(arglist-cont-nonempty . c-lineup-arglist)
(arglist-close . +)
(stream-op . c-lineup-streamop)
(inclass . +)
(cpp-macro . -1000)
(friend . 0)
(objc-method-intro . -1000)
(objc-method-args-cont . c-lineup-ObjC-method-args)
(objc-method-call-cont . c-lineup-ObjC-method-call)
(extern-lang-open . 0)
(extern-lang-close . 0)
(inextern-lang . +)
)
"Association list of syntactic element symbols and indentation offsets.
As described below, each cons cell in this list has the form:
(SYNTACTIC-SYMBOL . OFFSET)
When a line is indented, CC Mode first determines the syntactic
context of the line by generating a list of symbols called syntactic
elements. This list can contain more than one syntactic element and
the global variable `c-syntactic-context' contains the context list
for the line being indented. Each element in this list is actually a
cons cell of the syntactic symbol and a buffer position. This buffer
position is called the relative indent point for the line. Some
syntactic symbols may not have a relative indent point associated with
them.
After the syntactic context list for a line is generated, CC Mode
calculates the absolute indentation for the line by looking at each
syntactic element in the list. First, it compares the syntactic
element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
finds a match, it adds the OFFSET to the column of the relative indent
point. The sum of this calculation for each element in the syntactic
list is the absolute offset for line being indented.
If the syntactic element does not match any in the `c-offsets-alist',
an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
element is ignored.
Actually, OFFSET can be an integer, a function, a variable, or one of
the following symbols: `+', `-', `++', `--', `*', or `/'. These
latter designate positive or negative multiples of `c-basic-offset',
respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
is called with a single argument containing the cons of the syntactic
element symbol and the relative indent point. The function should
return an integer offset.
Here is the current list of valid syntactic element symbols:
string -- inside multi-line string
c -- inside a multi-line C style block comment
defun-open -- brace that opens a function definition
defun-close -- brace that closes a function definition
defun-block-intro -- the first line in a top-level defun
class-open -- brace that opens a class definition
class-close -- brace that closes a class definition
inline-open -- brace that opens an in-class inline method
inline-close -- brace that closes an in-class inline method
func-decl-cont -- the region between a function definition's
argument list and the function opening brace
(excluding K&R argument declarations). In C, you
cannot put anything but whitespace and comments
between them; in C++ and Java, throws declarations
and other things can appear in this context.
knr-argdecl-intro -- first line of a K&R C argument declaration
knr-argdecl -- subsequent lines in a K&R C argument declaration
topmost-intro -- the first line in a topmost construct definition
topmost-intro-cont -- topmost definition continuation lines
member-init-intro -- first line in a member initialization list
member-init-cont -- subsequent member initialization list lines
inher-intro -- first line of a multiple inheritance list
inher-cont -- subsequent multiple inheritance lines
block-open -- statement block open brace
block-close -- statement block close brace
brace-list-open -- open brace of an enum or static array list
brace-list-close -- close brace of an enum or static array list
brace-list-intro -- first line in an enum or static array list
brace-list-entry -- subsequent lines in an enum or static array list
statement -- a C (or like) statement
statement-cont -- a continuation of a C (or like) statement
statement-block-intro -- the first line in a new statement block
statement-case-intro -- the first line in a case \"block\"
statement-case-open -- the first line in a case block starting with brace
substatement -- the first line after an if/while/for/do/else
substatement-open -- the brace that opens a substatement block
case-label -- a `case' or `default' label
access-label -- C++ private/protected/public access label
label -- any ordinary label
do-while-closure -- the `while' that ends a do/while construct
else-clause -- the `else' of an if/else construct
comment-intro -- a line containing only a comment introduction
arglist-intro -- the first line in an argument list
arglist-cont -- subsequent argument list lines when no
arguments follow on the same line as the
arglist opening paren
arglist-cont-nonempty -- subsequent argument list lines when at
least one argument follows on the same
line as the arglist opening paren
arglist-close -- the solo close paren of an argument list
stream-op -- lines continuing a stream operator construct
inclass -- the construct is nested inside a class definition
cpp-macro -- the start of a cpp macro
friend -- a C++ friend declaration
objc-method-intro -- the first line of an Objective-C method definition
objc-method-args-cont -- lines continuing an Objective-C method definition
objc-method-call-cont -- lines continuing an Objective-C method call
extern-lang-open -- brace that opens an external language block
extern-lang-close -- brace that closes an external language block
inextern-lang -- analogous to `inclass' syntactic symbol
")
(defun c-get-offset (langelem)
;; Get offset from LANGELEM which is a cons cell of the form:
;; (SYMBOL . RELPOS). The symbol is matched against
;; c-offsets-alist and the offset found there is either returned,
;; or added to the indentation at RELPOS. If RELPOS is nil, then
;; the offset is simply returned.
(let* ((symbol (car langelem))
(relpos (cdr langelem))
(match (assq symbol c-offsets-alist))
(offset (cdr-safe match)))
;; offset can be a number, a function, a variable, or one of the
;; symbols + or -
(cond
((not match)
(if c-strict-syntax-p
(error "don't know how to indent a %s" symbol)
(setq offset 0
relpos 0)))
((eq offset '+) (setq offset c-basic-offset))
((eq offset '-) (setq offset (- c-basic-offset)))
((eq offset '++) (setq offset (* 2 c-basic-offset)))
((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
((eq offset '*) (setq offset (/ c-basic-offset 2)))
((eq offset '/) (setq offset (/ (- c-basic-offset) 2)))
((functionp offset) (setq offset (funcall offset langelem)))
((not (numberp offset)) (setq offset (symbol-value offset)))
)
(+ (if (and relpos
(< relpos (c-point 'bol)))
(save-excursion
(goto-char relpos)
(current-column))
0)
offset)))
(defvar c-read-offset-history nil)
(defun c-read-offset (langelem)
;; read new offset value for LANGELEM from minibuffer. return a
;; legal value only
(let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
(defstr (format "(default %s): " oldoff))
(errmsg (concat "Offset must be int, func, var, "
"or in [+,-,++,--,*,/] "
defstr))
(prompt (concat "Offset " defstr))
offset input interned raw)
(while (not offset)
(setq input (completing-read prompt obarray 'fboundp nil nil
'c-read-offset-history)
offset (cond ((string-equal "" input) oldoff) ; default
((string-equal "+" input) '+)
((string-equal "-" input) '-)
((string-equal "++" input) '++)
((string-equal "--" input) '--)
((string-equal "*" input) '*)
((string-equal "/" input) '/)
((string-match "^-?[0-9]+$" input)
(string-to-int input))
;; a symbol with a function binding
((fboundp (setq interned (intern input)))
interned)
;; a lambda function
((c-safe (functionp (setq raw (read input))))
raw)
;; a symbol with variable binding
((boundp interned) interned)
;; error, but don't signal one, keep trying
;; to read an input value
(t (ding)
(setq prompt errmsg)
nil))))
offset))
(defun c-set-offset (symbol offset &optional add-p)
"Change the value of a syntactic element symbol in `c-offsets-alist'.
SYMBOL is the syntactic element symbol to change and OFFSET is the new
offset for that syntactic element. Optional ADD says to add SYMBOL to
`c-offsets-alist' if it doesn't already appear there."
(interactive
(let* ((langelem
(intern (completing-read
(concat "Syntactic symbol to change"
(if current-prefix-arg " or add" "")
": ")
(mapcar
#'(lambda (langelem)
(cons (format "%s" (car langelem)) nil))
c-offsets-alist)
nil (not current-prefix-arg)
;; initial contents tries to be the last element
;; on the syntactic analysis list for the current
;; line
(let* ((syntax (c-guess-basic-syntax))
(len (length syntax))
(ic (format "%s" (car (nth (1- len) syntax)))))
(cons ic 0))
)))
(offset (c-read-offset langelem)))
(list langelem offset current-prefix-arg)))
;; sanity check offset
(or (eq offset '+)
(eq offset '-)
(eq offset '++)
(eq offset '--)
(eq offset '*)
(eq offset '/)
(integerp offset)
(functionp offset)
(boundp offset)
(error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
offset))
(let ((entry (assq symbol c-offsets-alist)))
(if entry
(setcdr entry offset)
(if add-p
(setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
(error "%s is not a valid syntactic symbol." symbol))))
(c-keep-region-active))
(defun c-initialize-builtin-style ()
;; Dynamically append the default value of most variables. This is
;; crucial because future c-set-style calls will always reset the
;; variables first to the `cc-mode' style before instituting the new
;; style. Only do this once!
(require 'cl)
(or (assoc "cc-mode" c-style-alist)
(progn
(c-add-style "cc-mode"
(mapcar
(function
(lambda (var)
(let ((val (symbol-value var)))
(cons var (if (atom val) val
(copy-tree val)
))
)))
'(c-backslash-column
c-basic-offset
c-cleanup-list
c-comment-only-line-offset
c-electric-pound-behavior
c-hanging-braces-alist
c-hanging-colons-alist
c-hanging-comment-starter-p
c-hanging-comment-ender-p
c-offsets-alist
)))
;; the default style is now GNU. This can be overridden in
;; c-mode-common-hook or {c,c++,objc,java}-mode-hook.
(c-set-style c-site-default-style))))
(defun c-make-styles-buffer-local ()
"Make all CC Mode style variables buffer local.
If you edit primarily one style of C (or C++, Objective-C, Java) code,
you probably want style variables to be global. This is the default.
If you edit many different styles of C (or C++, Objective-C, Java) at
the same time, you probably want the CC Mode style variables to be
buffer local. If you do, then you will need to set any CC Mode style
variables in a hook function (e.g. off of c-mode-common-hook), instead
of at the top level of your ~/.emacs file.
This function makes all the CC Mode style variables buffer local.
Call it after CC Mode is loaded into your Emacs environment.
Conversely, set the variable `c-style-variables-are-local-p' to t in
your .emacs file, before CC Mode is loaded, and this function will be
automatically called when CC Mode is loaded."
;; style variables
(make-variable-buffer-local 'c-offsets-alist)
(make-variable-buffer-local 'c-basic-offset)
(make-variable-buffer-local 'c-file-style)
(make-variable-buffer-local 'c-file-offsets)
(make-variable-buffer-local 'c-comment-only-line-offset)
(make-variable-buffer-local 'c-cleanup-list)
(make-variable-buffer-local 'c-hanging-braces-alist)
(make-variable-buffer-local 'c-hanging-colons-alist)
(make-variable-buffer-local 'c-hanging-comment-starter-p)
(make-variable-buffer-local 'c-hanging-comment-ender-p)
(make-variable-buffer-local 'c-backslash-column)
(make-variable-buffer-local 'c-label-minimum-indentation)
(make-variable-buffer-local 'c-special-indent-hook)
(make-variable-buffer-local 'c-indentation-style))
(provide 'cc-styles)
;;; cc-styles.el ends here

391
lisp/progmodes/cc-vars.el Normal file
View file

@ -0,0 +1,391 @@
;;; cc-vars.el --- user customization variables for CC Mode
;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
;; Authors: 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Maintainer: cc-mode-help@python.org
;; Created: 22-Apr-1997 (split from cc-mode.el)
;; Version: 5.12
;; Keywords: c languages oop
;; This file is part of GNU Emacs.
;; 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 2, 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
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
(require 'custom)
(defcustom c-strict-syntax-p nil
"*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, an error is generated, otherwise no error is
reported and the syntactic symbol is ignored."
:type 'boolean
:group 'c)
(defcustom c-echo-syntactic-information-p nil
"*If non-nil, syntactic info is echoed when the line is indented."
:type 'boolean
:group 'c)
(defcustom c-basic-offset 4
"*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
:type 'integer
:group 'c)
(defcustom c-tab-always-indent t
"*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 insert a `real' tab character
\(see note\). If other than nil or t, then tab is inserted only
within literals -- defined as comments and strings -- and inside
preprocessor directives, but line is always reindented.
Note: The value of `indent-tabs-mode' will determine whether a real
tab character will be inserted, or the equivalent number of space.
When inserting a tab, actually the function stored in the variable
`c-insert-tab-function' is called.
Note: indentation of lines containing only comments is also controlled
by the `c-comment-only-line-offset' variable."
:type '(radio
:extra-offset 8
:format "%{C Tab Always Indent%}:\n The TAB key:\n%v"
(const :tag "always indents, never inserts TAB" t)
(const :tag "indents in left margin, otherwise inserts TAB" nil)
(const :tag "inserts TAB in literals, otherwise indent" other))
:group 'c)
(defcustom c-insert-tab-function 'insert-tab
"*Function used when inserting a tab for \\[TAB].
Only used when `c-tab-always-indent' indicates a `real' tab character
should be inserted. Value must be a function taking no arguments."
:type 'function
:group 'c)
(defcustom c-comment-only-line-offset 0
"*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)
Where NON-ANCHORED-OFFSET is the amount of offset given to
non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
the amount of offset to give column-zero anchored comment-only lines.
Just an integer as value is equivalent to (<val> . -1000)."
:type '(choice (integer :tag "Non-anchored offset")
(cons :tag "Non-anchored & anchored offset"
:value (0 . 0)
:extra-offset 8
(integer :tag "Non-anchored offset")
(integer :tag "Anchored offset")))
:group 'c)
(defcustom c-indent-comments-syntactically-p nil
"*Specifies how comment-only lines should be indented.
When this variable is non-nil, comment-only lines are indented
according to syntactic analysis via `c-offsets-alist', even when
\\[indent-for-comment] is used."
:type 'boolean
:group 'c)
(defcustom c-cleanup-list '(scope-operator)
"*List of various C/C++/ObjC constructs to \"clean up\".
These clean ups only take place when the auto-newline feature is
turned on, as evidenced by the `/a' or `/ah' appearing next to the
mode name. Valid symbols are:
brace-else-brace -- cleans up `} else {' constructs by placing entire
construct on a single line. This clean up
only takes place when there is nothing but
white space between the braces and the `else'.
Clean up occurs when the open-brace after the
`else' is typed.
brace-elseif-brace -- similar to brace-else-brace, but cleans up
`} else if {' constructs.
empty-defun-braces -- cleans up empty defun braces by placing the
braces on the same line. Clean up occurs when
the defun closing brace is typed.
defun-close-semi -- cleans up the terminating semi-colon on defuns
by placing the semi-colon on the same line as
the closing brace. Clean up occurs when the
semi-colon is typed.
list-close-comma -- cleans up commas following braces in array
and aggregate initializers. Clean up occurs
when the comma is typed.
scope-operator -- cleans up double colons which may designate
a C++ scope operator split across multiple
lines. Note that certain C++ constructs can
generate ambiguous situations. This clean up
only takes place when there is nothing but
whitespace between colons. Clean up occurs
when the second colon is typed."
:type '(set
:extra-offset 8
(const :tag "Put `} else {' on one line" brace-else-brace)
(const :tag "Put `} else if {' on one line" brace-elseif-brace)
(const :tag "Put empty defun braces on one line" empty-defun-braces)
(const :tag "Put `},' in aggregates on one line" list-close-comma)
(const :tag "Put C++ style `::' on one line" scope-operator))
:group 'c)
(defcustom c-hanging-braces-alist '((brace-list-open)
(substatement-open after)
(block-close . c-snug-do-while)
(extern-lang-open after)
)
"*Controls the insertion of newlines before and after braces.
This variable contains an association list with elements of the
following form: (SYNTACTIC-SYMBOL . ACTION).
When a brace (either opening or closing) is inserted, the syntactic
context it defines is looked up in this list, and if found, the
associated ACTION is used to determine where newlines are inserted.
If the context is not found, the default is to insert a newline both
before and after the brace.
SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
class-close, inline-open, inline-close, block-open, block-close,
substatement-open, statement-case-open, extern-lang-open,
extern-lang-close, brace-list-open, brace-list-close,
brace-list-intro, or brace-list-entry. See `c-offsets-alist' for
details.
ACTION can be either a function symbol or a list containing any
combination of the symbols `before' or `after'. If the list is empty,
no newlines are inserted either before or after the brace.
When ACTION is a function symbol, the function is called with a two
arguments: the syntactic symbol for the brace and the buffer position
at which the brace was inserted. The function must return a list as
described in the preceding paragraph. Note that during the call to
the function, the variable `c-syntactic-context' is set to the entire
syntactic context for the brace line."
:type '(repeat
(cons :format "%v"
(choice :tag "Syntax"
(const defun-open) (const defun-close)
(const class-open) (const class-close)
(const inline-open) (const inline-close)
(const block-open) (const block-close)
(const substatement-open) (const statement-case-open)
(const extern-lang-open) (const extern-lang-close)
(const brace-list-open) (const brace-list-close)
(const brace-list-intro) (const brace-list-entry))
(choice :tag "Action"
(set :format "Insert a newline %v"
:extra-offset 38
(const :tag "before brace" before)
(const :tag "after brace" after))
(function :format "Run function %v" :value c-)
)))
:group 'c)
(defcustom c-hanging-colons-alist nil
"*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).
SYNTACTIC-SYMBOL can be any of: case-label, label, access-label,
member-init-intro, or inher-intro.
See the variable `c-hanging-braces-alist' for the semantics of this
variable. Note however that making ACTION a function symbol is
currently not supported for this variable."
:type '(repeat
(cons :format "%v"
(choice :tag "Syntax"
(const case-label) (const label) (const access-label)
(const member-init-intro) (const inher-intro))
(set :tag "Action"
:format "%t: %v"
:extra-offset 8
(const before) (const after))))
:group 'c)
(defcustom c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
"*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
`c-electric-semi&comma'). Each function in this list is called with
no arguments, and should return one of the following values:
nil -- no determination made, continue checking
'stop -- do not insert a newline, and stop checking
(anything else) -- insert a newline, and stop checking
If every function in the list is called with no determination made,
then no newline is inserted."
:type '(repeat function)
:group 'c)
(defcustom c-hanging-comment-ender-p t
"*Controls what \\[fill-paragraph] does to C block comment enders.
When set to nil, C block comment enders are left on their own line.
When set to t, block comment enders will be placed at the end of the
previous line (i.e. they `hang' on that line)."
:type 'boolean
:group 'c)
(defcustom c-hanging-comment-starter-p t
"*Controls what \\[fill-paragraph] does to C block comment starters.
When set to nil, C block comment starters are left on their own line.
When set to t, text that follows a block comment starter will be
placed on the same line as the block comment starter (i.e. the text
`hangs' on that line)."
:type 'boolean
:group 'c)
(defcustom c-backslash-column 48
"*Column to insert backslashes when macroizing a region."
:type 'integer
:group 'c)
(defcustom c-special-indent-hook nil
"*Hook for user defined special indentation adjustments.
This hook gets called after a line is indented by the mode."
:type 'hook
:group 'c)
(defcustom c-backspace-function 'backward-delete-char-untabify
"*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' when deleting forwards."
:type 'function
:group 'c)
(defcustom c-electric-pound-behavior nil
"*List of behaviors for electric pound insertion.
Only currently supported behavior is `alignleft'."
:type '(set :extra-offset 8 (const alignleft))
:group 'c)
(defcustom c-label-minimum-indentation 1
"*Minimum indentation for lines inside of top-level constructs.
This variable typically only affects code using the `gnu' style, which
mandates a minimum of one space in front of every line inside
top-level constructs. Specifically, the function
`c-gnu-impose-minimum' on your `c-special-indent-hook' is what
enforces this."
:type 'integer
:group 'c)
(defcustom c-progress-interval 5
"*Interval used to update progress status during long re-indentation.
If a number, percentage complete gets updated after each interval of
that many seconds. Set to nil to inhibit updating. This is only
useful for Emacs 19."
:type 'integer
:group 'c)
(defcustom c-site-default-style "gnu"
"Default style for your site.
To change the default style at your site, you can set this variable to
any style defined in `c-style-alist'. However, if CC Mode is usually
loaded into your Emacs at compile time, you will need to set this
variable in the `site-init.el' file before CC Mode is loaded, then
re-dump Emacs."
:type 'string
:group 'c)
(defcustom c-style-variables-are-local-p nil
"*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
localized, they cannot be made global again.
The list of variables to buffer localize are:
c-offsets-alist
c-basic-offset
c-file-style
c-file-offsets
c-comment-only-line-offset
c-cleanup-list
c-hanging-braces-alist
c-hanging-colons-alist
c-hanging-comment-starter-p
c-hanging-comment-ender-p
c-backslash-column
c-label-minimum-indentation
c-special-indent-hook
c-indentation-style"
:type 'boolean
:group 'c)
(defcustom c-mode-hook nil
"*Hook called by `c-mode'."
:type '(hook :format "%{C Mode Hook%}:\n%v")
:group 'c)
(defcustom c++-mode-hook nil
"*Hook called by `c++-mode'."
:type 'hook
:group 'c)
(defcustom objc-mode-hook nil
"*Hook called by `objc-mode'."
:type 'hook
:group 'c)
(defcustom java-mode-hook nil
"*Hook called by `java-mode'."
:type 'hook
:group 'c)
(defcustom c-mode-common-hook nil
"*Hook called by all CC Mode modes for common initializations."
:type '(hook :format "%{CC Mode Common Hook%}:\n%v")
:group 'c)
;; Non-customizable variables, still part of the interface to CC Mode
(defvar c-file-style nil
"Variable interface for setting style via File Local Variables.
In a file's Local Variable section, you can set this variable to a
string suitable for `c-set-style'. When the file is visited, CC Mode
will set the style of the file to this value automatically.
Note that file style settings are applied before file offset settings
as designated in the variable `c-file-offsets'.")
(defvar c-file-offsets nil
"Variable interface for setting offsets via File Local Variables.
In a file's Local Variable section, you can set this variable to an
association list similar to the values allowed in `c-offsets-alist'.
When the file is visited, CC Mode will institute these offset settings
automatically.
Note that file offset settings are applied after file style settings
as designated in the variable `c-file-style'.")
(defvar c-syntactic-context nil
"Variable containing syntactic analysis list during indentation.")
(defvar c-indentation-style c-site-default-style
"Name of style installed in the current buffer.")
(provide 'cc-vars)
;;; cc-vars.el ends here