Sams Teach Yourself Emacs in 24 Hours

ContentsIndex

Hour 18: Editing C, C++, and Java Files

Previous HourNext Hour

Sections in this Hour:

 

Viewing Code with Expanded Macros

Sometimes it is easier to understand source code with complex conditionals or macros if you can get a good view of what it would look like after it's been through the preprocessor. The first of several methods is provided in the default C mode with the macro expand region command bound to C-c C-e. This is the most robust of the many macro interpreters provided with Emacs; it calls the C preprocessor and collects its output for viewing. All macros, including macro functions, constants, and conditionals are all expanded out so nothing but the plain source code is left.

This command can be slow because it has to run an external process in which to interpret the code. It also has the disadvantage of showing the modified code in a separate buffer. Although this is the best you'll get for macros, there are two interpreters for preprocessor conditionals to use that mesh the display properties in your source code, with complete control of what code is shown or hidden.

A fancy conditional collapse program is called cpp after the C preprocessor. To start, run the program M-x cpp-highlight-buffer. This command brings up a control buffer with several buttons in it and highlights all the conditionals in the current buffer. Through this control buffer, you can specify background colors for different conditional results, and even mark sections read-only or hide them completely. The end result is a buffer with only the data you want and colors of your choosing marking the meaning of different code sections.

When the control buffer is active, use the middle mouse button (or both together if you have only two) on different bold buttons to make modifications. First, make sure you specify your background color on the Background section. Next, at the bottom is a list of macros. You can middle-click the True and False face and pick a special background for a conditional. Next, click Apply, and each element of the conditional disappears leaving only the code you requested behind. If you have a good selection of items, you can save the settings and load them back in later, applying them to other buffers as well.

If you run in a terminal and can't access the mouse, you can change any element by pressing the key enclosed in brackets ([]) near the field you want to change. For example, use b for the background or t to set the True face on a symbol.

Caution - Unfortunately, there is no way to remove all the highlighting colors from your buffer without going back to the cpp buffer and clicking, and rechoosing everything. You can kill the buffer and load it in again afterward, however.


The second preprocess collapsing program is called hideif. Unlike cpp, which has a control panel and lots of color options, hideif takes a different approach. To enable its features, you need to run the command M-x hide-ifdef-mode. When enabled, the string Ifdef should appear in the mode line and several new commands are made available on the prefix C-c @.

You can now move to different conditionals in your program and hide them quickly with the command C-c @ C-d, and you can bring them back with C-c @ C-s. This lets you control each individual occurrence of a conditional as you need it. If you want to have entire classifications of conditionals hidden, you need to specify some define lists. Unlike the cpp package, which has controls and fonts, hideif takes a little more effort to make it hide what you want and requires that you do some programming in your .emacs file to save configured information.

Caution - When using hideif, hidden conditionals are still in the buffer and are merely invisible. It is possible to type new code into a hidden block without realizing it. To avoid this you can make the buffer read-only whenever something is hidden with C-c @ C-q.


If you want all conditionals in your buffer to be hidden at once, run the hide ifdefs command with C-c @ h to hide all conditionals. By default, it assumes that no macros have been defined. This causes everything to be hidden or have only the #else clause shown. If you want to see a specific hidden entry, you can either show it with C-c @ C-s or tell hide if that a given variable is to be defined.

If you have a conditional that looks like this


#ifdef HAVE_FUNCTION 
    system_function(d); 
#else 
    local_system_function(d); 
#endif 

by default, the code between the #ifdef and #else is hidden with C-c @ h. To make all conditionals that depend on HAVE_FUNCTION appear, use C-c @ d. At the prompt, enter HAVE_FUNCTION. Now all conditionals depending on HAVE_FUNCTION will show the then clause, and not the else clause. To remove this definition, use C-c @ u and enter the variable you want removed, and all the hiding will be updated.

If you have a set of elements you always want defined in Emacs, you have to modify your .emacs file. Do this by adding a hidif mode hook. The entry in your .emacs file would look like the following:


(setq hide-ifdef-define-alist 
      '( (list-name-1 HAVE_FUNC_1 HAVE_FUNC_2) 
         (list-name-2 HAVE_HEADER_1) ) ) 
(add-hook 'hide-ifdef-mode-hook 
          '(lambda () (hide-ifdef-use-define-alist 'list-name-2) ) ) 

The first setq creates a list of define groups. Each element of the hide-ifdef-define-alist starts with a list name. All elements after that are symbols whose names match that of the macro the conditionals are using. The hook then sets the default list to be 'list-name-2. This is a symbol matching the names in the preceding alist. You can switch between these specified lists by using C-c @ U. At the prompt, type the name of the list you want to use, such as list-name-1. You can manage lists of this nature as well. For example, if you've used C-c @ d.to define some symbols you like, use C-c @ D, and type a name for that list. This lasts only to the end of your session, however, so if you want it saved, you need to add it to your .emacs file yourself.

Sams Teach Yourself Emacs in 24 Hours

ContentsIndex

Hour 18: Editing C, C++, and Java Files

Previous HourNext Hour

Sections in this Hour: