ccmode: Custom Braces

 
 8.1.1 Custom Brace Hanging
 --------------------------
 
 Syntactic symbols aren’t the only place where you can customize CC Mode
 with the lisp equivalent of callback functions.  Remember that ACTIONs
 are usually a list containing some combination of the symbols ‘before’
 and ‘after’ (SeeHanging Braces).  For more flexibility, you can
 instead specify brace “hanginess” by giving a syntactic symbol an
 “action function” in ‘c-hanging-braces-alist’; this function determines
 the “hanginess” of a brace, usually by looking at the code near it.
 
    An action function is called with two arguments: the syntactic symbol
 for the brace (e.g., ‘substatement-open’), and the buffer position where
 the brace has been inserted.  Point is undefined on entry to an action
 function, but the function must preserve it (e.g., by using
 ‘save-excursion’).  The return value should be a list containing some
 combination of ‘before’ and ‘after’, including neither of them (i.e.,
 ‘nil’).
 
  -- Variable: c-syntactic-context
      During the call to the indentation or brace hanging ACTION
      function, this variable is bound to the full syntactic analysis
      list.  This might be, for example, ‘((block-close 73))’.  Don’t
      ever give ‘c-syntactic-context’ a value yourself—this would disrupt
      the proper functioning of CC Mode.
 
      This variable is also bound in three other circumstances: (i) when
      Semicolons and Commas::); (ii) when calling a line-up function
      (SeeCustom Line-Up); (iii) when calling a
      c-special-indent-hook function (SeeOther Indentation).
 
    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."
        (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 "\\<do\\>[^_]")))
                '(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.