comparison lisp/tempo.el @ 11196:a74358cc05c6

(tempo-insert): Added the P tag and modified the s tag accordingly (tempo-insert-named): Checks for valid name, insert mark otherwise. (tempo-dolist): Changed (cadr ...) to (car (cdr ...)) (tempo-expand-if-complete): New function
author Richard M. Stallman <rms@gnu.org>
date Mon, 03 Apr 1995 22:23:51 +0000
parents 488c5be866c3
children 577f71dad5c3
comparison
equal deleted inserted replaced
11195:0833fb6a29bb 11196:a74358cc05c6
1 ;;; tempo.el --- Flexible template insertion 1 ;;; tempo.el --- Flexible template insertion
2 ;; Copyright (C) 1994 Free Software Foundation, Inc. 2 ;; Copyright (C) 1994 Free Software Foundation, Inc.
3 3
4 ;; Author: David K}gedal <davidk@lysator.liu.se > 4 ;; Author: David K}gedal <davidk@lysator.liu.se >
5 ;; Created: 16 Feb 1994 5 ;; Created: 16 Feb 1994
6 ;; Version: 1.2 6 ;; Version: 1.2.1
7 ;; Keywords: extensions, languages, tools 7 ;; Keywords: extensions, languages, tools
8 ;; $Revision: 1.29 $
8 9
9 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
10 11
11 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by 13 ;; it under the terms of the GNU General Public License as published by
26 27
27 ;; This file provides a simple way to define powerful templates, or 28 ;; This file provides a simple way to define powerful templates, or
28 ;; macros, if you wish. It is mainly intended for, but not limited to, 29 ;; macros, if you wish. It is mainly intended for, but not limited to,
29 ;; other programmers to be used for creating shortcuts for editing 30 ;; other programmers to be used for creating shortcuts for editing
30 ;; certain kind of documents. It was originally written to be used by 31 ;; certain kind of documents. It was originally written to be used by
31 ;; a HTML editing mode written by Nelson Minar <nelson@reed.edu>, and 32 ;; a HTML editing mode written by Nelson Minar <nelson@santafe.edu>,
32 ;; his html-helper-mode.el is probably the best example of how to use 33 ;; and his html-helper-mode.el is probably the best example of how to
33 ;; this program. 34 ;; use this program.
34 35
35 ;; A template is defined as a list of items to be inserted in the 36 ;; A template is defined as a list of items to be inserted in the
36 ;; current buffer at point. Some of the items can be simple strings, 37 ;; current buffer at point. Some of the items can be simple strings,
37 ;; while other can control formatting or define special points of 38 ;; while other can control formatting or define special points of
38 ;; interest in the inserted text. 39 ;; interest in the inserted text.
88 89
89 ;; There is a bug in some emacs versions that prevents completion from 90 ;; There is a bug in some emacs versions that prevents completion from
90 ;; working. If it doesn't work for you, send me a note indicating your 91 ;; working. If it doesn't work for you, send me a note indicating your
91 ;; emacs version and your problems. 92 ;; emacs version and your problems.
92 93
94 ;;; Contributors:
95
96 ;; These people have given me importand feedback and new ideas for
97 ;; tempo.el. Thanks.
98
99 ;; Nelson Minar <nelson@santafe.edu>
100 ;; Richard Stallman <rms@gnu.ai.mit.edu>
101 ;; Lars Lindberg <Lars.Lindberg@sypro.cap.se>
102 ;; Glen Whitney <Glen.Whitney@math.lsa.umich.edu>
103
93 ;;; Code: 104 ;;; Code:
94 105
95 ;; (provide 'tempo) 106 ;; (provide 'tempo)
96 107
97 ;;; User options 108 ;;; User options
185 (make-variable-buffer-local 'tempo-match-finder) 196 (make-variable-buffer-local 'tempo-match-finder)
186 (make-variable-buffer-local 'tempo-collection) 197 (make-variable-buffer-local 'tempo-collection)
187 (make-variable-buffer-local 'tempo-dirty-collection) 198 (make-variable-buffer-local 'tempo-dirty-collection)
188 199
189 ;;; Functions 200 ;;; Functions
201
202 ;;; First some useful functions and macros
203
204 (defun tempo-mapc (fun lst)
205 (if (null lst) nil
206 (funcall fun (car lst))
207 (tempo-mapc fun (cdr lst))))
208
209 (defmacro tempo-dolist (il &rest forms)
210 (let ((i (car il))
211 (l (car (cdr il))))
212 (list 'tempo-mapc
213 (list 'function (append (list 'lambda
214 (list (car il)))
215 forms))
216 (cadr il))))
217 (put 'tempo-dolist 'lisp-indent-function 1)
190 218
191 ;; 219 ;;
192 ;; tempo-define-template 220 ;; tempo-define-template
193 221
194 (defun tempo-define-template (name elements &optional tag documentation taglist) 222 (defun tempo-define-template (name elements &optional tag documentation taglist)
292 See documentation for `tempo-define-template' for the kind of elements 320 See documentation for `tempo-define-template' for the kind of elements
293 possible." 321 possible."
294 (cond ((stringp element) (tempo-process-and-insert-string element)) 322 (cond ((stringp element) (tempo-process-and-insert-string element))
295 ((and (consp element) (eq (car element) 'p)) 323 ((and (consp element) (eq (car element) 'p))
296 (tempo-insert-prompt (cdr element))) 324 (tempo-insert-prompt (cdr element)))
325 ((and (consp element) (eq (car element) 'P))
326 (let ((tempo-interactive t))
327 (tempo-insert-prompt (cdr element))))
297 ((and (consp element) (eq (car element) 'r)) 328 ((and (consp element) (eq (car element) 'r))
298 (if on-region 329 (if on-region
299 (goto-char tempo-region-stop) 330 (goto-char tempo-region-stop)
300 (tempo-insert-prompt (cdr element)))) 331 (tempo-insert-prompt (cdr element))))
301 ((and (consp element) (eq (car element) 's)) 332 ((and (consp element) (eq (car element) 's))
302 (if tempo-interactive 333 (tempo-insert-named (car (cdr element))))
303 (tempo-insert-named (cdr element))
304 (tempo-insert-mark (point-marker))))
305 ((and (consp element) (eq (car element) 'l)) 334 ((and (consp element) (eq (car element) 'l))
306 (mapcar (function (lambda (elt) (tempo-insert elt on-region))) 335 (mapcar (function (lambda (elt) (tempo-insert elt on-region)))
307 (cdr element))) 336 (cdr element)))
308 ((eq element 'p) (tempo-insert-mark (point-marker))) 337 ((eq element 'p) (tempo-insert-mark (point-marker)))
309 ((eq element 'r) (if on-region 338 ((eq element 'r) (if on-region
397 (setq tempo-named-insertions nil)) 426 (setq tempo-named-insertions nil))
398 427
399 ;;; 428 ;;;
400 ;;; tempo-insert-named 429 ;;; tempo-insert-named
401 430
402 (defun tempo-insert-named (elt) 431 (defun tempo-insert-named (name)
403 "Insert the previous insertion saved under a named specified in ELT. 432 "Insert the previous insertion saved under a named specified in NAME.
404 The name is in the car of ELT." 433 If there is no such name saved, a tempo mark is inserted."
405 (let* ((name (car elt)) 434 (let* ((insertion (cdr (assq name tempo-named-insertions))))
406 (insertion (cdr (assq name tempo-named-insertions))))
407 (if insertion 435 (if insertion
408 (insert insertion) 436 (insert insertion)
409 (error "Named insertion not found")))) 437 (tempo-insert-mark (point-marker)))))
410 438
411 ;;; 439 ;;;
412 ;;; tempo-process-and-insert-string 440 ;;; tempo-process-and-insert-string
413 441
414 (defun tempo-process-and-insert-string (string) 442 (defun tempo-process-and-insert-string (string)
417 and insert the results." 445 and insert the results."
418 (cond ((null tempo-insert-string-functions) 446 (cond ((null tempo-insert-string-functions)
419 nil) 447 nil)
420 ((symbolp tempo-insert-string-functions) 448 ((symbolp tempo-insert-string-functions)
421 (setq string 449 (setq string
422 (apply tempo-insert-string-functions (list string)))) 450 (funcall tempo-insert-string-functions string)))
423 ((listp tempo-insert-string-functions) 451 ((listp tempo-insert-string-functions)
424 (mapcar (function (lambda (fn) 452 (tempo-dolist (fn tempo-insert-string-functions)
425 (setq string (apply fn string)))) 453 (setq string (funcall fn string))))
426 tempo-insert-string-functions))
427 (t 454 (t
428 (error "Bogus value in tempo-insert-string-functions: %s" 455 (error "Bogus value in tempo-insert-string-functions: %s"
429 tempo-insert-string-functions))) 456 tempo-insert-string-functions)))
430 (insert string)) 457 (insert string))
431 458
546 ;;; 573 ;;;
547 ;;; tempo-find-match-string 574 ;;; tempo-find-match-string
548 575
549 (defun tempo-find-match-string (finder) 576 (defun tempo-find-match-string (finder)
550 "Find a string to be matched against a tag list. 577 "Find a string to be matched against a tag list.
551 FINDER is a function or a string. Returns (STRING . POS)." 578 FINDER is a function or a string. Returns (STRING . POS), or nil
579 if no reasonable string is found."
552 (cond ((stringp finder) 580 (cond ((stringp finder)
553 (save-excursion 581 (let (successful)
554 (or (re-search-backward finder nil t) 582 (save-excursion
555 0)) 583 (or (setq successful (re-search-backward finder nil t))
556 (cons (buffer-substring (match-beginning 1) 584 0))
557 (match-end 1)) ; This seems to be a 585 (if successful
558 ; bug in emacs 586 (cons (buffer-substring (match-beginning 1)
559 (match-beginning 1))) 587 (match-end 1)) ; This seems to be a
588 ; bug in emacs
589 (match-beginning 1))
590 nil)))
560 (t 591 (t
561 (funcall finder)))) 592 (funcall finder))))
562 593
563 ;;; 594 ;;;
564 ;;; tempo-complete-tag 595 ;;; tempo-complete-tag
565 596
566 (defun tempo-complete-tag (&optional silent) 597 (defun tempo-complete-tag (&optional silent)
567 "Look for a tag and expand it. 598 "Look for a tag and expand it.
568 All the tags in the tag lists in `tempo-local-tags' (this includes 599 All the tags in the tag lists in `tempo-local-tags'
569 `tempo-tags') are searched for a match for the text before the point. 600 (this includes `tempo-tags') are searched for a match for the text
570 The way the string to match for is determined can be altered with the 601 before the point. The way the string to match for is determined can
571 variable `tempo-match-finder' 602 be altered with the variable `tempo-match-finder'. If
603 `tempo-match-finder' returns nil, then the results are the same as
604 no match at all.
572 605
573 If a single match is found, the corresponding template is expanded in 606 If a single match is found, the corresponding template is expanded in
574 place of the matching string. 607 place of the matching string.
575 608
576 If a partial completion or no match at all is found, and SILENT is 609 If a partial completion or no match at all is found, and SILENT is
586 (match-info (tempo-find-match-string tempo-match-finder)) 619 (match-info (tempo-find-match-string tempo-match-finder))
587 (match-string (car match-info)) 620 (match-string (car match-info))
588 (match-start (cdr match-info)) 621 (match-start (cdr match-info))
589 (exact (assoc match-string collection)) 622 (exact (assoc match-string collection))
590 (compl (or (car exact) 623 (compl (or (car exact)
591 (try-completion match-string collection)))) 624 (and match-info (try-completion match-string collection)))))
592 (if compl (delete-region match-start (point))) 625 (if compl (delete-region match-start (point)))
593 (cond ((null compl) (or silent (ding))) 626 (cond ((null match-info) (or silent (ding)))
627 ((null compl) (or silent (ding)))
594 ((eq compl t) (tempo-insert-template 628 ((eq compl t) (tempo-insert-template
595 (cdr (assoc match-string 629 (cdr (assoc match-string
596 collection)) 630 collection))
597 nil)) 631 nil))
598 (t (if (setq exact (assoc compl collection)) 632 (t (if (setq exact (assoc compl collection))
617 (with-output-to-temp-buffer "*Completions*" 651 (with-output-to-temp-buffer "*Completions*"
618 (display-completion-list 652 (display-completion-list
619 (all-completions string tag-list))) 653 (all-completions string tag-list)))
620 (sit-for 32767)))) 654 (sit-for 32767))))
621 655
656 ;;;
657 ;;; tempo-expand-if-complete
658
659 (defun tempo-expand-if-complete ()
660 "Expand the tag before point if it is complete.
661 Returns non-nil if an expansion was made and nil otherwise.
662
663 This could as an example be used in a command that is bound to the
664 space bar, and looks something like this:
665
666 (defun tempo-space ()
667 (interactive \"*\")
668 (or (tempo-expand-if-complete)
669 (insert \" \")))"
670
671 (interactive "*")
672 (let* ((collection (tempo-build-collection))
673 (match-info (tempo-find-match-string tempo-match-finder))
674 (match-string (car match-info))
675 (match-start (cdr match-info))
676 (exact (assoc match-string collection)))
677 (if exact
678 (progn
679 (delete-region match-start (point))
680 (tempo-insert-template (cdr exact) nil)
681 t)
682 nil)))
683
622 (provide 'tempo) 684 (provide 'tempo)
623 685
624 ;;; tempo.el ends here 686 ;;; tempo.el ends here