Also (unrelated change) initialize the modes' keymaps at each loading.
* lisp/progmodes/cc-cmds.el (c-update-modeline): amend for the new information
on the modeline.
(c-block-comment-flag): New variable.
(c-toggle-comment-style): New function.
* lisp/progmodes/cc-langs.el (c-block-comment-starter)
(c-line-comment-starter): Make them c-lang-defvars.
(c-block-comment-is-default): New c-lang-defvar.
(comment-start, comment-end): Make the default values dependent on
c-block-comment-is-default.
* lisp/progmodes/cc-mode.el (c-mode-base-map): Define C-c C-k in this map.
(c-basic-common-init): Initialize c-block-comment-flag.
(c-mode-map, c++-mode-map, objc-mode-map, java-mode-map, idl-mode-map)
(pike-mode-map, awk-mode-map): Make entries in these key maps each time the
mode is loaded rather than just once per Emacs session.
* doc/misc/cc-mode.texi (Comment Commands): Introduce the notion of comment
style.
(Minor Modes): Define comment style. Describe how comment style influences
the information displayed on the modeline. Document c-toggle-comment-style.
(FAQ): Add a question about toggling the comment style.
@cindex comments (insertion of)
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+When the commands in this section add comment delimiters, they use
+either line comments or block comments depending on the setting of the
+comment style (@pxref{Minor Modes}).
+
@table @asis
@item @kbd{C-c C-c} (@code{comment-region})
@kindex C-c C-c
find useful while writing new code or editing old code:
@table @asis
+@item comment style
+This specifies whether comment commands (such as @kbd{M-;}) insert
+block comments or line comments.
@item electric mode
When this is enabled, certain visible characters cause reformatting as
they are typed. This is normally helpful, but can be a nuisance when
You can toggle each of these minor modes on and off, and you can
configure @ccmode{} so that it starts up with your favorite
combination of them (@pxref{Sample Init File}). By default, when
-you initialize a buffer, electric mode and syntactic-indentation mode
-are enabled but the other three modes are disabled.
-
-@ccmode{} displays the current state of the first four of these minor
-modes on the modeline by appending letters to the major mode's name,
-one letter for each enabled minor mode: @samp{l} for electric mode,
-@samp{a} for auto-newline mode, @samp{h} for hungry delete mode, and
-@samp{w} for subword mode. If all these modes were enabled, you'd see
-@samp{C/lahw}@footnote{The @samp{C} would be replaced with the name of
-the language in question for the other languages @ccmode{} supports.}.
+you initialize a buffer, the comment style is set to the default for
+the major mode, electric mode and syntactic-indentation mode are
+enabled, but the other three modes are disabled.
+
+@ccmode{} displays the current state of the first five of these minor
+modes on the mode line by appending characters to the major mode's
+name: @samp{/} or @samp{*} to indicate the comment style (respectively
+line or block), and one letter for each of the other minor modes which
+is enabled - @samp{l} for electric mode, @samp{a} for auto-newline
+mode, @samp{h} for hungry delete mode, and @samp{w} for subword mode.
+If the comment style was block and all the other modes were enabled,
+you'd see @samp{C/*lahw}@footnote{The @samp{C} would be replaced with
+the name of the language in question for the other languages @ccmode{}
+supports.}.
Here are the commands to toggle these modes:
@table @asis
+@item @kbd{C-c C-k} (@code{c-toggle-comment-style})
+@kindex C-c C-k
+@findex c-toggle-comment-style
+@findex toggle-comment-style (c-)
+Toggle the comment style between line style and block style. In modes
+(such as AWK Mode) which only have one of these styles, this function
+does nothing.
+
@item @kbd{C-c C-l} (@code{c-toggle-electric-state})
@kindex C-c C-l
@findex c-toggle-electric-state
@end table
Common to all the toggle functions above is that if they are called
-programmatically, they take an optional numerical argument. A
-positive value will turn on the minor mode (or both of them in the
-case of @code{c-toggle-auto-hungry-state}) and a negative value will
-turn it (or them) off.
+programmatically, they take an optional numerical argument. For
+@code{c-toggle-comment style}, a positive value will select block
+comments, a negative value will select line comments. For the other
+functions, a positive value will turn on the minor mode (or both of
+them in the case of @code{c-toggle-auto-hungry-state}) and a negative
+value will turn it (or them) off.
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@xref{Getting Started}. This was a very common question.
+@item
+@emph{How do I get block comments in my C++ files?}
+
+Interactively, change the comment style with @kbd{C-c C-k}.
+@xref{Minor Modes}.
+
+To configure this setting, say, for files within the gdb project, you
+could amend your C++ Mode hook like this:
+
+@example
+(defun my-c++-mode-hook ()
+ (if (string-match "/gdb/" (buffer-file-name))
+ (c-toggle-comment-style 1)))
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+@end example
+
@item
@emph{How do I stop my C++ lambda expressions being indented way over
to the right?}
\f
;; Minor mode functions.
(defun c-update-modeline ()
- (let ((fmt (format "/%s%s%s%s"
+ (let ((fmt (format "/%s%s%s%s%s"
+ (if c-block-comment-flag "*" "/")
(if c-electric-flag "l" "")
(if (and c-electric-flag c-auto-newline)
"a" "")
(bare-mode-name (if (string-match "\\(^[^/]*\\)/" mode-name)
(match-string 1 mode-name)
mode-name)))
-;; (setq c-submode-indicators
-;; (if (> (length fmt) 1)
-;; fmt))
(setq mode-name
(if (> (length fmt) 1)
(concat bare-mode-name fmt)
(electric-indent-local-mode (if c-electric-flag 1 0)))
(c-keep-region-active))
+;; `c-block-comment-flag' gets initialized to the current mode's default in
+;; c-basic-common-init.
+(defvar c-block-comment-flag nil)
+(make-variable-buffer-local 'c-block-comment-flag)
+
+(defun c-toggle-comment-style (&optional arg)
+ "Toggle the comment style between block and line comments.
+Optional numeric ARG, if supplied, switches to block comment
+style when positive, to line comment style when negative, and
+just toggles it when zero or left out.
+
+This action does nothing when the mode only has one comment style."
+ (interactive "P")
+ (setq c-block-comment-flag
+ (cond
+ ((and c-line-comment-starter c-block-comment-starter)
+ (c-calculate-state arg c-block-comment-flag))
+ (c-line-comment-starter nil)
+ (t t)))
+ (setq comment-start
+ (concat (if c-block-comment-flag
+ c-block-comment-starter
+ c-line-comment-starter)
+ " "))
+ (setq comment-end
+ (if c-block-comment-flag
+ (concat " " c-block-comment-ender)
+ ""))
+ (c-update-modeline)
+ (c-keep-region-active))
+
\f
;; Electric keys
properly."
t "/*"
awk nil)
+(c-lang-defvar c-block-comment-starter (c-lang-const c-block-comment-starter))
(c-lang-defconst c-block-comment-ender
"String that ends block comments, or nil if such don't exist.
properly."
t "*/"
awk nil)
+(c-lang-defvar c-block-comment-ender (c-lang-const c-block-comment-ender))
(c-lang-defconst c-block-comment-ender-regexp
;; Regexp which matches the end of a block comment (if such exists in the
(c-lang-defvar c-doc-comment-start-regexp
(c-lang-const c-doc-comment-start-regexp))
+(c-lang-defconst c-block-comment-is-default
+ "Non-nil when the default comment style is block comment."
+ ;; Note to maintainers of derived modes: You are responsible for ensuring
+ ;; the pertinent `c-block-comment-{starter,ender}' or
+ ;; `c-line-comment-{starter,ender}' are non-nil.
+ t nil
+ c t)
+(c-lang-defvar c-block-comment-is-default
+ (c-lang-const c-block-comment-is-default))
+
(c-lang-defconst comment-start
"String that starts comments inserted with M-; etc.
`comment-start' is initialized from this."
- ;; Default: Prefer line comments to block comments, and pad with a space.
- t (concat (or (c-lang-const c-line-comment-starter)
- (c-lang-const c-block-comment-starter))
- " ")
- ;; In C we still default to the block comment style since line
- ;; comments aren't entirely portable.
- c "/* ")
+ t (concat
+ (if (c-lang-const c-block-comment-is-default)
+ (c-lang-const c-block-comment-starter)
+ (c-lang-const c-line-comment-starter))
+ " "))
(c-lang-setvar comment-start (c-lang-const comment-start))
(c-lang-defconst comment-end
"String that ends comments inserted with M-; etc.
`comment-end' is initialized from this."
- ;; Default: Use block comment style if comment-start uses block
- ;; comments, and pad with a space in that case.
- t (if (string-match (concat "\\`\\("
- (c-lang-const c-block-comment-start-regexp)
- "\\)")
- (c-lang-const comment-start))
+ t (if (c-lang-const c-block-comment-is-default)
(concat " " (c-lang-const c-block-comment-ender))
""))
(c-lang-setvar comment-end (c-lang-const comment-end))
;;(define-key c-mode-base-map "\C-c\C-v" 'c-version)
;; (define-key c-mode-base-map "\C-c\C-y" 'c-toggle-hungry-state) Commented out by ACM, 2005-11-22.
(define-key c-mode-base-map "\C-c\C-w" 'c-subword-mode)
- )
+ (define-key c-mode-base-map "\C-c\C-k" 'c-toggle-comment-style))
;; We don't require the outline package, but we configure it a bit anyway.
(cc-bytecomp-defvar outline-level)
(setq yank-handled-properties (remq yank-cat-handler
yank-handled-properties)))))
- ;; For the benefit of adaptive file, which otherwise mis-fills.
+ ;; For the benefit of adaptive fill, which otherwise mis-fills.
(setq fill-paragraph-handle-comment nil)
;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a
;; setup the comment indent variable in a Emacs version portable way
(set (make-local-variable 'comment-indent-function) 'c-comment-indent)
+ ;; What sort of comments are default for M-;?
+ (setq c-block-comment-flag c-block-comment-is-default)
;; 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'
(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.")
+;; 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"
(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.")
+;; 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++)))
(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.")
+;; 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)))
(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.")
+;; 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
(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.")
+;; 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)))
(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.")
+;; 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)))
(defvar awk-mode-map
(let ((map (c-make-inherited-keymap)))
- ;; Add bindings which are only useful for awk.
- (define-key map "#" 'self-insert-command);Overrides electric parent binding.
- (define-key map "/" 'self-insert-command);Overrides electric parent binding.
- (define-key map "*" 'self-insert-command);Overrides electric parent binding.
- (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.")
+;; Add bindings which are only useful for awk.
+(define-key awk-mode-map "#" 'self-insert-command);Overrides electric parent binding.
+(define-key awk-mode-map "/" 'self-insert-command);Overrides electric parent binding.
+(define-key awk-mode-map "*" 'self-insert-command);Overrides electric parent binding.
+(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)))