Mercurial > emacs
comparison lisp/tempo.el @ 7410:4eca60cb3c4d
(tempo-insert-region, tempo-show-completion-buffer,
tempo-leave-completion-buffer): New variables.
(tempo-complete-tag): Added a completion buffer mechanism.
(tempo-display-completions): New function.
(tempo-insert-template): An extension to the (p ...) tag
enables named insertion for later insertion using a (s ...) tag.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 08 May 1994 21:11:37 +0000 |
parents | eb888748ca9b |
children | 488c5be866c3 |
comparison
equal
deleted
inserted
replaced
7409:fe56a02838ba | 7410:4eca60cb3c4d |
---|---|
1 ;;; tempo.el --- templates with hotspots | 1 ;;; tempo.el --- templates with hotspots |
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.0 | 6 ;; Version: 1.1.1 |
7 ;; Keywords: extensions, languages, tools | 7 ;; Keywords: extensions, languages, tools |
8 | 8 |
9 ;; This file is part of GNU Emacs. | 9 ;; This file is part of GNU Emacs. |
10 | 10 |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | 11 ;; GNU Emacs is free software; you can redistribute it and/or modify |
87 (defvar tempo-interactive nil | 87 (defvar tempo-interactive nil |
88 "*Prompt user for strings in templates. | 88 "*Prompt user for strings in templates. |
89 If this variable is non-nil, `tempo-insert' prompts the | 89 If this variable is non-nil, `tempo-insert' prompts the |
90 user for text to insert in the templates") | 90 user for text to insert in the templates") |
91 | 91 |
92 (defvar tempo-insert-region nil | |
93 "*Automatically insert current region when there is a `r' in the template | |
94 If this variable is NIL, `r' elements will be treated just like `p' | |
95 elements, unless the template function is given a prefix (or a non-nil | |
96 argument). If this variable is non-NIL, the behaviour is reversed.") | |
97 | |
98 (defvar tempo-show-completion-buffer t | |
99 "*If non-NIL, show a buffer with possible completions, when only | |
100 a partial completion can be found") | |
101 | |
102 (defvar tempo-leave-completion-buffer nil | |
103 "*If NIL, a completion buffer generated by \\[tempo-complete-tag] | |
104 disappears at the next keypress; otherwise, it remains forever.") | |
105 | |
92 (defvar tempo-insert-string-functions nil | 106 (defvar tempo-insert-string-functions nil |
93 "List of functions to run when inserting a string. | 107 "List of functions to run when inserting a string. |
94 Each function is called with a single arg, STRING." ) | 108 Each function is called with a single arg, STRING." ) |
95 | 109 |
96 (defvar tempo-tags nil | 110 (defvar tempo-tags nil |
109 (defvar tempo-marks nil | 123 (defvar tempo-marks nil |
110 "A list of marks to jump to with `\\[tempo-forward-mark]' and `\\[tempo-backward-mark]'.") | 124 "A list of marks to jump to with `\\[tempo-forward-mark]' and `\\[tempo-backward-mark]'.") |
111 | 125 |
112 (defvar tempo-default-match-finder "\\b\\([^\\b]*\\)\\=" | 126 (defvar tempo-default-match-finder "\\b\\([^\\b]*\\)\\=" |
113 "The default regexp used to find the string to match against the tags.") | 127 "The default regexp used to find the string to match against the tags.") |
128 | |
129 (defvar tempo-named-insertions nil | |
130 "Temporary storage for named insertions") | |
114 | 131 |
115 ;; Make some variables local to every buffer | 132 ;; Make some variables local to every buffer |
116 | 133 |
117 (make-variable-buffer-local 'tempo-marks) | 134 (make-variable-buffer-local 'tempo-marks) |
118 (make-variable-buffer-local 'tempo-local-tags) | 135 (make-variable-buffer-local 'tempo-local-tags) |
140 - A string. It is sent to the hooks in `tempo-insert-string-functions', | 157 - A string. It is sent to the hooks in `tempo-insert-string-functions', |
141 and the result is inserted. | 158 and the result is inserted. |
142 - The symbol 'p. This position is saved in `tempo-marks'. | 159 - The symbol 'p. This position is saved in `tempo-marks'. |
143 - The symbol 'r. If `tempo-insert' is called with ON-REGION non-nil | 160 - The symbol 'r. If `tempo-insert' is called with ON-REGION non-nil |
144 the current region is placed here. Otherwise it works like 'p. | 161 the current region is placed here. Otherwise it works like 'p. |
145 - (p . PROMPT) If `tempo-interactive' is non-nil, the user is | 162 - (p PROMPT <NAME>) If `tempo-interactive' is non-nil, the user is |
146 prompted in the minbuffer with PROMPT for a string to be inserted. | 163 prompted in the minbuffer with PROMPT for a string to be inserted. |
164 If the optional parameter NAME is non-nil, the text is saved for | |
165 later insertion with the `s' tag. | |
147 If `tempo-interactive is nil, it works like 'p. | 166 If `tempo-interactive is nil, it works like 'p. |
148 - (r . PROMPT) like the previou, but if `tempo-interactive' is nil | 167 - (r PROMPT) like the previous, but if `tempo-interactive' is nil |
149 and `tempo-insert' is called with ON-REGION non-nil, the current | 168 and `tempo-insert' is called with ON-REGION non-nil, the current |
150 region is placed here. | 169 region is placed here. |
170 - (s NAME) Inserts text previously read with the (p ..) construct. | |
171 Finds the insertion saved under NAME and inserts it. Acts like 'p | |
172 if tempo-interactive is nil. | |
151 - '& If there is only whitespace between the line start and point, | 173 - '& If there is only whitespace between the line start and point, |
152 nothing happens. Otherwise a newline is inserted. | 174 nothing happens. Otherwise a newline is inserted. |
153 - '% If there is only whitespace between point and end-of-line | 175 - '% If there is only whitespace between point and end-of-line |
154 nothing happens. Otherwise a newline is inserted. | 176 nothing happens. Otherwise a newline is inserted. |
155 - 'n inserts a newline. | 177 - 'n inserts a newline. |
167 (fset command-name (list 'lambda (list '&optional 'arg) | 189 (fset command-name (list 'lambda (list '&optional 'arg) |
168 (or documentation | 190 (or documentation |
169 (concat "Insert a " name ".")) | 191 (concat "Insert a " name ".")) |
170 (list 'interactive "*P") | 192 (list 'interactive "*P") |
171 (list 'tempo-insert-template (list 'quote | 193 (list 'tempo-insert-template (list 'quote |
172 template-name) | 194 template-name) |
173 'arg))) | 195 (list 'if 'tempo-insert-region |
196 (list 'not 'arg) 'arg)))) | |
174 (and tag | 197 (and tag |
175 (tempo-add-tag tag template-name taglist)) | 198 (tempo-add-tag tag template-name taglist)) |
176 command-name)) | 199 command-name)) |
177 | 200 |
178 ;;; | 201 ;;; |
188 (save-excursion | 211 (save-excursion |
189 (tempo-insert-mark (point-marker)) | 212 (tempo-insert-mark (point-marker)) |
190 (mapcar 'tempo-insert | 213 (mapcar 'tempo-insert |
191 (symbol-value template)) | 214 (symbol-value template)) |
192 (tempo-insert-mark (point-marker))) | 215 (tempo-insert-mark (point-marker))) |
193 (tempo-forward-mark)) | 216 (tempo-forward-mark) |
217 (tempo-forget-insertions)) | |
194 | 218 |
195 ;;; | 219 ;;; |
196 ;;; tempo-insert | 220 ;;; tempo-insert |
197 | 221 |
198 (defun tempo-insert (element) | 222 (defun tempo-insert (element) |
204 (tempo-insert-prompt (cdr element))) | 228 (tempo-insert-prompt (cdr element))) |
205 ((and (consp element) (eq (car element) 'r)) | 229 ((and (consp element) (eq (car element) 'r)) |
206 (if on-region | 230 (if on-region |
207 (exchange-point-and-mark) | 231 (exchange-point-and-mark) |
208 (tempo-insert-prompt (cdr element)))) | 232 (tempo-insert-prompt (cdr element)))) |
233 ((and (consp element) (eq (car element) 's)) | |
234 (if tempo-interactive | |
235 (tempo-insert-named (cdr element)) | |
236 (tempo-insert-mark (point-marker)))) | |
209 ((eq element 'p) (tempo-insert-mark (point-marker))) | 237 ((eq element 'p) (tempo-insert-mark (point-marker))) |
210 ((eq element 'r) (if on-region | 238 ((eq element 'r) (if on-region |
211 (exchange-point-and-mark) | 239 (exchange-point-and-mark) |
212 (tempo-insert-mark (point-marker)))) | 240 (tempo-insert-mark (point-marker)))) |
213 ((eq element '>) (indent-according-to-mode)) | 241 ((eq element '>) (indent-according-to-mode)) |
232 (defun tempo-insert-prompt (prompt) | 260 (defun tempo-insert-prompt (prompt) |
233 "Prompt for a text string and insert it in the current buffer. | 261 "Prompt for a text string and insert it in the current buffer. |
234 If the variable `tempo-interactive' is non-nil the user is prompted | 262 If the variable `tempo-interactive' is non-nil the user is prompted |
235 for a string in the minibuffer, which is then inserted in the current | 263 for a string in the minibuffer, which is then inserted in the current |
236 buffer. If `tempo-interactive' is nil, the current point is placed on | 264 buffer. If `tempo-interactive' is nil, the current point is placed on |
237 `tempo-forward-mark-list'. | 265 `tempo-mark'. |
238 | 266 |
239 PROMPT is the prompt string." | 267 PROMPT is the prompt string or a list containing the prompt string and |
268 a name to save the inserted text under." | |
240 (if tempo-interactive | 269 (if tempo-interactive |
241 (insert (read-string prompt)) | 270 (let ((prompt-string (if (listp prompt) |
271 (car prompt) | |
272 prompt)) | |
273 (save-name (and (listp prompt) (nth 1 prompt))) | |
274 inserted-text) | |
275 | |
276 (progn | |
277 (setq inserted-text (read-string prompt-string)) | |
278 (insert inserted-text) | |
279 (if save-name | |
280 (tempo-remember-insertion save-name inserted-text)))) | |
242 (tempo-insert-mark (point-marker)))) | 281 (tempo-insert-mark (point-marker)))) |
282 | |
283 ;;; | |
284 ;;; tempo-remember-insertion | |
285 | |
286 (defun tempo-remember-insertion (save-name string) | |
287 "Save the text in STRING under the name SAVE-NAME for later retrieval." | |
288 (setq tempo-named-insertions (cons (cons save-name string) | |
289 tempo-named-insertions))) | |
290 | |
291 ;;; | |
292 ;;; tempo-forget-insertions | |
293 | |
294 (defun tempo-forget-insertions () | |
295 "Forget all the saved named insertions." | |
296 (setq tempo-named-insertions nil)) | |
297 | |
298 ;;; | |
299 ;;; tempo-insert-named | |
300 | |
301 (defun tempo-insert-named (elt) | |
302 "Insert the previous insertion saved under a named specified in ELT. | |
303 The name is in the car of ELT." | |
304 (let* ((name (car elt)) | |
305 (insertion (cdr (assq name tempo-named-insertions)))) | |
306 (if insertion | |
307 (insert insertion) | |
308 (error "Named insertion not found")))) | |
243 | 309 |
244 ;;; | 310 ;;; |
245 ;;; tempo-process-and-insert-string | 311 ;;; tempo-process-and-insert-string |
246 | 312 |
247 (defun tempo-process-and-insert-string (string) | 313 (defun tempo-process-and-insert-string (string) |
248 "Insert a string from a template. | 314 "Insert a string from a template. |
249 Run a string through the preprocessors in `tempo-insert-string-functions' | 315 Run a string through the preprocessors in `tempo-insert-string-functions' |
250 and insert the results." | 316 and insert the results." |
251 | |
252 (cond ((null tempo-insert-string-functions) | 317 (cond ((null tempo-insert-string-functions) |
253 nil) | 318 nil) |
254 ((symbolp tempo-insert-string-functions) | 319 ((symbolp tempo-insert-string-functions) |
255 (setq string | 320 (setq string |
256 (apply tempo-insert-string-functions (list string)))) | 321 (apply tempo-insert-string-functions (list string)))) |
379 | 444 |
380 ;;; | 445 ;;; |
381 ;;; tempo-complete-tag | 446 ;;; tempo-complete-tag |
382 | 447 |
383 (defun tempo-complete-tag (&optional silent) | 448 (defun tempo-complete-tag (&optional silent) |
384 "Look for a tag and expand it.. | 449 "Look for a tag and expand it. |
385 | 450 |
386 It goes through the tag lists in `tempo-local-tags' (this includes | 451 It goes through the tag lists in `tempo-local-tags' (this includes |
387 `tempo-tags') and for each list it uses the corresponding match-finder | 452 `tempo-tags') and for each list it uses the corresponding match-finder |
388 function, or `tempo-default-match-finder' if none is given, and tries | 453 function, or `tempo-default-match-finder' if none is given, and tries |
389 to match the match string against the tags in the list using | 454 to match the match string against the tags in the list using |
395 When doing partial completion, only tags in the currently examined | 460 When doing partial completion, only tags in the currently examined |
396 list are considered, so if you provide similar tags in different lists | 461 list are considered, so if you provide similar tags in different lists |
397 in `tempo-local-tags', the result may not be desirable. | 462 in `tempo-local-tags', the result may not be desirable. |
398 | 463 |
399 If no match is found or a partial match is found, and SILENT is | 464 If no match is found or a partial match is found, and SILENT is |
400 non-nil, the function will give a signal." | 465 non-nil, the function will give a signal. |
401 | 466 |
467 If tempo-show-completion-buffer is non-NIL, a buffer containing | |
468 possible completions is displayed when a partial completion is found." | |
469 | |
470 ;; This function is really messy. Some cleaning up is necessary. | |
402 (interactive) | 471 (interactive) |
403 (if (catch 'completed | 472 (if (catch 'completed |
404 (mapcar | 473 (mapcar |
405 (function | 474 (function |
406 (lambda (tag-list-a) | 475 (lambda (tag-list-a) |
409 tempo-default-match-finder)) | 478 tempo-default-match-finder)) |
410 (match-info (tempo-find-match-string match-string-finder)) | 479 (match-info (tempo-find-match-string match-string-finder)) |
411 (match-string (car match-info)) | 480 (match-string (car match-info)) |
412 (match-start (cdr match-info)) | 481 (match-start (cdr match-info)) |
413 (compl (or (cdr (assoc match-string tag-list)) | 482 (compl (or (cdr (assoc match-string tag-list)) |
414 (try-completion (car match-info) | 483 (try-completion match-string |
415 tag-list)))) | 484 tag-list)))) |
416 | 485 |
417 (if compl ;any match | 486 (if compl ;any match |
418 (delete-region match-start (point))) | 487 (delete-region match-start (point))) |
419 | 488 |
420 (cond | 489 (cond |
421 ((null compl) | 490 ((null compl) ; No match |
422 nil) | 491 nil) |
423 ((symbolp compl) | 492 ((symbolp compl) ; ?? |
424 (tempo-insert-template compl nil) | 493 (tempo-insert-template compl nil) |
425 (throw 'completed t)) | 494 (throw 'completed t)) |
426 ((eq compl t) | 495 ((eq compl t) ; Exact, sole match |
427 (tempo-insert-template (cdr (assoc match-string tag-list)) | 496 (tempo-insert-template (cdr (assoc match-string tag-list)) |
428 nil) | 497 nil) |
429 (throw 'completed t)) | 498 (throw 'completed t)) |
430 ((stringp compl) | 499 ((stringp compl) ; (partial) completion found |
431 (let ((compl2 (assoc compl tag-list))) | 500 (let ((compl2 (assoc compl tag-list))) |
432 (if compl2 | 501 (if compl2 |
433 (tempo-insert-template (cdr compl2) nil) | 502 (tempo-insert-template (cdr compl2) nil) |
434 (insert compl) | 503 (insert compl) |
435 (if (string= match-string compl) | 504 (if t ;(string= match-string compl) |
436 (if (not silent) | 505 (if tempo-show-completion-buffer |
437 (ding))))) | 506 (tempo-display-completions match-string |
507 tag-list) | |
508 (if (not silent) | |
509 (ding)))))) | |
438 (throw 'completed t)))))) | 510 (throw 'completed t)))))) |
439 tempo-local-tags) | 511 tempo-local-tags) |
440 ;; No completion found. Return nil | 512 ;; No completion found. Return nil |
441 nil) | 513 nil) |
442 ;; Do nothing if a completion was found | 514 ;; Do nothing if a completion was found |
444 ;; No completion was found | 516 ;; No completion was found |
445 (if (not silent) | 517 (if (not silent) |
446 (ding)) | 518 (ding)) |
447 nil)) | 519 nil)) |
448 | 520 |
521 ;;; | |
522 ;;; tempo-display-completions | |
523 | |
524 (defun tempo-display-completions (string tag-list) | |
525 "Show a buffer containing possible completions for STRING." | |
526 (if tempo-leave-completion-buffer | |
527 (with-output-to-temp-buffer "*Completions*" | |
528 (display-completion-list | |
529 (all-completions string tag-list))) | |
530 (save-window-excursion | |
531 (with-output-to-temp-buffer "*Completions*" | |
532 (display-completion-list | |
533 (all-completions string tag-list))) | |
534 (sit-for 32767)))) | |
535 | |
449 ;;; tempo.el ends here | 536 ;;; tempo.el ends here |