X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/6a8f8193298e05931baeebb1bd3aba6f8f5a7b5e..83d208a5dd293caae48beb9d36dd45529375631a:/lisp/progmodes/cc-mode.el diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 50eaebe4de..1ce076734f 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1,6 +1,6 @@ ;;; cc-mode.el --- major mode for editing C and similar languages -;; Copyright (C) 1985, 1987, 1992-2012 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1987, 1992-2014 Free Software Foundation, Inc. ;; Authors: 2003- Alan Mackenzie ;; 1998- Martin Stjernholm @@ -75,7 +75,7 @@ ;; For Emacs < 22.2. (eval-and-compile - (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))) + (unless (fboundp 'declare-function) (defmacro declare-function (&rest _r)))) (eval-when-compile (let ((load-path @@ -86,8 +86,8 @@ (load "cc-bytecomp" nil t))) (cc-require 'cc-defs) -(cc-require-when-compile 'cc-langs) (cc-require 'cc-vars) +(cc-require-when-compile 'cc-langs) (cc-require 'cc-engine) (cc-require 'cc-styles) (cc-require 'cc-cmds) @@ -97,7 +97,6 @@ ;; Silence the compiler. (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs -(cc-bytecomp-defun set-keymap-parents) ; XEmacs (cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 ;; We set these variables during mode init, yet we don't require @@ -189,7 +188,12 @@ control). See \"cc-mode.el\" for more info." (setq c-block-comment-prefix (symbol-value 'c-comment-continuation-stars))) (add-hook 'change-major-mode-hook 'c-leave-cc-mode-mode) - (setq c-initialization-ok t)) + (setq c-initialization-ok t) + ;; Connect up with Emacs's electric-indent-mode, for >= Emacs 24.4 + (when (fboundp 'electric-indent-local-mode) + (add-hook 'electric-indent-mode-hook 'c-electric-indent-mode-hook) + (add-hook 'electric-indent-local-mode-hook + 'c-electric-indent-local-mode-hook))) ;; Will try initialization hooks again if they failed. (put 'c-initialize-cc-mode initprop c-initialization-ok)))) @@ -212,18 +216,22 @@ control). See \"cc-mode.el\" for more info." ((cc-bytecomp-fboundp 'set-keymap-parent) (set-keymap-parent map c-mode-base-map)) ;; XEmacs - ((cc-bytecomp-fboundp 'set-keymap-parents) + ((fboundp 'set-keymap-parents) (set-keymap-parents map c-mode-base-map)) ;; incompatible (t (error "CC Mode is incompatible with this version of Emacs"))) map)) -(defun c-define-abbrev-table (name defs) +(defun c-define-abbrev-table (name defs &optional doc) ;; Compatibility wrapper for `define-abbrev' which passes a non-nil ;; sixth argument for SYSTEM-FLAG in emacsen that support it ;; (currently only Emacs >= 21.2). - (let ((table (or (symbol-value name) - (progn (define-abbrev-table name nil) + (let ((table (or (and (boundp name) (symbol-value name)) + (progn (condition-case nil + (define-abbrev-table name nil doc) + (wrong-number-of-arguments ;E.g. Emacs<23. + (eval `(defvar ,name nil ,doc)) + (define-abbrev-table name nil))) (symbol-value name))))) (while defs (condition-case nil @@ -575,6 +583,15 @@ that requires a literal mode spec at compile time." ;; setup the comment indent variable in a Emacs version portable way (set (make-local-variable 'comment-indent-function) 'c-comment-indent) + ;; In Emacs 24.4 onwards, prevent Emacs's built in electric indentation from + ;; messing up CC Mode's, and set `c-electric-flag' if `electric-indent-mode' + ;; has been called by the user. + (when (boundp 'electric-indent-inhibit) (setq electric-indent-inhibit t)) + ;; CC-mode should obey Emacs's generic preferences, tho only do it if + ;; Emacs's generic preferences can be set per-buffer (Emacs>=24.4). + (when (fboundp 'electric-indent-local-mode) + (setq c-electric-flag electric-indent-mode)) + ;; ;; Put submode indicators onto minor-mode-alist, but only once. ;; (or (assq 'c-submode-indicators minor-mode-alist) ;; (setq minor-mode-alist @@ -647,7 +664,9 @@ compatible with old code; callers should always specify it." (set (make-local-variable 'outline-regexp) "[^#\n\^M]") (set (make-local-variable 'outline-level) 'c-outline-level) - + (set (make-local-variable 'add-log-current-defun-function) + (lambda () + (or (c-cpp-define-name) (c-defun-name)))) (let ((rfn (assq mode c-require-final-newline))) (when rfn (and (cdr rfn) @@ -802,7 +821,7 @@ Note that the style variables are always made local to the buffer." `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks)))) -;;; Change hooks, linking with Font Lock. +;;; Change hooks, linking with Font Lock and electric-indent-mode. ;; Buffer local variables recording Beginning/End-of-Macro position before a ;; change, when a macro straddles, respectively, the BEG or END (or both) of @@ -934,7 +953,8 @@ Note that the style variables are always made local to the buffer." ;; Add needed properties to each CPP construct in the region. (goto-char c-new-BEG) - (let ((pps-position c-new-BEG) pps-state mbeg) + (skip-chars-backward " \t") + (let ((pps-position (point)) pps-state mbeg) (while (and (< (point) c-new-END) (search-forward-regexp c-anchored-cpp-prefix c-new-END t)) ;; If we've found a "#" inside a string/comment, ignore it. @@ -943,14 +963,12 @@ Note that the style variables are always made local to the buffer." pps-position (point)) (unless (or (nth 3 pps-state) ; in a string? (nth 4 pps-state)) ; in a comment? - (goto-char (match-beginning 0)) + (goto-char (match-beginning 1)) (setq mbeg (point)) (if (> (c-syntactic-end-of-macro) mbeg) (progn (c-neutralize-CPP-line mbeg (point)) - (c-set-cpp-delimiters mbeg (point)) - ;(setq pps-position (point)) - ) + (c-set-cpp-delimiters mbeg (point))) (forward-line)) ; no infinite loop with, e.g., "#//" ))))) @@ -1028,13 +1046,17 @@ Note that the style variables are always made local to the buffer." (list type marked-id type-pos term-pos (buffer-substring-no-properties type-pos term-pos) - (buffer-substring-no-properties beg end))))))) - - (if c-get-state-before-change-functions - (mapc (lambda (fn) - (funcall fn beg end)) - c-get-state-before-change-functions)) - )))) + (buffer-substring-no-properties beg end))))))) + + (if c-get-state-before-change-functions + (let (open-paren-in-column-0-is-defun-start) + (mapc (lambda (fn) + (funcall fn beg end)) + c-get-state-before-change-functions))) + ))) + ;; The following must be done here rather than in `c-after-change' because + ;; newly inserted parens would foul up the invalidation algorithm. + (c-invalidate-state-cache beg)) (defvar c-in-after-change-fontification nil) (make-variable-buffer-local 'c-in-after-change-fontification) @@ -1055,7 +1077,7 @@ Note that the style variables are always made local to the buffer." ;; This calls the language variable c-before-font-lock-functions, if non nil. ;; This typically sets `syntax-table' properties. - (c-save-buffer-state () + (c-save-buffer-state (case-fold-search open-paren-in-column-0-is-defun-start) ;; When `combine-after-change-calls' is used we might get calls ;; with regions outside the current narrowing. This has been ;; observed in Emacs 20.7. @@ -1073,16 +1095,17 @@ Note that the style variables are always made local to the buffer." (setq beg end))) ;; C-y is capable of spuriously converting category properties - ;; c--as-paren-syntax into hard syntax-table properties. Remove - ;; these when it happens. + ;; c--as-paren-syntax and c-cpp-delimiter into hard syntax-table + ;; properties. Remove these when it happens. (c-clear-char-property-with-value beg end 'syntax-table c-<-as-paren-syntax) (c-clear-char-property-with-value beg end 'syntax-table c->-as-paren-syntax) + (c-clear-char-property-with-value beg end 'syntax-table nil) (c-trim-found-types beg end old-len) ; maybe we don't need all of these. (c-invalidate-sws-region-after beg end) - (c-invalidate-state-cache beg) + ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'. (c-invalidate-find-decl-cache beg) (when c-recognize-<>-arglists @@ -1142,7 +1165,7 @@ Note that the style variables are always made local to the buffer." (backward-char)) new-pos)) ; back over (, [, <. -(defun c-change-set-fl-decl-start (beg end old-len) +(defun c-change-set-fl-decl-start (_beg _end _old-len) ;; Set c-new-BEG to the beginning of a "local" declaration if it('s BOL) is ;; inside one. This is called from an after-change-function, but the ;; parameters BEG END and OLD-LEN are ignored. See `c-set-fl-decl-start' @@ -1156,9 +1179,6 @@ Note that the style variables are always made local to the buffer." ;; `c-set-fl-decl-start' for the detailed functionality. (cons (c-set-fl-decl-start beg) end)) -(defvar c-standard-font-lock-fontify-region-function nil - "Standard value of `font-lock-fontify-region-function'") - (defun c-font-lock-fontify-region (beg end &optional verbose) ;; Effectively advice around `font-lock-fontify-region' which extends the ;; region (BEG END), for example, to avoid context fontification chopping @@ -1173,7 +1193,8 @@ Note that the style variables are always made local to the buffer." ;; ;; Type a space in the first blank line, and the fontification of the next ;; line was fouled up by context fontification. - (let ((new-beg beg) (new-end end) new-region case-fold-search) + (let ((new-beg beg) (new-end end) new-region case-fold-search + open-paren-in-column-0-is-defun-start) (if c-in-after-change-fontification (setq c-in-after-change-fontification nil) (save-restriction @@ -1183,17 +1204,14 @@ Note that the style variables are always made local to the buffer." (setq new-region (funcall fn new-beg new-end)) (setq new-beg (car new-region) new-end (cdr new-region))) c-before-context-fontification-functions)))) - (funcall c-standard-font-lock-fontify-region-function + (funcall (default-value 'font-lock-fontify-region-function) new-beg new-end verbose))) (defun c-after-font-lock-init () ;; Put on `font-lock-mode-hook'. This function ensures our after-change - ;; function will get executed before the font-lock one. Amongst other - ;; things. + ;; function will get executed before the font-lock one. (remove-hook 'after-change-functions 'c-after-change t) - (add-hook 'after-change-functions 'c-after-change nil t) - (setq c-standard-font-lock-fontify-region-function - (default-value 'font-lock-fontify-region-function))) + (add-hook 'after-change-functions 'c-after-change nil t)) (defun c-font-lock-init () "Set up the font-lock variables for using the font-lock support in CC Mode. @@ -1221,7 +1239,7 @@ This function is called from `c-common-init', once per mode initialization." (make-local-hook 'font-lock-mode-hook)) (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t)) -(defun c-extend-after-change-region (beg end old-len) +(defun c-extend-after-change-region (_beg _end _old-len) "Extend the region to be fontified, if necessary." ;; Note: the parameters are ignored here. This somewhat indirect ;; implementation exists because it is minimally different from the @@ -1234,30 +1252,44 @@ This function is called from `c-common-init', once per mode initialization." ;; function. (cons c-new-BEG c-new-END)) +;; Connect up to `electric-indent-mode' (Emacs 24.4 and later). +(defun c-electric-indent-mode-hook () + ;; Emacs has en/disabled `electric-indent-mode'. Propagate this through to + ;; each CC Mode buffer. + (mapc (lambda (buf) + (with-current-buffer buf + (when c-buffer-is-cc-mode + ;; Don't use `c-toggle-electric-state' here due to recursion. + (setq c-electric-flag electric-indent-mode) + (c-update-modeline)))) + (buffer-list))) + +(defun c-electric-indent-local-mode-hook () + ;; Emacs has en/disabled `electric-indent-local-mode' for this buffer. + ;; Propagate this through to this buffer's value of `c-electric-flag' + (when c-buffer-is-cc-mode + (setq c-electric-flag electric-indent-mode) + (c-update-modeline))) + ;; Support for C -;;;###autoload -(defvar c-mode-syntax-table nil +(defvar c-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table c)) "Syntax table used in c-mode buffers.") -(or c-mode-syntax-table - (setq c-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table c)))) -(defvar c-mode-abbrev-table nil - "Abbreviation table used in c-mode buffers.") (c-define-abbrev-table 'c-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) - ("while" "while" c-electric-continued-statement 0))) + ("while" "while" c-electric-continued-statement 0)) + "Abbreviation table used in c-mode buffers.") -(defvar c-mode-map () +(defvar c-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for C. + (define-key map "\C-c\C-e" 'c-macro-expand) + 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-e" 'c-macro-expand) - ) + (easy-menu-define c-c-menu c-mode-map "C Mode Commands" (cons "C" (c-lang-const c-mode-menu c))) @@ -1322,30 +1354,25 @@ Key bindings: ;; Support for C++ -;;;###autoload -(defvar c++-mode-syntax-table nil +(defvar c++-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table c++)) "Syntax table used in c++-mode buffers.") -(or c++-mode-syntax-table - (setq c++-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table c++)))) -(defvar c++-mode-abbrev-table nil - "Abbreviation table used in c++-mode buffers.") (c-define-abbrev-table 'c++-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) ("while" "while" c-electric-continued-statement 0) - ("catch" "catch" c-electric-continued-statement 0))) + ("catch" "catch" c-electric-continued-statement 0)) + "Abbreviation table used in c++-mode buffers.") -(defvar c++-mode-map () +(defvar c++-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for C++. + (define-key map "\C-c\C-e" 'c-macro-expand) + (define-key map "\C-c:" 'c-scope-operator) + (define-key map "<" 'c-electric-lt-gt) + (define-key map ">" 'c-electric-lt-gt) + 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-e" 'c-macro-expand) - (define-key c++-mode-map "\C-c:" 'c-scope-operator) - (define-key c++-mode-map "<" 'c-electric-lt-gt) - (define-key c++-mode-map ">" 'c-electric-lt-gt)) (easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands" (cons "C++" (c-lang-const c-mode-menu c++))) @@ -1382,26 +1409,21 @@ Key bindings: ;; Support for Objective-C -;;;###autoload -(defvar objc-mode-syntax-table nil +(defvar objc-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table objc)) "Syntax table used in objc-mode buffers.") -(or objc-mode-syntax-table - (setq objc-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table objc)))) -(defvar objc-mode-abbrev-table nil - "Abbreviation table used in objc-mode buffers.") (c-define-abbrev-table 'objc-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) - ("while" "while" c-electric-continued-statement 0))) + ("while" "while" c-electric-continued-statement 0)) + "Abbreviation table used in objc-mode buffers.") -(defvar objc-mode-map () +(defvar objc-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for Objective-C. + (define-key map "\C-c\C-e" 'c-macro-expand) + 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-c\C-e" 'c-macro-expand)) (easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands" (cons "ObjC" (c-lang-const c-mode-menu objc))) @@ -1440,28 +1462,22 @@ Key bindings: ;; Support for Java -;;;###autoload -(defvar java-mode-syntax-table nil +(defvar java-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table java)) "Syntax table used in java-mode buffers.") -(or java-mode-syntax-table - (setq java-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table java)))) -(defvar java-mode-abbrev-table nil - "Abbreviation table used in java-mode buffers.") (c-define-abbrev-table 'java-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) ("while" "while" c-electric-continued-statement 0) ("catch" "catch" c-electric-continued-statement 0) - ("finally" "finally" c-electric-continued-statement 0))) + ("finally" "finally" c-electric-continued-statement 0)) + "Abbreviation table used in java-mode buffers.") -(defvar java-mode-map () +(defvar java-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for Java. + 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 - ) ;; Regexp trying to describe the beginning of a Java top-level ;; definition. This is not used by CC Mode, nor is it maintained @@ -1506,24 +1522,18 @@ Key bindings: ;; Support for CORBA's IDL language -;;;###autoload -(defvar idl-mode-syntax-table nil +(defvar idl-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table idl)) "Syntax table used in idl-mode buffers.") -(or idl-mode-syntax-table - (setq idl-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table idl)))) -(defvar idl-mode-abbrev-table nil +(c-define-abbrev-table 'idl-mode-abbrev-table nil "Abbreviation table used in idl-mode buffers.") -(c-define-abbrev-table 'idl-mode-abbrev-table nil) -(defvar idl-mode-map () +(defvar idl-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for IDL. + map) "Keymap used in idl-mode buffers.") -(if idl-mode-map - nil - (setq idl-mode-map (c-make-inherited-keymap)) - ;; add bindings which are only useful for IDL - ) (easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands" (cons "IDL" (c-lang-const c-mode-menu idl))) @@ -1560,26 +1570,21 @@ Key bindings: ;; Support for Pike -;;;###autoload -(defvar pike-mode-syntax-table nil +(defvar pike-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table pike)) "Syntax table used in pike-mode buffers.") -(or pike-mode-syntax-table - (setq pike-mode-syntax-table - (funcall (c-lang-const c-make-mode-syntax-table pike)))) -(defvar pike-mode-abbrev-table nil - "Abbreviation table used in pike-mode buffers.") (c-define-abbrev-table 'pike-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) - ("while" "while" c-electric-continued-statement 0))) + ("while" "while" c-electric-continued-statement 0)) + "Abbreviation table used in pike-mode buffers.") -(defvar pike-mode-map () +(defvar pike-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Additional bindings. + (define-key map "\C-c\C-e" 'c-macro-expand) + map) "Keymap used in pike-mode buffers.") -(if pike-mode-map - nil - (setq pike-mode-map (c-make-inherited-keymap)) - ;; additional bindings - (define-key pike-mode-map "\C-c\C-e" 'c-macro-expand)) (easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands" (cons "Pike" (c-lang-const c-mode-menu pike))) @@ -1624,32 +1629,26 @@ Key bindings: ;;;###autoload (add-to-list 'interpreter-mode-alist '("nawk" . awk-mode)) ;;;###autoload (add-to-list 'interpreter-mode-alist '("gawk" . awk-mode)) -;;; Autoload directives must be on the top level, so we construct an -;;; autoload form instead. -;;;###autoload (autoload 'awk-mode "cc-mode" "Major mode for editing AWK code." t) - -(defvar awk-mode-abbrev-table nil - "Abbreviation table used in awk-mode buffers.") (c-define-abbrev-table 'awk-mode-abbrev-table '(("else" "else" c-electric-continued-statement 0) - ("while" "while" c-electric-continued-statement 0))) + ("while" "while" c-electric-continued-statement 0)) + "Abbreviation table used in awk-mode buffers.") -(defvar awk-mode-map () +(defvar awk-mode-map + (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for awk. + (define-key map "#" 'self-insert-command) + (define-key map "/" 'self-insert-command) + (define-key map "*" 'self-insert-command) + (define-key map "\C-c\C-n" 'undefined) ; #if doesn't exist in awk. + (define-key map "\C-c\C-p" 'undefined) + (define-key map "\C-c\C-u" 'undefined) + (define-key map "\M-a" 'c-beginning-of-statement) ; 2003/10/7 + (define-key map "\M-e" 'c-end-of-statement) ; 2003/10/7 + (define-key map "\C-\M-a" 'c-awk-beginning-of-defun) + (define-key map "\C-\M-e" 'c-awk-end-of-defun) + map) "Keymap used in awk-mode buffers.") -(if awk-mode-map - nil - (setq awk-mode-map (c-make-inherited-keymap)) - ;; add bindings which are only useful for awk. - (define-key awk-mode-map "#" 'self-insert-command) - (define-key awk-mode-map "/" 'self-insert-command) - (define-key awk-mode-map "*" 'self-insert-command) - (define-key awk-mode-map "\C-c\C-n" 'undefined) ; #if doesn't exist in awk. - (define-key awk-mode-map "\C-c\C-p" 'undefined) - (define-key awk-mode-map "\C-c\C-u" 'undefined) - (define-key awk-mode-map "\M-a" 'c-beginning-of-statement) ; 2003/10/7 - (define-key awk-mode-map "\M-e" 'c-end-of-statement) ; 2003/10/7 - (define-key awk-mode-map "\C-\M-a" 'c-awk-beginning-of-defun) - (define-key awk-mode-map "\C-\M-e" 'c-awk-end-of-defun)) (easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands" (cons "AWK" (c-lang-const c-mode-menu awk))) @@ -1767,6 +1766,7 @@ Key bindings: filladapt-mode defun-prompt-regexp font-lock-mode + auto-fill-mode font-lock-maximum-decoration parse-sexp-lookup-properties lookup-syntax-properties))