When auto-newline is enabled, it causes Emacs to add a newline character and indent the new line properly whenever you type a semicolon (;), curly brace ({ or }), or, at certain times, comma (,) or colon (:). These features can save you some time and help you format your code in a consistent style.
Auto-newline is off by default. To turn it on, type C-c C-afor c-toggle-auto-state. (Repeat the same command to turn it off again.) You will see the (C)in the mode line change to (C/a)as an indication. As an example of how it works, try typing in the code for our times( )
function. Type the first two lines up to the yon the second line:
int times (x, y)
int x, y
_
Now press the semicolon; notice that Emacs inserts a newline and brings you down to the next line:
int times (x, y)
int x, y;
_
Type the opening curly brace, and it happens again:
int times (x, y)
int x, y;
{
_
Of course, the number of spaces Emacs indents after you type the { depends on the indentation style you are using.
The other optional electric feature, hungry-delete-key, is also off by default. To toggle it on, type C-c C-d(for c-toggle-hungry-state). You will see the (C)on the mode line change to (C/h), or if you have auto-newlineturned on, from (C/a)to (C/ah).
Turning on hungry-delete-keyempowers the Delkey 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-newlineand hungry-delete-keywith 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-linecontrols 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-jafter 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-lineto 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-ufor c-up-conditional), c-macro-expandhelps 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-expandwith a different C preprocessor command, instead of the default /lib/cpp -C(the -Coption 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 -Coption 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 Stroustrupwith 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.
Читать дальше