www.delorie.com/gnu/docs/emacs/cc-mode_29.html   search  
 
Buy the book!


CC Mode Manual

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.5.2 Custom Brace and Colon Hanging

Syntactic symbols aren't the only place where you can customize CC Mode with the lisp equivalent of callback functions. Brace "hanginess" can also be determined by custom functions associated with syntactic symbols on the c-hanging-braces-alist style variable. Remember that ACTION's are typically a list containing some combination of the symbols before and after (see section 4.1.1 Hanging Braces). However, an ACTION can also be a function which gets called when a brace matching that syntactic symbol is entered.

These ACTION functions are called with two arguments: the syntactic symbol for the brace, and the buffer position at which the brace was inserted. The ACTION function is expected to return a list containing some combination of before and after, including neither of them (i.e. nil). This return value has the normal brace hanging semantics.

As an example, CC Mode itself uses this feature to dynamically determine the hanginess of braces which close "do-while" constructs:
 
void do_list( int count, char** atleast_one_string )
{
    int i=0;
    do {
        handle_string( atleast_one_string[i] );
        i++;
    } while( i < count );
}

CC Mode assigns the block-close syntactic symbol to the brace that closes the do construct, and normally we'd like the line that follows a block-close brace to begin on a separate line. However, with "do-while" constructs, we want the while clause to follow the closing brace. To do this, we associate the block-close symbol with the ACTION function c-snug-do-while:
 
(defun c-snug-do-while (syntax pos)
  "Dynamically calculate brace hanginess for do-while statements.
Using this function, `while' clauses that end a `do-while' block will
remain on the same line as the brace that closes that block.

See `c-hanging-braces-alist' for how to utilize this function as an
ACTION associated with `block-close' syntax."
  (save-excursion
    (let (langelem)
      (if (and (eq syntax 'block-close)
               (setq langelem (assq 'block-close c-syntactic-context))
               (progn (goto-char (cdr langelem))
                      (if (= (following-char) ?{)
                          (forward-sexp -1))
                      (looking-at "\\[^_]")))
          '(before)
        '(before after)))))

This function simply looks to see if the brace closes a "do-while" clause and if so, returns the list `(before)' indicating that a newline should be inserted before the brace, but not after it. In all other cases, it returns the list `(before after)' so that the brace appears on a line by itself.

During the call to the brace hanging ACTION function, the variable c-syntactic-context is bound to the full syntactic analysis list.

Note that for symmetry, colon hanginess should be customizable by allowing function symbols as ACTIONs on the c-hanging-colon-alist style variable. Since no use has actually been found for this feature, it isn't currently implemented!


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003