annotate lisp/skeleton.el @ 6463:380e8fcde9a2

entered into RCS
author Richard M. Stallman <rms@gnu.org>
date Tue, 22 Mar 1994 05:43:25 +0000
parents
children e4a565cee722
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6463
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
1 ;;; skeleton.el --- Metalanguage for writing statement skeletons
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
2 ;; Copyright (C) 1993 by Free Software Foundation, Inc.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
3
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
4 ;; Author: Daniel Pfeiffer, fax (+49 69) 75 88 529, c/o <bonhoure@cict.fr>
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
5 ;; Maintainer: FSF
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
6 ;; Keywords: shell programming
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
7
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
8 ;; This file is part of GNU Emacs.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
9
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
11 ;; it under the terms of the GNU General Public License as published by
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
12 ;; the Free Software Foundation; either version 2, or (at your option)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
13 ;; any later version.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
14
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
15 ;; GNU Emacs is distributed in the hope that it will be useful,
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
18 ;; GNU General Public License for more details.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
19
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
21 ;; along with GNU Emacs; see the file COPYING. If not, write to
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
22 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
23
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
24 ;;; Commentary:
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
25
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
26 ;; A very concise metalanguage for writing structured statement
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
27 ;; skeleton insertion commands for programming language modes. This
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
28 ;; originated in shell-script mode and was applied to ada-mode's
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
29 ;; commands which shrunk to one third. And these commands are now
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
30 ;; user configurable.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
31
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
32 ;;; Code:
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
33
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
34 ;; page 1: statement skeleton metalanguage definition & interpreter
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
35 ;; page 2: paired insertion
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
36 ;; page 3: mirror-mode, an example for setting up paired insertion
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
37
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
38
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
39 (defvar skeleton-transformation nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
40 "*If non-nil, function applied to strings before they are inserted.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
41 It should take strings and characters and return them transformed, or nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
42 which means no transformation.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
43 Typical examples might be `upcase' or `capitalize'.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
44
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
45 ; this should be a fourth argument to defvar
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
46 (put 'skeleton-transformation 'variable-interactive
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
47 "aTransformation function: ")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
48
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
49
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
50
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
51 (defvar skeleton-subprompt
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
52 (substitute-command-keys
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
53 "RET, \\<minibuffer-local-map>\\[abort-recursive-edit] or \\[help-command]")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
54 "*Replacement for %s in prompts of recursive skeleton definitions.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
55
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
56
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
57
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
58 (defvar skeleton-debug nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
59 "*If non-nil `define-skeleton' will override previous definition.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
60
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
61
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
62
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
63 ;;;###autoload
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
64 (defmacro define-skeleton (command documentation &rest definition)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
65 "Define a user-configurable COMMAND that enters a statement skeleton.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
66 DOCUMENTATION is that of the command, while the variable of the same name,
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
67 which contains the definition, has a documentation to that effect.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
68 PROMPT and ELEMENT ... are as defined under `skeleton-insert'."
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
69 (if skeleton-debug
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
70 (set command definition))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
71 (require 'backquote)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
72 (`(progn
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
73 (defvar (, command) '(, definition)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
74 (, (concat "*Definition for the "
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
75 (symbol-name command)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
76 " skeleton command.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
77 See function `skeleton-insert' for meaning.")) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
78 (defun (, command) ()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
79 (, documentation)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
80 (interactive)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
81 ;; Don't use last-command to guarantee command does the same thing,
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
82 ;; whatever other name it is given.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
83 (skeleton-insert (, command))))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
84
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
85
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
86
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
87 ;;;###autoload
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
88 (defun skeleton-insert (definition &optional no-newline)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
89 "Insert the complex statement skeleton DEFINITION describes very concisely.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
90 If optional NO-NEWLINE is nil the skeleton will end on a line of its own.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
91
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
92 DEFINITION is made up as (PROMPT ELEMENT ...). PROMPT may be nil if not
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
93 needed, a prompt-string or an expression for complex read functions.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
94
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
95 If ELEMENT is a string or a character it gets inserted (see also
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
96 `skeleton-transformation'). Other possibilities are:
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
97
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
98 \\n go to next line and align cursor
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
99 > indent according to major mode
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
100 < undent tab-width spaces but not beyond beginning of line
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
101 _ cursor after termination
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
102 & skip next ELEMENT if previous didn't move point
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
103 | skip next ELEMENT if previous moved point
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
104 -num delete num preceding characters
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
105 resume: skipped, continue here if quit is signaled
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
106 nil skipped
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
107
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
108 ELEMENT may itself be DEFINITION with a PROMPT. The user is prompted
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
109 repeatedly for different inputs. The DEFINITION is processed as often
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
110 as the user enters a non-empty string. \\[keyboard-quit] terminates
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
111 skeleton insertion, but continues after `resume:' and positions at `_'
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
112 if any. If PROMPT in such a sub-definition contains a \".. %s ..\" it
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
113 is replaced by `skeleton-subprompt'.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
114
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
115 Other lisp-expressions are evaluated and the value treated as above.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
116 The following local variables are available:
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
117
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
118 str first time: read a string prompting with PROMPT and insert it
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
119 if PROMPT is not a string it is evaluated instead
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
120 then: insert previously read string once more
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
121 quit non-nil when resume: section is entered by keyboard quit
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
122 v1, v2 local variables for memorising anything you want"
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
123 (let (modified opoint point resume: quit v1 v2)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
124 (skeleton-internal-list definition (car definition))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
125 (or no-newline
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
126 (eolp)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
127 (newline)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
128 (indent-relative t))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
129 (if point
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
130 (goto-char point))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
131
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
132
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
133
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
134 (defun skeleton-internal-read (str)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
135 (let ((minibuffer-help-form "\
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
136 As long as you provide input you will insert another subskeleton.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
137
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
138 If you enter the empty string, the loop inserting subskeletons is
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
139 left, and the current one is removed as far as it has been entered.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
140
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
141 If you quit, the current subskeleton is removed as far as it has been
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
142 entered. No more of the skeleton will be inserted, except maybe for a
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
143 syntactically necessary termination."))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
144 (setq str (if (stringp str)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
145 (read-string
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
146 (format str skeleton-subprompt))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
147 (eval str))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
148 (if (string= str "")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
149 (signal 'quit t)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
150 str))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
151
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
152
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
153 (defun skeleton-internal-list (definition &optional str recursive start line)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
154 (condition-case quit
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
155 (progn
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
156 (setq start (save-excursion (beginning-of-line) (point))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
157 column (current-column)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
158 line (buffer-substring start
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
159 (save-excursion (end-of-line) (point)))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
160 str (list 'setq 'str
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
161 (if recursive
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
162 (list 'skeleton-internal-read (list 'quote str))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
163 (list (if (stringp str)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
164 'read-string
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
165 'eval)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
166 str))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
167 (while (setq modified (eq opoint (point))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
168 opoint (point)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
169 definition (cdr definition))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
170 (skeleton-internal-1 (car definition)))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
171 ;; maybe continue loop
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
172 recursive)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
173 (quit ;; remove the subskeleton as far as it has been shown
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
174 (if (eq (cdr quit) 'recursive)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
175 ()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
176 ;; the subskeleton shouldn't have deleted outside current line
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
177 (end-of-line)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
178 (delete-region start (point))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
179 (insert line)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
180 (move-to-column column))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
181 (if (eq (cdr quit) t)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
182 ;; empty string entered
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
183 nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
184 (while (if definition
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
185 (not (eq (car (setq definition (cdr definition)))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
186 'resume:))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
187 (if definition
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
188 (skeleton-internal-list definition)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
189 ;; propagate signal we can't handle
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
190 (if recursive (signal 'quit 'recursive)))))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
191
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
192
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
193
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
194 (defun skeleton-internal-1 (element)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
195 (cond ( (and (integerp element)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
196 (< element 0))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
197 (delete-char element))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
198 ( (char-or-string-p element)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
199 (insert (if skeleton-transformation
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
200 (funcall skeleton-transformation element)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
201 element)) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
202 ( (eq element '\n) ; actually (eq '\n 'n)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
203 (newline)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
204 (indent-relative t) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
205 ( (eq element '>)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
206 (indent-for-tab-command) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
207 ( (eq element '<)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
208 (backward-delete-char-untabify (min tab-width (current-column))) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
209 ( (eq element '_)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
210 (or point
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
211 (setq point (point))) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
212 ( (eq element '&)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
213 (if modified
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
214 (setq definition (cdr definition))) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
215 ( (eq element '|)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
216 (or modified
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
217 (setq definition (cdr definition))) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
218 ( (if (consp element)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
219 (or (stringp (car element))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
220 (consp (car element))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
221 (while (skeleton-internal-list element (car element) t)) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
222 ( (null element) )
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
223 ( (skeleton-internal-1 (eval element)) )))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
224
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
225
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
226 ;; variables and command for automatically inserting pairs like () or ""
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
227
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
228 (defvar pair nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
229 "*If this is nil pairing is turned off, no matter what else is set.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
230 Otherwise modes with `pair-insert-maybe' on some keys will attempt this.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
231
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
232
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
233 (defvar pair-on-word nil
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
234 "*If this is nil pairing is not attempted before or inside a word.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
235
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
236
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
237 (defvar pair-filter (lambda ())
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
238 "Attempt pairing if this function returns nil, before inserting.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
239 This allows for context-sensitive checking whether pairing is appropriate.")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
240
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
241
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
242 (defvar pair-alist ()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
243 "An override alist of pairing partners matched against
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
244 `last-command-char'. Each alist element, which looks like (ELEMENT
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
245 ...), is passed to `skeleton-insert' with no prompt. Variable `str'
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
246 does nothing.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
247
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
248 Elements might be (?` ?` _ \"''\"), (?\\( ? _ \" )\") or (?{ \\n > _ \\n < ?}).")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
249
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
250
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
251
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
252 ;;;###autoload
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
253 (defun pair-insert-maybe (arg)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
254 "Insert the character you type ARG times.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
255
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
256 With no ARG, if `pair' is non-nil, and if
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
257 `pair-on-word' is non-nil or we are not before or inside a
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
258 word, and if `pair-filter' returns nil, pairing is performed.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
259
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
260 If a match is found in `pair-alist', that is inserted, else
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
261 the defaults are used. These are (), [], {}, <> and `' for the
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
262 symmetrical ones, and the same character twice for the others."
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
263 (interactive "*P")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
264 (if (or arg
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
265 (not pair)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
266 (if (not pair-on-word) (looking-at "\\w"))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
267 (funcall pair-filter))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
268 (self-insert-command (prefix-numeric-value arg))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
269 (insert last-command-char)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
270 (if (setq arg (assq last-command-char pair-alist))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
271 ;; typed char is inserted, and car means no prompt
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
272 (skeleton-insert arg t)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
273 (save-excursion
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
274 (insert (or (cdr (assq last-command-char
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
275 '((?( . ?))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
276 (?[ . ?])
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
277 (?{ . ?})
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
278 (?< . ?>)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
279 (?` . ?'))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
280 last-command-char))))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
281
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
282
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
283
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
284 ;;;###autoload
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
285 ;; a more serious example can be found in shell-script.el
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
286 (defun mirror-mode ()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
287 "This major mode is an amusing little example of paired insertion.
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
288 All printable characters do a paired self insert, while the other commands
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
289 work normally."
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
290 (interactive)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
291 (kill-all-local-variables)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
292 (make-local-variable 'pair)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
293 (make-local-variable 'pair-on-word)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
294 (make-local-variable 'pair-filter)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
295 (make-local-variable 'pair-alist)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
296 (setq major-mode 'mirror-mode
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
297 mode-name "Mirror"
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
298 pair-on-word t
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
299 ;; in the middle column insert one or none if odd window-width
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
300 pair-filter (lambda ()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
301 (if (>= (current-column)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
302 (/ (window-width) 2))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
303 ;; insert both on next line
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
304 (next-line 1)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
305 ;; insert one or both?
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
306 (= (* 2 (1+ (current-column)))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
307 (window-width))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
308 ;; mirror these the other way round as well
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
309 pair-alist '((?) _ ?()
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
310 (?] _ ?[)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
311 (?} _ ?{)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
312 (?> _ ?<)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
313 (?/ _ ?\\)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
314 (?\\ _ ?/)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
315 (?` ?` _ "''")
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
316 (?' ?' _ "``"))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
317 ;; in this mode we exceptionally ignore the user, else it's no fun
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
318 pair t)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
319 (let ((map (make-keymap))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
320 (i ? ))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
321 (use-local-map map)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
322 (setq map (car (cdr map)))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
323 (while (< i ?\^?)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
324 (aset map i 'pair-insert-maybe)
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
325 (setq i (1+ i))))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
326 (run-hooks 'mirror-mode-hook))
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
327
380e8fcde9a2 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
328 ;; skeleton.el ends here