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.
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.
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:
Variable: c-initialization-hook
Hook run only once per Emacs session, when CC Mode is initialized. This is a good place to change
key bindings (or add new ones) in any of the CC Mode key maps. See
Sample Init File.
The sample it gives is here: https://www.gnu.org/software/emacs/manual/html_node/ccmode/Sample-Init-File.html#Sample-Init-File
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 your print
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.