diff options
| -rw-r--r-- | lisp/skeleton.el | 139 |
1 files changed, 76 insertions, 63 deletions
diff --git a/lisp/skeleton.el b/lisp/skeleton.el index 317410b6219..2bb33ee4db6 100644 --- a/lisp/skeleton.el +++ b/lisp/skeleton.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; skeleton.el --- Lisp language extension for writing statement skeletons | 1 | ;;; skeleton.el --- Lisp language extension for writing statement skeletons |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1993, 1994, 1995 by Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1993, 1994, 1995, 1996 by Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Daniel.Pfeiffer@Informatik.START.dbp.de, fax (+49 69) 7588-2389 | 5 | ;; Author: Daniel.Pfeiffer@Informatik.START.dbp.de, fax (+49 69) 7588-2389 |
| 6 | ;; Maintainer: FSF | 6 | ;; Maintainer: FSF |
| @@ -49,6 +49,16 @@ Typical examples might be `upcase' or `capitalize'.") | |||
| 49 | "aTransformation function: ") | 49 | "aTransformation function: ") |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | (defvar skeleton-autowrap t | ||
| 53 | "Controls wrapping behaviour of functions created with `define-skeleton'. | ||
| 54 | When the region is visible (due to `transient-mark-mode' or marking a region | ||
| 55 | with the mouse) and this is non-`nil' and the function was called without an | ||
| 56 | explicit ARG, then the ARG defaults to -1, i.e. wrapping around the visible | ||
| 57 | region. | ||
| 58 | |||
| 59 | We will probably delete this variable in a future Emacs version | ||
| 60 | unless we get a substantial number of complaints about the auto-wrap | ||
| 61 | feature.") | ||
| 52 | 62 | ||
| 53 | (defvar skeleton-end-hook | 63 | (defvar skeleton-end-hook |
| 54 | (lambda () | 64 | (lambda () |
| @@ -60,7 +70,7 @@ The variables `v1' and `v2' are still set when calling this.") | |||
| 60 | 70 | ||
| 61 | ;;;###autoload | 71 | ;;;###autoload |
| 62 | (defvar skeleton-filter 'identity | 72 | (defvar skeleton-filter 'identity |
| 63 | "Function for transforming a skeleton-proxy's aliases' variable value.") | 73 | "Function for transforming a skeleton proxy's aliases' variable value.") |
| 64 | 74 | ||
| 65 | (defvar skeleton-untabify t | 75 | (defvar skeleton-untabify t |
| 66 | "When non-`nil' untabifies when deleting backwards with element -ARG.") | 76 | "When non-`nil' untabifies when deleting backwards with element -ARG.") |
| @@ -83,7 +93,8 @@ skeleton elements.") | |||
| 83 | "*Replacement for %s in prompts of recursive subskeletons.") | 93 | "*Replacement for %s in prompts of recursive subskeletons.") |
| 84 | 94 | ||
| 85 | 95 | ||
| 86 | (defvar skeleton-abbrev-cleanup nil) | 96 | (defvar skeleton-abbrev-cleanup nil |
| 97 | "Variable used to delete the character that led to abbrev expansion.") | ||
| 87 | 98 | ||
| 88 | 99 | ||
| 89 | (defvar skeleton-debug nil | 100 | (defvar skeleton-debug nil |
| @@ -115,6 +126,8 @@ INTERACTOR and ELEMENT ... are as defined under `skeleton-insert'." | |||
| 115 | (defun skeleton-proxy (&optional str arg) | 126 | (defun skeleton-proxy (&optional str arg) |
| 116 | "Insert skeleton defined by variable of same name (see `skeleton-insert'). | 127 | "Insert skeleton defined by variable of same name (see `skeleton-insert'). |
| 117 | Prefix ARG allows wrapping around words or regions (see `skeleton-insert'). | 128 | Prefix ARG allows wrapping around words or regions (see `skeleton-insert'). |
| 129 | If no ARG was given, and the region is visible, it defaults to -1 depending | ||
| 130 | on `skeleton-autowrap'. An ARG of M-0 will prevent this just for once. | ||
| 118 | This command can also be an abbrev expansion (3rd and 4th columns in | 131 | This command can also be an abbrev expansion (3rd and 4th columns in |
| 119 | \\[edit-abbrevs] buffer: \"\" command-name). | 132 | \\[edit-abbrevs] buffer: \"\" command-name). |
| 120 | 133 | ||
| @@ -123,7 +136,7 @@ which will be the value of `str' whereas the skeleton's interactor is then | |||
| 123 | ignored." | 136 | ignored." |
| 124 | (interactive "*P\nP") | 137 | (interactive "*P\nP") |
| 125 | (let ((function (nth 1 (backtrace-frame 1)))) | 138 | (let ((function (nth 1 (backtrace-frame 1)))) |
| 126 | (if (eq function 'nth) ; uncompiled lisp function | 139 | (if (eq function 'nth) ; uncompiled Lisp function |
| 127 | (setq function (nth 1 (backtrace-frame 5))) | 140 | (setq function (nth 1 (backtrace-frame 5))) |
| 128 | (if (eq function 'byte-code) ; tracing byte-compiled function | 141 | (if (eq function 'byte-code) ; tracing byte-compiled function |
| 129 | (setq function (nth 1 (backtrace-frame 2))))) | 142 | (setq function (nth 1 (backtrace-frame 2))))) |
| @@ -141,13 +154,16 @@ ignored." | |||
| 141 | ;; Pretend C-x a e passed its prefix arg to us | 154 | ;; Pretend C-x a e passed its prefix arg to us |
| 142 | (if (or arg current-prefix-arg) | 155 | (if (or arg current-prefix-arg) |
| 143 | (prefix-numeric-value (or arg | 156 | (prefix-numeric-value (or arg |
| 144 | current-prefix-arg)))) | 157 | current-prefix-arg)) |
| 158 | (and skeleton-autowrap | ||
| 159 | (or (eq last-command 'mouse-drag-region) | ||
| 160 | (and transient-mark-mode mark-active)) | ||
| 161 | -1))) | ||
| 145 | (if (stringp str) | 162 | (if (stringp str) |
| 146 | str)) | 163 | str)) |
| 147 | (if skeleton-abbrev-cleanup | 164 | (and skeleton-abbrev-cleanup |
| 148 | (setq deferred-action-list t | 165 | (setq skeleton-abbrev-cleanup (point)) |
| 149 | deferred-action-function 'skeleton-abbrev-cleanup | 166 | (add-hook 'post-command-hook 'skeleton-abbrev-cleanup nil t))))) |
| 150 | skeleton-abbrev-cleanup (point)))))) | ||
| 151 | 167 | ||
| 152 | 168 | ||
| 153 | (defun skeleton-abbrev-cleanup (&rest list) | 169 | (defun skeleton-abbrev-cleanup (&rest list) |
| @@ -155,9 +171,8 @@ ignored." | |||
| 155 | (if (integerp skeleton-abbrev-cleanup) | 171 | (if (integerp skeleton-abbrev-cleanup) |
| 156 | (progn | 172 | (progn |
| 157 | (delete-region skeleton-abbrev-cleanup (point)) | 173 | (delete-region skeleton-abbrev-cleanup (point)) |
| 158 | (setq deferred-action-list () | 174 | (setq skeleton-abbrev-cleanup) |
| 159 | deferred-action-function nil | 175 | (remove-hook 'post-command-hook 'skeleton-abbrev-cleanup t)))) |
| 160 | skeleton-abbrev-cleanup nil)))) | ||
| 161 | 176 | ||
| 162 | 177 | ||
| 163 | ;;;###autoload | 178 | ;;;###autoload |
| @@ -200,8 +215,8 @@ a subskeleton is a prompt-string which contains a \".. %s ..\" it is | |||
| 200 | formatted with `skeleton-subprompt'. Such an INTERACTOR may also a list of | 215 | formatted with `skeleton-subprompt'. Such an INTERACTOR may also a list of |
| 201 | strings with the subskeleton being repeated once for each string. | 216 | strings with the subskeleton being repeated once for each string. |
| 202 | 217 | ||
| 203 | Quoted lisp-expressions are evaluated evaluated for their side-effect. | 218 | Quoted Lisp expressions are evaluated evaluated for their side-effect. |
| 204 | Other lisp-expressions are evaluated and the value treated as above. | 219 | Other Lisp expressions are evaluated and the value treated as above. |
| 205 | Note that expressions may not return `t' since this implies an | 220 | Note that expressions may not return `t' since this implies an |
| 206 | endless loop. Modes can define other symbols by locally setting them | 221 | endless loop. Modes can define other symbols by locally setting them |
| 207 | to any valid skeleton element. The following local variables are | 222 | to any valid skeleton element. The following local variables are |
| @@ -211,7 +226,7 @@ available: | |||
| 211 | then: insert previously read string once more | 226 | then: insert previously read string once more |
| 212 | help help-form during interaction with the user or `nil' | 227 | help help-form during interaction with the user or `nil' |
| 213 | input initial input (string or cons with index) while reading str | 228 | input initial input (string or cons with index) while reading str |
| 214 | v1, v2 local variables for memorising anything you want | 229 | v1, v2 local variables for memorizing anything you want |
| 215 | 230 | ||
| 216 | When done with skeleton, but before going back to `_'-point call | 231 | When done with skeleton, but before going back to `_'-point call |
| 217 | `skeleton-end-hook' if that is non-`nil'." | 232 | `skeleton-end-hook' if that is non-`nil'." |
| @@ -384,17 +399,16 @@ automatically, and you are prompted to fill in the variable parts."))) | |||
| 384 | 399 | ||
| 385 | ;;;(define-skeleton local-variables-section | 400 | ;;;(define-skeleton local-variables-section |
| 386 | ;;; "Insert a local variables section. Use current comment syntax if any." | 401 | ;;; "Insert a local variables section. Use current comment syntax if any." |
| 387 | ;;; () | ||
| 388 | ;;; '(save-excursion | ||
| 389 | ;;; (if (re-search-forward page-delimiter nil t) | ||
| 390 | ;;; (error "Not on last page."))) | ||
| 391 | ;;; comment-start "Local Variables:" comment-end \n | ||
| 392 | ;;; comment-start "mode: " | ||
| 393 | ;;; (completing-read "Mode: " obarray | 402 | ;;; (completing-read "Mode: " obarray |
| 394 | ;;; (lambda (symbol) | 403 | ;;; (lambda (symbol) |
| 395 | ;;; (if (commandp symbol) | 404 | ;;; (if (commandp symbol) |
| 396 | ;;; (string-match "-mode$" (symbol-name symbol)))) | 405 | ;;; (string-match "-mode$" (symbol-name symbol)))) |
| 397 | ;;; t) | 406 | ;;; t) |
| 407 | ;;; '(save-excursion | ||
| 408 | ;;; (if (re-search-forward page-delimiter nil t) | ||
| 409 | ;;; (error "Not on last page."))) | ||
| 410 | ;;; comment-start "Local Variables:" comment-end \n | ||
| 411 | ;;; comment-start "mode: " str | ||
| 398 | ;;; & -5 | '(kill-line 0) & -1 | comment-end \n | 412 | ;;; & -5 | '(kill-line 0) & -1 | comment-end \n |
| 399 | ;;; ( (completing-read (format "Variable, %s: " skeleton-subprompt) | 413 | ;;; ( (completing-read (format "Variable, %s: " skeleton-subprompt) |
| 400 | ;;; obarray | 414 | ;;; obarray |
| @@ -470,49 +484,48 @@ symmetrical ones, and the same character twice for the others." | |||
| 470 | last-command-char))))))) | 484 | last-command-char))))))) |
| 471 | 485 | ||
| 472 | 486 | ||
| 473 | ;;; ;; A more serious example can be found in sh-script.el | 487 | ;;; A more serious example can be found in sh-script.el |
| 474 | ;;; ;; The quote before (defun prevents this from being byte-compiled. | ||
| 475 | ;;;(defun mirror-mode () | 488 | ;;;(defun mirror-mode () |
| 476 | ;;; "This major mode is an amusing little example of paired insertion. | 489 | ;; "This major mode is an amusing little example of paired insertion. |
| 477 | ;;;All printable characters do a paired self insert, while the other commands | 490 | ;;All printable characters do a paired self insert, while the other commands |
| 478 | ;;;work normally." | 491 | ;;work normally." |
| 479 | ;;; (interactive) | 492 | ;; (interactive) |
| 480 | ;;; (kill-all-local-variables) | 493 | ;; (kill-all-local-variables) |
| 481 | ;;; (make-local-variable 'pair) | 494 | ;; (make-local-variable 'pair) |
| 482 | ;;; (make-local-variable 'pair-on-word) | 495 | ;; (make-local-variable 'pair-on-word) |
| 483 | ;;; (make-local-variable 'pair-filter) | 496 | ;; (make-local-variable 'pair-filter) |
| 484 | ;;; (make-local-variable 'pair-alist) | 497 | ;; (make-local-variable 'pair-alist) |
| 485 | ;;; (setq major-mode 'mirror-mode | 498 | ;; (setq major-mode 'mirror-mode |
| 486 | ;;; mode-name "Mirror" | 499 | ;; mode-name "Mirror" |
| 487 | ;;; pair-on-word t | 500 | ;; pair-on-word t |
| 488 | ;;; ;; in the middle column insert one or none if odd window-width | 501 | ;; ;; in the middle column insert one or none if odd window-width |
| 489 | ;;; pair-filter (lambda () | 502 | ;; pair-filter (lambda () |
| 490 | ;;; (if (>= (current-column) | 503 | ;; (if (>= (current-column) |
| 491 | ;;; (/ (window-width) 2)) | 504 | ;; (/ (window-width) 2)) |
| 492 | ;;; ;; insert both on next line | 505 | ;; ;; insert both on next line |
| 493 | ;;; (next-line 1) | 506 | ;; (next-line 1) |
| 494 | ;;; ;; insert one or both? | 507 | ;; ;; insert one or both? |
| 495 | ;;; (= (* 2 (1+ (current-column))) | 508 | ;; (= (* 2 (1+ (current-column))) |
| 496 | ;;; (window-width)))) | 509 | ;; (window-width)))) |
| 497 | ;;; ;; mirror these the other way round as well | 510 | ;; ;; mirror these the other way round as well |
| 498 | ;;; pair-alist '((?) _ ?() | 511 | ;; pair-alist '((?) _ ?() |
| 499 | ;;; (?] _ ?[) | 512 | ;; (?] _ ?[) |
| 500 | ;;; (?} _ ?{) | 513 | ;; (?} _ ?{) |
| 501 | ;;; (?> _ ?<) | 514 | ;; (?> _ ?<) |
| 502 | ;;; (?/ _ ?\\) | 515 | ;; (?/ _ ?\\) |
| 503 | ;;; (?\\ _ ?/) | 516 | ;; (?\\ _ ?/) |
| 504 | ;;; (?` ?` _ "''") | 517 | ;; (?` ?` _ "''") |
| 505 | ;;; (?' ?' _ "``")) | 518 | ;; (?' ?' _ "``")) |
| 506 | ;;; ;; in this mode we exceptionally ignore the user, else it's no fun | 519 | ;; ;; in this mode we exceptionally ignore the user, else it's no fun |
| 507 | ;;; pair t) | 520 | ;; pair t) |
| 508 | ;;; (let ((map (make-keymap)) | 521 | ;; (let ((map (make-keymap)) |
| 509 | ;;; (i ? )) | 522 | ;; (i ? )) |
| 510 | ;;; (use-local-map map) | 523 | ;; (use-local-map map) |
| 511 | ;;; (setq map (car (cdr map))) | 524 | ;; (setq map (car (cdr map))) |
| 512 | ;;; (while (< i ?\^?) | 525 | ;; (while (< i ?\^?) |
| 513 | ;;; (aset map i 'skeleton-pair-insert-maybe) | 526 | ;; (aset map i 'skeleton-pair-insert-maybe) |
| 514 | ;;; (setq i (1+ i)))) | 527 | ;; (setq i (1+ i)))) |
| 515 | ;;; (run-hooks 'mirror-mode-hook)) | 528 | ;; (run-hooks 'mirror-mode-hook)) |
| 516 | 529 | ||
| 517 | (provide 'skeleton) | 530 | (provide 'skeleton) |
| 518 | 531 | ||