I came across this piece of lisp the other day whilst
I was poking around on gnu.emacs.help, and thought that people on this
list might be interested. 

       Its been noted that the tempo template mechanism doesnt
necessarily but the braces into the right place for peoples coding
style. The "K&R" option works by setting different standard defaults
for the templates. This means that if you change a template at all the
k&r option will cease to work as the templates will be overridden by
the saved values in custom.

       Now I never understood why tempo doesnt respond to the electric
braces utility in cc-mode. I still dont understand why tempo doesnt
respond, but fortunately someone on gnu.emacs.help did understand, and
further knew how to get around it. And thats what this package
does. It only makes any difference if you have the electric minor mode
switched on, but if you do tempo templates will now automatically
respond. At least so long as you change the templates so that they
do. You have to remove all the "{" 's in the template with (i ?{)
instead.

        Its only been roughly tested so far although it appears to
work for me on both Gnu and X emacs on linux. Let me know if you get
it to work. And many thanks to the generosity of Klaus Berndl who
wrote it!!



;;; cc-tempo-electric-support.el --- provides support for insertion of
;; electric characters in cc-mode using tempo
;; $Revision: 1.1 $
;; $Date: 2000/02/17 12:49:19 $

;; This file is not part of Emacs

;; Author: Klaus Berndl <[EMAIL PROTECTED]>
;; Maintainer: This is a little unclear at the moment

;; Copyright (c) 2000 Klaus Berndl <[EMAIL PROTECTED]>

;; COPYRIGHT NOTICE
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:
;;
;;  This package provides support for insertion of electric characters
;;  with the tempo package into cc-mode buffers.  The current problem
;;  with tempo is that it requires hard coding in the templates where
;;  braces, and such forth should go, whilst cc-mode is perfectly
;;  capable of making these decisions automatically.  This package
;;  allows tempo to insert these characters and have cc-mode behave
;;  appropriately.
;;
;;  In practice what this means is that instead of putting "{" into
;;  your tempo template, you put (i ?{) (this should NOT be quoted, as
;;  tempo needs to evaluate it!). If you have switched on the auto
;;  electric mode within cc-mode it will now newline and reindent this
;;  "{" depending on your indentation settings.

;;; Installation
;;
;;  Place this file into your load-path, and add this to your .emacs
;;  (require 'cc-tempo-electric-support)


;;; History:
;; 

(require 'tempo)
(require 'cc-mode)

;;; Code:
(defun cc-tempo-process-character-for-insert (character)
  "Check if CHARACTER is bound to `self-insert-command' and insert it if yes.
But if bound to any other function `last-command-char' will be set to
CHARACTER and the bounded function will be called with nil as argument or -
if this fails without any argument.  This is very usefull if you want to
insert charcters from a lisp-program and still having the key-bindung of
this character in current mode active.  For example you can insert
characters with it�s special electric meaning in a certain mode
(e.g. inserting a '{' with its electric behaviour)."
  (let* ((old-last-command-char last-command-char)
         (defn (key-binding (char-to-string character)))
         (is-self-insert (if (string-match "self-insert-command"
                                           (symbol-name defn)) t nil))
         (arglist (list 1)))
    (if is-self-insert
        (setq defn 'self-insert-command)
      (setq arglist (list nil)))
    (setq last-command-char character)
    (condition-case nil
        (apply defn arglist)
      ;; some commands (like newline-and-indent) must not be called
      ;; with any argument!
      (wrong-number-of-arguments
       (apply defn nil)))
    (setq last-command-char old-last-command-char)))



(defun cc-tempo-process-insert (elem)
  "Process the user element (i <something>).
The 'something' is one of the following: string: insert the string
integer: process the integer with `process-character-for-insert'
number: insert the number as string lisp-expression of a
function-call: Evaluate the function other: Insertion of \"CAN NOT
INSERT\".  Returns nil if ELEM != (i <something>) otherwise '(not t)
to avoid an endless recursion-loop (look at 'tempo-insert)"
  (if (and (consp elem)
           (eq (car elem) 'i))
      (let ((insertion (car (cdr elem)))
            (default-ins (concat comment-start "CAN NOT INSERT"
                                 comment-end))
            (ret-val '(not t)))
        (cond ((stringp insertion) (insert insertion))
              ((integerp insertion) (cc-tempo-process-character-for-insert insertion))
              ((numberp insertion) (insert (number-to-string insertion)))
              ((and (symbolp insertion) (fboundp insertion))
               (apply insertion (cddr insertion)))
              (t (insert default-ins)
                 (setq ret-val 'n>)))
        ret-val)
    nil))
 
;; add to user-handlers for user-elements
(add-to-list 'tempo-user-elements 'cc-tempo-process-insert)

(provide 'cc-tempo-electric-support)

;;; cc-tempo-electric-support.el ends here


Reply via email to