From 7a2038d7c887e4fa08a91950a7494d1dd20c39e1 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Thu, 15 Jun 2017 20:47:11 +0000 Subject: [PATCH] Create a toggle between block and line comments in CC Mode. 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. --- doc/misc/cc-mode.texi | 65 ++++++++++++++++++++++++++++++-------- lisp/progmodes/cc-cmds.el | 37 +++++++++++++++++++--- lisp/progmodes/cc-langs.el | 31 ++++++++++-------- lisp/progmodes/cc-mode.el | 54 ++++++++++++++++--------------- 4 files changed, 130 insertions(+), 57 deletions(-) diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi index 91e20fa7247..f9ba5cc3921 100644 --- a/doc/misc/cc-mode.texi +++ b/doc/misc/cc-mode.texi @@ -812,6 +812,10 @@ often (in seconds) progress messages are to be displayed. @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 @@ -1133,6 +1137,9 @@ line break. 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 @@ -1168,20 +1175,32 @@ and @ref{Indentation Engine Basics}. 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 @@ -1218,10 +1237,12 @@ Toggle syntactic-indentation mode. @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 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -7231,6 +7252,22 @@ too, add this to your @code{c-initialization-hook}: @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?} diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 9c0798e7529..6250725c179 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -252,7 +252,8 @@ With universal argument, inserts the analysis as a comment on that line." ;; 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" "") @@ -270,9 +271,6 @@ With universal argument, inserts the analysis as a comment on that line." (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) @@ -362,6 +360,37 @@ left out." (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)) + ;; Electric keys diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 84d4eab75af..a9d5ac34ad4 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1449,6 +1449,7 @@ comment style. Other stuff like the syntax table must also be set up 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. @@ -1458,6 +1459,7 @@ comment style. Other stuff like the syntax table must also be set up 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 @@ -1515,27 +1517,30 @@ properly." (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)) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 20c63d4dbe2..a501ebba256 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -398,7 +398,7 @@ control). See \"cc-mode.el\" for more info." ;;(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) @@ -547,7 +547,7 @@ that requires a literal mode spec at compile time." (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 @@ -623,6 +623,8 @@ 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) + ;; 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' @@ -1621,10 +1623,10 @@ This function is called from `c-common-init', once per mode initialization." (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" @@ -1737,13 +1739,13 @@ the code is C or C++ and based on that chooses whether to enable (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++))) @@ -1789,10 +1791,10 @@ Key bindings: (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))) @@ -1842,9 +1844,9 @@ Key bindings: (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 @@ -1895,9 +1897,9 @@ Key bindings: (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))) @@ -1942,10 +1944,10 @@ Key bindings: (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))) @@ -1994,19 +1996,19 @@ Key bindings: (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))) -- 2.39.2