Mercurial > emacs
annotate lisp/subr.el @ 88331:87edb010d368
*** empty log message ***
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Thu, 09 Mar 2006 02:16:39 +0000 |
parents | d7ddb3e565de |
children |
rev | line source |
---|---|
658
7cbd4fcd8b0f
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
648
diff
changeset
|
1 ;;; subr.el --- basic lisp subroutines for Emacs |
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
779
diff
changeset
|
2 |
88155 | 3 ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003, |
4 ;; 2004, 2005 Free Software Foundation, Inc. | |
114 | 5 |
45078 | 6 ;; Maintainer: FSF |
7 ;; Keywords: internal | |
8 | |
114 | 9 ;; This file is part of GNU Emacs. |
10 | |
11 ;; 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 | |
707 | 13 ;; the Free Software Foundation; either version 2, or (at your option) |
114 | 14 ;; any later version. |
15 | |
16 ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
14169 | 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
88155 | 23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
24 ;; Boston, MA 02110-1301, USA. | |
114 | 25 |
38414
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
37070
diff
changeset
|
26 ;;; Commentary: |
67b464da13ec
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
37070
diff
changeset
|
27 |
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
779
diff
changeset
|
28 ;;; Code: |
18880
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
29 (defvar custom-declare-variable-list nil |
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
30 "Record `defcustom' calls made before `custom.el' is loaded to handle them. |
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
31 Each element of this list holds the arguments to one call to `defcustom'.") |
114 | 32 |
19662 | 33 ;; Use this, rather than defcustom, in subr.el and other files loaded |
18880
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
34 ;; before custom.el. |
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
35 (defun custom-declare-variable-early (&rest arguments) |
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
36 (setq custom-declare-variable-list |
1ed40ed8e0c1
(custom-declare-variable-early): New function.
Richard M. Stallman <rms@gnu.org>
parents:
18828
diff
changeset
|
37 (cons arguments custom-declare-variable-list))) |
44129
444bd245e176
(macro-declaration-function): New function. Set the
Gerd Moellmann <gerd@gnu.org>
parents:
43833
diff
changeset
|
38 |
444bd245e176
(macro-declaration-function): New function. Set the
Gerd Moellmann <gerd@gnu.org>
parents:
43833
diff
changeset
|
39 |
88155 | 40 ;;;; Basic Lisp macros. |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
41 |
40822
b10e7d6fb95b
(with-local-quit): New macro.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
40282
diff
changeset
|
42 (defalias 'not 'null) |
b10e7d6fb95b
(with-local-quit): New macro.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
40282
diff
changeset
|
43 |
88155 | 44 (defmacro noreturn (form) |
45 "Evaluate FORM, expecting it not to return. | |
46 If FORM does return, signal an error." | |
47 `(prog1 ,form | |
48 (error "Form marked with `noreturn' did return"))) | |
49 | |
50 (defmacro 1value (form) | |
51 "Evaluate FORM, expecting a constant return value. | |
52 This is the global do-nothing version. There is also `testcover-1value' | |
53 that complains if FORM ever does return differing values." | |
54 form) | |
55 | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
56 (defmacro lambda (&rest cdr) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
57 "Return a lambda expression. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
58 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
59 self-quoting; the result of evaluating the lambda expression is the |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
60 expression itself. The lambda expression may then be treated as a |
10178 | 61 function, i.e., stored as the function value of a symbol, passed to |
88155 | 62 `funcall' or `mapcar', etc. |
10178 | 63 |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
64 ARGS should take the same form as an argument list for a `defun'. |
12395 | 65 DOCSTRING is an optional documentation string. |
66 If present, it should describe how to call the function. | |
67 But documentation strings are usually not useful in nameless functions. | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
68 INTERACTIVE should be a call to the function `interactive', which see. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
69 It may also be omitted. |
88155 | 70 BODY should be a list of Lisp expressions. |
71 | |
72 \(fn ARGS [DOCSTRING] [INTERACTIVE] BODY)" | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
73 ;; Note that this definition should not use backquotes; subr.el should not |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
74 ;; depend on backquote.el. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
75 (list 'function (cons 'lambda cdr))) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
76 |
25437 | 77 (defmacro push (newelt listname) |
25580 | 78 "Add NEWELT to the list stored in the symbol LISTNAME. |
25437 | 79 This is equivalent to (setq LISTNAME (cons NEWELT LISTNAME)). |
25436
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
80 LISTNAME must be a symbol." |
88155 | 81 (declare (debug (form sexp))) |
25469 | 82 (list 'setq listname |
83 (list 'cons newelt listname))) | |
25436
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
84 |
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
85 (defmacro pop (listname) |
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
86 "Return the first element of LISTNAME's value, and remove it from the list. |
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
87 LISTNAME must be a symbol whose value is a list. |
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
88 If the value is nil, `pop' returns nil but does not actually |
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
89 change the list." |
88155 | 90 (declare (debug (sexp))) |
45823
7ec7fff5e571
(pop): Move the call to `car' outside the prog1, as the compiler
Miles Bader <miles@gnu.org>
parents:
45821
diff
changeset
|
91 (list 'car |
7ec7fff5e571
(pop): Move the call to `car' outside the prog1, as the compiler
Miles Bader <miles@gnu.org>
parents:
45821
diff
changeset
|
92 (list 'prog1 listname |
7ec7fff5e571
(pop): Move the call to `car' outside the prog1, as the compiler
Miles Bader <miles@gnu.org>
parents:
45821
diff
changeset
|
93 (list 'setq listname (list 'cdr listname))))) |
25436
d24cf1a4dd34
(push, pop): New macros.
Richard M. Stallman <rms@gnu.org>
parents:
25295
diff
changeset
|
94 |
16845
adc714dc8e3c
(when, unless): Definitions moved from cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
16556
diff
changeset
|
95 (defmacro when (cond &rest body) |
27810
1d7650c95e0a
(when, unless, split-string): Doc fix.
Dave Love <fx@gnu.org>
parents:
27482
diff
changeset
|
96 "If COND yields non-nil, do BODY, else return nil." |
88155 | 97 (declare (indent 1) (debug t)) |
16845
adc714dc8e3c
(when, unless): Definitions moved from cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
16556
diff
changeset
|
98 (list 'if cond (cons 'progn body))) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
99 |
16845
adc714dc8e3c
(when, unless): Definitions moved from cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
16556
diff
changeset
|
100 (defmacro unless (cond &rest body) |
27810
1d7650c95e0a
(when, unless, split-string): Doc fix.
Dave Love <fx@gnu.org>
parents:
27482
diff
changeset
|
101 "If COND yields nil, do BODY, else return nil." |
88155 | 102 (declare (indent 1) (debug t)) |
16845
adc714dc8e3c
(when, unless): Definitions moved from cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
16556
diff
changeset
|
103 (cons 'if (cons cond (cons nil body)))) |
19491
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
104 |
27376
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
105 (defmacro dolist (spec &rest body) |
88155 | 106 "Loop over a list. |
27376
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
107 Evaluate BODY with VAR bound to each car from LIST, in turn. |
88155 | 108 Then evaluate RESULT to get return value, default nil. |
109 | |
110 \(fn (VAR LIST [RESULT]) BODY...)" | |
111 (declare (indent 1) (debug ((symbolp form &optional form) body))) | |
27383
b1b3e778f7ac
Make the definitions of dolist and dotimes work
Richard M. Stallman <rms@gnu.org>
parents:
27376
diff
changeset
|
112 (let ((temp (make-symbol "--dolist-temp--"))) |
88155 | 113 `(let ((,temp ,(nth 1 spec)) |
114 ,(car spec)) | |
115 (while ,temp | |
116 (setq ,(car spec) (car ,temp)) | |
117 (setq ,temp (cdr ,temp)) | |
118 ,@body) | |
119 ,@(if (cdr (cdr spec)) | |
120 `((setq ,(car spec) nil) ,@(cdr (cdr spec))))))) | |
27376
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
121 |
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
122 (defmacro dotimes (spec &rest body) |
88155 | 123 "Loop a certain number of times. |
27376
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
124 Evaluate BODY with VAR bound to successive integers running from 0, |
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
125 inclusive, to COUNT, exclusive. Then evaluate RESULT to get |
88155 | 126 the return value (nil if RESULT is omitted). |
127 | |
128 \(fn (VAR COUNT [RESULT]) BODY...)" | |
129 (declare (indent 1) (debug dolist)) | |
130 (let ((temp (make-symbol "--dotimes-temp--")) | |
131 (start 0) | |
132 (end (nth 1 spec))) | |
133 `(let ((,temp ,end) | |
134 (,(car spec) ,start)) | |
135 (while (< ,(car spec) ,temp) | |
136 ,@body | |
137 (setq ,(car spec) (1+ ,(car spec)))) | |
138 ,@(cdr (cdr spec))))) | |
139 | |
140 (defmacro declare (&rest specs) | |
141 "Do not evaluate any arguments and return nil. | |
142 Treated as a declaration when used at the right place in a | |
143 `defmacro' form. \(See Info anchor `(elisp)Definition of declare'.)" | |
144 nil) | |
145 | |
146 ;;;; Basic Lisp functions. | |
147 | |
148 (defun ignore (&rest ignore) | |
149 "Do nothing and return nil. | |
150 This function accepts any number of arguments, but ignores them." | |
151 (interactive) | |
152 nil) | |
153 | |
154 (defun error (&rest args) | |
155 "Signal an error, making error message by passing all args to `format'. | |
156 In Emacs, the convention is that error messages start with a capital | |
157 letter but *do not* end with a period. Please follow this convention | |
158 for the sake of consistency." | |
159 (while t | |
160 (signal 'error (list (apply 'format args))))) | |
161 | |
162 ;; We put this here instead of in frame.el so that it's defined even on | |
163 ;; systems where frame.el isn't loaded. | |
164 (defun frame-configuration-p (object) | |
165 "Return non-nil if OBJECT seems to be a frame configuration. | |
166 Any list whose car is `frame-configuration' is assumed to be a frame | |
167 configuration." | |
168 (and (consp object) | |
169 (eq (car object) 'frame-configuration))) | |
170 | |
171 (defun functionp (object) | |
172 "Non-nil if OBJECT is any kind of function or a special form. | |
173 Also non-nil if OBJECT is a symbol and its function definition is | |
174 \(recursively) a function or special form. This does not include | |
175 macros." | |
176 (or (and (symbolp object) (fboundp object) | |
177 (condition-case nil | |
178 (setq object (indirect-function object)) | |
179 (error nil)) | |
180 (eq (car-safe object) 'autoload) | |
181 (not (car-safe (cdr-safe (cdr-safe (cdr-safe (cdr-safe object))))))) | |
182 (subrp object) (byte-code-function-p object) | |
183 (eq (car-safe object) 'lambda))) | |
184 | |
185 ;;;; List functions. | |
27376
674b7f75841e
(dolist, dotimes): Moved from cl-macs.el.
Richard M. Stallman <rms@gnu.org>
parents:
27297
diff
changeset
|
186 |
19491
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
187 (defsubst caar (x) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
188 "Return the car of the car of X." |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
189 (car (car x))) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
190 |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
191 (defsubst cadr (x) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
192 "Return the car of the cdr of X." |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
193 (car (cdr x))) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
194 |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
195 (defsubst cdar (x) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
196 "Return the cdr of the car of X." |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
197 (cdr (car x))) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
198 |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
199 (defsubst cddr (x) |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
200 "Return the cdr of the cdr of X." |
f5fd22f3462c
(caar, cadr, cdar, cddr): Definitions moved here and changed into defsubsts.
Richard M. Stallman <rms@gnu.org>
parents:
19176
diff
changeset
|
201 (cdr (cdr x))) |
19492 | 202 |
88155 | 203 (defun last (list &optional n) |
204 "Return the last link of LIST. Its car is the last element. | |
205 If LIST is nil, return nil. | |
206 If N is non-nil, return the Nth-to-last link of LIST. | |
207 If N is bigger than the length of LIST, return LIST." | |
19584
17db1ee36bbb
(last): Accept optional second argument.
Richard M. Stallman <rms@gnu.org>
parents:
19492
diff
changeset
|
208 (if n |
88155 | 209 (let ((m 0) (p list)) |
19584
17db1ee36bbb
(last): Accept optional second argument.
Richard M. Stallman <rms@gnu.org>
parents:
19492
diff
changeset
|
210 (while (consp p) |
17db1ee36bbb
(last): Accept optional second argument.
Richard M. Stallman <rms@gnu.org>
parents:
19492
diff
changeset
|
211 (setq m (1+ m) p (cdr p))) |
17db1ee36bbb
(last): Accept optional second argument.
Richard M. Stallman <rms@gnu.org>
parents:
19492
diff
changeset
|
212 (if (<= n 0) p |
88155 | 213 (if (< n m) (nthcdr (- m n) list) list))) |
214 (while (consp (cdr list)) | |
215 (setq list (cdr list))) | |
216 list)) | |
217 | |
218 (defun butlast (list &optional n) | |
219 "Return a copy of LIST with the last N elements removed." | |
220 (if (and n (<= n 0)) list | |
221 (nbutlast (copy-sequence list) n))) | |
222 | |
223 (defun nbutlast (list &optional n) | |
34898
1486728b21f0
(butlast, nbutlast): Moved from cl.el to here.
Kenichi Handa <handa@m17n.org>
parents:
34853
diff
changeset
|
224 "Modifies LIST to remove the last N elements." |
88155 | 225 (let ((m (length list))) |
34898
1486728b21f0
(butlast, nbutlast): Moved from cl.el to here.
Kenichi Handa <handa@m17n.org>
parents:
34853
diff
changeset
|
226 (or n (setq n 1)) |
1486728b21f0
(butlast, nbutlast): Moved from cl.el to here.
Kenichi Handa <handa@m17n.org>
parents:
34853
diff
changeset
|
227 (and (< n m) |
1486728b21f0
(butlast, nbutlast): Moved from cl.el to here.
Kenichi Handa <handa@m17n.org>
parents:
34853
diff
changeset
|
228 (progn |
88155 | 229 (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil)) |
230 list)))) | |
231 | |
232 (defun delete-dups (list) | |
233 "Destructively remove `equal' duplicates from LIST. | |
234 Store the result in LIST and return it. LIST must be a proper list. | |
235 Of several `equal' occurrences of an element in LIST, the first | |
236 one is kept." | |
237 (let ((tail list)) | |
238 (while tail | |
239 (setcdr tail (delete (car tail) (cdr tail))) | |
240 (setq tail (cdr tail)))) | |
241 list) | |
242 | |
243 (defun number-sequence (from &optional to inc) | |
244 "Return a sequence of numbers from FROM to TO (both inclusive) as a list. | |
245 INC is the increment used between numbers in the sequence and defaults to 1. | |
246 So, the Nth element of the list is \(+ FROM \(* N INC)) where N counts from | |
247 zero. TO is only included if there is an N for which TO = FROM + N * INC. | |
248 If TO is nil or numerically equal to FROM, return \(FROM). | |
249 If INC is positive and TO is less than FROM, or INC is negative | |
250 and TO is larger than FROM, return nil. | |
251 If INC is zero and TO is neither nil nor numerically equal to | |
252 FROM, signal an error. | |
253 | |
254 This function is primarily designed for integer arguments. | |
255 Nevertheless, FROM, TO and INC can be integer or float. However, | |
256 floating point arithmetic is inexact. For instance, depending on | |
257 the machine, it may quite well happen that | |
258 \(number-sequence 0.4 0.6 0.2) returns the one element list \(0.4), | |
259 whereas \(number-sequence 0.4 0.8 0.2) returns a list with three | |
260 elements. Thus, if some of the arguments are floats and one wants | |
261 to make sure that TO is included, one may have to explicitly write | |
262 TO as \(+ FROM \(* N INC)) or use a variable whose value was | |
263 computed with this exact expression. Alternatively, you can, | |
264 of course, also replace TO with a slightly larger value | |
265 \(or a slightly more negative value if INC is negative)." | |
266 (if (or (not to) (= from to)) | |
267 (list from) | |
268 (or inc (setq inc 1)) | |
269 (when (zerop inc) (error "The increment can not be zero")) | |
270 (let (seq (n 0) (next from)) | |
271 (if (> inc 0) | |
272 (while (<= next to) | |
273 (setq seq (cons next seq) | |
274 n (1+ n) | |
275 next (+ from (* n inc)))) | |
276 (while (>= next to) | |
277 (setq seq (cons next seq) | |
278 n (1+ n) | |
279 next (+ from (* n inc))))) | |
280 (nreverse seq)))) | |
30515
6165183bc490
(remove, remq): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
29354
diff
changeset
|
281 |
45690
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
282 (defun copy-tree (tree &optional vecp) |
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
283 "Make a copy of TREE. |
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
284 If TREE is a cons cell, this recursively copies both its car and its cdr. |
45740
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
285 Contrast to `copy-sequence', which copies only along the cdrs. With second |
45690
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
286 argument VECP, this copies vectors as well as conses." |
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
287 (if (consp tree) |
45740
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
288 (let (result) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
289 (while (consp tree) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
290 (let ((newcar (car tree))) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
291 (if (or (consp (car tree)) (and vecp (vectorp (car tree)))) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
292 (setq newcar (copy-tree (car tree) vecp))) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
293 (push newcar result)) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
294 (setq tree (cdr tree))) |
45821
41129d3d126b
(copy-tree): Use `nconc' and `nreverse' instead of `nreconc'.
Miles Bader <miles@gnu.org>
parents:
45740
diff
changeset
|
295 (nconc (nreverse result) tree)) |
45690
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
296 (if (and vecp (vectorp tree)) |
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
297 (let ((i (length (setq tree (copy-sequence tree))))) |
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
298 (while (>= (setq i (1- i)) 0) |
45740
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
299 (aset tree i (copy-tree (aref tree i) vecp))) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
300 tree) |
4e576724db9f
(copy-list): Moved to cl.el.
Richard M. Stallman <rms@gnu.org>
parents:
45690
diff
changeset
|
301 tree))) |
88155 | 302 |
303 ;;;; Various list-search functions. | |
45690
9d351e5869c8
(copy-list): Moved here from cl.el.
Colin Walters <walters@gnu.org>
parents:
45587
diff
changeset
|
304 |
22959
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
305 (defun assoc-default (key alist &optional test default) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
306 "Find object KEY in a pseudo-alist ALIST. |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
307 ALIST is a list of conses or objects. Each element (or the element's car, |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
308 if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY). |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
309 If that is non-nil, the element matches; |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
310 then `assoc-default' returns the element's cdr, if it is a cons, |
22860
349fa4ee1f27
(assoc-default): New function.
Richard M. Stallman <rms@gnu.org>
parents:
22755
diff
changeset
|
311 or DEFAULT if the element is not a cons. |
22959
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
312 |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
313 If no element matches, the value is nil. |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
314 If TEST is omitted or nil, `equal' is used." |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
315 (let (found (tail alist) value) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
316 (while (and tail (not found)) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
317 (let ((elt (car tail))) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
318 (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
319 (setq found t value (if (consp elt) (cdr elt) default)))) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
320 (setq tail (cdr tail))) |
73a21b5f9bd8
(assoc-default): Rewrite not to use dolist.
Richard M. Stallman <rms@gnu.org>
parents:
22860
diff
changeset
|
321 value)) |
25295
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
322 |
88155 | 323 (make-obsolete 'assoc-ignore-case 'assoc-string) |
25295
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
324 (defun assoc-ignore-case (key alist) |
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
325 "Like `assoc', but ignores differences in case and text representation. |
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
326 KEY must be a string. Upper-case and lower-case letters are treated as equal. |
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
327 Unibyte strings are converted to multibyte for comparison." |
88155 | 328 (assoc-string key alist t)) |
329 | |
330 (make-obsolete 'assoc-ignore-representation 'assoc-string) | |
25295
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
331 (defun assoc-ignore-representation (key alist) |
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
332 "Like `assoc', but ignores differences in text representation. |
47916 | 333 KEY must be a string. |
25295
737e82c21934
(assoc-ignore-case, assoc-ignore-representation): Moved here from simple.el.
Karl Heuer <kwzh@gnu.org>
parents:
25293
diff
changeset
|
334 Unibyte strings are converted to multibyte for comparison." |
88155 | 335 (assoc-string key alist nil)) |
28490
9958b6d95bd6
(member-ignore-case): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28234
diff
changeset
|
336 |
9958b6d95bd6
(member-ignore-case): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28234
diff
changeset
|
337 (defun member-ignore-case (elt list) |
9958b6d95bd6
(member-ignore-case): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28234
diff
changeset
|
338 "Like `member', but ignores differences in case and text representation. |
9958b6d95bd6
(member-ignore-case): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28234
diff
changeset
|
339 ELT must be a string. Upper-case and lower-case letters are treated as equal. |
44900
e4975d9c93ff
(insert-for-yank): Replace `category' property
Richard M. Stallman <rms@gnu.org>
parents:
44723
diff
changeset
|
340 Unibyte strings are converted to multibyte for comparison. |
e4975d9c93ff
(insert-for-yank): Replace `category' property
Richard M. Stallman <rms@gnu.org>
parents:
44723
diff
changeset
|
341 Non-strings in LIST are ignored." |
e4975d9c93ff
(insert-for-yank): Replace `category' property
Richard M. Stallman <rms@gnu.org>
parents:
44723
diff
changeset
|
342 (while (and list |
e4975d9c93ff
(insert-for-yank): Replace `category' property
Richard M. Stallman <rms@gnu.org>
parents:
44723
diff
changeset
|
343 (not (and (stringp (car list)) |
e4975d9c93ff
(insert-for-yank): Replace `category' property
Richard M. Stallman <rms@gnu.org>
parents:
44723
diff
changeset
|
344 (eq t (compare-strings elt 0 nil (car list) 0 nil t))))) |
33978
9aa3fd6779f7
(member-ignore-case): Return the tail of the list who's car matches,
Miles Bader <miles@gnu.org>
parents:
33835
diff
changeset
|
345 (setq list (cdr list))) |
9aa3fd6779f7
(member-ignore-case): Return the tail of the list who's car matches,
Miles Bader <miles@gnu.org>
parents:
33835
diff
changeset
|
346 list) |
28490
9958b6d95bd6
(member-ignore-case): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28234
diff
changeset
|
347 |
88155 | 348 (defun assq-delete-all (key alist) |
349 "Delete from ALIST all elements whose car is `eq' to KEY. | |
350 Return the modified alist. | |
351 Elements of ALIST that are not conses are ignored." | |
352 (while (and (consp (car alist)) | |
353 (eq (car (car alist)) key)) | |
354 (setq alist (cdr alist))) | |
355 (let ((tail alist) tail-cdr) | |
356 (while (setq tail-cdr (cdr tail)) | |
357 (if (and (consp (car tail-cdr)) | |
358 (eq (car (car tail-cdr)) key)) | |
359 (setcdr tail (cdr tail-cdr)) | |
360 (setq tail tail-cdr)))) | |
361 alist) | |
362 | |
363 (defun rassq-delete-all (value alist) | |
364 "Delete from ALIST all elements whose cdr is `eq' to VALUE. | |
365 Return the modified alist. | |
366 Elements of ALIST that are not conses are ignored." | |
367 (while (and (consp (car alist)) | |
368 (eq (cdr (car alist)) value)) | |
369 (setq alist (cdr alist))) | |
370 (let ((tail alist) tail-cdr) | |
371 (while (setq tail-cdr (cdr tail)) | |
372 (if (and (consp (car tail-cdr)) | |
373 (eq (cdr (car tail-cdr)) value)) | |
374 (setcdr tail (cdr tail-cdr)) | |
375 (setq tail tail-cdr)))) | |
376 alist) | |
377 | |
378 (defun remove (elt seq) | |
379 "Return a copy of SEQ with all occurrences of ELT removed. | |
380 SEQ must be a list, vector, or string. The comparison is done with `equal'." | |
381 (if (nlistp seq) | |
382 ;; If SEQ isn't a list, there's no need to copy SEQ because | |
383 ;; `delete' will return a new object. | |
384 (delete elt seq) | |
385 (delete elt (copy-sequence seq)))) | |
386 | |
387 (defun remq (elt list) | |
388 "Return LIST with all occurrences of ELT removed. | |
389 The comparison is done with `eq'. Contrary to `delq', this does not use | |
390 side-effects, and the argument LIST is not modified." | |
391 (if (memq elt list) | |
392 (delq elt (copy-sequence list)) | |
393 list)) | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
394 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
395 ;;;; Keymap support. |
114 | 396 |
88155 | 397 (defmacro kbd (keys) |
398 "Convert KEYS to the internal Emacs key representation. | |
399 KEYS should be a string constant in the format used for | |
400 saving keyboard macros (see `edmacro-mode')." | |
401 (read-kbd-macro keys)) | |
402 | |
114 | 403 (defun undefined () |
404 (interactive) | |
405 (ding)) | |
406 | |
88155 | 407 ;; Prevent the \{...} documentation construct |
408 ;; from mentioning keys that run this command. | |
114 | 409 (put 'undefined 'suppress-keymap t) |
410 | |
411 (defun suppress-keymap (map &optional nodigits) | |
412 "Make MAP override all normally self-inserting keys to be undefined. | |
413 Normally, as an exception, digits and minus-sign are set to make prefix args, | |
414 but optional second arg NODIGITS non-nil treats them like other chars." | |
47042
74f8b41068e0
(suppress-keymap): Use command remapping instead of
Kim F. Storm <storm@cua.dk>
parents:
47025
diff
changeset
|
415 (define-key map [remap self-insert-command] 'undefined) |
114 | 416 (or nodigits |
417 (let (loop) | |
418 (define-key map "-" 'negative-argument) | |
419 ;; Make plain numbers do numeric args. | |
420 (setq loop ?0) | |
421 (while (<= loop ?9) | |
422 (define-key map (char-to-string loop) 'digit-argument) | |
423 (setq loop (1+ loop)))))) | |
424 | |
27821
5ef5616e8304
(define-key-after): Default AFTER to t. Doc fix.
Dave Love <fx@gnu.org>
parents:
27810
diff
changeset
|
425 (defun define-key-after (keymap key definition &optional after) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
426 "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding. |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
427 This is like `define-key' except that the binding for KEY is placed |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
428 just after the binding for the event AFTER, instead of at the beginning |
16556
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
429 of the map. Note that AFTER must be an event type (like KEY), NOT a command |
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
430 \(like DEFINITION). |
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
431 |
27821
5ef5616e8304
(define-key-after): Default AFTER to t. Doc fix.
Dave Love <fx@gnu.org>
parents:
27810
diff
changeset
|
432 If AFTER is t or omitted, the new binding goes at the end of the keymap. |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
433 AFTER should be a single event type--a symbol or a character, not a sequence. |
27821
5ef5616e8304
(define-key-after): Default AFTER to t. Doc fix.
Dave Love <fx@gnu.org>
parents:
27810
diff
changeset
|
434 |
5ef5616e8304
(define-key-after): Default AFTER to t. Doc fix.
Dave Love <fx@gnu.org>
parents:
27810
diff
changeset
|
435 Bindings are always added before any inherited map. |
16556
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
436 |
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
437 The order of bindings in a keymap matters when it is used as a menu." |
27821
5ef5616e8304
(define-key-after): Default AFTER to t. Doc fix.
Dave Love <fx@gnu.org>
parents:
27810
diff
changeset
|
438 (unless after (setq after t)) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
439 (or (keymapp keymap) |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
440 (signal 'wrong-type-argument (list 'keymapp keymap))) |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
441 (setq key |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
442 (if (<= (length key) 1) (aref key 0) |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
443 (setq keymap (lookup-key keymap |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
444 (apply 'vector |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
445 (butlast (mapcar 'identity key))))) |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
446 (aref key (1- (length key))))) |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
447 (let ((tail keymap) done inserted) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
448 (while (and (not done) tail) |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
449 ;; Delete any earlier bindings for the same key. |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
450 (if (eq (car-safe (car (cdr tail))) key) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
451 (setcdr tail (cdr (cdr tail)))) |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
452 ;; If we hit an included map, go down that one. |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
453 (if (keymapp (car tail)) (setq tail (car tail))) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
454 ;; When we reach AFTER's binding, insert the new binding after. |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
455 ;; If we reach an inherited keymap, insert just before that. |
3927
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
456 ;; If we reach the end of this keymap, insert at the end. |
16556
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
457 (if (or (and (eq (car-safe (car tail)) after) |
3a1df67c6677
(define-key-after): If AFTER is t, always put new binding at the end.
Richard M. Stallman <rms@gnu.org>
parents:
16549
diff
changeset
|
458 (not (eq after t))) |
3927
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
459 (eq (car (cdr tail)) 'keymap) |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
460 (null (cdr tail))) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
461 (progn |
3927
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
462 ;; Stop the scan only if we find a parent keymap. |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
463 ;; Keep going past the inserted element |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
464 ;; so we can delete any duplications that come later. |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
465 (if (eq (car (cdr tail)) 'keymap) |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
466 (setq done t)) |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
467 ;; Don't insert more than once. |
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
468 (or inserted |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
469 (setcdr tail (cons (cons key definition) (cdr tail)))) |
3927
1f1fefc400ed
(define-key-after): Delete duplicate bindings that come
Richard M. Stallman <rms@gnu.org>
parents:
3902
diff
changeset
|
470 (setq inserted t))) |
3901
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
471 (setq tail (cdr tail))))) |
c78753b7eea8
(define-key-in-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
3860
diff
changeset
|
472 |
88155 | 473 (defun map-keymap-internal (function keymap &optional sort-first) |
474 "Implement `map-keymap' with sorting. | |
475 Don't call this function; it is for internal use only." | |
476 (if sort-first | |
477 (let (list) | |
478 (map-keymap (lambda (a b) (push (cons a b) list)) | |
479 keymap) | |
480 (setq list (sort list | |
481 (lambda (a b) | |
482 (setq a (car a) b (car b)) | |
483 (if (integerp a) | |
484 (if (integerp b) (< a b) | |
485 t) | |
486 (if (integerp b) t | |
487 (string< a b)))))) | |
488 (dolist (p list) | |
489 (funcall function (car p) (cdr p)))) | |
490 (map-keymap function keymap))) | |
17437 | 491 |
15894
efd2835a7c96
(keyboard-translate): Use a char-table.
Richard M. Stallman <rms@gnu.org>
parents:
15599
diff
changeset
|
492 (put 'keyboard-translate-table 'char-table-extra-slots 0) |
efd2835a7c96
(keyboard-translate): Use a char-table.
Richard M. Stallman <rms@gnu.org>
parents:
15599
diff
changeset
|
493 |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
494 (defun keyboard-translate (from to) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
495 "Translate character FROM to TO at a low level. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
496 This function creates a `keyboard-translate-table' if necessary |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
497 and then modifies one entry in it." |
15894
efd2835a7c96
(keyboard-translate): Use a char-table.
Richard M. Stallman <rms@gnu.org>
parents:
15599
diff
changeset
|
498 (or (char-table-p keyboard-translate-table) |
efd2835a7c96
(keyboard-translate): Use a char-table.
Richard M. Stallman <rms@gnu.org>
parents:
15599
diff
changeset
|
499 (setq keyboard-translate-table |
efd2835a7c96
(keyboard-translate): Use a char-table.
Richard M. Stallman <rms@gnu.org>
parents:
15599
diff
changeset
|
500 (make-char-table 'keyboard-translate-table nil))) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
501 (aset keyboard-translate-table from to)) |
88155 | 502 |
503 ;;;; Key binding commands. | |
504 | |
505 (defun global-set-key (key command) | |
506 "Give KEY a global binding as COMMAND. | |
507 COMMAND is the command definition to use; usually it is | |
508 a symbol naming an interactively-callable function. | |
509 KEY is a key sequence; noninteractively, it is a string or vector | |
510 of characters or event types, and non-ASCII characters with codes | |
511 above 127 (such as ISO Latin-1) can be included if you use a vector. | |
512 | |
513 Note that if KEY has a local binding in the current buffer, | |
514 that local binding will continue to shadow any global binding | |
515 that you make with this function." | |
516 (interactive "KSet key globally: \nCSet key %s to command: ") | |
517 (or (vectorp key) (stringp key) | |
518 (signal 'wrong-type-argument (list 'arrayp key))) | |
519 (define-key (current-global-map) key command)) | |
520 | |
521 (defun local-set-key (key command) | |
522 "Give KEY a local binding as COMMAND. | |
523 COMMAND is the command definition to use; usually it is | |
524 a symbol naming an interactively-callable function. | |
525 KEY is a key sequence; noninteractively, it is a string or vector | |
526 of characters or event types, and non-ASCII characters with codes | |
527 above 127 (such as ISO Latin-1) can be included if you use a vector. | |
528 | |
529 The binding goes in the current buffer's local map, | |
530 which in most cases is shared with all other buffers in the same major mode." | |
531 (interactive "KSet key locally: \nCSet key %s locally to command: ") | |
532 (let ((map (current-local-map))) | |
533 (or map | |
534 (use-local-map (setq map (make-sparse-keymap)))) | |
535 (or (vectorp key) (stringp key) | |
536 (signal 'wrong-type-argument (list 'arrayp key))) | |
537 (define-key map key command))) | |
538 | |
539 (defun global-unset-key (key) | |
540 "Remove global binding of KEY. | |
541 KEY is a string or vector representing a sequence of keystrokes." | |
542 (interactive "kUnset key globally: ") | |
543 (global-set-key key nil)) | |
544 | |
545 (defun local-unset-key (key) | |
546 "Remove local binding of KEY. | |
547 KEY is a string or vector representing a sequence of keystrokes." | |
548 (interactive "kUnset key locally: ") | |
549 (if (current-local-map) | |
550 (local-set-key key nil)) | |
551 nil) | |
552 | |
553 ;;;; substitute-key-definition and its subroutines. | |
554 | |
555 (defvar key-substitution-in-progress nil | |
556 "Used internally by `substitute-key-definition'.") | |
557 | |
558 (defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix) | |
559 "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF. | |
560 In other words, OLDDEF is replaced with NEWDEF where ever it appears. | |
561 Alternatively, if optional fourth argument OLDMAP is specified, we redefine | |
562 in KEYMAP as NEWDEF those keys which are defined as OLDDEF in OLDMAP. | |
563 | |
564 For most uses, it is simpler and safer to use command remappping like this: | |
565 \(define-key KEYMAP [remap OLDDEF] NEWDEF)" | |
566 ;; Don't document PREFIX in the doc string because we don't want to | |
567 ;; advertise it. It's meant for recursive calls only. Here's its | |
568 ;; meaning | |
569 | |
570 ;; If optional argument PREFIX is specified, it should be a key | |
571 ;; prefix, a string. Redefined bindings will then be bound to the | |
572 ;; original key, with PREFIX added at the front. | |
573 (or prefix (setq prefix "")) | |
574 (let* ((scan (or oldmap keymap)) | |
575 (prefix1 (vconcat prefix [nil])) | |
576 (key-substitution-in-progress | |
577 (cons scan key-substitution-in-progress))) | |
578 ;; Scan OLDMAP, finding each char or event-symbol that | |
579 ;; has any definition, and act on it with hack-key. | |
580 (map-keymap | |
581 (lambda (char defn) | |
582 (aset prefix1 (length prefix) char) | |
583 (substitute-key-definition-key defn olddef newdef prefix1 keymap)) | |
584 scan))) | |
585 | |
586 (defun substitute-key-definition-key (defn olddef newdef prefix keymap) | |
587 (let (inner-def skipped menu-item) | |
588 ;; Find the actual command name within the binding. | |
589 (if (eq (car-safe defn) 'menu-item) | |
590 (setq menu-item defn defn (nth 2 defn)) | |
591 ;; Skip past menu-prompt. | |
592 (while (stringp (car-safe defn)) | |
593 (push (pop defn) skipped)) | |
594 ;; Skip past cached key-equivalence data for menu items. | |
595 (if (consp (car-safe defn)) | |
596 (setq defn (cdr defn)))) | |
597 (if (or (eq defn olddef) | |
598 ;; Compare with equal if definition is a key sequence. | |
599 ;; That is useful for operating on function-key-map. | |
600 (and (or (stringp defn) (vectorp defn)) | |
601 (equal defn olddef))) | |
602 (define-key keymap prefix | |
603 (if menu-item | |
604 (let ((copy (copy-sequence menu-item))) | |
605 (setcar (nthcdr 2 copy) newdef) | |
606 copy) | |
607 (nconc (nreverse skipped) newdef))) | |
608 ;; Look past a symbol that names a keymap. | |
609 (setq inner-def | |
610 (and defn | |
611 (condition-case nil (indirect-function defn) (error defn)))) | |
612 ;; For nested keymaps, we use `inner-def' rather than `defn' so as to | |
613 ;; avoid autoloading a keymap. This is mostly done to preserve the | |
614 ;; original non-autoloading behavior of pre-map-keymap times. | |
615 (if (and (keymapp inner-def) | |
616 ;; Avoid recursively scanning | |
617 ;; where KEYMAP does not have a submap. | |
618 (let ((elt (lookup-key keymap prefix))) | |
619 (or (null elt) (natnump elt) (keymapp elt))) | |
620 ;; Avoid recursively rescanning keymap being scanned. | |
621 (not (memq inner-def key-substitution-in-progress))) | |
622 ;; If this one isn't being scanned already, scan it now. | |
623 (substitute-key-definition olddef newdef keymap inner-def prefix))))) | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
624 |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
625 |
47916 | 626 ;;;; The global keymap tree. |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
627 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
628 ;;; global-map, esc-map, and ctl-x-map have their values set up in |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
629 ;;; keymap.c; we just give them docstrings here. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
630 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
631 (defvar global-map nil |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
632 "Default global keymap mapping Emacs keyboard input into commands. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
633 The value is a keymap which is usually (but not necessarily) Emacs's |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
634 global map.") |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
635 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
636 (defvar esc-map nil |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
637 "Default keymap for ESC (meta) commands. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
638 The normal global definition of the character ESC indirects to this keymap.") |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
639 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
640 (defvar ctl-x-map nil |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
641 "Default keymap for C-x commands. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
642 The normal global definition of the character C-x indirects to this keymap.") |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
643 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
644 (defvar ctl-x-4-map (make-sparse-keymap) |
41955 | 645 "Keymap for subcommands of C-x 4.") |
2569
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
646 (defalias 'ctl-x-4-prefix ctl-x-4-map) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
647 (define-key ctl-x-map "4" 'ctl-x-4-prefix) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
648 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
649 (defvar ctl-x-5-map (make-sparse-keymap) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
650 "Keymap for frame commands.") |
2569
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
651 (defalias 'ctl-x-5-prefix ctl-x-5-map) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
652 (define-key ctl-x-map "5" 'ctl-x-5-prefix) |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
653 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
654 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
655 ;;;; Event manipulation functions. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
656 |
10693
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
657 ;; The call to `read' is to ensure that the value is computed at load time |
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
658 ;; and not compiled into the .elc file. The value is negative on most |
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
659 ;; machines, but not on all! |
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
660 (defconst listify-key-sequence-1 (logior 128 (read "?\\M-\\^@"))) |
3153
4c94c9faf1af
(listify-key-sequence): Avoid the constant ?\M-\200.
Richard M. Stallman <rms@gnu.org>
parents:
2963
diff
changeset
|
661 |
2021
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
662 (defun listify-key-sequence (key) |
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
663 "Convert a key sequence to a list of events." |
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
664 (if (vectorp key) |
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
665 (append key nil) |
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
666 (mapcar (function (lambda (c) |
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
667 (if (> c 127) |
3153
4c94c9faf1af
(listify-key-sequence): Avoid the constant ?\M-\200.
Richard M. Stallman <rms@gnu.org>
parents:
2963
diff
changeset
|
668 (logxor c listify-key-sequence-1) |
2021
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
669 c))) |
88155 | 670 key))) |
2021
8b9286bffef8
(listify-key-sequence): New function.
Richard M. Stallman <rms@gnu.org>
parents:
1959
diff
changeset
|
671 |
2040
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
672 (defsubst eventp (obj) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
673 "True if the argument is an event object." |
88155 | 674 (or (and (integerp obj) |
675 ;; Filter out integers too large to be events. | |
676 ;; M is the biggest modifier. | |
677 (zerop (logand obj (lognot (1- (lsh ?\M-\^@ 1))))) | |
678 (char-valid-p (event-basic-type obj))) | |
2040
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
679 (and (symbolp obj) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
680 (get obj 'event-symbol-elements)) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
681 (and (consp obj) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
682 (symbolp (car obj)) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
683 (get (car obj) 'event-symbol-elements)))) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
684 |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
685 (defun event-modifiers (event) |
88155 | 686 "Return a list of symbols representing the modifier keys in event EVENT. |
2040
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
687 The elements of the list may include `meta', `control', |
4414
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
688 `shift', `hyper', `super', `alt', `click', `double', `triple', `drag', |
88155 | 689 and `down'. |
690 EVENT may be an event or an event type. If EVENT is a symbol | |
691 that has never been used in an event that has been read as input | |
692 in the current Emacs session, then this function can return nil, | |
693 even when EVENT actually has modifiers." | |
2040
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
694 (let ((type event)) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
695 (if (listp type) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
696 (setq type (car type))) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
697 (if (symbolp type) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
698 (cdr (get type 'event-symbol-elements)) |
88155 | 699 (let ((list nil) |
700 (char (logand type (lognot (logior ?\M-\^@ ?\C-\^@ ?\S-\^@ | |
701 ?\H-\^@ ?\s-\^@ ?\A-\^@))))) | |
702 (if (not (zerop (logand type ?\M-\^@))) | |
703 (push 'meta list)) | |
704 (if (or (not (zerop (logand type ?\C-\^@))) | |
705 (< char 32)) | |
706 (push 'control list)) | |
707 (if (or (not (zerop (logand type ?\S-\^@))) | |
708 (/= char (downcase char))) | |
709 (push 'shift list)) | |
10693
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
710 (or (zerop (logand type ?\H-\^@)) |
88155 | 711 (push 'hyper list)) |
10693
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
712 (or (zerop (logand type ?\s-\^@)) |
88155 | 713 (push 'super list)) |
10693
0875851842f0
(listify-key-sequence-1, event-modifiers): Don't presume internal bit layout
Karl Heuer <kwzh@gnu.org>
parents:
10681
diff
changeset
|
714 (or (zerop (logand type ?\A-\^@)) |
88155 | 715 (push 'alt list)) |
2040
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
716 list)))) |
aa926beb4caa
(event-modifiers): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2033
diff
changeset
|
717 |
2063
2f0555b428c4
(event-basic-type): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2040
diff
changeset
|
718 (defun event-basic-type (event) |
88155 | 719 "Return the basic type of the given event (all modifiers removed). |
720 The value is a printing character (not upper case) or a symbol. | |
721 EVENT may be an event or an event type. If EVENT is a symbol | |
722 that has never been used in an event that has been read as input | |
723 in the current Emacs session, then this function may return nil." | |
3784
d2df5ca46b39
* subr.el (event-basic-type): Deal with listy events properly.
Jim Blandy <jimb@redhat.com>
parents:
3591
diff
changeset
|
724 (if (consp event) |
d2df5ca46b39
* subr.el (event-basic-type): Deal with listy events properly.
Jim Blandy <jimb@redhat.com>
parents:
3591
diff
changeset
|
725 (setq event (car event))) |
2063
2f0555b428c4
(event-basic-type): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2040
diff
changeset
|
726 (if (symbolp event) |
2f0555b428c4
(event-basic-type): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2040
diff
changeset
|
727 (car (get event 'event-symbol-elements)) |
88155 | 728 (let* ((base (logand event (1- ?\A-\^@))) |
729 (uncontrolled (if (< base 32) (logior base 64) base))) | |
730 ;; There are some numbers that are invalid characters and | |
731 ;; cause `downcase' to get an error. | |
732 (condition-case () | |
733 (downcase uncontrolled) | |
734 (error uncontrolled))))) | |
2063
2f0555b428c4
(event-basic-type): New function.
Richard M. Stallman <rms@gnu.org>
parents:
2040
diff
changeset
|
735 |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
736 (defsubst mouse-movement-p (object) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
737 "Return non-nil if OBJECT is a mouse movement event." |
88155 | 738 (eq (car-safe object) 'mouse-movement)) |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
739 |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
740 (defsubst event-start (event) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
741 "Return the starting position of EVENT. |
88155 | 742 If EVENT is a mouse or key press or a mouse click, this returns the location |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
743 of the event. |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
744 If EVENT is a drag, this returns the drag's starting position. |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
745 The return value is of the form |
88155 | 746 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW) |
747 IMAGE (DX . DY) (WIDTH . HEIGHT)) | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
748 The `posn-' functions access elements of such lists." |
45978
a8fbafaa31ad
(event-start, event-end, event-click-count):
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
45823
diff
changeset
|
749 (if (consp event) (nth 1 event) |
a8fbafaa31ad
(event-start, event-end, event-click-count):
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
45823
diff
changeset
|
750 (list (selected-window) (point) '(0 . 0) 0))) |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
751 |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
752 (defsubst event-end (event) |
88155 | 753 "Return the ending location of EVENT. |
754 EVENT should be a click, drag, or key press event. | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
755 If EVENT is a click event, this function is the same as `event-start'. |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
756 The return value is of the form |
88155 | 757 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW) |
758 IMAGE (DX . DY) (WIDTH . HEIGHT)) | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
759 The `posn-' functions access elements of such lists." |
45978
a8fbafaa31ad
(event-start, event-end, event-click-count):
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
45823
diff
changeset
|
760 (if (consp event) (nth (if (consp (nth 2 event)) 2 1) event) |
a8fbafaa31ad
(event-start, event-end, event-click-count):
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
45823
diff
changeset
|
761 (list (selected-window) (point) '(0 . 0) 0))) |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
762 |
4414
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
763 (defsubst event-click-count (event) |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
764 "Return the multi-click count of EVENT, a click or drag event. |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
765 The return value is a positive integer." |
45978
a8fbafaa31ad
(event-start, event-end, event-click-count):
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
45823
diff
changeset
|
766 (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1)) |
88155 | 767 |
768 ;;;; Extracting fields of the positions in an event. | |
4414
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
769 |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
770 (defsubst posn-window (position) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
771 "Return the window in POSITION. |
88155 | 772 POSITION should be a list of the form returned by the `event-start' |
773 and `event-end' functions." | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
774 (nth 0 position)) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
775 |
88155 | 776 (defsubst posn-area (position) |
777 "Return the window area recorded in POSITION, or nil for the text area. | |
778 POSITION should be a list of the form returned by the `event-start' | |
779 and `event-end' functions." | |
780 (let ((area (if (consp (nth 1 position)) | |
781 (car (nth 1 position)) | |
782 (nth 1 position)))) | |
783 (and (symbolp area) area))) | |
784 | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
785 (defsubst posn-point (position) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
786 "Return the buffer location in POSITION. |
88155 | 787 POSITION should be a list of the form returned by the `event-start' |
788 and `event-end' functions." | |
789 (or (nth 5 position) | |
790 (if (consp (nth 1 position)) | |
791 (car (nth 1 position)) | |
792 (nth 1 position)))) | |
793 | |
794 (defun posn-set-point (position) | |
795 "Move point to POSITION. | |
796 Select the corresponding window as well." | |
797 (if (not (windowp (posn-window position))) | |
798 (error "Position not in text area of window")) | |
799 (select-window (posn-window position)) | |
800 (if (numberp (posn-point position)) | |
801 (goto-char (posn-point position)))) | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
802 |
6039
4eb7f4633370
(posn-x-y): New function.
Richard M. Stallman <rms@gnu.org>
parents:
6005
diff
changeset
|
803 (defsubst posn-x-y (position) |
4eb7f4633370
(posn-x-y): New function.
Richard M. Stallman <rms@gnu.org>
parents:
6005
diff
changeset
|
804 "Return the x and y coordinates in POSITION. |
88155 | 805 POSITION should be a list of the form returned by the `event-start' |
806 and `event-end' functions." | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
807 (nth 2 position)) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
808 |
7636
83dba60657ef
(posn-col-row): Do something useful for scroll bar event.
Richard M. Stallman <rms@gnu.org>
parents:
7615
diff
changeset
|
809 (defun posn-col-row (position) |
88155 | 810 "Return the nominal column and row in POSITION, measured in characters. |
811 The column and row values are approximations calculated from the x | |
812 and y coordinates in POSITION and the frame's default character width | |
813 and height. | |
7636
83dba60657ef
(posn-col-row): Do something useful for scroll bar event.
Richard M. Stallman <rms@gnu.org>
parents:
7615
diff
changeset
|
814 For a scroll-bar event, the result column is 0, and the row |
88155 | 815 corresponds to the vertical position of the click in the scroll bar. |
816 POSITION should be a list of the form returned by the `event-start' | |
817 and `event-end' functions." | |
818 (let* ((pair (posn-x-y position)) | |
819 (window (posn-window position)) | |
820 (area (posn-area position))) | |
821 (cond | |
822 ((null window) | |
823 '(0 . 0)) | |
824 ((eq area 'vertical-scroll-bar) | |
825 (cons 0 (scroll-bar-scale pair (1- (window-height window))))) | |
826 ((eq area 'horizontal-scroll-bar) | |
827 (cons (scroll-bar-scale pair (window-width window)) 0)) | |
828 (t | |
829 (let* ((frame (if (framep window) window (window-frame window))) | |
830 (x (/ (car pair) (frame-char-width frame))) | |
831 (y (/ (cdr pair) (+ (frame-char-height frame) | |
832 (or (frame-parameter frame 'line-spacing) | |
833 default-line-spacing | |
834 0))))) | |
835 (cons x y)))))) | |
836 | |
837 (defun posn-actual-col-row (position) | |
838 "Return the actual column and row in POSITION, measured in characters. | |
839 These are the actual row number in the window and character number in that row. | |
840 Return nil if POSITION does not contain the actual position; in that case | |
841 `posn-col-row' can be used to get approximate values. | |
842 POSITION should be a list of the form returned by the `event-start' | |
843 and `event-end' functions." | |
844 (nth 6 position)) | |
6039
4eb7f4633370
(posn-x-y): New function.
Richard M. Stallman <rms@gnu.org>
parents:
6005
diff
changeset
|
845 |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
846 (defsubst posn-timestamp (position) |
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
847 "Return the timestamp of POSITION. |
88155 | 848 POSITION should be a list of the form returned by the `event-start' |
849 and `event-end' functions." | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
850 (nth 3 position)) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
851 |
88155 | 852 (defsubst posn-string (position) |
853 "Return the string object of POSITION, or nil if a buffer position. | |
854 POSITION should be a list of the form returned by the `event-start' | |
855 and `event-end' functions." | |
856 (nth 4 position)) | |
857 | |
858 (defsubst posn-image (position) | |
859 "Return the image object of POSITION, or nil if a not an image. | |
860 POSITION should be a list of the form returned by the `event-start' | |
861 and `event-end' functions." | |
862 (nth 7 position)) | |
863 | |
864 (defsubst posn-object (position) | |
865 "Return the object (image or string) of POSITION. | |
866 POSITION should be a list of the form returned by the `event-start' | |
867 and `event-end' functions." | |
868 (or (posn-image position) (posn-string position))) | |
869 | |
870 (defsubst posn-object-x-y (position) | |
871 "Return the x and y coordinates relative to the object of POSITION. | |
872 POSITION should be a list of the form returned by the `event-start' | |
873 and `event-end' functions." | |
874 (nth 8 position)) | |
875 | |
876 (defsubst posn-object-width-height (position) | |
877 "Return the pixel width and height of the object of POSITION. | |
878 POSITION should be a list of the form returned by the `event-start' | |
879 and `event-end' functions." | |
880 (nth 9 position)) | |
881 | |
2071
8f410f56d98f
(posn-timestamp, posn-col-row, posn-point, posn-window):
Richard M. Stallman <rms@gnu.org>
parents:
2063
diff
changeset
|
882 |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
883 ;;;; Obsolescent names for functions. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
884 |
88155 | 885 (define-obsolete-function-alias 'window-dot 'window-point "22.1") |
886 (define-obsolete-function-alias 'set-window-dot 'set-window-point "22.1") | |
887 (define-obsolete-function-alias 'read-input 'read-string "22.1") | |
888 (define-obsolete-function-alias 'show-buffer 'set-window-buffer "22.1") | |
889 (define-obsolete-function-alias 'eval-current-buffer 'eval-buffer "22.1") | |
890 (define-obsolete-function-alias 'string-to-int 'string-to-number "22.1") | |
891 | |
47652
a5316596929f
(read-key-auxiliary-map): New var.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47406
diff
changeset
|
892 (make-obsolete 'char-bytes "now always returns 1." "20.4") |
20605 | 893 |
42266
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
894 (defun insert-string (&rest args) |
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
895 "Mocklisp-compatibility insert function. |
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
896 Like the function `insert' except that any argument that is a number |
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
897 is converted into a string by expressing it in decimal." |
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
898 (dolist (el args) |
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
899 (insert (if (integerp el) (number-to-string el) el)))) |
88155 | 900 (make-obsolete 'insert-string 'insert "22.1") |
901 | |
46219
56b79cbf05d2
(insert-string): Update the obsolete info.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46148
diff
changeset
|
902 (defun makehash (&optional test) (make-hash-table :test (or test 'eql))) |
88155 | 903 (make-obsolete 'makehash 'make-hash-table "22.1") |
42266
75bbe9d566d9
(insert-string): Moved from mocklisp.c, reimplemented in Lisp. Obsoleted.
Pavel Janík <Pavel@Janik.cz>
parents:
42083
diff
changeset
|
904 |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
905 ;; Some programs still use this as a function. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
906 (defun baud-rate () |
46052
4d27fe417297
(char-bytes): Fix obsolescence declaration.
Juanma Barranquero <lekktu@gmail.com>
parents:
45978
diff
changeset
|
907 "Return the value of the `baud-rate' variable." |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
908 baud-rate) |
88155 | 909 (make-obsolete 'baud-rate "use the `baud-rate' variable instead." "before 19.15") |
910 | |
911 ;; These are used by VM and some old programs | |
912 (defalias 'focus-frame 'ignore "") | |
913 (make-obsolete 'focus-frame "it does nothing." "22.1") | |
914 (defalias 'unfocus-frame 'ignore "") | |
915 (make-obsolete 'unfocus-frame "it does nothing." "22.1") | |
46537
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
916 |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
917 |
88155 | 918 ;;;; Obsolescence declarations for variables, and aliases. |
46537
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
919 |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
920 (make-obsolete-variable 'directory-sep-char "do not use it." "21.1") |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
921 (make-obsolete-variable 'mode-line-inverse-video "use the appropriate faces instead." "21.1") |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
922 (make-obsolete-variable 'unread-command-char |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
923 "use `unread-command-events' instead. That variable is a list of events to reread, so it now uses nil to mean `no event', instead of -1." |
46f175ecf5d4
(unread-command-char, executing-macro, post-command-idle-hook,
Juanma Barranquero <lekktu@gmail.com>
parents:
46532
diff
changeset
|
924 "before 19.15") |
88155 | 925 |
926 ;; Lisp manual only updated in 22.1. | |
927 (define-obsolete-variable-alias 'executing-macro 'executing-kbd-macro | |
928 "before 19.34") | |
929 | |
930 (defvaralias 'x-lost-selection-hooks 'x-lost-selection-functions) | |
931 (make-obsolete-variable 'x-lost-selection-hooks 'x-lost-selection-functions "22.1") | |
932 (defvaralias 'x-sent-selection-hooks 'x-sent-selection-functions) | |
933 (make-obsolete-variable 'x-sent-selection-hooks 'x-sent-selection-functions "22.1") | |
934 | |
935 (defvaralias 'messages-buffer-max-lines 'message-log-max) | |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
936 |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
937 ;;;; Alternate names for functions - these are not being phased out. |
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
938 |
88155 | 939 (defalias 'send-string 'process-send-string) |
940 (defalias 'send-region 'process-send-region) | |
2569
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
941 (defalias 'string= 'string-equal) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
942 (defalias 'string< 'string-lessp) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
943 (defalias 'move-marker 'set-marker) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
944 (defalias 'rplaca 'setcar) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
945 (defalias 'rplacd 'setcdr) |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3411
diff
changeset
|
946 (defalias 'beep 'ding) ;preserve lingual purity |
2569
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
947 (defalias 'indent-to-column 'indent-to) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
948 (defalias 'backward-delete-char 'delete-backward-char) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
949 (defalias 'search-forward-regexp (symbol-function 're-search-forward)) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
950 (defalias 'search-backward-regexp (symbol-function 're-search-backward)) |
39ad4eda7fea
All fsets changed to defaliases.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2504
diff
changeset
|
951 (defalias 'int-to-string 'number-to-string) |
21173
e917eb0d4e01
(save-match-data): store-match-data => set-match-data.
Richard M. Stallman <rms@gnu.org>
parents:
21092
diff
changeset
|
952 (defalias 'store-match-data 'set-match-data) |
47078
6e9df2174ee2
(make-variable-frame-localizable): New alias for `make-variable-frame-local'.
Juanma Barranquero <lekktu@gmail.com>
parents:
47042
diff
changeset
|
953 (defalias 'make-variable-frame-localizable 'make-variable-frame-local) |
31563
96b9757bfd45
(add-minor-mode): Use toggle-fun arg.
Dave Love <fx@gnu.org>
parents:
30515
diff
changeset
|
954 ;; These are the XEmacs names: |
25293
fd43e1a99384
(point-at-eol, point-at-bol): New aliases.
Karl Heuer <kwzh@gnu.org>
parents:
25140
diff
changeset
|
955 (defalias 'point-at-eol 'line-end-position) |
fd43e1a99384
(point-at-eol, point-at-bol): New aliases.
Karl Heuer <kwzh@gnu.org>
parents:
25140
diff
changeset
|
956 (defalias 'point-at-bol 'line-beginning-position) |
1903
87f63305319f
* subr.el (string-to-int): Make this an alias for
Jim Blandy <jimb@redhat.com>
parents:
1867
diff
changeset
|
957 |
88155 | 958 (defalias 'user-original-login-name 'user-login-name) |
959 | |
114 | 960 |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
961 ;;;; Hook manipulation functions. |
388 | 962 |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
963 (defun make-local-hook (hook) |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
964 "Make the hook HOOK local to the current buffer. |
23786
673204d56938
(make-local-hook): Return the hook variable.
Richard M. Stallman <rms@gnu.org>
parents:
23736
diff
changeset
|
965 The return value is HOOK. |
673204d56938
(make-local-hook): Return the hook variable.
Richard M. Stallman <rms@gnu.org>
parents:
23736
diff
changeset
|
966 |
33707
2b9847c18f31
(make-local-hook): Docstring fix.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
32355
diff
changeset
|
967 You never need to call this function now that `add-hook' does it for you |
2b9847c18f31
(make-local-hook): Docstring fix.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
32355
diff
changeset
|
968 if its LOCAL argument is non-nil. |
2b9847c18f31
(make-local-hook): Docstring fix.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
32355
diff
changeset
|
969 |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
970 When a hook is local, its local and global values |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
971 work in concert: running the hook actually runs all the hook |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
972 functions listed in *either* the local value *or* the global value |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
973 of the hook variable. |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
974 |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
975 This function works by making t a member of the buffer-local value, |
12258
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
976 which acts as a flag to run the hook functions in the default value as |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
977 well. This works for all normal hooks, but does not work for most |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
978 non-normal hooks yet. We will be changing the callers of non-normal |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
979 hooks so that they can handle localness; this has to be done one by |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
980 one. |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
981 |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
982 This function does nothing if HOOK is already local in the current |
95ebca0a74d8
(make-local-hook): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
12108
diff
changeset
|
983 buffer. |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
984 |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
985 Do not use `make-local-variable' to make a hook variable buffer-local." |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
986 (if (local-variable-p hook) |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
987 nil |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
988 (or (boundp hook) (set hook nil)) |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
989 (make-local-variable hook) |
23786
673204d56938
(make-local-hook): Return the hook variable.
Richard M. Stallman <rms@gnu.org>
parents:
23736
diff
changeset
|
990 (set hook (list t))) |
673204d56938
(make-local-hook): Return the hook variable.
Richard M. Stallman <rms@gnu.org>
parents:
23736
diff
changeset
|
991 hook) |
46052
4d27fe417297
(char-bytes): Fix obsolescence declaration.
Juanma Barranquero <lekktu@gmail.com>
parents:
45978
diff
changeset
|
992 (make-obsolete 'make-local-hook "not necessary any more." "21.1") |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
993 |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
994 (defun add-hook (hook function &optional append local) |
4414
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
995 "Add to the value of HOOK the function FUNCTION. |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
996 FUNCTION is not added if already present. |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
997 FUNCTION is added (if necessary) at the beginning of the hook list |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
998 unless the optional argument APPEND is non-nil, in which case |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
999 FUNCTION is added at the end. |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
1000 |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1001 The optional fourth argument, LOCAL, if non-nil, says to modify |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1002 the hook's buffer-local value rather than its default value. |
43435 | 1003 This makes the hook buffer-local if needed, and it makes t a member |
1004 of the buffer-local value. That acts as a flag to run the hook | |
1005 functions in the default value as well as in the local value. | |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1006 |
4414
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
1007 HOOK should be a symbol, and FUNCTION may be any valid function. If |
3356419b94c1
(add-hook): Change a single function into a list.
Richard M. Stallman <rms@gnu.org>
parents:
4235
diff
changeset
|
1008 HOOK is void, it is first set to nil. If HOOK's value is a single |
8959
d33302427a47
(remove-hook, add-hook): Copy existing list before modifying.
Richard M. Stallman <rms@gnu.org>
parents:
8928
diff
changeset
|
1009 function, it is changed to a list of functions." |
114 | 1010 (or (boundp hook) (set hook nil)) |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1011 (or (default-boundp hook) (set-default hook nil)) |
39557
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
1012 (if local (unless (local-variable-if-set-p hook) |
fb85410efef7
(define-key-after): Allow `key' to be longer than 1.
Gerd Moellmann <gerd@gnu.org>
parents:
38760
diff
changeset
|
1013 (set (make-local-variable hook) (list t))) |
28863
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1014 ;; Detect the case where make-local-variable was used on a hook |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1015 ;; and do what we used to do. |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1016 (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook))) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1017 (setq local t))) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1018 (let ((hook-value (if local (symbol-value hook) (default-value hook)))) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1019 ;; If the hook value is a single function, turn it into a list. |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1020 (when (or (not (listp hook-value)) (eq (car hook-value) 'lambda)) |
28940
2a91228f7aa3
(add-hook): setq hook-value, not set
Sam Steingold <sds@gnu.org>
parents:
28868
diff
changeset
|
1021 (setq hook-value (list hook-value))) |
28863
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1022 ;; Do the actual addition if necessary |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1023 (unless (member function hook-value) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1024 (setq hook-value |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1025 (if append |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1026 (append hook-value (list function)) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1027 (cons function hook-value)))) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1028 ;; Set the actual variable |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1029 (if local (set hook hook-value) (set-default hook hook-value)))) |
2504
181eef669324
* subr.el (overlay-start, overlay-end, overlay-buffer): New
Jim Blandy <jimb@redhat.com>
parents:
2428
diff
changeset
|
1030 |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1031 (defun remove-hook (hook function &optional local) |
4964
78c13f3054e5
(remove-hook): New function, analogous to add-hook. This
Richard M. Stallman <rms@gnu.org>
parents:
4767
diff
changeset
|
1032 "Remove from the value of HOOK the function FUNCTION. |
78c13f3054e5
(remove-hook): New function, analogous to add-hook. This
Richard M. Stallman <rms@gnu.org>
parents:
4767
diff
changeset
|
1033 HOOK should be a symbol, and FUNCTION may be any valid function. If |
78c13f3054e5
(remove-hook): New function, analogous to add-hook. This
Richard M. Stallman <rms@gnu.org>
parents:
4767
diff
changeset
|
1034 FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the |
9195
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1035 list of hooks to run in HOOK, then nothing is done. See `add-hook'. |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1036 |
70b00615cb75
(add-hook): Initialize default value and local value.
Richard M. Stallman <rms@gnu.org>
parents:
8959
diff
changeset
|
1037 The optional third argument, LOCAL, if non-nil, says to modify |
88155 | 1038 the hook's buffer-local value rather than its default value." |
28863
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1039 (or (boundp hook) (set hook nil)) |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1040 (or (default-boundp hook) (set-default hook nil)) |
88155 | 1041 ;; Do nothing if LOCAL is t but this hook has no local binding. |
1042 (unless (and local (not (local-variable-p hook))) | |
28863
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1043 ;; Detect the case where make-local-variable was used on a hook |
6430ce03c28a
(add-hook, remove-hook): Make hook buffer-local if needed..
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28811
diff
changeset
|
1044 ;; and do what we used to do. |
88155 | 1045 (when (and (local-variable-p hook) |
1046 (not (and (consp (symbol-value hook)) | |
1047 (memq t (symbol-value hook))))) | |
1048 (setq local t)) | |
1049 (let ((hook-value (if local (symbol-value hook) (default-value hook)))) | |
1050 ;; Remove the function, for both the list and the non-list cases. | |
1051 (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda)) | |
1052 (if (equal hook-value function) (setq hook-value nil)) | |
1053 (setq hook-value (delete function (copy-sequence hook-value)))) | |
1054 ;; If the function is on the global hook, we need to shadow it locally | |
1055 ;;(when (and local (member function (default-value hook)) | |
1056 ;; (not (member (cons 'not function) hook-value))) | |
1057 ;; (push (cons 'not function) hook-value)) | |
1058 ;; Set the actual variable | |
1059 (if (not local) | |
1060 (set-default hook hook-value) | |
1061 (if (equal hook-value '(t)) | |
1062 (kill-local-variable hook) | |
1063 (set hook hook-value)))))) | |
9510
f03544494d1c
(add-to-list): New function.
Richard M. Stallman <rms@gnu.org>
parents:
9202
diff
changeset
|
1064 |
32355
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1065 (defun add-to-list (list-var element &optional append) |
88155 | 1066 "Add ELEMENT to the value of LIST-VAR if it isn't there yet. |
13812 | 1067 The test for presence of ELEMENT is done with `equal'. |
32355
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1068 If ELEMENT is added, it is added at the beginning of the list, |
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1069 unless the optional argument APPEND is non-nil, in which case |
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1070 ELEMENT is added at the end. |
24757
f4127409d184
(add-to-list): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
24699
diff
changeset
|
1071 |
43833 | 1072 The return value is the new value of LIST-VAR. |
1073 | |
9535 | 1074 If you want to use `add-to-list' on a variable that is not defined |
1075 until a certain package is loaded, you should put the call to `add-to-list' | |
1076 into a hook function that will be run only after loading the package. | |
1077 `eval-after-load' provides one way to do this. In some cases | |
1078 other hooks, such as major mode hooks, can do the job." | |
21409
3e8b7782f4f5
(add-to-list): Always return updated value of LIST-VAR.
Karl Heuer <kwzh@gnu.org>
parents:
21173
diff
changeset
|
1079 (if (member element (symbol-value list-var)) |
3e8b7782f4f5
(add-to-list): Always return updated value of LIST-VAR.
Karl Heuer <kwzh@gnu.org>
parents:
21173
diff
changeset
|
1080 (symbol-value list-var) |
32355
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1081 (set list-var |
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1082 (if append |
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1083 (append (symbol-value list-var) (list element)) |
6bf2ae19e286
(add-to-list): Add optional argument APPEND.
Miles Bader <miles@gnu.org>
parents:
32131
diff
changeset
|
1084 (cons element (symbol-value list-var)))))) |
39725
c64d3e3adf5d
(symbol-file-load-history-loaded)
Miles Bader <miles@gnu.org>
parents:
39598
diff
changeset
|
1085 |
88155 | 1086 |
1087 (defun add-to-ordered-list (list-var element &optional order) | |
1088 "Add ELEMENT to the value of LIST-VAR if it isn't there yet. | |
1089 The test for presence of ELEMENT is done with `eq'. | |
1090 | |
1091 The resulting list is reordered so that the elements are in the | |
1092 order given by each element's numeric list order. Elements | |
1093 without a numeric list order are placed at the end of the list. | |
1094 | |
1095 If the third optional argument ORDER is a number (integer or | |
1096 float), set the element's list order to the given value. If | |
1097 ORDER is nil or omitted, do not change the numeric order of | |
1098 ELEMENT. If ORDER has any other value, remove the numeric order | |
1099 of ELEMENT if it has one. | |
1100 | |
1101 The list order for each element is stored in LIST-VAR's | |
1102 `list-order' property. | |
1103 | |
1104 The return value is the new value of LIST-VAR." | |
1105 (let ((ordering (get list-var 'list-order))) | |
1106 (unless ordering | |
1107 (put list-var 'list-order | |
1108 (setq ordering (make-hash-table :weakness 'key :test 'eq)))) | |
1109 (when order | |
1110 (puthash element (and (numberp order) order) ordering)) | |
1111 (unless (memq element (symbol-value list-var)) | |
1112 (set list-var (cons element (symbol-value list-var)))) | |
1113 (set list-var (sort (symbol-value list-var) | |
1114 (lambda (a b) | |
1115 (let ((oa (gethash a ordering)) | |
1116 (ob (gethash b ordering))) | |
1117 (if (and oa ob) | |
1118 (< oa ob) | |
1119 oa))))))) | |
43126
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1120 |
88155 | 1121 ;;;; Mode hooks. |
28234
763c6639628b
(combine-run-hooks): New function.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
28148
diff
changeset
|
1122 |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1123 (defvar delay-mode-hooks nil |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1124 "If non-nil, `run-mode-hooks' should delay running the hooks.") |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1125 (defvar delayed-mode-hooks nil |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1126 "List of delayed mode hooks waiting to be run.") |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1127 (make-variable-buffer-local 'delayed-mode-hooks) |
88155 | 1128 (put 'delay-mode-hooks 'permanent-local t) |
1129 | |
1130 (defvar after-change-major-mode-hook nil | |
1131 "Normal hook run at the very end of major mode functions.") | |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1132 |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1133 (defun run-mode-hooks (&rest hooks) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1134 "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1135 Execution is delayed if `delay-mode-hooks' is non-nil. |
88155 | 1136 If `delay-mode-hooks' is nil, run `after-change-major-mode-hook' |
1137 after running the mode hooks. | |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1138 Major mode functions should use this." |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1139 (if delay-mode-hooks |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1140 ;; Delaying case. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1141 (dolist (hook hooks) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1142 (push hook delayed-mode-hooks)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1143 ;; Normal case, just run the hook as before plus any delayed hooks. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1144 (setq hooks (nconc (nreverse delayed-mode-hooks) hooks)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1145 (setq delayed-mode-hooks nil) |
88155 | 1146 (apply 'run-hooks hooks) |
1147 (run-hooks 'after-change-major-mode-hook))) | |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1148 |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1149 (defmacro delay-mode-hooks (&rest body) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1150 "Execute BODY, but delay any `run-mode-hooks'. |
88155 | 1151 These hooks will be executed by the first following call to |
1152 `run-mode-hooks' that occurs outside any `delayed-mode-hooks' form. | |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1153 Only affects hooks run in the current buffer." |
88155 | 1154 (declare (debug t) (indent 0)) |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1155 `(progn |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1156 (make-local-variable 'delay-mode-hooks) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1157 (let ((delay-mode-hooks t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1158 ,@body))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
1159 |
41975
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1160 ;; PUBLIC: find if the current mode derives from another. |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1161 |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1162 (defun derived-mode-p (&rest modes) |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1163 "Non-nil if the current major mode is derived from one of MODES. |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1164 Uses the `derived-mode-parent' property of the symbol to trace backwards." |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1165 (let ((parent major-mode)) |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1166 (while (and (not (memq parent modes)) |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1167 (setq parent (get parent 'derived-mode-parent)))) |
2b1145fdbe6e
(derived-mode-p): Moved here from derived.el.
Richard M. Stallman <rms@gnu.org>
parents:
41955
diff
changeset
|
1168 parent)) |
16379
dcc3625f52e2
(with-current-buffer): Minor cleanup.
Erik Naggum <erik@naggum.no>
parents:
16359
diff
changeset
|
1169 |
88155 | 1170 ;;;; Minor modes. |
1171 | |
1172 ;; If a minor mode is not defined with define-minor-mode, | |
1173 ;; add it here explicitly. | |
1174 ;; isearch-mode is deliberately excluded, since you should | |
1175 ;; not call it yourself. | |
1176 (defvar minor-mode-list '(auto-save-mode auto-fill-mode abbrev-mode | |
1177 overwrite-mode view-mode | |
1178 hs-minor-mode) | |
1179 "List of all minor mode functions.") | |
1180 | |
28751 | 1181 (defun add-minor-mode (toggle name &optional keymap after toggle-fun) |
28720
f8379b011476
(add-minor-mode): New function.
Gerd Moellmann <gerd@gnu.org>
parents:
28628
diff
changeset
|
1182 "Register a new minor mode. |
28751 | 1183 |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1184 This is an XEmacs-compatibility function. Use `define-minor-mode' instead. |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1185 |
28751 | 1186 TOGGLE is a symbol which is the name of a buffer-local variable that |
1187 is toggled on or off to say whether the minor mode is active or not. | |
1188 | |
1189 NAME specifies what will appear in the mode line when the minor mode | |
1190 is active. NAME should be either a string starting with a space, or a | |
1191 symbol whose value is such a string. | |
1192 | |
1193 Optional KEYMAP is the keymap for the minor mode that will be added | |
1194 to `minor-mode-map-alist'. | |
1195 | |
1196 Optional AFTER specifies that TOGGLE should be added after AFTER | |
1197 in `minor-mode-alist'. | |
1198 | |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1199 Optional TOGGLE-FUN is an interactive function to toggle the mode. |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1200 It defaults to (and should by convention be) TOGGLE. |
31563
96b9757bfd45
(add-minor-mode): Use toggle-fun arg.
Dave Love <fx@gnu.org>
parents:
30515
diff
changeset
|
1201 |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1202 If TOGGLE has a non-nil `:included' property, an entry for the mode is |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1203 included in the mode-line minor mode menu. |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1204 If TOGGLE has a `:menu-tag', that is used for the menu item's label." |
88155 | 1205 (unless (memq toggle minor-mode-list) |
1206 (push toggle minor-mode-list)) | |
1207 | |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1208 (unless toggle-fun (setq toggle-fun toggle)) |
88155 | 1209 (unless (eq toggle-fun toggle) |
1210 (put toggle :minor-mode-function toggle-fun)) | |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1211 ;; Add the name to the minor-mode-alist. |
28751 | 1212 (when name |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1213 (let ((existing (assq toggle minor-mode-alist))) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1214 (if existing |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1215 (setcdr existing (list name)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1216 (let ((tail minor-mode-alist) found) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1217 (while (and tail (not found)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1218 (if (eq after (caar tail)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1219 (setq found tail) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1220 (setq tail (cdr tail)))) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1221 (if found |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1222 (let ((rest (cdr found))) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1223 (setcdr found nil) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1224 (nconc found (list (list toggle name)) rest)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1225 (setq minor-mode-alist (cons (list toggle name) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1226 minor-mode-alist))))))) |
43126
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1227 ;; Add the toggle to the minor-modes menu if requested. |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1228 (when (get toggle :included) |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1229 (define-key mode-line-mode-menu |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1230 (vector toggle) |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1231 (list 'menu-item |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1232 (concat |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1233 (or (get toggle :menu-tag) |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1234 (if (stringp name) name (symbol-name toggle))) |
47652
a5316596929f
(read-key-auxiliary-map): New var.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47406
diff
changeset
|
1235 (let ((mode-name (if (symbolp name) (symbol-value name)))) |
a5316596929f
(read-key-auxiliary-map): New var.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47406
diff
changeset
|
1236 (if (and (stringp mode-name) (string-match "[^ ]+" mode-name)) |
a5316596929f
(read-key-auxiliary-map): New var.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47406
diff
changeset
|
1237 (concat " (" (match-string 0 mode-name) ")")))) |
43126
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1238 toggle-fun |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1239 :button (cons :toggle toggle)))) |
6f39ff1c6d8f
(atomic-change-group, prepare-change-group, activate-change-group)
Richard M. Stallman <rms@gnu.org>
parents:
42941
diff
changeset
|
1240 |
47652
a5316596929f
(read-key-auxiliary-map): New var.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47406
diff
changeset
|
1241 ;; Add the map to the minor-mode-map-alist. |
28751 | 1242 (when keymap |
1243 (let ((existing (assq toggle minor-mode-map-alist))) | |
31979
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1244 (if existing |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1245 (setcdr existing keymap) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1246 (let ((tail minor-mode-map-alist) found) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1247 (while (and tail (not found)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1248 (if (eq after (caar tail)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1249 (setq found tail) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1250 (setq tail (cdr tail)))) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1251 (if found |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1252 (let ((rest (cdr found))) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1253 (setcdr found nil) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1254 (nconc found (list (cons toggle keymap)) rest)) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1255 (setq minor-mode-map-alist (cons (cons toggle keymap) |
6085a3297ebc
(add-minor-mode): Don't eval NAME.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
31563
diff
changeset
|
1256 minor-mode-map-alist)))))))) |
44668
52222efc9d4d
(insert-for-yank): New function.
Richard M. Stallman <rms@gnu.org>
parents:
44473
diff
changeset
|
1257 |
88155 | 1258 ;;; Load history |
1259 | |
1260 ;;; (defvar symbol-file-load-history-loaded nil | |
1261 ;;; "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'. | |
1262 ;;; That file records the part of `load-history' for preloaded files, | |
1263 ;;; which is cleared out before dumping to make Emacs smaller.") | |
1264 | |
1265 ;;; (defun load-symbol-file-load-history () | |
1266 ;;; "Load the file `fns-VERSION.el' in `exec-directory' if not already done. | |
1267 ;;; That file records the part of `load-history' for preloaded files, | |
1268 ;;; which is cleared out before dumping to make Emacs smaller." | |
1269 ;;; (unless symbol-file-load-history-loaded | |
1270 ;;; (load (expand-file-name | |
1271 ;;; ;; fns-XX.YY.ZZ.el does not work on DOS filesystem. | |
1272 ;;; (if (eq system-type 'ms-dos) | |
1273 ;;; "fns.el" | |
1274 ;;; (format "fns-%s.el" emacs-version)) | |
1275 ;;; exec-directory) | |
1276 ;;; ;; The file name fns-%s.el already has a .el extension. | |
1277 ;;; nil nil t) | |
1278 ;;; (setq symbol-file-load-history-loaded t))) | |
1279 | |
1280 (defun symbol-file (symbol &optional type) | |
1281 "Return the input source in which SYMBOL was defined. | |
1282 The value is an absolute file name. | |
1283 It can also be nil, if the definition is not associated with any file. | |
1284 | |
1285 If TYPE is nil, then any kind of definition is acceptable. | |
1286 If TYPE is `defun' or `defvar', that specifies function | |
1287 definition only or variable definition only. | |
1288 `defface' specifies a face definition only." | |
1289 (if (and (or (null type) (eq type 'defun)) | |
1290 (symbolp symbol) (fboundp symbol) | |
1291 (eq 'autoload (car-safe (symbol-function symbol)))) | |
1292 (nth 1 (symbol-function symbol)) | |
1293 (let ((files load-history) | |
1294 file) | |
1295 (while files | |
1296 (if (if type | |
1297 (if (eq type 'defvar) | |
1298 ;; Variables are present just as their names. | |
1299 (member symbol (cdr (car files))) | |
1300 ;; Other types are represented as (TYPE . NAME). | |
1301 (member (cons type symbol) (cdr (car files)))) | |
1302 ;; We accept all types, so look for variable def | |
1303 ;; and then for any other kind. | |
1304 (or (member symbol (cdr (car files))) | |
1305 (rassq symbol (cdr (car files))))) | |
1306 (setq file (car (car files)) files nil)) | |
1307 (setq files (cdr files))) | |
1308 file))) | |
1309 | |
1310 ;;;###autoload | |
1311 (defun locate-library (library &optional nosuffix path interactive-call) | |
1312 "Show the precise file name of Emacs library LIBRARY. | |
1313 This command searches the directories in `load-path' like `\\[load-library]' | |
1314 to find the file that `\\[load-library] RET LIBRARY RET' would load. | |
1315 Optional second arg NOSUFFIX non-nil means don't add suffixes `load-suffixes' | |
1316 to the specified name LIBRARY. | |
1317 | |
1318 If the optional third arg PATH is specified, that list of directories | |
1319 is used instead of `load-path'. | |
1320 | |
1321 When called from a program, the file name is normaly returned as a | |
1322 string. When run interactively, the argument INTERACTIVE-CALL is t, | |
1323 and the file name is displayed in the echo area." | |
1324 (interactive (list (completing-read "Locate library: " | |
1325 'locate-file-completion | |
1326 (cons load-path load-suffixes)) | |
1327 nil nil | |
1328 t)) | |
1329 (let ((file (locate-file library | |
1330 (or path load-path) | |
1331 (append (unless nosuffix load-suffixes) '(""))))) | |
1332 (if interactive-call | |
1333 (if file | |
1334 (message "Library is file %s" (abbreviate-file-name file)) | |
1335 (message "No library %s in search path" library))) | |
1336 file)) | |
1337 | |
1338 | |
1339 ;;;; Specifying things to do later. | |
1340 | |
1341 (defmacro eval-at-startup (&rest body) | |
1342 "Make arrangements to evaluate BODY when Emacs starts up. | |
1343 If this is run after Emacs startup, evaluate BODY immediately. | |
1344 Always returns nil. | |
1345 | |
1346 This works by adding a function to `before-init-hook'. | |
1347 That function's doc string says which file created it." | |
1348 `(progn | |
1349 (if command-line-processed | |
1350 (progn . ,body) | |
1351 (add-hook 'before-init-hook | |
1352 '(lambda () ,(concat "From " (or load-file-name "no file")) | |
1353 . ,body) | |
1354 t)) | |
1355 nil)) | |
1356 | |
1357 (defun eval-after-load (file form) | |
1358 "Arrange that, if FILE is ever loaded, FORM will be run at that time. | |
1359 This makes or adds to an entry on `after-load-alist'. | |
1360 If FILE is already loaded, evaluate FORM right now. | |
1361 It does nothing if FORM is already on the list for FILE. | |
1362 FILE must match exactly. Normally FILE is the name of a library, | |
1363 with no directory or extension specified, since that is how `load' | |
1364 is normally called. | |
1365 FILE can also be a feature (i.e. a symbol), in which case FORM is | |
1366 evaluated whenever that feature is `provide'd." | |
1367 (let ((elt (assoc file after-load-alist))) | |
1368 ;; Make sure there is an element for FILE. | |
1369 (unless elt (setq elt (list file)) (push elt after-load-alist)) | |
1370 ;; Add FORM to the element if it isn't there. | |
1371 (unless (member form (cdr elt)) | |
1372 (nconc elt (list form)) | |
1373 ;; If the file has been loaded already, run FORM right away. | |
1374 (if (if (symbolp file) | |
1375 (featurep file) | |
1376 ;; Make sure `load-history' contains the files dumped with | |
1377 ;; Emacs for the case that FILE is one of them. | |
1378 ;; (load-symbol-file-load-history) | |
1379 (when (locate-library file) | |
1380 (assoc (locate-library file) load-history))) | |
1381 (eval form)))) | |
1382 form) | |
1383 | |
1384 (defun eval-next-after-load (file) | |
1385 "Read the following input sexp, and run it whenever FILE is loaded. | |
1386 This makes or adds to an entry on `after-load-alist'. | |
1387 FILE should be the name of a library, with no directory name." | |
1388 (eval-after-load file (read))) | |
1389 | |
1390 ;;;; Process stuff. | |
1391 | |
1392 ;; open-network-stream is a wrapper around make-network-process. | |
1393 | |
1394 (when (featurep 'make-network-process) | |
1395 (defun open-network-stream (name buffer host service) | |
1396 "Open a TCP connection for a service to a host. | |
1397 Returns a subprocess-object to represent the connection. | |
1398 Input and output work as for subprocesses; `delete-process' closes it. | |
1399 | |
1400 Args are NAME BUFFER HOST SERVICE. | |
1401 NAME is name for process. It is modified if necessary to make it unique. | |
1402 BUFFER is the buffer (or buffer name) to associate with the process. | |
1403 Process output goes at end of that buffer, unless you specify | |
1404 an output stream or filter function to handle the output. | |
1405 BUFFER may be also nil, meaning that this process is not associated | |
1406 with any buffer. | |
1407 HOST is name of the host to connect to, or its IP address. | |
1408 SERVICE is name of the service desired, or an integer specifying | |
1409 a port number to connect to." | |
1410 (make-network-process :name name :buffer buffer | |
1411 :host host :service service))) | |
1412 | |
1413 ;; compatibility | |
1414 | |
1415 (make-obsolete 'process-kill-without-query | |
1416 "use `process-query-on-exit-flag' or `set-process-query-on-exit-flag'." | |
1417 "22.1") | |
1418 (defun process-kill-without-query (process &optional flag) | |
1419 "Say no query needed if PROCESS is running when Emacs is exited. | |
1420 Optional second argument if non-nil says to require a query. | |
1421 Value is t if a query was formerly required." | |
1422 (let ((old (process-query-on-exit-flag process))) | |
1423 (set-process-query-on-exit-flag process nil) | |
1424 old)) | |
1425 | |
1426 ;; process plist management | |
1427 | |
1428 (defun process-get (process propname) | |
1429 "Return the value of PROCESS' PROPNAME property. | |
1430 This is the last value stored with `(process-put PROCESS PROPNAME VALUE)'." | |
1431 (plist-get (process-plist process) propname)) | |
1432 | |
1433 (defun process-put (process propname value) | |
1434 "Change PROCESS' PROPNAME property to VALUE. | |
1435 It can be retrieved with `(process-get PROCESS PROPNAME)'." | |
1436 (set-process-plist process | |
1437 (plist-put (process-plist process) propname value))) | |
1438 | |
1439 | |
1440 ;;;; Input and display facilities. | |
1441 | |
1442 (defvar read-quoted-char-radix 8 | |
1443 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'. | |
1444 Legitimate radix values are 8, 10 and 16.") | |
1445 | |
1446 (custom-declare-variable-early | |
1447 'read-quoted-char-radix 8 | |
1448 "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'. | |
1449 Legitimate radix values are 8, 10 and 16." | |
1450 :type '(choice (const 8) (const 10) (const 16)) | |
1451 :group 'editing-basics) | |
1452 | |
1453 (defun read-quoted-char (&optional prompt) | |
1454 "Like `read-char', but do not allow quitting. | |
1455 Also, if the first character read is an octal digit, | |
1456 we read any number of octal digits and return the | |
1457 specified character code. Any nondigit terminates the sequence. | |
1458 If the terminator is RET, it is discarded; | |
1459 any other terminator is used itself as input. | |
1460 | |
1461 The optional argument PROMPT specifies a string to use to prompt the user. | |
1462 The variable `read-quoted-char-radix' controls which radix to use | |
1463 for numeric input." | |
1464 (let ((message-log-max nil) done (first t) (code 0) char translated) | |
1465 (while (not done) | |
1466 (let ((inhibit-quit first) | |
1467 ;; Don't let C-h get the help message--only help function keys. | |
1468 (help-char nil) | |
1469 (help-form | |
1470 "Type the special character you want to use, | |
1471 or the octal character code. | |
1472 RET terminates the character code and is discarded; | |
1473 any other non-digit terminates the character code and is then used as input.")) | |
1474 (setq char (read-event (and prompt (format "%s-" prompt)) t)) | |
1475 (if inhibit-quit (setq quit-flag nil))) | |
1476 ;; Translate TAB key into control-I ASCII character, and so on. | |
1477 ;; Note: `read-char' does it using the `ascii-character' property. | |
1478 ;; We could try and use read-key-sequence instead, but then C-q ESC | |
1479 ;; or C-q C-x might not return immediately since ESC or C-x might be | |
1480 ;; bound to some prefix in function-key-map or key-translation-map. | |
1481 (setq translated char) | |
1482 (let ((translation (lookup-key function-key-map (vector char)))) | |
1483 (if (arrayp translation) | |
1484 (setq translated (aref translation 0)))) | |
1485 (cond ((null translated)) | |
1486 ((not (integerp translated)) | |
1487 (setq unread-command-events (list char) | |
1488 done t)) | |
1489 ((/= (logand translated ?\M-\^@) 0) | |
1490 ;; Turn a meta-character into a character with the 0200 bit set. | |
1491 (setq code (logior (logand translated (lognot ?\M-\^@)) 128) | |
1492 done t)) | |
1493 ((and (<= ?0 translated) (< translated (+ ?0 (min 10 read-quoted-char-radix)))) | |
1494 (setq code (+ (* code read-quoted-char-radix) (- translated ?0))) | |
1495 (and prompt (setq prompt (message "%s %c" prompt translated)))) | |
1496 ((and (<= ?a (downcase translated)) | |
1497 (< (downcase translated) (+ ?a -10 (min 36 read-quoted-char-radix)))) | |
1498 (setq code (+ (* code read-quoted-char-radix) | |
1499 (+ 10 (- (downcase translated) ?a)))) | |
1500 (and prompt (setq prompt (message "%s %c" prompt translated)))) | |
1501 ((and (not first) (eq translated ?\C-m)) | |
1502 (setq done t)) | |
1503 ((not first) | |
1504 (setq unread-command-events (list char) | |
1505 done t)) | |
1506 (t (setq code translated | |
1507 done t))) | |
1508 (setq first nil)) | |
1509 code)) | |
1510 | |
1511 (defun read-passwd (prompt &optional confirm default) | |
1512 "Read a password, prompting with PROMPT, and return it. | |
1513 If optional CONFIRM is non-nil, read the password twice to make sure. | |
1514 Optional DEFAULT is a default password to use instead of empty input. | |
1515 | |
1516 This function echoes `.' for each character that the user types. | |
1517 The user ends with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line. | |
1518 C-g quits; if `inhibit-quit' was non-nil around this function, | |
1519 then it returns nil if the user types C-g. | |
1520 | |
1521 Once the caller uses the password, it can erase the password | |
1522 by doing (clear-string STRING)." | |
1523 (with-local-quit | |
1524 (if confirm | |
1525 (let (success) | |
1526 (while (not success) | |
1527 (let ((first (read-passwd prompt nil default)) | |
1528 (second (read-passwd "Confirm password: " nil default))) | |
1529 (if (equal first second) | |
1530 (progn | |
1531 (and (arrayp second) (clear-string second)) | |
1532 (setq success first)) | |
1533 (and (arrayp first) (clear-string first)) | |
1534 (and (arrayp second) (clear-string second)) | |
1535 (message "Password not repeated accurately; please start over") | |
1536 (sit-for 1)))) | |
1537 success) | |
1538 (let ((pass nil) | |
1539 (c 0) | |
1540 (echo-keystrokes 0) | |
1541 (cursor-in-echo-area t)) | |
1542 (add-text-properties 0 (length prompt) | |
1543 minibuffer-prompt-properties prompt) | |
1544 (while (progn (message "%s%s" | |
1545 prompt | |
1546 (make-string (length pass) ?.)) | |
1547 (setq c (read-char-exclusive nil t)) | |
1548 (and (/= c ?\r) (/= c ?\n) (/= c ?\e))) | |
1549 (clear-this-command-keys) | |
1550 (if (= c ?\C-u) | |
1551 (progn | |
1552 (and (arrayp pass) (clear-string pass)) | |
1553 (setq pass "")) | |
1554 (if (and (/= c ?\b) (/= c ?\177)) | |
1555 (let* ((new-char (char-to-string c)) | |
1556 (new-pass (concat pass new-char))) | |
1557 (and (arrayp pass) (clear-string pass)) | |
1558 (clear-string new-char) | |
1559 (setq c ?\0) | |
1560 (setq pass new-pass)) | |
1561 (if (> (length pass) 0) | |
1562 (let ((new-pass (substring pass 0 -1))) | |
1563 (and (arrayp pass) (clear-string pass)) | |
1564 (setq pass new-pass)))))) | |
1565 (message nil) | |
1566 (or pass default ""))))) | |
1567 | |
1568 ;; This should be used by `call-interactively' for `n' specs. | |
1569 (defun read-number (prompt &optional default) | |
1570 (let ((n nil)) | |
1571 (when default | |
1572 (setq prompt | |
1573 (if (string-match "\\(\\):[ \t]*\\'" prompt) | |
1574 (replace-match (format " (default %s)" default) t t prompt 1) | |
1575 (replace-regexp-in-string "[ \t]*\\'" | |
1576 (format " (default %s) " default) | |
1577 prompt t t)))) | |
1578 (while | |
1579 (progn | |
1580 (let ((str (read-from-minibuffer prompt nil nil nil nil | |
1581 (and default | |
1582 (number-to-string default))))) | |
1583 (setq n (cond | |
1584 ((zerop (length str)) default) | |
1585 ((stringp str) (read str))))) | |
1586 (unless (numberp n) | |
1587 (message "Please enter a number.") | |
1588 (sit-for 1) | |
1589 t))) | |
1590 n)) | |
1591 | |
1592 ;;; Atomic change groups. | |
1593 | |
1594 (defmacro atomic-change-group (&rest body) | |
1595 "Perform BODY as an atomic change group. | |
1596 This means that if BODY exits abnormally, | |
1597 all of its changes to the current buffer are undone. | |
1598 This works regardless of whether undo is enabled in the buffer. | |
1599 | |
1600 This mechanism is transparent to ordinary use of undo; | |
1601 if undo is enabled in the buffer and BODY succeeds, the | |
1602 user can undo the change normally." | |
1603 (declare (indent 0) (debug t)) | |
1604 (let ((handle (make-symbol "--change-group-handle--")) | |
1605 (success (make-symbol "--change-group-success--"))) | |
1606 `(let ((,handle (prepare-change-group)) | |
1607 (,success nil)) | |
1608 (unwind-protect | |
1609 (progn | |
1610 ;; This is inside the unwind-protect because | |
1611 ;; it enables undo if that was disabled; we need | |
1612 ;; to make sure that it gets disabled again. | |
1613 (activate-change-group ,handle) | |
1614 ,@body | |
1615 (setq ,success t)) | |
1616 ;; Either of these functions will disable undo | |
1617 ;; if it was disabled before. | |
1618 (if ,success | |
1619 (accept-change-group ,handle) | |
1620 (cancel-change-group ,handle)))))) | |
1621 | |
1622 (defun prepare-change-group (&optional buffer) | |
1623 "Return a handle for the current buffer's state, for a change group. | |
1624 If you specify BUFFER, make a handle for BUFFER's state instead. | |
1625 | |
1626 Pass the handle to `activate-change-group' afterward to initiate | |
1627 the actual changes of the change group. | |
1628 | |
1629 To finish the change group, call either `accept-change-group' or | |
1630 `cancel-change-group' passing the same handle as argument. Call | |
1631 `accept-change-group' to accept the changes in the group as final; | |
1632 call `cancel-change-group' to undo them all. You should use | |
1633 `unwind-protect' to make sure the group is always finished. The call | |
1634 to `activate-change-group' should be inside the `unwind-protect'. | |
1635 Once you finish the group, don't use the handle again--don't try to | |
1636 finish the same group twice. For a simple example of correct use, see | |
1637 the source code of `atomic-change-group'. | |
1638 | |
1639 The handle records only the specified buffer. To make a multibuffer | |
1640 change group, call this function once for each buffer you want to | |
1641 cover, then use `nconc' to combine the returned values, like this: | |
1642 | |
1643 (nconc (prepare-change-group buffer-1) | |
1644 (prepare-change-group buffer-2)) | |
1645 | |
1646 You can then activate that multibuffer change group with a single | |
1647 call to `activate-change-group' and finish it with a single call | |
1648 to `accept-change-group' or `cancel-change-group'." | |
1649 | |
1650 (if buffer | |
1651 (list (cons buffer (with-current-buffer buffer buffer-undo-list))) | |
1652 (list (cons (current-buffer) buffer-undo-list)))) | |
1653 | |
1654 (defun activate-change-group (handle) | |
1655 "Activate a change group made with `prepare-change-group' (which see)." | |
1656 (dolist (elt handle) | |
1657 (with-current-buffer (car elt) | |
1658 (if (eq buffer-undo-list t) | |
1659 (setq buffer-undo-list nil))))) | |
1660 | |
1661 (defun accept-change-group (handle) | |
1662 "Finish a change group made with `prepare-change-group' (which see). | |
1663 This finishes the change group by accepting its changes as final." | |
1664 (dolist (elt handle) | |
1665 (with-current-buffer (car elt) | |
1666 (if (eq elt t) | |
1667 (setq buffer-undo-list t))))) | |
1668 | |
1669 (defun cancel-change-group (handle) | |
1670 "Finish a change group made with `prepare-change-group' (which see). | |
1671 This finishes the change group by reverting all of its changes." | |
1672 (dolist (elt handle) | |
1673 (with-current-buffer (car elt) | |
1674 (setq elt (cdr elt)) | |
1675 (let ((old-car | |
1676 (if (consp elt) (car elt))) | |
1677 (old-cdr | |
1678 (if (consp elt) (cdr elt)))) | |
1679 ;; Temporarily truncate the undo log at ELT. | |
1680 (when (consp elt) | |
1681 (setcar elt nil) (setcdr elt nil)) | |
1682 (unless (eq last-command 'undo) (undo-start)) | |
1683 ;; Make sure there's no confusion. | |
1684 (when (and (consp elt) (not (eq elt (last pending-undo-list)))) | |
1685 (error "Undoing to some unrelated state")) | |
1686 ;; Undo it all. | |
1687 (while (listp pending-undo-list) (undo-more 1)) | |
1688 ;; Reset the modified cons cell ELT to its original content. | |
1689 (when (consp elt) | |
1690 (setcar elt old-car) | |
1691 (setcdr elt old-cdr)) | |
1692 ;; Revert the undo info to what it was when we grabbed the state. | |
1693 (setq buffer-undo-list elt))))) | |
1694 | |
1695 ;;;; Display-related functions. | |
1696 | |
1697 ;; For compatibility. | |
1698 (defalias 'redraw-modeline 'force-mode-line-update) | |
1699 | |
1700 (defun force-mode-line-update (&optional all) | |
1701 "Force redisplay of the current buffer's mode line and header line. | |
1702 With optional non-nil ALL, force redisplay of all mode lines and | |
1703 header lines. This function also forces recomputation of the | |
1704 menu bar menus and the frame title." | |
1705 (if all (save-excursion (set-buffer (other-buffer)))) | |
1706 (set-buffer-modified-p (buffer-modified-p))) | |
1707 | |
1708 (defun momentary-string-display (string pos &optional exit-char message) | |
1709 "Momentarily display STRING in the buffer at POS. | |
1710 Display remains until next event is input. | |
1711 Optional third arg EXIT-CHAR can be a character, event or event | |
1712 description list. EXIT-CHAR defaults to SPC. If the input is | |
1713 EXIT-CHAR it is swallowed; otherwise it is then available as | |
1714 input (as a command if nothing else). | |
1715 Display MESSAGE (optional fourth arg) in the echo area. | |
1716 If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there." | |
1717 (or exit-char (setq exit-char ?\ )) | |
1718 (let ((inhibit-read-only t) | |
1719 ;; Don't modify the undo list at all. | |
1720 (buffer-undo-list t) | |
1721 (modified (buffer-modified-p)) | |
1722 (name buffer-file-name) | |
1723 insert-end) | |
1724 (unwind-protect | |
1725 (progn | |
1726 (save-excursion | |
1727 (goto-char pos) | |
1728 ;; defeat file locking... don't try this at home, kids! | |
1729 (setq buffer-file-name nil) | |
1730 (insert-before-markers string) | |
1731 (setq insert-end (point)) | |
1732 ;; If the message end is off screen, recenter now. | |
1733 (if (< (window-end nil t) insert-end) | |
1734 (recenter (/ (window-height) 2))) | |
1735 ;; If that pushed message start off the screen, | |
1736 ;; scroll to start it at the top of the screen. | |
1737 (move-to-window-line 0) | |
1738 (if (> (point) pos) | |
1739 (progn | |
1740 (goto-char pos) | |
1741 (recenter 0)))) | |
1742 (message (or message "Type %s to continue editing.") | |
1743 (single-key-description exit-char)) | |
1744 (let (char) | |
1745 (if (integerp exit-char) | |
1746 (condition-case nil | |
1747 (progn | |
1748 (setq char (read-char)) | |
1749 (or (eq char exit-char) | |
1750 (setq unread-command-events (list char)))) | |
1751 (error | |
1752 ;; `exit-char' is a character, hence it differs | |
1753 ;; from char, which is an event. | |
1754 (setq unread-command-events (list char)))) | |
1755 ;; `exit-char' can be an event, or an event description | |
1756 ;; list. | |
1757 (setq char (read-event)) | |
1758 (or (eq char exit-char) | |
1759 (eq char (event-convert-list exit-char)) | |
1760 (setq unread-command-events (list char)))))) | |
1761 (if insert-end | |
1762 (save-excursion | |
1763 (delete-region pos insert-end))) | |
1764 (setq buffer-file-name name) | |
1765 (set-buffer-modified-p modified)))) | |
1766 | |
1767 | |
1768 ;;;; Overlay operations | |
1769 | |
1770 (defun copy-overlay (o) | |
1771 "Return a copy of overlay O." | |
1772 (let ((o1 (make-overlay (overlay-start o) (overlay-end o) | |
1773 ;; FIXME: there's no easy way to find the | |
1774 ;; insertion-type of the two markers. | |
1775 (overlay-buffer o))) | |
1776 (props (overlay-properties o))) | |
1777 (while props | |
1778 (overlay-put o1 (pop props) (pop props))) | |
1779 o1)) | |
1780 | |
1781 (defun remove-overlays (&optional beg end name val) | |
1782 "Clear BEG and END of overlays whose property NAME has value VAL. | |
1783 Overlays might be moved and/or split. | |
1784 BEG and END default respectively to the beginning and end of buffer." | |
1785 (unless beg (setq beg (point-min))) | |
1786 (unless end (setq end (point-max))) | |
1787 (if (< end beg) | |
1788 (setq beg (prog1 end (setq end beg)))) | |
1789 (save-excursion | |
1790 (dolist (o (overlays-in beg end)) | |
1791 (when (eq (overlay-get o name) val) | |
1792 ;; Either push this overlay outside beg...end | |
1793 ;; or split it to exclude beg...end | |
1794 ;; or delete it entirely (if it is contained in beg...end). | |
1795 (if (< (overlay-start o) beg) | |
1796 (if (> (overlay-end o) end) | |
1797 (progn | |
1798 (move-overlay (copy-overlay o) | |
1799 (overlay-start o) beg) | |
1800 (move-overlay o end (overlay-end o))) | |
1801 (move-overlay o (overlay-start o) beg)) | |
1802 (if (> (overlay-end o) end) | |
1803 (move-overlay o end (overlay-end o)) | |
1804 (delete-overlay o))))))) | |
1805 | |
1806 ;;;; Miscellanea. | |
1807 | |
1808 (defvar suspend-hook nil | |
1809 "Normal hook run by `suspend-emacs', before suspending.") | |
1810 | |
1811 (defvar suspend-resume-hook nil | |
1812 "Normal hook run by `suspend-emacs', after Emacs is continued.") | |
1813 | |
1814 (defvar temp-buffer-show-hook nil | |
1815 "Normal hook run by `with-output-to-temp-buffer' after displaying the buffer. | |
1816 When the hook runs, the temporary buffer is current, and the window it | |
1817 was displayed in is selected. This hook is normally set up with a | |
1818 function to make the buffer read only, and find function names and | |
1819 variable names in it, provided the major mode is still Help mode.") | |
1820 | |
1821 (defvar temp-buffer-setup-hook nil | |
1822 "Normal hook run by `with-output-to-temp-buffer' at the start. | |
1823 When the hook runs, the temporary buffer is current. | |
1824 This hook is normally set up with a function to put the buffer in Help | |
1825 mode.") | |
1826 | |
1827 ;; Avoid compiler warnings about this variable, | |
1828 ;; which has a special meaning on certain system types. | |
1829 (defvar buffer-file-type nil | |
1830 "Non-nil if the visited file is a binary file. | |
1831 This variable is meaningful on MS-DOG and Windows NT. | |
1832 On those systems, it is automatically local in every buffer. | |
1833 On other systems, this variable is normally always nil.") | |
1834 | |
1835 ;;;; Misc. useful functions. | |
1836 | |
1837 (defun find-tag-default () | |
1838 "Determine default tag to search for, based on text at point. | |
1839 If there is no plausible default, return nil." | |
1840 (save-excursion | |
1841 (while (looking-at "\\sw\\|\\s_") | |
1842 (forward-char 1)) | |
1843 (if (or (re-search-backward "\\sw\\|\\s_" | |
1844 (save-excursion (beginning-of-line) (point)) | |
1845 t) | |
1846 (re-search-forward "\\(\\sw\\|\\s_\\)+" | |
1847 (save-excursion (end-of-line) (point)) | |
1848 t)) | |
1849 (progn | |
1850 (goto-char (match-end 0)) | |
1851 (condition-case nil | |
1852 (buffer-substring-no-properties | |
1853 (point) | |
1854 (progn (forward-sexp -1) | |
1855 (while (looking-at "\\s'") | |
1856 (forward-char 1)) | |
1857 (point))) | |
1858 (error nil))) | |
1859 nil))) | |
1860 | |
1861 (defun play-sound (sound) | |
1862 "SOUND is a list of the form `(sound KEYWORD VALUE...)'. | |
1863 The following keywords are recognized: | |
1864 | |
1865 :file FILE - read sound data from FILE. If FILE isn't an | |
1866 absolute file name, it is searched in `data-directory'. | |
1867 | |
1868 :data DATA - read sound data from string DATA. | |
1869 | |
1870 Exactly one of :file or :data must be present. | |
1871 | |
1872 :volume VOL - set volume to VOL. VOL must an integer in the | |
1873 range 0..100 or a float in the range 0..1.0. If not specified, | |
1874 don't change the volume setting of the sound device. | |
1875 | |
1876 :device DEVICE - play sound on DEVICE. If not specified, | |
1877 a system-dependent default device name is used." | |
1878 (if (fboundp 'play-sound-internal) | |
1879 (play-sound-internal sound) | |
1880 (error "This Emacs binary lacks sound support"))) | |
1881 | |
1882 (defun shell-quote-argument (argument) | |
1883 "Quote an argument for passing as argument to an inferior shell." | |
1884 (if (eq system-type 'ms-dos) | |
1885 ;; Quote using double quotes, but escape any existing quotes in | |
1886 ;; the argument with backslashes. | |
1887 (let ((result "") | |
1888 (start 0) | |
1889 end) | |
1890 (if (or (null (string-match "[^\"]" argument)) | |
1891 (< (match-end 0) (length argument))) | |
1892 (while (string-match "[\"]" argument start) | |
1893 (setq end (match-beginning 0) | |
1894 result (concat result (substring argument start end) | |
1895 "\\" (substring argument end (1+ end))) | |
1896 start (1+ end)))) | |
1897 (concat "\"" result (substring argument start) "\"")) | |
1898 (if (eq system-type 'windows-nt) | |
1899 (concat "\"" argument "\"") | |
1900 (if (equal argument "") | |
1901 "''" | |
1902 ;; Quote everything except POSIX filename characters. | |
1903 ;; This should be safe enough even for really weird shells. | |
1904 (let ((result "") (start 0) end) | |
1905 (while (string-match "[^-0-9a-zA-Z_./]" argument start) | |
1906 (setq end (match-beginning 0) | |
1907 result (concat result (substring argument start end) | |
1908 "\\" (substring argument end (1+ end))) | |
1909 start (1+ end))) | |
1910 (concat result (substring argument start))))))) | |
1911 | |
1912 ;;;; Support for yanking and text properties. | |
1913 | |
1914 (defvar yank-excluded-properties) | |
1915 | |
1916 (defun remove-yank-excluded-properties (start end) | |
1917 "Remove `yank-excluded-properties' between START and END positions. | |
1918 Replaces `category' properties with their defined properties." | |
1919 (let ((inhibit-read-only t)) | |
1920 ;; Replace any `category' property with the properties it stands for. | |
1921 (unless (memq yank-excluded-properties '(t nil)) | |
1922 (save-excursion | |
1923 (goto-char start) | |
1924 (while (< (point) end) | |
1925 (let ((cat (get-text-property (point) 'category)) | |
1926 run-end) | |
1927 (setq run-end | |
1928 (next-single-property-change (point) 'category nil end)) | |
1929 (when cat | |
1930 (let (run-end2 original) | |
1931 (remove-list-of-text-properties (point) run-end '(category)) | |
1932 (while (< (point) run-end) | |
1933 (setq run-end2 (next-property-change (point) nil run-end)) | |
1934 (setq original (text-properties-at (point))) | |
1935 (set-text-properties (point) run-end2 (symbol-plist cat)) | |
1936 (add-text-properties (point) run-end2 original) | |
1937 (goto-char run-end2)))) | |
1938 (goto-char run-end))))) | |
1939 (if (eq yank-excluded-properties t) | |
1940 (set-text-properties start end nil) | |
1941 (remove-list-of-text-properties start end yank-excluded-properties)))) | |
1942 | |
1943 (defvar yank-undo-function) | |
1944 | |
1945 (defun insert-for-yank (string) | |
1946 "Calls `insert-for-yank-1' repetitively for each `yank-handler' segment. | |
1947 | |
1948 See `insert-for-yank-1' for more details." | |
1949 (let (to) | |
1950 (while (setq to (next-single-property-change 0 'yank-handler string)) | |
1951 (insert-for-yank-1 (substring string 0 to)) | |
1952 (setq string (substring string to)))) | |
1953 (insert-for-yank-1 string)) | |
1954 | |
1955 (defun insert-for-yank-1 (string) | |
1956 "Insert STRING at point, stripping some text properties. | |
1957 | |
1958 Strip text properties from the inserted text according to | |
1959 `yank-excluded-properties'. Otherwise just like (insert STRING). | |
1960 | |
1961 If STRING has a non-nil `yank-handler' property on the first character, | |
1962 the normal insert behavior is modified in various ways. The value of | |
1963 the yank-handler property must be a list with one to four elements | |
1964 with the following format: (FUNCTION PARAM NOEXCLUDE UNDO). | |
1965 When FUNCTION is present and non-nil, it is called instead of `insert' | |
1966 to insert the string. FUNCTION takes one argument--the object to insert. | |
1967 If PARAM is present and non-nil, it replaces STRING as the object | |
1968 passed to FUNCTION (or `insert'); for example, if FUNCTION is | |
1969 `yank-rectangle', PARAM may be a list of strings to insert as a | |
1970 rectangle. | |
1971 If NOEXCLUDE is present and non-nil, the normal removal of the | |
1972 yank-excluded-properties is not performed; instead FUNCTION is | |
1973 responsible for removing those properties. This may be necessary | |
1974 if FUNCTION adjusts point before or after inserting the object. | |
1975 If UNDO is present and non-nil, it is a function that will be called | |
1976 by `yank-pop' to undo the insertion of the current object. It is | |
1977 called with two arguments, the start and end of the current region. | |
1978 FUNCTION may set `yank-undo-function' to override the UNDO value." | |
1979 (let* ((handler (and (stringp string) | |
1980 (get-text-property 0 'yank-handler string))) | |
1981 (param (or (nth 1 handler) string)) | |
1982 (opoint (point))) | |
1983 (setq yank-undo-function t) | |
1984 (if (nth 0 handler) ;; FUNCTION | |
1985 (funcall (car handler) param) | |
1986 (insert param)) | |
1987 (unless (nth 2 handler) ;; NOEXCLUDE | |
1988 (remove-yank-excluded-properties opoint (point))) | |
1989 (if (eq yank-undo-function t) ;; not set by FUNCTION | |
1990 (setq yank-undo-function (nth 3 handler))) ;; UNDO | |
1991 (if (nth 4 handler) ;; COMMAND | |
1992 (setq this-command (nth 4 handler))))) | |
1993 | |
1994 (defun insert-buffer-substring-no-properties (buffer &optional start end) | |
1995 "Insert before point a substring of BUFFER, without text properties. | |
1996 BUFFER may be a buffer or a buffer name. | |
1997 Arguments START and END are character positions specifying the substring. | |
1998 They default to the values of (point-min) and (point-max) in BUFFER." | |
1999 (let ((opoint (point))) | |
2000 (insert-buffer-substring buffer start end) | |
2001 (let ((inhibit-read-only t)) | |
2002 (set-text-properties opoint (point) nil)))) | |
2003 | |
2004 (defun insert-buffer-substring-as-yank (buffer &optional start end) | |
2005 "Insert before point a part of BUFFER, stripping some text properties. | |
2006 BUFFER may be a buffer or a buffer name. | |
2007 Arguments START and END are character positions specifying the substring. | |
2008 They default to the values of (point-min) and (point-max) in BUFFER. | |
2009 Strip text properties from the inserted text according to | |
2010 `yank-excluded-properties'." | |
2011 ;; Since the buffer text should not normally have yank-handler properties, | |
2012 ;; there is no need to handle them here. | |
2013 (let ((opoint (point))) | |
2014 (insert-buffer-substring buffer start end) | |
2015 (remove-yank-excluded-properties opoint (point)))) | |
2016 | |
2017 | |
2018 ;;;; Synchronous shell commands. | |
2019 | |
2020 (defun start-process-shell-command (name buffer &rest args) | |
2021 "Start a program in a subprocess. Return the process object for it. | |
2022 NAME is name for process. It is modified if necessary to make it unique. | |
2023 BUFFER is the buffer (or buffer name) to associate with the process. | |
2024 Process output goes at end of that buffer, unless you specify | |
2025 an output stream or filter function to handle the output. | |
2026 BUFFER may be also nil, meaning that this process is not associated | |
2027 with any buffer | |
2028 COMMAND is the name of a shell command. | |
2029 Remaining arguments are the arguments for the command. | |
2030 Wildcards and redirection are handled as usual in the shell. | |
2031 | |
2032 \(fn NAME BUFFER COMMAND &rest COMMAND-ARGS)" | |
2033 (cond | |
2034 ((eq system-type 'vax-vms) | |
2035 (apply 'start-process name buffer args)) | |
2036 ;; We used to use `exec' to replace the shell with the command, | |
2037 ;; but that failed to handle (...) and semicolon, etc. | |
2038 (t | |
2039 (start-process name buffer shell-file-name shell-command-switch | |
2040 (mapconcat 'identity args " "))))) | |
2041 | |
2042 (defun call-process-shell-command (command &optional infile buffer display | |
2043 &rest args) | |
2044 "Execute the shell command COMMAND synchronously in separate process. | |
2045 The remaining arguments are optional. | |
2046 The program's input comes from file INFILE (nil means `/dev/null'). | |
2047 Insert output in BUFFER before point; t means current buffer; | |
2048 nil for BUFFER means discard it; 0 means discard and don't wait. | |
2049 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, | |
2050 REAL-BUFFER says what to do with standard output, as above, | |
2051 while STDERR-FILE says what to do with standard error in the child. | |
2052 STDERR-FILE may be nil (discard standard error output), | |
2053 t (mix it with ordinary output), or a file name string. | |
2054 | |
2055 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. | |
2056 Remaining arguments are strings passed as additional arguments for COMMAND. | |
2057 Wildcards and redirection are handled as usual in the shell. | |
2058 | |
2059 If BUFFER is 0, `call-process-shell-command' returns immediately with value nil. | |
2060 Otherwise it waits for COMMAND to terminate and returns a numeric exit | |
2061 status or a signal description string. | |
2062 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again." | |
2063 (cond | |
2064 ((eq system-type 'vax-vms) | |
2065 (apply 'call-process command infile buffer display args)) | |
2066 ;; We used to use `exec' to replace the shell with the command, | |
2067 ;; but that failed to handle (...) and semicolon, etc. | |
2068 (t | |
2069 (call-process shell-file-name | |
2070 infile buffer display | |
2071 shell-command-switch | |
2072 (mapconcat 'identity (cons command args) " "))))) | |
2073 | |
2074 ;;;; Lisp macros to do various things temporarily. | |
2075 | |
2076 (defmacro with-current-buffer (buffer &rest body) | |
2077 "Execute the forms in BODY with BUFFER as the current buffer. | |
2078 The value returned is the value of the last form in BODY. | |
2079 See also `with-temp-buffer'." | |
2080 (declare (indent 1) (debug t)) | |
2081 `(save-current-buffer | |
2082 (set-buffer ,buffer) | |
2083 ,@body)) | |
2084 | |
2085 (defmacro with-selected-window (window &rest body) | |
2086 "Execute the forms in BODY with WINDOW as the selected window. | |
2087 The value returned is the value of the last form in BODY. | |
2088 | |
2089 This macro saves and restores the current buffer, since otherwise | |
2090 its normal operation could potentially make a different | |
2091 buffer current. It does not alter the buffer list ordering. | |
2092 | |
2093 This macro saves and restores the selected window, as well as | |
2094 the selected window in each frame. If the previously selected | |
2095 window of some frame is no longer live at the end of BODY, that | |
2096 frame's selected window is left alone. If the selected window is | |
2097 no longer live, then whatever window is selected at the end of | |
2098 BODY remains selected. | |
2099 See also `with-temp-buffer'." | |
2100 (declare (indent 1) (debug t)) | |
2101 ;; Most of this code is a copy of save-selected-window. | |
2102 `(let ((save-selected-window-window (selected-window)) | |
2103 ;; It is necessary to save all of these, because calling | |
2104 ;; select-window changes frame-selected-window for whatever | |
2105 ;; frame that window is in. | |
2106 (save-selected-window-alist | |
2107 (mapcar (lambda (frame) (list frame (frame-selected-window frame))) | |
2108 (frame-list)))) | |
2109 (save-current-buffer | |
2110 (unwind-protect | |
2111 (progn (select-window ,window 'norecord) | |
2112 ,@body) | |
2113 (dolist (elt save-selected-window-alist) | |
2114 (and (frame-live-p (car elt)) | |
2115 (window-live-p (cadr elt)) | |
2116 (set-frame-selected-window (car elt) (cadr elt)))) | |
2117 (if (window-live-p save-selected-window-window) | |
2118 (select-window save-selected-window-window 'norecord)))))) | |
2119 | |
2120 (defmacro with-temp-file (file &rest body) | |
2121 "Create a new buffer, evaluate BODY there, and write the buffer to FILE. | |
2122 The value returned is the value of the last form in BODY. | |
2123 See also `with-temp-buffer'." | |
2124 (declare (debug t)) | |
2125 (let ((temp-file (make-symbol "temp-file")) | |
2126 (temp-buffer (make-symbol "temp-buffer"))) | |
2127 `(let ((,temp-file ,file) | |
2128 (,temp-buffer | |
2129 (get-buffer-create (generate-new-buffer-name " *temp file*")))) | |
2130 (unwind-protect | |
2131 (prog1 | |
2132 (with-current-buffer ,temp-buffer | |
2133 ,@body) | |
2134 (with-current-buffer ,temp-buffer | |
2135 (widen) | |
2136 (write-region (point-min) (point-max) ,temp-file nil 0))) | |
2137 (and (buffer-name ,temp-buffer) | |
2138 (kill-buffer ,temp-buffer)))))) | |
2139 | |
2140 (defmacro with-temp-message (message &rest body) | |
2141 "Display MESSAGE temporarily if non-nil while BODY is evaluated. | |
2142 The original message is restored to the echo area after BODY has finished. | |
2143 The value returned is the value of the last form in BODY. | |
2144 MESSAGE is written to the message log buffer if `message-log-max' is non-nil. | |
2145 If MESSAGE is nil, the echo area and message log buffer are unchanged. | |
2146 Use a MESSAGE of \"\" to temporarily clear the echo area." | |
2147 (declare (debug t)) | |
2148 (let ((current-message (make-symbol "current-message")) | |
2149 (temp-message (make-symbol "with-temp-message"))) | |
2150 `(let ((,temp-message ,message) | |
2151 (,current-message)) | |
2152 (unwind-protect | |
2153 (progn | |
2154 (when ,temp-message | |
2155 (setq ,current-message (current-message)) | |
2156 (message "%s" ,temp-message)) | |
2157 ,@body) | |
2158 (and ,temp-message | |
2159 (if ,current-message | |
2160 (message "%s" ,current-message) | |
2161 (message nil))))))) | |
2162 | |
2163 (defmacro with-temp-buffer (&rest body) | |
2164 "Create a temporary buffer, and evaluate BODY there like `progn'. | |
2165 See also `with-temp-file' and `with-output-to-string'." | |
2166 (declare (indent 0) (debug t)) | |
2167 (let ((temp-buffer (make-symbol "temp-buffer"))) | |
2168 `(let ((,temp-buffer (generate-new-buffer " *temp*"))) | |
2169 (unwind-protect | |
2170 (with-current-buffer ,temp-buffer | |
2171 ,@body) | |
2172 (and (buffer-name ,temp-buffer) | |
2173 (kill-buffer ,temp-buffer)))))) | |
2174 | |
2175 (defmacro with-output-to-string (&rest body) | |
2176 "Execute BODY, return the text it sent to `standard-output', as a string." | |
2177 (declare (indent 0) (debug t)) | |
2178 `(let ((standard-output | |
2179 (get-buffer-create (generate-new-buffer-name " *string-output*")))) | |
2180 (let ((standard-output standard-output)) | |
2181 ,@body) | |
2182 (with-current-buffer standard-output | |
2183 (prog1 | |
2184 (buffer-string) | |
2185 (kill-buffer nil))))) | |
2186 | |
2187 (defmacro with-local-quit (&rest body) | |
2188 "Execute BODY, allowing quits to terminate BODY but not escape further. | |
2189 When a quit terminates BODY, `with-local-quit' returns nil but | |
2190 requests another quit. That quit will be processed, the next time quitting | |
2191 is allowed once again." | |
2192 (declare (debug t) (indent 0)) | |
2193 `(condition-case nil | |
2194 (let ((inhibit-quit nil)) | |
2195 ,@body) | |
2196 (quit (setq quit-flag t) nil))) | |
2197 | |
2198 (defmacro while-no-input (&rest body) | |
2199 "Execute BODY only as long as there's no pending input. | |
2200 If input arrives, that ends the execution of BODY, | |
2201 and `while-no-input' returns t. Quitting makes it return nil. | |
2202 If BODY finishes, `while-no-input' returns whatever value BODY produced." | |
2203 (declare (debug t) (indent 0)) | |
2204 (let ((catch-sym (make-symbol "input"))) | |
2205 `(with-local-quit | |
2206 (catch ',catch-sym | |
2207 (let ((throw-on-input ',catch-sym)) | |
2208 (or (not (sit-for 0 0 t)) | |
2209 ,@body)))))) | |
2210 | |
2211 (defmacro combine-after-change-calls (&rest body) | |
2212 "Execute BODY, but don't call the after-change functions till the end. | |
2213 If BODY makes changes in the buffer, they are recorded | |
2214 and the functions on `after-change-functions' are called several times | |
2215 when BODY is finished. | |
2216 The return value is the value of the last form in BODY. | |
2217 | |
2218 If `before-change-functions' is non-nil, then calls to the after-change | |
2219 functions can't be deferred, so in that case this macro has no effect. | |
2220 | |
2221 Do not alter `after-change-functions' or `before-change-functions' | |
2222 in BODY." | |
2223 (declare (indent 0) (debug t)) | |
2224 `(unwind-protect | |
2225 (let ((combine-after-change-calls t)) | |
2226 . ,body) | |
2227 (combine-after-change-execute))) | |
2228 | |
2229 ;;;; Constructing completion tables. | |
2230 | |
2231 (defmacro dynamic-completion-table (fun) | |
2232 "Use function FUN as a dynamic completion table. | |
2233 FUN is called with one argument, the string for which completion is required, | |
2234 and it should return an alist containing all the intended possible | |
2235 completions. This alist may be a full list of possible completions so that FUN | |
2236 can ignore the value of its argument. If completion is performed in the | |
2237 minibuffer, FUN will be called in the buffer from which the minibuffer was | |
2238 entered. | |
2239 | |
2240 The result of the `dynamic-completion-table' form is a function | |
2241 that can be used as the ALIST argument to `try-completion' and | |
2242 `all-completion'. See Info node `(elisp)Programmed Completion'." | |
2243 (declare (debug (lambda-expr))) | |
2244 (let ((win (make-symbol "window")) | |
2245 (string (make-symbol "string")) | |
2246 (predicate (make-symbol "predicate")) | |
2247 (mode (make-symbol "mode"))) | |
2248 `(lambda (,string ,predicate ,mode) | |
2249 (with-current-buffer (let ((,win (minibuffer-selected-window))) | |
2250 (if (window-live-p ,win) (window-buffer ,win) | |
2251 (current-buffer))) | |
2252 (cond | |
2253 ((eq ,mode t) (all-completions ,string (,fun ,string) ,predicate)) | |
2254 ((not ,mode) (try-completion ,string (,fun ,string) ,predicate)) | |
2255 (t (test-completion ,string (,fun ,string) ,predicate))))))) | |
2256 | |
2257 (defmacro lazy-completion-table (var fun) | |
2258 ;; We used to have `&rest args' where `args' were evaluated late (at the | |
2259 ;; time of the call to `fun'), which was counter intuitive. But to get | |
2260 ;; them to be evaluated early, we have to either use lexical-let (which is | |
2261 ;; not available in subr.el) or use `(lambda (,str) ...) which prevents the use | |
2262 ;; of lexical-let in the callers. | |
2263 ;; So we just removed the argument. Callers can then simply use either of: | |
2264 ;; (lazy-completion-table var (lambda () (fun x y))) | |
2265 ;; or | |
2266 ;; (lazy-completion-table var `(lambda () (fun ',x ',y))) | |
2267 ;; or | |
2268 ;; (lexical-let ((x x)) ((y y)) | |
2269 ;; (lazy-completion-table var (lambda () (fun x y)))) | |
2270 ;; depending on the behavior they want. | |
2271 "Initialize variable VAR as a lazy completion table. | |
2272 If the completion table VAR is used for the first time (e.g., by passing VAR | |
2273 as an argument to `try-completion'), the function FUN is called with no | |
2274 arguments. FUN must return the completion table that will be stored in VAR. | |
2275 If completion is requested in the minibuffer, FUN will be called in the buffer | |
2276 from which the minibuffer was entered. The return value of | |
2277 `lazy-completion-table' must be used to initialize the value of VAR." | |
2278 (declare (debug (symbol lambda-expr))) | |
2279 (let ((str (make-symbol "string"))) | |
2280 `(dynamic-completion-table | |
2281 (lambda (,str) | |
2282 (when (functionp ,var) | |
2283 (setq ,var (,fun))) | |
2284 ,var)))) | |
2285 | |
2286 (defmacro complete-in-turn (a b) | |
2287 "Create a completion table that first tries completion in A and then in B. | |
2288 A and B should not be costly (or side-effecting) expressions." | |
2289 (declare (debug (def-form def-form))) | |
2290 `(lambda (string predicate mode) | |
2291 (cond | |
2292 ((eq mode t) | |
2293 (or (all-completions string ,a predicate) | |
2294 (all-completions string ,b predicate))) | |
2295 ((eq mode nil) | |
2296 (or (try-completion string ,a predicate) | |
2297 (try-completion string ,b predicate))) | |
2298 (t | |
2299 (or (test-completion string ,a predicate) | |
2300 (test-completion string ,b predicate)))))) | |
2301 | |
2302 ;;; Matching and match data. | |
2303 | |
2304 (defvar save-match-data-internal) | |
2305 | |
2306 ;; We use save-match-data-internal as the local variable because | |
2307 ;; that works ok in practice (people should not use that variable elsewhere). | |
2308 ;; We used to use an uninterned symbol; the compiler handles that properly | |
2309 ;; now, but it generates slower code. | |
2310 (defmacro save-match-data (&rest body) | |
2311 "Execute the BODY forms, restoring the global value of the match data. | |
2312 The value returned is the value of the last form in BODY." | |
2313 ;; It is better not to use backquote here, | |
2314 ;; because that makes a bootstrapping problem | |
2315 ;; if you need to recompile all the Lisp files using interpreted code. | |
2316 (declare (indent 0) (debug t)) | |
2317 (list 'let | |
2318 '((save-match-data-internal (match-data))) | |
2319 (list 'unwind-protect | |
2320 (cons 'progn body) | |
2321 ;; It is safe to free (evaporate) markers immediately here, | |
2322 ;; as Lisp programs should not copy from save-match-data-internal. | |
2323 '(set-match-data save-match-data-internal 'evaporate)))) | |
2324 | |
2325 (defun match-string (num &optional string) | |
2326 "Return string of text matched by last search. | |
2327 NUM specifies which parenthesized expression in the last regexp. | |
2328 Value is nil if NUMth pair didn't match, or there were less than NUM pairs. | |
2329 Zero means the entire text matched by the whole regexp or whole string. | |
2330 STRING should be given if the last search was by `string-match' on STRING." | |
2331 (if (match-beginning num) | |
2332 (if string | |
2333 (substring string (match-beginning num) (match-end num)) | |
2334 (buffer-substring (match-beginning num) (match-end num))))) | |
2335 | |
2336 (defun match-string-no-properties (num &optional string) | |
2337 "Return string of text matched by last search, without text properties. | |
2338 NUM specifies which parenthesized expression in the last regexp. | |
2339 Value is nil if NUMth pair didn't match, or there were less than NUM pairs. | |
2340 Zero means the entire text matched by the whole regexp or whole string. | |
2341 STRING should be given if the last search was by `string-match' on STRING." | |
2342 (if (match-beginning num) | |
2343 (if string | |
2344 (substring-no-properties string (match-beginning num) | |
2345 (match-end num)) | |
2346 (buffer-substring-no-properties (match-beginning num) | |
2347 (match-end num))))) | |
2348 | |
2349 (defun looking-back (regexp &optional limit greedy) | |
2350 "Return non-nil if text before point matches regular expression REGEXP. | |
2351 Like `looking-at' except matches before point, and is slower. | |
2352 LIMIT if non-nil speeds up the search by specifying how far back the | |
2353 match can start. | |
2354 | |
2355 If GREEDY is non-nil, extend the match backwards as far as possible, | |
2356 stopping when a single additional previous character cannot be part | |
2357 of a match for REGEXP." | |
2358 (let ((start (point)) | |
2359 (pos | |
2360 (save-excursion | |
2361 (and (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t) | |
2362 (point))))) | |
2363 (if (and greedy pos) | |
2364 (save-restriction | |
2365 (narrow-to-region (point-min) start) | |
2366 (while (and (> pos (point-min)) | |
2367 (save-excursion | |
2368 (goto-char pos) | |
2369 (backward-char 1) | |
2370 (looking-at (concat "\\(?:" regexp "\\)\\'")))) | |
2371 (setq pos (1- pos))) | |
2372 (save-excursion | |
2373 (goto-char pos) | |
2374 (looking-at (concat "\\(?:" regexp "\\)\\'"))))) | |
2375 (not (null pos)))) | |
2376 | |
2377 (defun subregexp-context-p (regexp pos &optional start) | |
2378 "Return non-nil if POS is in a normal subregexp context in REGEXP. | |
2379 A subregexp context is one where a sub-regexp can appear. | |
2380 A non-subregexp context is for example within brackets, or within a | |
2381 repetition bounds operator `\\=\\{...\\}', or right after a `\\'. | |
2382 If START is non-nil, it should be a position in REGEXP, smaller | |
2383 than POS, and known to be in a subregexp context." | |
2384 ;; Here's one possible implementation, with the great benefit that it | |
2385 ;; reuses the regexp-matcher's own parser, so it understands all the | |
2386 ;; details of the syntax. A disadvantage is that it needs to match the | |
2387 ;; error string. | |
2388 (condition-case err | |
2389 (progn | |
2390 (string-match (substring regexp (or start 0) pos) "") | |
2391 t) | |
2392 (invalid-regexp | |
2393 (not (member (cadr err) '("Unmatched [ or [^" | |
2394 "Unmatched \\{" | |
2395 "Trailing backslash"))))) | |
2396 ;; An alternative implementation: | |
2397 ;; (defconst re-context-re | |
2398 ;; (let* ((harmless-ch "[^\\[]") | |
2399 ;; (harmless-esc "\\\\[^{]") | |
2400 ;; (class-harmless-ch "[^][]") | |
2401 ;; (class-lb-harmless "[^]:]") | |
2402 ;; (class-lb-colon-maybe-charclass ":\\([a-z]+:]\\)?") | |
2403 ;; (class-lb (concat "\\[\\(" class-lb-harmless | |
2404 ;; "\\|" class-lb-colon-maybe-charclass "\\)")) | |
2405 ;; (class | |
2406 ;; (concat "\\[^?]?" | |
2407 ;; "\\(" class-harmless-ch | |
2408 ;; "\\|" class-lb "\\)*" | |
2409 ;; "\\[?]")) ; special handling for bare [ at end of re | |
2410 ;; (braces "\\\\{[0-9,]+\\\\}")) | |
2411 ;; (concat "\\`\\(" harmless-ch "\\|" harmless-esc | |
2412 ;; "\\|" class "\\|" braces "\\)*\\'")) | |
2413 ;; "Matches any prefix that corresponds to a normal subregexp context.") | |
2414 ;; (string-match re-context-re (substring regexp (or start 0) pos)) | |
2415 ) | |
2416 | |
2417 ;;;; split-string | |
2418 | |
2419 (defconst split-string-default-separators "[ \f\t\n\r\v]+" | |
2420 "The default value of separators for `split-string'. | |
2421 | |
2422 A regexp matching strings of whitespace. May be locale-dependent | |
2423 \(as yet unimplemented). Should not match non-breaking spaces. | |
2424 | |
2425 Warning: binding this to a different value and using it as default is | |
2426 likely to have undesired semantics.") | |
2427 | |
2428 ;; The specification says that if both SEPARATORS and OMIT-NULLS are | |
2429 ;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical | |
2430 ;; expression leads to the equivalent implementation that if SEPARATORS | |
2431 ;; is defaulted, OMIT-NULLS is treated as t. | |
2432 (defun split-string (string &optional separators omit-nulls) | |
2433 "Split STRING into substrings bounded by matches for SEPARATORS. | |
2434 | |
2435 The beginning and end of STRING, and each match for SEPARATORS, are | |
2436 splitting points. The substrings matching SEPARATORS are removed, and | |
2437 the substrings between the splitting points are collected as a list, | |
2438 which is returned. | |
2439 | |
2440 If SEPARATORS is non-nil, it should be a regular expression matching text | |
2441 which separates, but is not part of, the substrings. If nil it defaults to | |
2442 `split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and | |
2443 OMIT-NULLS is forced to t. | |
2444 | |
2445 If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so | |
2446 that for the default value of SEPARATORS leading and trailing whitespace | |
2447 are effectively trimmed). If nil, all zero-length substrings are retained, | |
2448 which correctly parses CSV format, for example. | |
2449 | |
2450 Note that the effect of `(split-string STRING)' is the same as | |
2451 `(split-string STRING split-string-default-separators t)'). In the rare | |
2452 case that you wish to retain zero-length substrings when splitting on | |
2453 whitespace, use `(split-string STRING split-string-default-separators)'. | |
2454 | |
2455 Modifies the match data; use `save-match-data' if necessary." | |
2456 (let ((keep-nulls (not (if separators omit-nulls t))) | |
2457 (rexp (or separators split-string-default-separators)) | |
2458 (start 0) | |
2459 notfirst | |
2460 (list nil)) | |
2461 (while (and (string-match rexp string | |
2462 (if (and notfirst | |
2463 (= start (match-beginning 0)) | |
2464 (< start (length string))) | |
2465 (1+ start) start)) | |
2466 (< start (length string))) | |
2467 (setq notfirst t) | |
2468 (if (or keep-nulls (< start (match-beginning 0))) | |
2469 (setq list | |
2470 (cons (substring string start (match-beginning 0)) | |
2471 list))) | |
2472 (setq start (match-end 0))) | |
2473 (if (or keep-nulls (< start (length string))) | |
2474 (setq list | |
2475 (cons (substring string start) | |
2476 list))) | |
2477 (nreverse list))) | |
2478 | |
2479 ;;;; Replacement in strings. | |
2480 | |
2481 (defun subst-char-in-string (fromchar tochar string &optional inplace) | |
2482 "Replace FROMCHAR with TOCHAR in STRING each time it occurs. | |
2483 Unless optional argument INPLACE is non-nil, return a new string." | |
2484 (let ((i (length string)) | |
2485 (newstr (if inplace string (copy-sequence string)))) | |
2486 (while (> i 0) | |
2487 (setq i (1- i)) | |
2488 (if (eq (aref newstr i) fromchar) | |
2489 (aset newstr i tochar))) | |
2490 newstr)) | |
2491 | |
2492 (defun replace-regexp-in-string (regexp rep string &optional | |
2493 fixedcase literal subexp start) | |
2494 "Replace all matches for REGEXP with REP in STRING. | |
2495 | |
2496 Return a new string containing the replacements. | |
2497 | |
2498 Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the | |
2499 arguments with the same names of function `replace-match'. If START | |
2500 is non-nil, start replacements at that index in STRING. | |
2501 | |
2502 REP is either a string used as the NEWTEXT arg of `replace-match' or a | |
2503 function. If it is a function, it is called with the actual text of each | |
2504 match, and its value is used as the replacement text. When REP is called, | |
2505 the match-data are the result of matching REGEXP against a substring | |
2506 of STRING. | |
2507 | |
2508 To replace only the first match (if any), make REGEXP match up to \\' | |
2509 and replace a sub-expression, e.g. | |
2510 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil nil 1) | |
2511 => \" bar foo\" | |
2512 " | |
2513 | |
2514 ;; To avoid excessive consing from multiple matches in long strings, | |
2515 ;; don't just call `replace-match' continually. Walk down the | |
2516 ;; string looking for matches of REGEXP and building up a (reversed) | |
2517 ;; list MATCHES. This comprises segments of STRING which weren't | |
2518 ;; matched interspersed with replacements for segments that were. | |
2519 ;; [For a `large' number of replacements it's more efficient to | |
2520 ;; operate in a temporary buffer; we can't tell from the function's | |
2521 ;; args whether to choose the buffer-based implementation, though it | |
2522 ;; might be reasonable to do so for long enough STRING.] | |
2523 (let ((l (length string)) | |
2524 (start (or start 0)) | |
2525 matches str mb me) | |
2526 (save-match-data | |
2527 (while (and (< start l) (string-match regexp string start)) | |
2528 (setq mb (match-beginning 0) | |
2529 me (match-end 0)) | |
2530 ;; If we matched the empty string, make sure we advance by one char | |
2531 (when (= me mb) (setq me (min l (1+ mb)))) | |
2532 ;; Generate a replacement for the matched substring. | |
2533 ;; Operate only on the substring to minimize string consing. | |
2534 ;; Set up match data for the substring for replacement; | |
2535 ;; presumably this is likely to be faster than munging the | |
2536 ;; match data directly in Lisp. | |
2537 (string-match regexp (setq str (substring string mb me))) | |
2538 (setq matches | |
2539 (cons (replace-match (if (stringp rep) | |
2540 rep | |
2541 (funcall rep (match-string 0 str))) | |
2542 fixedcase literal str subexp) | |
2543 (cons (substring string start mb) ; unmatched prefix | |
2544 matches))) | |
2545 (setq start me)) | |
2546 ;; Reconstruct a string from the pieces. | |
2547 (setq matches (cons (substring string start l) matches)) ; leftover | |
2548 (apply #'concat (nreverse matches))))) | |
2549 | |
2550 ;;;; invisibility specs | |
2551 | |
2552 (defun add-to-invisibility-spec (element) | |
2553 "Add ELEMENT to `buffer-invisibility-spec'. | |
2554 See documentation for `buffer-invisibility-spec' for the kind of elements | |
2555 that can be added." | |
2556 (if (eq buffer-invisibility-spec t) | |
2557 (setq buffer-invisibility-spec (list t))) | |
2558 (setq buffer-invisibility-spec | |
2559 (cons element buffer-invisibility-spec))) | |
2560 | |
2561 (defun remove-from-invisibility-spec (element) | |
2562 "Remove ELEMENT from `buffer-invisibility-spec'." | |
2563 (if (consp buffer-invisibility-spec) | |
2564 (setq buffer-invisibility-spec (delete element buffer-invisibility-spec)))) | |
2565 | |
2566 ;;;; Syntax tables. | |
2567 | |
2568 (defmacro with-syntax-table (table &rest body) | |
2569 "Evaluate BODY with syntax table of current buffer set to TABLE. | |
2570 The syntax table of the current buffer is saved, BODY is evaluated, and the | |
2571 saved table is restored, even in case of an abnormal exit. | |
2572 Value is what BODY returns." | |
2573 (declare (debug t)) | |
2574 (let ((old-table (make-symbol "table")) | |
2575 (old-buffer (make-symbol "buffer"))) | |
2576 `(let ((,old-table (syntax-table)) | |
2577 (,old-buffer (current-buffer))) | |
2578 (unwind-protect | |
2579 (progn | |
2580 (set-syntax-table ,table) | |
2581 ,@body) | |
2582 (save-current-buffer | |
2583 (set-buffer ,old-buffer) | |
2584 (set-syntax-table ,old-table)))))) | |
2585 | |
2586 (defun make-syntax-table (&optional oldtable) | |
2587 "Return a new syntax table. | |
2588 Create a syntax table which inherits from OLDTABLE (if non-nil) or | |
2589 from `standard-syntax-table' otherwise." | |
2590 (let ((table (make-char-table 'syntax-table nil))) | |
2591 (set-char-table-parent table (or oldtable (standard-syntax-table))) | |
2592 table)) | |
2593 | |
2594 (defun syntax-after (pos) | |
2595 "Return the raw syntax of the char after POS. | |
2596 If POS is outside the buffer's accessible portion, return nil." | |
2597 (unless (or (< pos (point-min)) (>= pos (point-max))) | |
2598 (let ((st (if parse-sexp-lookup-properties | |
2599 (get-char-property pos 'syntax-table)))) | |
2600 (if (consp st) st | |
2601 (aref (or st (syntax-table)) (char-after pos)))))) | |
2602 | |
2603 (defun syntax-class (syntax) | |
2604 "Return the syntax class part of the syntax descriptor SYNTAX. | |
2605 If SYNTAX is nil, return nil." | |
2606 (and syntax (logand (car syntax) 65535))) | |
2607 | |
2608 ;;;; Text clones | |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2609 |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2610 (defun text-clone-maintain (ol1 after beg end &optional len) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2611 "Propagate the changes made under the overlay OL1 to the other clones. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2612 This is used on the `modification-hooks' property of text clones." |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2613 (when (and after (not undo-in-progress) (overlay-start ol1)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2614 (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2615 (setq beg (max beg (+ (overlay-start ol1) margin))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2616 (setq end (min end (- (overlay-end ol1) margin))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2617 (when (<= beg end) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2618 (save-excursion |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2619 (when (overlay-get ol1 'text-clone-syntax) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2620 ;; Check content of the clone's text. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2621 (let ((cbeg (+ (overlay-start ol1) margin)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2622 (cend (- (overlay-end ol1) margin))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2623 (goto-char cbeg) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2624 (save-match-data |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2625 (if (not (re-search-forward |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2626 (overlay-get ol1 'text-clone-syntax) cend t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2627 ;; Mark the overlay for deletion. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2628 (overlay-put ol1 'text-clones nil) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2629 (when (< (match-end 0) cend) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2630 ;; Shrink the clone at its end. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2631 (setq end (min end (match-end 0))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2632 (move-overlay ol1 (overlay-start ol1) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2633 (+ (match-end 0) margin))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2634 (when (> (match-beginning 0) cbeg) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2635 ;; Shrink the clone at its beginning. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2636 (setq beg (max (match-beginning 0) beg)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2637 (move-overlay ol1 (- (match-beginning 0) margin) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2638 (overlay-end ol1))))))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2639 ;; Now go ahead and update the clones. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2640 (let ((head (- beg (overlay-start ol1))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2641 (tail (- (overlay-end ol1) end)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2642 (str (buffer-substring beg end)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2643 (nothing-left t) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2644 (inhibit-modification-hooks t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2645 (dolist (ol2 (overlay-get ol1 'text-clones)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2646 (let ((oe (overlay-end ol2))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2647 (unless (or (eq ol1 ol2) (null oe)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2648 (setq nothing-left nil) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2649 (let ((mod-beg (+ (overlay-start ol2) head))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2650 ;;(overlay-put ol2 'modification-hooks nil) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2651 (goto-char (- (overlay-end ol2) tail)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2652 (unless (> mod-beg (point)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2653 (save-excursion (insert str)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2654 (delete-region mod-beg (point))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2655 ;;(overlay-put ol2 'modification-hooks '(text-clone-maintain)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2656 )))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2657 (if nothing-left (delete-overlay ol1)))))))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2658 |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2659 (defun text-clone-create (start end &optional spreadp syntax) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2660 "Create a text clone of START...END at point. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2661 Text clones are chunks of text that are automatically kept identical: |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2662 changes done to one of the clones will be immediately propagated to the other. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2663 |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2664 The buffer's content at point is assumed to be already identical to |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2665 the one between START and END. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2666 If SYNTAX is provided it's a regexp that describes the possible text of |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2667 the clones; the clone will be shrunk or killed if necessary to ensure that |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2668 its text matches the regexp. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2669 If SPREADP is non-nil it indicates that text inserted before/after the |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2670 clone should be incorporated in the clone." |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2671 ;; To deal with SPREADP we can either use an overlay with `nil t' along |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2672 ;; with insert-(behind|in-front-of)-hooks or use a slightly larger overlay |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2673 ;; (with a one-char margin at each end) with `t nil'. |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2674 ;; We opted for a larger overlay because it behaves better in the case |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2675 ;; where the clone is reduced to the empty string (we want the overlay to |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2676 ;; stay when the clone's content is the empty string and we want to use |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2677 ;; `evaporate' to make sure those overlays get deleted when needed). |
47916 | 2678 ;; |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2679 (let* ((pt-end (+ (point) (- end start))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2680 (start-margin (if (or (not spreadp) (bobp) (<= start (point-min))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2681 0 1)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2682 (end-margin (if (or (not spreadp) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2683 (>= pt-end (point-max)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2684 (>= start (point-max))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2685 0 1)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2686 (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2687 (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2688 (dups (list ol1 ol2))) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2689 (overlay-put ol1 'modification-hooks '(text-clone-maintain)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2690 (when spreadp (overlay-put ol1 'text-clone-spreadp t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2691 (when syntax (overlay-put ol1 'text-clone-syntax syntax)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2692 ;;(overlay-put ol1 'face 'underline) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2693 (overlay-put ol1 'evaporate t) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2694 (overlay-put ol1 'text-clones dups) |
47916 | 2695 ;; |
40282
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2696 (overlay-put ol2 'modification-hooks '(text-clone-maintain)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2697 (when spreadp (overlay-put ol2 'text-clone-spreadp t)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2698 (when syntax (overlay-put ol2 'text-clone-syntax syntax)) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2699 ;;(overlay-put ol2 'face 'underline) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2700 (overlay-put ol2 'evaporate t) |
7f05eff77ea2
(delay-mode-hooks, delayed-mode-hooks, run-mode-hooks): New vars and functions.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
39725
diff
changeset
|
2701 (overlay-put ol2 'text-clones dups))) |
88155 | 2702 |
2703 ;;;; Mail user agents. | |
2704 | |
2705 ;; Here we include just enough for other packages to be able | |
2706 ;; to define them. | |
44422
5f7f8b191a8c
(play-sound): Move here from simple.el.
Pavel Janík <Pavel@Janik.cz>
parents:
44285
diff
changeset
|
2707 |
47406
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2708 (defun define-mail-user-agent (symbol composefunc sendfunc |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2709 &optional abortfunc hookvar) |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2710 "Define a symbol to identify a mail-sending package for `mail-user-agent'. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2711 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2712 SYMBOL can be any Lisp symbol. Its function definition and/or |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2713 value as a variable do not matter for this usage; we use only certain |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2714 properties on its property list, to encode the rest of the arguments. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2715 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2716 COMPOSEFUNC is program callable function that composes an outgoing |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2717 mail message buffer. This function should set up the basics of the |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2718 buffer without requiring user interaction. It should populate the |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2719 standard mail headers, leaving the `to:' and `subject:' headers blank |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2720 by default. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2721 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2722 COMPOSEFUNC should accept several optional arguments--the same |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2723 arguments that `compose-mail' takes. See that function's documentation. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2724 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2725 SENDFUNC is the command a user would run to send the message. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2726 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2727 Optional ABORTFUNC is the command a user would run to abort the |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2728 message. For mail packages that don't have a separate abort function, |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2729 this can be `kill-buffer' (the equivalent of omitting this argument). |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2730 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2731 Optional HOOKVAR is a hook variable that gets run before the message |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2732 is actually sent. Callers that use the `mail-user-agent' may |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2733 install a hook function temporarily on this hook variable. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2734 If HOOKVAR is nil, `mail-send-hook' is used. |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2735 |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2736 The properties used on SYMBOL are `composefunc', `sendfunc', |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2737 `abortfunc', and `hookvar'." |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2738 (put symbol 'composefunc composefunc) |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2739 (put symbol 'sendfunc sendfunc) |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2740 (put symbol 'abortfunc (or abortfunc 'kill-buffer)) |
fbd7a9a8682c
(define-mail-user-agent): Moved from simple.el.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
47355
diff
changeset
|
2741 (put symbol 'hookvar (or hookvar 'mail-send-hook))) |
88155 | 2742 |
2743 ;;;; Progress reporters. | |
2744 | |
2745 ;; Progress reporter has the following structure: | |
2746 ;; | |
2747 ;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME | |
2748 ;; MIN-VALUE | |
2749 ;; MAX-VALUE | |
2750 ;; MESSAGE | |
2751 ;; MIN-CHANGE | |
2752 ;; MIN-TIME]) | |
2753 ;; | |
2754 ;; This weirdeness is for optimization reasons: we want | |
2755 ;; `progress-reporter-update' to be as fast as possible, so | |
2756 ;; `(car reporter)' is better than `(aref reporter 0)'. | |
2757 ;; | |
2758 ;; NEXT-UPDATE-TIME is a float. While `float-time' loses a couple | |
2759 ;; digits of precision, it doesn't really matter here. On the other | |
2760 ;; hand, it greatly simplifies the code. | |
2761 | |
2762 (defsubst progress-reporter-update (reporter value) | |
2763 "Report progress of an operation in the echo area. | |
2764 However, if the change since last echo area update is too small | |
2765 or not enough time has passed, then do nothing (see | |
2766 `make-progress-reporter' for details). | |
2767 | |
2768 First parameter, REPORTER, should be the result of a call to | |
2769 `make-progress-reporter'. Second, VALUE, determines the actual | |
2770 progress of operation; it must be between MIN-VALUE and MAX-VALUE | |
2771 as passed to `make-progress-reporter'. | |
2772 | |
2773 This function is very inexpensive, you may not bother how often | |
2774 you call it." | |
2775 (when (>= value (car reporter)) | |
2776 (progress-reporter-do-update reporter value))) | |
2777 | |
2778 (defun make-progress-reporter (message min-value max-value | |
2779 &optional current-value | |
2780 min-change min-time) | |
2781 "Return progress reporter object to be used with `progress-reporter-update'. | |
2782 | |
2783 MESSAGE is shown in the echo area. When at least 1% of operation | |
2784 is complete, the exact percentage will be appended to the | |
2785 MESSAGE. When you call `progress-reporter-done', word \"done\" | |
2786 is printed after the MESSAGE. You can change MESSAGE of an | |
2787 existing progress reporter with `progress-reporter-force-update'. | |
2788 | |
2789 MIN-VALUE and MAX-VALUE designate starting (0% complete) and | |
2790 final (100% complete) states of operation. The latter should be | |
2791 larger; if this is not the case, then simply negate all values. | |
2792 Optional CURRENT-VALUE specifies the progress by the moment you | |
2793 call this function. You should omit it or set it to nil in most | |
2794 cases since it defaults to MIN-VALUE. | |
2795 | |
2796 Optional MIN-CHANGE determines the minimal change in percents to | |
2797 report (default is 1%.) Optional MIN-TIME specifies the minimal | |
2798 time before echo area updates (default is 0.2 seconds.) If | |
2799 `float-time' function is not present, then time is not tracked | |
2800 at all. If OS is not capable of measuring fractions of seconds, | |
2801 then this parameter is effectively rounded up." | |
2802 | |
2803 (unless min-time | |
2804 (setq min-time 0.2)) | |
2805 (let ((reporter | |
2806 (cons min-value ;; Force a call to `message' now | |
2807 (vector (if (and (fboundp 'float-time) | |
2808 (>= min-time 0.02)) | |
2809 (float-time) nil) | |
2810 min-value | |
2811 max-value | |
2812 message | |
2813 (if min-change (max (min min-change 50) 1) 1) | |
2814 min-time)))) | |
2815 (progress-reporter-update reporter (or current-value min-value)) | |
2816 reporter)) | |
2817 | |
2818 (defun progress-reporter-force-update (reporter value &optional new-message) | |
2819 "Report progress of an operation in the echo area unconditionally. | |
2820 | |
2821 First two parameters are the same as for | |
2822 `progress-reporter-update'. Optional NEW-MESSAGE allows you to | |
2823 change the displayed message." | |
2824 (let ((parameters (cdr reporter))) | |
2825 (when new-message | |
2826 (aset parameters 3 new-message)) | |
2827 (when (aref parameters 0) | |
2828 (aset parameters 0 (float-time))) | |
2829 (progress-reporter-do-update reporter value))) | |
2830 | |
2831 (defun progress-reporter-do-update (reporter value) | |
2832 (let* ((parameters (cdr reporter)) | |
2833 (min-value (aref parameters 1)) | |
2834 (max-value (aref parameters 2)) | |
2835 (one-percent (/ (- max-value min-value) 100.0)) | |
2836 (percentage (if (= max-value min-value) | |
2837 0 | |
2838 (truncate (/ (- value min-value) one-percent)))) | |
2839 (update-time (aref parameters 0)) | |
2840 (current-time (float-time)) | |
2841 (enough-time-passed | |
2842 ;; See if enough time has passed since the last update. | |
2843 (or (not update-time) | |
2844 (when (>= current-time update-time) | |
2845 ;; Calculate time for the next update | |
2846 (aset parameters 0 (+ update-time (aref parameters 5))))))) | |
2847 ;; | |
2848 ;; Calculate NEXT-UPDATE-VALUE. If we are not going to print | |
2849 ;; message this time because not enough time has passed, then use | |
2850 ;; 1 instead of MIN-CHANGE. This makes delays between echo area | |
2851 ;; updates closer to MIN-TIME. | |
2852 (setcar reporter | |
2853 (min (+ min-value (* (+ percentage | |
2854 (if enough-time-passed | |
2855 (aref parameters 4) ;; MIN-CHANGE | |
2856 1)) | |
2857 one-percent)) | |
2858 max-value)) | |
2859 (when (integerp value) | |
2860 (setcar reporter (ceiling (car reporter)))) | |
2861 ;; | |
2862 ;; Only print message if enough time has passed | |
2863 (when enough-time-passed | |
2864 (if (> percentage 0) | |
2865 (message "%s%d%%" (aref parameters 3) percentage) | |
2866 (message "%s" (aref parameters 3)))))) | |
2867 | |
2868 (defun progress-reporter-done (reporter) | |
2869 "Print reporter's message followed by word \"done\" in echo area." | |
2870 (message "%sdone" (aref (cdr reporter) 3))) | |
2871 | |
2872 (defmacro dotimes-with-progress-reporter (spec message &rest body) | |
2873 "Loop a certain number of times and report progress in the echo area. | |
2874 Evaluate BODY with VAR bound to successive integers running from | |
2875 0, inclusive, to COUNT, exclusive. Then evaluate RESULT to get | |
2876 the return value (nil if RESULT is omitted). | |
2877 | |
2878 At each iteration MESSAGE followed by progress percentage is | |
2879 printed in the echo area. After the loop is finished, MESSAGE | |
2880 followed by word \"done\" is printed. This macro is a | |
2881 convenience wrapper around `make-progress-reporter' and friends. | |
2882 | |
2883 \(fn (VAR COUNT [RESULT]) MESSAGE BODY...)" | |
2884 (declare (indent 2) (debug ((symbolp form &optional form) form body))) | |
2885 (let ((temp (make-symbol "--dotimes-temp--")) | |
2886 (temp2 (make-symbol "--dotimes-temp2--")) | |
2887 (start 0) | |
2888 (end (nth 1 spec))) | |
2889 `(let ((,temp ,end) | |
2890 (,(car spec) ,start) | |
2891 (,temp2 (make-progress-reporter ,message ,start ,end))) | |
2892 (while (< ,(car spec) ,temp) | |
2893 ,@body | |
2894 (progress-reporter-update ,temp2 | |
2895 (setq ,(car spec) (1+ ,(car spec))))) | |
2896 (progress-reporter-done ,temp2) | |
2897 nil ,@(cdr (cdr spec))))) | |
2898 | |
2899 | |
2900 ;;;; Comparing version strings. | |
2901 | |
2902 (defvar version-separator "." | |
2903 "*Specify the string used to separate the version elements. | |
2904 | |
2905 Usually the separator is \".\", but it can be any other string.") | |
2906 | |
2907 | |
2908 (defvar version-regexp-alist | |
2909 '(("^[-_+ ]?a\\(lpha\\)?$" . -3) | |
2910 ("^[-_+]$" . -3) ; treat "1.2.3-20050920" and "1.2-3" as alpha releases | |
2911 ("^[-_+ ]cvs$" . -3) ; treat "1.2.3-CVS" as alpha release | |
2912 ("^[-_+ ]?b\\(eta\\)?$" . -2) | |
2913 ("^[-_+ ]?\\(pre\\|rc\\)$" . -1)) | |
2914 "*Specify association between non-numeric version part and a priority. | |
2915 | |
2916 This association is used to handle version string like \"1.0pre2\", | |
2917 \"0.9alpha1\", etc. It's used by `version-to-list' (which see) to convert the | |
2918 non-numeric part to an integer. For example: | |
2919 | |
2920 String Version Integer List Version | |
2921 \"1.0pre2\" (1 0 -1 2) | |
2922 \"1.0PRE2\" (1 0 -1 2) | |
2923 \"22.8beta3\" (22 8 -2 3) | |
2924 \"22.8 Beta3\" (22 8 -2 3) | |
2925 \"0.9alpha1\" (0 9 -3 1) | |
2926 \"0.9AlphA1\" (0 9 -3 1) | |
2927 \"0.9 alpha\" (0 9 -3) | |
2928 | |
2929 Each element has the following form: | |
2930 | |
2931 (REGEXP . PRIORITY) | |
2932 | |
2933 Where: | |
2934 | |
2935 REGEXP regexp used to match non-numeric part of a version string. | |
2936 It should begin with a `^' anchor and end with a `$' to | |
2937 prevent false hits. Letter-case is ignored while matching | |
2938 REGEXP. | |
2939 | |
2940 PRIORITY negative integer which indicate the non-numeric priority.") | |
2941 | |
2942 | |
2943 (defun version-to-list (ver) | |
2944 "Convert version string VER into an integer list. | |
2945 | |
2946 The version syntax is given by the following EBNF: | |
2947 | |
2948 VERSION ::= NUMBER ( SEPARATOR NUMBER )*. | |
2949 | |
2950 NUMBER ::= (0|1|2|3|4|5|6|7|8|9)+. | |
2951 | |
2952 SEPARATOR ::= `version-separator' (which see) | |
2953 | `version-regexp-alist' (which see). | |
2954 | |
2955 The NUMBER part is optional if SEPARATOR is a match for an element | |
2956 in `version-regexp-alist'. | |
2957 | |
2958 As an example of valid version syntax: | |
2959 | |
2960 1.0pre2 1.0.7.5 22.8beta3 0.9alpha1 6.9.30Beta | |
2961 | |
2962 As an example of invalid version syntax: | |
2963 | |
2964 1.0prepre2 1.0..7.5 22.8X3 alpha3.2 .5 | |
2965 | |
2966 As an example of version convertion: | |
2967 | |
2968 String Version Integer List Version | |
2969 \"1.0.7.5\" (1 0 7 5) | |
2970 \"1.0pre2\" (1 0 -1 2) | |
2971 \"1.0PRE2\" (1 0 -1 2) | |
2972 \"22.8beta3\" (22 8 -2 3) | |
2973 \"22.8Beta3\" (22 8 -2 3) | |
2974 \"0.9alpha1\" (0 9 -3 1) | |
2975 \"0.9AlphA1\" (0 9 -3 1) | |
2976 \"0.9alpha\" (0 9 -3) | |
2977 | |
2978 See documentation for `version-separator' and `version-regexp-alist'." | |
2979 (or (and (stringp ver) (> (length ver) 0)) | |
2980 (error "Invalid version string: '%s'" ver)) | |
2981 ;; Change .x.y to 0.x.y | |
2982 (if (and (>= (length ver) (length version-separator)) | |
2983 (string-equal (substring ver 0 (length version-separator)) | |
2984 version-separator)) | |
2985 (setq ver (concat "0" ver))) | |
2986 (save-match-data | |
2987 (let ((i 0) | |
2988 (case-fold-search t) ; ignore case in matching | |
2989 lst s al) | |
2990 (while (and (setq s (string-match "[0-9]+" ver i)) | |
2991 (= s i)) | |
2992 ;; handle numeric part | |
2993 (setq lst (cons (string-to-number (substring ver i (match-end 0))) | |
2994 lst) | |
2995 i (match-end 0)) | |
2996 ;; handle non-numeric part | |
2997 (when (and (setq s (string-match "[^0-9]+" ver i)) | |
2998 (= s i)) | |
2999 (setq s (substring ver i (match-end 0)) | |
3000 i (match-end 0)) | |
3001 ;; handle alpha, beta, pre, etc. separator | |
3002 (unless (string= s version-separator) | |
3003 (setq al version-regexp-alist) | |
3004 (while (and al (not (string-match (caar al) s))) | |
3005 (setq al (cdr al))) | |
3006 (or al (error "Invalid version syntax: '%s'" ver)) | |
3007 (setq lst (cons (cdar al) lst))))) | |
3008 (if (null lst) | |
3009 (error "Invalid version syntax: '%s'" ver) | |
3010 (nreverse lst))))) | |
3011 | |
3012 | |
3013 (defun version-list-< (l1 l2) | |
3014 "Return t if integer list L1 is lesser than L2. | |
3015 | |
3016 Note that integer list (1) is equal to (1 0), (1 0 0), (1 0 0 0), | |
3017 etc. That is, the trailing zeroes are irrelevant. Also, integer | |
3018 list (1) is greater than (1 -1) which is greater than (1 -2) | |
3019 which is greater than (1 -3)." | |
3020 (while (and l1 l2 (= (car l1) (car l2))) | |
3021 (setq l1 (cdr l1) | |
3022 l2 (cdr l2))) | |
3023 (cond | |
3024 ;; l1 not null and l2 not null | |
3025 ((and l1 l2) (< (car l1) (car l2))) | |
3026 ;; l1 null and l2 null ==> l1 length = l2 length | |
3027 ((and (null l1) (null l2)) nil) | |
3028 ;; l1 not null and l2 null ==> l1 length > l2 length | |
3029 (l1 (< (version-list-not-zero l1) 0)) | |
3030 ;; l1 null and l2 not null ==> l2 length > l1 length | |
3031 (t (< 0 (version-list-not-zero l2))))) | |
3032 | |
3033 | |
3034 (defun version-list-= (l1 l2) | |
3035 "Return t if integer list L1 is equal to L2. | |
3036 | |
3037 Note that integer list (1) is equal to (1 0), (1 0 0), (1 0 0 0), | |
3038 etc. That is, the trailing zeroes are irrelevant. Also, integer | |
3039 list (1) is greater than (1 -1) which is greater than (1 -2) | |
3040 which is greater than (1 -3)." | |
3041 (while (and l1 l2 (= (car l1) (car l2))) | |
3042 (setq l1 (cdr l1) | |
3043 l2 (cdr l2))) | |
3044 (cond | |
3045 ;; l1 not null and l2 not null | |
3046 ((and l1 l2) nil) | |
3047 ;; l1 null and l2 null ==> l1 length = l2 length | |
3048 ((and (null l1) (null l2))) | |
3049 ;; l1 not null and l2 null ==> l1 length > l2 length | |
3050 (l1 (zerop (version-list-not-zero l1))) | |
3051 ;; l1 null and l2 not null ==> l2 length > l1 length | |
3052 (t (zerop (version-list-not-zero l2))))) | |
3053 | |
3054 | |
3055 (defun version-list-<= (l1 l2) | |
3056 "Return t if integer list L1 is lesser than or equal to L2. | |
3057 | |
3058 Note that integer list (1) is equal to (1 0), (1 0 0), (1 0 0 0), | |
3059 etc. That is, the trailing zeroes are irrelevant. Also, integer | |
3060 list (1) is greater than (1 -1) which is greater than (1 -2) | |
3061 which is greater than (1 -3)." | |
3062 (while (and l1 l2 (= (car l1) (car l2))) | |
3063 (setq l1 (cdr l1) | |
3064 l2 (cdr l2))) | |
3065 (cond | |
3066 ;; l1 not null and l2 not null | |
3067 ((and l1 l2) (< (car l1) (car l2))) | |
3068 ;; l1 null and l2 null ==> l1 length = l2 length | |
3069 ((and (null l1) (null l2))) | |
3070 ;; l1 not null and l2 null ==> l1 length > l2 length | |
3071 (l1 (<= (version-list-not-zero l1) 0)) | |
3072 ;; l1 null and l2 not null ==> l2 length > l1 length | |
3073 (t (<= 0 (version-list-not-zero l2))))) | |
3074 | |
3075 (defun version-list-not-zero (lst) | |
3076 "Return the first non-zero element of integer list LST. | |
3077 | |
3078 If all LST elements are zeroes or LST is nil, return zero." | |
3079 (while (and lst (zerop (car lst))) | |
3080 (setq lst (cdr lst))) | |
3081 (if lst | |
3082 (car lst) | |
3083 ;; there is no element different of zero | |
3084 0)) | |
3085 | |
3086 | |
3087 (defun version< (v1 v2) | |
3088 "Return t if version V1 is lesser than V2. | |
3089 | |
3090 Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\", | |
3091 etc. That is, the trailing \".0\"s are irrelevant. Also, version string \"1\" | |
3092 is greater than \"1pre\" which is greater than \"1beta\" which is greater than | |
3093 \"1alpha\"." | |
3094 (version-list-< (version-to-list v1) (version-to-list v2))) | |
3095 | |
3096 | |
3097 (defun version<= (v1 v2) | |
3098 "Return t if version V1 is lesser than or equal to V2. | |
3099 | |
3100 Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\", | |
3101 etc. That is, the trailing \".0\"s are irrelevant. Also, version string \"1\" | |
3102 is greater than \"1pre\" which is greater than \"1beta\" which is greater than | |
3103 \"1alpha\"." | |
3104 (version-list-<= (version-to-list v1) (version-to-list v2))) | |
3105 | |
3106 (defun version= (v1 v2) | |
3107 "Return t if version V1 is equal to V2. | |
3108 | |
3109 Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\", | |
3110 etc. That is, the trailing \".0\"s are irrelevant. Also, version string \"1\" | |
3111 is greater than \"1pre\" which is greater than \"1beta\" which is greater than | |
3112 \"1alpha\"." | |
3113 (version-list-= (version-to-list v1) (version-to-list v2))) | |
3114 | |
3115 | |
3116 | |
3117 ;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc | |
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
779
diff
changeset
|
3118 ;;; subr.el ends here |