I use this command to start emacs
$ emacs -Q c-mode-test.el
then I use C-xC-e to eval every line
(require 'cc-mode)
(add-hook 'c-mode-common-hook '(lambda () (print "hello")))
(add-hook 'c-mode-hook '(lambda () (print "hello c")))
(c-mode)
after this, the minibuffer shows
"hello"
"hello c"
"hello c"
nil
and c++-mode-hook run just the same
(add-hook 'c++-mode-hook '(lambda () (print "hello c++")))
(c++-mode)
the minibuffer
"hello"
"hello c++"
"hello c++"
nil
why it run twice or something wrong.
It seems that the language-specific hooks are getting run more than once. You can confirm that this is the case by running
(run-hooks c-mode-hook)
or(run-hooks c-mode-common-hook)
, and you'll notice that yourprint
statement only happens once.The general advice with hooks is to not be dependent on the order in which they're run -- not depending on how many times they're run seems like a natural extension there.
There is a bug report about this http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16759 I don't think that language hooks are guaranteed to be executed once for a number of language modes. I suspect the issue is due to using
define-derived-mode
which is a lisp macro for defining a mode that already includes calls to hooks, this means the hooks called in the mode will be an additional execution.You might want to try the initialization hook. The manual says:
The sample it gives is here: https://www.gnu.org/software/emacs/manual/html_node/ccmode/Sample-Init-File.html#Sample-Init-File
You are using the wrong hook for your "C" files. The correct hook to use is "c-mode-hook".
The hook "c-mode-common-hook" is run before every c-style language. That is, the hook is run for many languages such as java, objective-c, awk and others. You can find more information about these hooks here.