Turning on hungry-delete-key empowers the Del key to delete all whitespace to the left of the point. To go back to the previous example, assume you just typed the open curly brace. Then, if you press Del, Emacs deletes everything back to the curly brace:
int times (x, y)
int x, y;
{_
You can toggle the states of both auto-newline and hungry-delete-key with the command C-c C-t (for c-toggle-auto-hungry-state).
If you want either of these features on by default when you invoke Emacs, you can put lines like the following in your .emacs file:
(add-hook 'c-mode-hook
'(lambda ( )
(c-toggle-auto-state)))
If you want to combine this customization with another C mode customization, such as the indentation style in the previous example, you need to combine the lines of Emacs Lisp code as follows:
(add-hook 'c-mode-hook
'(lambda ( )
(c-set-style "stylename")
(c-toggle-auto-state)))
Again, we will see what this hook construct means in "Customizing Existing Modes" in Chapter 11.
C mode also provides support for comments; earlier in the chapter, we saw examples of this support. There is, however, another feature. You can customize M-j (for indent-new-comment-line) so that Emacs continues the same comment on the next line instead of creating a new pair of delimiters. The variable comment-multi-line controls this feature: if it is set to nil (the default), Emacs generates a new comment on the next line, as in the example from earlier in the chapter:
result += y; /* add the multiplicand */
/* */
This outcome is the result of typing M-j after multiplicand, and it shows that the cursor is positioned so that you can type the text of the second comment line. However, if you set comment-multi-line to t (or any value other than nil), you get this outcome instead:
result += y; /* add the multiplicand
*/
The final feature we'll cover is C-c C-e, (for c-macro-expand). Like the conditional compilation motion commands (e.g., C-c C-u for c-up-conditional), c-macro-expand helps you answer the often difficult question, "What code actually gets compiled?" when your source code contains a morass of preprocessor directives.
To use c-macro-expand, you must first define a region. Then, when you type C-c C-e, it takes the code within the region, passes it through the actual C preprocessor, and places the output in a window called *Macroexpansion*.
To see how this procedure works, let's go back to the code example from earlier in this chapter that contains C preprocessor directives:
#define LUCYX
#define BADEXIT -1
#ifdef LUCYX
*ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return BADEXIT;
#else
fprintf (stderr, "You can't do that on this system!");
#endif
If you define a region around this chunk of code and type C-c C-e, you see following the message:
Invoking /lib/cpp -C on region...
followed by this:
done
Then you see a *Macroexpansion* window that contains this result:
*ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return -1;
If you want to use c-macro-expand with a different C preprocessor command, instead of the default /lib/cpp -C (the -C option means "preserve comments in the output"), you can set the variable c-macro-preprocessor. For example, if you want to use an experimental preprocessor whose filename is /usr/local/lib/cpp, put the following line in your .emacs file:
(setq c-macro-preprocessor "/usr/local/lib/cpp -C")
It's highly recommended that you keep the -C option for not deleting comments in your code.
9.3.4 C++ Mode Differences
As we mentioned before, C++ mode uses the same Emacs Lisp package as C mode. When you're in C++ mode, Emacs understands C++ syntax, as opposed to C (or Objective-C) syntax. That results in differences in how some of the commands discussed here behave, but in ways that are not noticeable to the user.
There are few apparent differences between C++ and C mode. The most important is the Emacs Lisp code you need to put in your .emacs file to customize C++ mode: instead of c-mode-hook, you use c++-mode-hook. For example, if you want C++ mode's indentation style set to Stroustrup with automatic newlines instead of the default style, put the following in your .emacs file:
(add-hook 'c++-mode-hook
'(lambda ( )
(c-set-style "Stroustrup")
(c-toggle-auto-state)))
Notice that you can set hooks for C mode and C++ mode separately this way, so that if you program in both languages, you can set up separate indentation styles for each.
C++ mode provides an additional command: C-c : (for c-scope-operator). This command inserts the C++ double colon (::) scope operator. It's necessary because the colon (:) is normally bound to electric functionality that can reindent the line when you don't want that done. The scope operator can appear virtually anywhere in C++ code whereas the single colon usually denotes a case label, which requires special indentation. The C-c : command may seem somewhat clumsy, but it's a necessary workaround to a syntactic clash in the C++ language.
Finally, both C and C++ mode contain the commands c-forward-into-nomenclature and c-backward-into-nomenclature, which aren't bound to any keystrokes by default. These are like forward-word and backward-word, respectively, but they treat capital letters in the middle of words as if they were starting new words. For example, they treat ThisVariableName as if it were three separate words while the standard forward-word and backward-word commands treat it as one word. ThisTypeOfVariableName is a style used by C++ programmers, as opposed to this_type_of_variable_name, which is somehow more endemic to old-school C code.