Mercurial > emacs
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 |