From 29238d289dc33b70059bdfd82588db84254004a1 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Mon, 17 Feb 2014 18:16:32 +0000 Subject: [PATCH] Connect electric-indent-mode up with CC Mode. Bug #15478. * progmodes/cc-mode.el (c-initialize-cc-mode): add CC Mode hooks to electric-indent-{,local-}-mode. (c-basic-common-init): Set electric-indent-inhibit. Initialise c-electric-flag from electric-indent-mode. (c-electric-indent-mode-hook, c-electric-indent-local-mode-hook): New hook functions which propagate electric-indent-mode to CC Mode. * progmodes/cc-cmds.el (c-toggle-electric-state): When C-c C-l is hit, toggle electric-indent-local-moode. * electric.el (electric-indent-mode-has-been-called): New variable. --- lisp/ChangeLog | 17 +++++++++++++++++ lisp/electric.el | 5 +++++ lisp/progmodes/cc-cmds.el | 2 ++ lisp/progmodes/cc-mode.el | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 27a0ffd30a..5dad77bcdf 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,20 @@ +2014-02-17 Alan Mackenzie + + Connect electric-indent-mode up with CC Mode. Bug #15478. + * progmodes/cc-mode.el (c-initialize-cc-mode): add CC Mode hooks + to electric-indent-{,local-}-mode. + (c-basic-common-init): Set electric-indent-inhibit. Initialise + c-electric-flag from electric-indent-mode. + (c-electric-indent-mode-hook, c-electric-indent-local-mode-hook): + New hook functions which propagate electric-indent-mode to CC + Mode. + + * progmodes/cc-cmds.el (c-toggle-electric-state): When C-c C-l is + hit, toggle electric-indent-local-moode. + + * electric.el (electric-indent-mode-has-been-called): New + variable. + 2014-02-17 Juanma Barranquero * frameset.el (frameset-cfg-id): New function. diff --git a/lisp/electric.el b/lisp/electric.el index 32c4a82449..4549fcad83 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -286,6 +286,9 @@ mode set `electric-indent-inhibit', but this can be used as a workaround.") (let ((electric-indent-mode nil)) (newline arg 'interactive))) +(defvar electric-indent-mode-has-been-called 0 + "How many times has `electric-indent-mode' been called? +It's > 1 if it's been called at least once by the user.") ;;;###autoload (define-minor-mode electric-indent-mode "Toggle on-the-fly reindentation (Electric Indent mode). @@ -299,6 +302,8 @@ insert a character from `electric-indent-chars'." :global t :group 'electricity :initialize 'custom-initialize-delay :init-value t + (setq electric-indent-mode-has-been-called + (1+ electric-indent-mode-has-been-called)) (if (not electric-indent-mode) (progn (when (eq (lookup-key global-map [?\C-j]) diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index bf651f8ae9..4f205d62a4 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -356,6 +356,8 @@ left out." (interactive "P") (setq c-electric-flag (c-calculate-state arg c-electric-flag)) (c-update-modeline) + (when (fboundp 'electric-indent-local-mode) ; Emacs 24.4 or later. + (electric-indent-local-mode (if c-electric-flag 1 0))) (c-keep-region-active)) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index e8d447cd1f..9b18bbf82a 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -188,7 +188,13 @@ 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-mode) + (add-hook 'electric-indent-mode-hook 'c-electric-indent-mode-hook) + (when (fboundp 'electric-indent-local-mode) + (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)))) @@ -578,6 +584,14 @@ 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)) + (when (and (boundp 'electric-indent-mode-has-been-called) + (> electric-indent-mode-has-been-called 1)) + (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 @@ -807,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 @@ -1238,6 +1252,27 @@ 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. + (when (and (boundp 'electric-indent-mode-has-been-called) + (> electric-indent-mode-has-been-called 1)) + (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 -- 2.20.1