146
|
1 /* Primitives for word-abbrev mode.
|
39584
|
2 Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001
|
|
3 Free Software Foundation, Inc.
|
146
|
4
|
|
5 This file is part of GNU Emacs.
|
|
6
|
|
7 GNU Emacs is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
1023
|
9 the Free Software Foundation; either version 2, or (at your option)
|
146
|
10 any later version.
|
|
11
|
|
12 GNU Emacs is distributed in the hope that it will be useful,
|
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 GNU General Public License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GNU Emacs; see the file COPYING. If not, write to
|
14186
|
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
20 Boston, MA 02111-1307, USA. */
|
146
|
21
|
|
22
|
4696
|
23 #include <config.h>
|
146
|
24 #include <stdio.h>
|
39988
|
25
|
146
|
26 #include "lisp.h"
|
|
27 #include "commands.h"
|
|
28 #include "buffer.h"
|
|
29 #include "window.h"
|
23715
|
30 #include "charset.h"
|
9054
|
31 #include "syntax.h"
|
146
|
32
|
|
33 /* An abbrev table is an obarray.
|
|
34 Each defined abbrev is represented by a symbol in that obarray
|
|
35 whose print name is the abbreviation.
|
|
36 The symbol's value is a string which is the expansion.
|
|
37 If its function definition is non-nil, it is called
|
|
38 after the expansion is done.
|
|
39 The plist slot of the abbrev symbol is its usage count. */
|
|
40
|
|
41 /* List of all abbrev-table name symbols:
|
|
42 symbols whose values are abbrev tables. */
|
|
43
|
|
44 Lisp_Object Vabbrev_table_name_list;
|
|
45
|
|
46 /* The table of global abbrevs. These are in effect
|
|
47 in any buffer in which abbrev mode is turned on. */
|
|
48
|
|
49 Lisp_Object Vglobal_abbrev_table;
|
|
50
|
|
51 /* The local abbrev table used by default (in Fundamental Mode buffers) */
|
|
52
|
|
53 Lisp_Object Vfundamental_mode_abbrev_table;
|
|
54
|
|
55 /* Set nonzero when an abbrev definition is changed */
|
|
56
|
|
57 int abbrevs_changed;
|
|
58
|
|
59 int abbrev_all_caps;
|
|
60
|
|
61 /* Non-nil => use this location as the start of abbrev to expand
|
|
62 (rather than taking the word before point as the abbrev) */
|
|
63
|
|
64 Lisp_Object Vabbrev_start_location;
|
|
65
|
|
66 /* Buffer that Vabbrev_start_location applies to */
|
|
67 Lisp_Object Vabbrev_start_location_buffer;
|
|
68
|
|
69 /* The symbol representing the abbrev most recently expanded */
|
|
70
|
|
71 Lisp_Object Vlast_abbrev;
|
|
72
|
|
73 /* A string for the actual text of the abbrev most recently expanded.
|
|
74 This has more info than Vlast_abbrev since case is significant. */
|
|
75
|
|
76 Lisp_Object Vlast_abbrev_text;
|
|
77
|
|
78 /* Character address of start of last abbrev expanded */
|
|
79
|
43713
f92c4d87863a
Change defvar_int def and vars to use EMACS_INT instead of just int.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
80 EMACS_INT last_abbrev_point;
|
146
|
81
|
458
|
82 /* Hook to run before expanding any abbrev. */
|
|
83
|
|
84 Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
|
42388
|
85
|
|
86 Lisp_Object Qsystem_type, Qcount;
|
146
|
87
|
|
88 DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
|
39988
|
89 doc: /* Create a new, empty abbrev table object. */)
|
|
90 ()
|
146
|
91 {
|
44739
|
92 /* The value 59 is arbitrary chosen prime number. */
|
146
|
93 return Fmake_vector (make_number (59), make_number (0));
|
|
94 }
|
|
95
|
|
96 DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0,
|
39988
|
97 doc: /* Undefine all abbrevs in abbrev table TABLE, leaving it empty. */)
|
|
98 (table)
|
146
|
99 Lisp_Object table;
|
|
100 {
|
|
101 int i, size;
|
|
102
|
40656
|
103 CHECK_VECTOR (table);
|
146
|
104 size = XVECTOR (table)->size;
|
|
105 abbrevs_changed = 1;
|
|
106 for (i = 0; i < size; i++)
|
|
107 XVECTOR (table)->contents[i] = make_number (0);
|
|
108 return Qnil;
|
|
109 }
|
|
110
|
42388
|
111 DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 6, 0,
|
39988
|
112 doc: /* Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK.
|
39960
|
113 NAME must be a string.
|
|
114 EXPANSION should usually be a string.
|
|
115 To undefine an abbrev, define it with EXPANSION = nil.
|
|
116 If HOOK is non-nil, it should be a function of no arguments;
|
|
117 it is called after EXPANSION is inserted.
|
|
118 If EXPANSION is not a string, the abbrev is a special one,
|
|
119 which does not expand in the usual way but only runs HOOK.
|
42388
|
120
|
|
121 COUNT, if specified, gives the initial value for the abbrev's
|
|
122 usage-count, which is incremented each time the abbrev is used.
|
|
123 \(The default is zero.)
|
|
124
|
|
125 SYSTEM-FLAG, if non-nil, says that this is a "system" abbreviation
|
|
126 which should not be saved in the user's abbreviation file. */)
|
|
127 (table, name, expansion, hook, count, system_flag)
|
|
128 Lisp_Object table, name, expansion, hook, count, system_flag;
|
146
|
129 {
|
|
130 Lisp_Object sym, oexp, ohook, tem;
|
40656
|
131 CHECK_VECTOR (table);
|
|
132 CHECK_STRING (name);
|
16565
|
133
|
484
|
134 if (NILP (count))
|
146
|
135 count = make_number (0);
|
|
136 else
|
40656
|
137 CHECK_NUMBER (count);
|
146
|
138
|
|
139 sym = Fintern (name, table);
|
|
140
|
39584
|
141 oexp = SYMBOL_VALUE (sym);
|
146
|
142 ohook = XSYMBOL (sym)->function;
|
|
143 if (!((EQ (oexp, expansion)
|
9140
3e7833a8e16f
(Fdefine_abbrev, Fexpand_abbrev, Funexpand_abbrev): Use type test macros.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
144 || (STRINGP (oexp) && STRINGP (expansion)
|
484
|
145 && (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
|
146
|
146 &&
|
|
147 (EQ (ohook, hook)
|
42388
|
148 || (tem = Fequal (ohook, hook), !NILP (tem))))
|
|
149 && NILP (system_flag))
|
146
|
150 abbrevs_changed = 1;
|
|
151
|
|
152 Fset (sym, expansion);
|
|
153 Ffset (sym, hook);
|
42388
|
154
|
|
155 if (! NILP (system_flag))
|
|
156 Fsetplist (sym, list4 (Qcount, count, Qsystem_type, system_flag));
|
|
157 else
|
|
158 Fsetplist (sym, count);
|
146
|
159
|
|
160 return name;
|
|
161 }
|
|
162
|
|
163 DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2,
|
39960
|
164 "sDefine global abbrev: \nsExpansion for %s: ",
|
39988
|
165 doc: /* Define ABBREV as a global abbreviation for EXPANSION. */)
|
|
166 (abbrev, expansion)
|
14059
|
167 Lisp_Object abbrev, expansion;
|
146
|
168 {
|
14059
|
169 Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
|
42388
|
170 expansion, Qnil, make_number (0), Qnil);
|
14059
|
171 return abbrev;
|
146
|
172 }
|
|
173
|
|
174 DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
|
39960
|
175 "sDefine mode abbrev: \nsExpansion for %s: ",
|
39988
|
176 doc: /* Define ABBREV as a mode-specific abbreviation for EXPANSION. */)
|
|
177 (abbrev, expansion)
|
14059
|
178 Lisp_Object abbrev, expansion;
|
146
|
179 {
|
484
|
180 if (NILP (current_buffer->abbrev_table))
|
146
|
181 error ("Major mode has no abbrev table");
|
|
182
|
14059
|
183 Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
|
42388
|
184 expansion, Qnil, make_number (0), Qnil);
|
14059
|
185 return abbrev;
|
146
|
186 }
|
|
187
|
|
188 DEFUN ("abbrev-symbol", Fabbrev_symbol, Sabbrev_symbol, 1, 2, 0,
|
39988
|
189 doc: /* Return the symbol representing abbrev named ABBREV.
|
39960
|
190 This symbol's name is ABBREV, but it is not the canonical symbol of that name;
|
|
191 it is interned in an abbrev-table rather than the normal obarray.
|
|
192 The value is nil if that abbrev is not defined.
|
|
193 Optional second arg TABLE is abbrev table to look it up in.
|
39988
|
194 The default is to try buffer's mode-specific abbrev table, then global table. */)
|
|
195 (abbrev, table)
|
146
|
196 Lisp_Object abbrev, table;
|
|
197 {
|
|
198 Lisp_Object sym;
|
40656
|
199 CHECK_STRING (abbrev);
|
484
|
200 if (!NILP (table))
|
146
|
201 sym = Fintern_soft (abbrev, table);
|
|
202 else
|
|
203 {
|
|
204 sym = Qnil;
|
484
|
205 if (!NILP (current_buffer->abbrev_table))
|
146
|
206 sym = Fintern_soft (abbrev, current_buffer->abbrev_table);
|
39584
|
207 if (NILP (SYMBOL_VALUE (sym)))
|
146
|
208 sym = Qnil;
|
484
|
209 if (NILP (sym))
|
146
|
210 sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
|
|
211 }
|
39584
|
212 if (NILP (SYMBOL_VALUE (sym)))
|
|
213 return Qnil;
|
146
|
214 return sym;
|
|
215 }
|
|
216
|
|
217 DEFUN ("abbrev-expansion", Fabbrev_expansion, Sabbrev_expansion, 1, 2, 0,
|
39988
|
218 doc: /* Return the string that ABBREV expands into in the current buffer.
|
39960
|
219 Optionally specify an abbrev table as second arg;
|
39988
|
220 then ABBREV is looked up in that table only. */)
|
|
221 (abbrev, table)
|
146
|
222 Lisp_Object abbrev, table;
|
|
223 {
|
|
224 Lisp_Object sym;
|
|
225 sym = Fabbrev_symbol (abbrev, table);
|
484
|
226 if (NILP (sym)) return sym;
|
146
|
227 return Fsymbol_value (sym);
|
|
228 }
|
|
229
|
|
230 /* Expand the word before point, if it is an abbrev.
|
|
231 Returns 1 if an expansion is done. */
|
|
232
|
|
233 DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "",
|
39988
|
234 doc: /* Expand the abbrev before point, if there is an abbrev there.
|
39960
|
235 Effective when explicitly called even when `abbrev-mode' is nil.
|
39988
|
236 Returns the abbrev symbol, if expansion took place. */)
|
|
237 ()
|
146
|
238 {
|
|
239 register char *buffer, *p;
|
20529
|
240 int wordstart, wordend;
|
46965
|
241 register int wordstart_byte, wordend_byte, idx, idx_byte;
|
146
|
242 int whitecnt;
|
|
243 int uccount = 0, lccount = 0;
|
|
244 register Lisp_Object sym;
|
|
245 Lisp_Object expansion, hook, tem;
|
1021
|
246 Lisp_Object value;
|
46965
|
247 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
|
146
|
248
|
16747
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
249 value = Qnil;
|
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
250
|
41522
|
251 Frun_hooks (1, &Qpre_abbrev_expand_hook);
|
458
|
252
|
11503
|
253 wordstart = 0;
|
16747
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
254 if (!(BUFFERP (Vabbrev_start_location_buffer)
|
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
255 && XBUFFER (Vabbrev_start_location_buffer) == current_buffer))
|
146
|
256 Vabbrev_start_location = Qnil;
|
484
|
257 if (!NILP (Vabbrev_start_location))
|
146
|
258 {
|
|
259 tem = Vabbrev_start_location;
|
40656
|
260 CHECK_NUMBER_COERCE_MARKER (tem);
|
146
|
261 wordstart = XINT (tem);
|
|
262 Vabbrev_start_location = Qnil;
|
11503
|
263 if (wordstart < BEGV || wordstart > ZV)
|
|
264 wordstart = 0;
|
20529
|
265 if (wordstart && wordstart != ZV)
|
|
266 {
|
|
267 wordstart_byte = CHAR_TO_BYTE (wordstart);
|
|
268 if (FETCH_BYTE (wordstart_byte) == '-')
|
|
269 del_range (wordstart, wordstart + 1);
|
|
270 }
|
146
|
271 }
|
11503
|
272 if (!wordstart)
|
16039
|
273 wordstart = scan_words (PT, -1);
|
146
|
274
|
|
275 if (!wordstart)
|
1021
|
276 return value;
|
146
|
277
|
20529
|
278 wordstart_byte = CHAR_TO_BYTE (wordstart);
|
146
|
279 wordend = scan_words (wordstart, 1);
|
|
280 if (!wordend)
|
1021
|
281 return value;
|
146
|
282
|
16039
|
283 if (wordend > PT)
|
|
284 wordend = PT;
|
20529
|
285
|
|
286 wordend_byte = CHAR_TO_BYTE (wordend);
|
16039
|
287 whitecnt = PT - wordend;
|
146
|
288 if (wordend <= wordstart)
|
1021
|
289 return value;
|
146
|
290
|
20529
|
291 p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
|
146
|
292
|
46965
|
293 for (idx = wordstart, idx_byte = wordstart_byte; idx < wordend; )
|
146
|
294 {
|
46965
|
295 register int c;
|
|
296
|
|
297 if (multibyte)
|
|
298 {
|
|
299 FETCH_CHAR_ADVANCE (c, idx, idx_byte);
|
|
300 }
|
|
301 else
|
|
302 {
|
|
303 c = FETCH_BYTE (idx_byte);
|
|
304 idx++, idx_byte++;
|
|
305 }
|
49600
|
306
|
146
|
307 if (UPPERCASEP (c))
|
|
308 c = DOWNCASE (c), uccount++;
|
|
309 else if (! NOCASEP (c))
|
|
310 lccount++;
|
46965
|
311 if (multibyte)
|
|
312 p += CHAR_STRING (c, p);
|
|
313 else
|
|
314 *p++ = c;
|
146
|
315 }
|
|
316
|
9140
3e7833a8e16f
(Fdefine_abbrev, Fexpand_abbrev, Funexpand_abbrev): Use type test macros.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
317 if (VECTORP (current_buffer->abbrev_table))
|
20590
|
318 sym = oblookup (current_buffer->abbrev_table, buffer,
|
46965
|
319 wordend - wordstart, p - buffer);
|
146
|
320 else
|
9294
|
321 XSETFASTINT (sym, 0);
|
42388
|
322
|
39584
|
323 if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
|
20590
|
324 sym = oblookup (Vglobal_abbrev_table, buffer,
|
46965
|
325 wordend - wordstart, p - buffer);
|
39584
|
326 if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
|
1021
|
327 return value;
|
146
|
328
|
|
329 if (INTERACTIVE && !EQ (minibuf_window, selected_window))
|
|
330 {
|
11554
|
331 /* Add an undo boundary, in case we are doing this for
|
|
332 a self-inserting command which has avoided making one so far. */
|
146
|
333 SET_PT (wordend);
|
|
334 Fundo_boundary ();
|
|
335 }
|
16565
|
336
|
146
|
337 Vlast_abbrev_text
|
|
338 = Fbuffer_substring (make_number (wordstart), make_number (wordend));
|
|
339
|
16565
|
340 /* Now sym is the abbrev symbol. */
|
146
|
341 Vlast_abbrev = sym;
|
16747
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
342 value = sym;
|
146
|
343 last_abbrev_point = wordstart;
|
|
344
|
42388
|
345 /* Increment use count. */
|
9140
3e7833a8e16f
(Fdefine_abbrev, Fexpand_abbrev, Funexpand_abbrev): Use type test macros.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
346 if (INTEGERP (XSYMBOL (sym)->plist))
|
146
|
347 XSETINT (XSYMBOL (sym)->plist,
|
42388
|
348 XINT (XSYMBOL (sym)->plist) + 1);
|
43671
b6abb8a7ea89
(Fexpand_abbrev): Increment plist as use count only if it is an integer.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
349 else if (INTEGERP (tem = Fget (sym, Qcount)))
|
42388
|
350 Fput (sym, Qcount, make_number (XINT (tem) + 1));
|
146
|
351
|
16565
|
352 /* If this abbrev has an expansion, delete the abbrev
|
|
353 and insert the expansion. */
|
39584
|
354 expansion = SYMBOL_VALUE (sym);
|
16565
|
355 if (STRINGP (expansion))
|
146
|
356 {
|
16565
|
357 SET_PT (wordstart);
|
|
358
|
20981
|
359 del_range_both (wordstart, wordstart_byte, wordend, wordend_byte, 1);
|
16565
|
360
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
361 insert_from_string (expansion, 0, 0, SCHARS (expansion),
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
362 SBYTES (expansion), 1);
|
16565
|
363 SET_PT (PT + whitecnt);
|
397
|
364
|
16565
|
365 if (uccount && !lccount)
|
|
366 {
|
|
367 /* Abbrev was all caps */
|
|
368 /* If expansion is multiple words, normally capitalize each word */
|
|
369 /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
|
|
370 but Megatest 68000 compiler can't handle that */
|
|
371 if (!abbrev_all_caps)
|
|
372 if (scan_words (PT, -1) > scan_words (wordstart, 1))
|
|
373 {
|
|
374 Fupcase_initials_region (make_number (wordstart),
|
|
375 make_number (PT));
|
|
376 goto caped;
|
|
377 }
|
|
378 /* If expansion is one word, or if user says so, upcase it all. */
|
|
379 Fupcase_region (make_number (wordstart), make_number (PT));
|
|
380 caped: ;
|
|
381 }
|
|
382 else if (uccount)
|
|
383 {
|
|
384 /* Abbrev included some caps. Cap first initial of expansion */
|
20529
|
385 int pos = wordstart_byte;
|
397
|
386
|
16565
|
387 /* Find the initial. */
|
20529
|
388 while (pos < PT_BYTE
|
|
389 && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword)
|
16565
|
390 pos++;
|
|
391
|
|
392 /* Change just that. */
|
20529
|
393 pos = BYTE_TO_CHAR (pos);
|
16565
|
394 Fupcase_initials_region (make_number (pos), make_number (pos + 1));
|
|
395 }
|
146
|
396 }
|
|
397
|
|
398 hook = XSYMBOL (sym)->function;
|
484
|
399 if (!NILP (hook))
|
27043
|
400 {
|
|
401 Lisp_Object expanded, prop;
|
|
402
|
27379
|
403 /* If the abbrev has a hook function, run it. */
|
27043
|
404 expanded = call0 (hook);
|
27379
|
405
|
44851
|
406 /* In addition, if the hook function is a symbol with
|
|
407 a non-nil `no-self-insert' property, let the value it returned
|
27379
|
408 specify whether we consider that an expansion took place. If
|
|
409 it returns nil, no expansion has been done. */
|
|
410
|
27043
|
411 if (SYMBOLP (hook)
|
|
412 && NILP (expanded)
|
|
413 && (prop = Fget (hook, intern ("no-self-insert")),
|
|
414 !NILP (prop)))
|
|
415 value = Qnil;
|
|
416 }
|
146
|
417
|
16747
126a42ee62ac
(Fexpand_abbrev): Return the abbrev symbol, or nil if no expansion.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
418 return value;
|
146
|
419 }
|
|
420
|
|
421 DEFUN ("unexpand-abbrev", Funexpand_abbrev, Sunexpand_abbrev, 0, 0, "",
|
39988
|
422 doc: /* Undo the expansion of the last abbrev that expanded.
|
39960
|
423 This differs from ordinary undo in that other editing done since then
|
39988
|
424 is not undone. */)
|
|
425 ()
|
146
|
426 {
|
16039
|
427 int opoint = PT;
|
146
|
428 int adjust = 0;
|
|
429 if (last_abbrev_point < BEGV
|
|
430 || last_abbrev_point > ZV)
|
|
431 return Qnil;
|
|
432 SET_PT (last_abbrev_point);
|
9140
3e7833a8e16f
(Fdefine_abbrev, Fexpand_abbrev, Funexpand_abbrev): Use type test macros.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
433 if (STRINGP (Vlast_abbrev_text))
|
146
|
434 {
|
|
435 /* This isn't correct if Vlast_abbrev->function was used
|
|
436 to do the expansion */
|
|
437 Lisp_Object val;
|
20529
|
438 int zv_before;
|
|
439
|
39584
|
440 val = SYMBOL_VALUE (Vlast_abbrev);
|
9140
3e7833a8e16f
(Fdefine_abbrev, Fexpand_abbrev, Funexpand_abbrev): Use type test macros.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
441 if (!STRINGP (val))
|
1499
|
442 error ("value of abbrev-symbol must be a string");
|
20529
|
443 zv_before = ZV;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
444 del_range_byte (PT_BYTE, PT_BYTE + SBYTES (val), 1);
|
4717
5297e155e1d2
(Funexpand_abbrev, Fexpand_abbrev): Pass new arg to insert_from_string.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
445 /* Don't inherit properties here; just copy from old contents. */
|
20590
|
446 insert_from_string (Vlast_abbrev_text, 0, 0,
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
447 SCHARS (Vlast_abbrev_text),
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
448 SBYTES (Vlast_abbrev_text), 0);
|
146
|
449 Vlast_abbrev_text = Qnil;
|
20529
|
450 /* Total number of characters deleted. */
|
|
451 adjust = ZV - zv_before;
|
146
|
452 }
|
22909
|
453 SET_PT (last_abbrev_point < opoint ? opoint + adjust : opoint);
|
146
|
454 return Qnil;
|
|
455 }
|
|
456
|
20529
|
457 static void
|
146
|
458 write_abbrev (sym, stream)
|
|
459 Lisp_Object sym, stream;
|
|
460 {
|
42388
|
461 Lisp_Object name, count, system_flag;
|
|
462
|
|
463 if (INTEGERP (XSYMBOL (sym)->plist))
|
|
464 {
|
|
465 count = XSYMBOL (sym)->plist;
|
|
466 system_flag = Qnil;
|
|
467 }
|
|
468 else
|
|
469 {
|
|
470 count = Fget (sym, Qcount);
|
|
471 system_flag = Fget (sym, Qsystem_type);
|
|
472 }
|
|
473
|
|
474 if (NILP (SYMBOL_VALUE (sym)) || ! NILP (system_flag))
|
146
|
475 return;
|
42388
|
476
|
146
|
477 insert (" (", 5);
|
45391
6c875925d507
* abbrev.c (write_abbrev): Use SYMBOL_NAME instead of XSYMBOL and
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
478 name = SYMBOL_NAME (sym);
|
146
|
479 Fprin1 (name, stream);
|
|
480 insert (" ", 1);
|
39584
|
481 Fprin1 (SYMBOL_VALUE (sym), stream);
|
146
|
482 insert (" ", 1);
|
|
483 Fprin1 (XSYMBOL (sym)->function, stream);
|
|
484 insert (" ", 1);
|
42388
|
485 Fprin1 (count, stream);
|
146
|
486 insert (")\n", 2);
|
|
487 }
|
|
488
|
20529
|
489 static void
|
146
|
490 describe_abbrev (sym, stream)
|
|
491 Lisp_Object sym, stream;
|
|
492 {
|
42388
|
493 Lisp_Object one, count, system_flag;
|
|
494
|
|
495 if (INTEGERP (XSYMBOL (sym)->plist))
|
|
496 {
|
|
497 count = XSYMBOL (sym)->plist;
|
|
498 system_flag = Qnil;
|
|
499 }
|
|
500 else
|
|
501 {
|
|
502 count = Fget (sym, Qcount);
|
|
503 system_flag = Fget (sym, Qsystem_type);
|
|
504 }
|
146
|
505
|
39584
|
506 if (NILP (SYMBOL_VALUE (sym)))
|
146
|
507 return;
|
42388
|
508
|
146
|
509 one = make_number (1);
|
|
510 Fprin1 (Fsymbol_name (sym), stream);
|
42388
|
511
|
|
512 if (!NILP (system_flag))
|
|
513 {
|
|
514 insert_string (" (sys)");
|
|
515 Findent_to (make_number (20), one);
|
|
516 }
|
|
517 else
|
|
518 Findent_to (make_number (15), one);
|
|
519
|
|
520 Fprin1 (count, stream);
|
146
|
521 Findent_to (make_number (20), one);
|
39584
|
522 Fprin1 (SYMBOL_VALUE (sym), stream);
|
484
|
523 if (!NILP (XSYMBOL (sym)->function))
|
146
|
524 {
|
|
525 Findent_to (make_number (45), one);
|
|
526 Fprin1 (XSYMBOL (sym)->function, stream);
|
|
527 }
|
|
528 Fterpri (stream);
|
|
529 }
|
|
530
|
16485
|
531 DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description,
|
40109
|
532 Sinsert_abbrev_table_description, 1, 2, 0,
|
39988
|
533 doc: /* Insert before point a full description of abbrev table named NAME.
|
39960
|
534 NAME is a symbol whose value is an abbrev table.
|
|
535 If optional 2nd arg READABLE is non-nil, a human-readable description
|
|
536 is inserted. Otherwise the description is an expression,
|
|
537 a call to `define-abbrev-table', which would
|
42388
|
538 define the abbrev table NAME exactly as it is currently defined.
|
|
539
|
|
540 Abbrevs marked as "system abbrevs" are omitted. */)
|
39988
|
541 (name, readable)
|
146
|
542 Lisp_Object name, readable;
|
|
543 {
|
|
544 Lisp_Object table;
|
|
545 Lisp_Object stream;
|
|
546
|
40656
|
547 CHECK_SYMBOL (name);
|
146
|
548 table = Fsymbol_value (name);
|
40656
|
549 CHECK_VECTOR (table);
|
146
|
550
|
9260
945ddb4e9e24
(write_abbrev, Finsert_abbrev_table_description): Use new accessor macros
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
551 XSETBUFFER (stream, current_buffer);
|
146
|
552
|
484
|
553 if (!NILP (readable))
|
146
|
554 {
|
|
555 insert_string ("(");
|
|
556 Fprin1 (name, stream);
|
|
557 insert_string (")\n\n");
|
|
558 map_obarray (table, describe_abbrev, stream);
|
|
559 insert_string ("\n\n");
|
|
560 }
|
|
561 else
|
|
562 {
|
|
563 insert_string ("(define-abbrev-table '");
|
|
564 Fprin1 (name, stream);
|
|
565 insert_string (" '(\n");
|
|
566 map_obarray (table, write_abbrev, stream);
|
|
567 insert_string (" ))\n\n");
|
|
568 }
|
|
569
|
|
570 return Qnil;
|
|
571 }
|
|
572
|
|
573 DEFUN ("define-abbrev-table", Fdefine_abbrev_table, Sdefine_abbrev_table,
|
|
574 2, 2, 0,
|
39988
|
575 doc: /* Define TABLENAME (a symbol) as an abbrev table name.
|
39960
|
576 Define abbrevs in it according to DEFINITIONS, which is a list of elements
|
42388
|
577 of the form (ABBREVNAME EXPANSION HOOK USECOUNT SYSTEMFLAG).
|
|
578 \(If the list is shorter than that, omitted elements default to nil). */)
|
39988
|
579 (tablename, definitions)
|
14098
|
580 Lisp_Object tablename, definitions;
|
146
|
581 {
|
|
582 Lisp_Object name, exp, hook, count;
|
42388
|
583 Lisp_Object table, elt, sys;
|
146
|
584
|
40656
|
585 CHECK_SYMBOL (tablename);
|
14059
|
586 table = Fboundp (tablename);
|
|
587 if (NILP (table) || (table = Fsymbol_value (tablename), NILP (table)))
|
146
|
588 {
|
|
589 table = Fmake_abbrev_table ();
|
14059
|
590 Fset (tablename, table);
|
14098
|
591 Vabbrev_table_name_list = Fcons (tablename, Vabbrev_table_name_list);
|
146
|
592 }
|
40656
|
593 CHECK_VECTOR (table);
|
146
|
594
|
14098
|
595 for (; !NILP (definitions); definitions = Fcdr (definitions))
|
146
|
596 {
|
14059
|
597 elt = Fcar (definitions);
|
988
|
598 name = Fcar (elt); elt = Fcdr (elt);
|
|
599 exp = Fcar (elt); elt = Fcdr (elt);
|
|
600 hook = Fcar (elt); elt = Fcdr (elt);
|
42388
|
601 count = Fcar (elt); elt = Fcdr (elt);
|
|
602 sys = Fcar (elt);
|
|
603 Fdefine_abbrev (table, name, exp, hook, count, sys);
|
146
|
604 }
|
|
605 return Qnil;
|
|
606 }
|
|
607
|
21514
|
608 void
|
146
|
609 syms_of_abbrev ()
|
|
610 {
|
42388
|
611 Qsystem_type = intern ("system-type");
|
|
612 staticpro (&Qsystem_type);
|
|
613
|
|
614 Qcount = intern ("count");
|
|
615 staticpro (&Qcount);
|
|
616
|
39988
|
617 DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
|
|
618 doc: /* List of symbols whose values are abbrev tables. */);
|
146
|
619 Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
|
|
620 Fcons (intern ("global-abbrev-table"),
|
|
621 Qnil));
|
|
622
|
39988
|
623 DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table,
|
|
624 doc: /* The abbrev table whose abbrevs affect all buffers.
|
39960
|
625 Each buffer may also have a local abbrev table.
|
|
626 If it does, the local table overrides the global one
|
|
627 for any particular abbrev defined in both. */);
|
146
|
628 Vglobal_abbrev_table = Fmake_abbrev_table ();
|
|
629
|
39988
|
630 DEFVAR_LISP ("fundamental-mode-abbrev-table", &Vfundamental_mode_abbrev_table,
|
|
631 doc: /* The abbrev table of mode-specific abbrevs for Fundamental Mode. */);
|
146
|
632 Vfundamental_mode_abbrev_table = Fmake_abbrev_table ();
|
|
633 current_buffer->abbrev_table = Vfundamental_mode_abbrev_table;
|
29742
|
634 buffer_defaults.abbrev_table = Vfundamental_mode_abbrev_table;
|
146
|
635
|
39988
|
636 DEFVAR_LISP ("last-abbrev", &Vlast_abbrev,
|
|
637 doc: /* The abbrev-symbol of the last abbrev expanded. See `abbrev-symbol'. */);
|
146
|
638
|
39988
|
639 DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text,
|
|
640 doc: /* The exact text of the last abbrev expanded.
|
39960
|
641 nil if the abbrev has already been unexpanded. */);
|
146
|
642
|
39988
|
643 DEFVAR_INT ("last-abbrev-location", &last_abbrev_point,
|
|
644 doc: /* The location of the start of the last abbrev expanded. */);
|
146
|
645
|
|
646 Vlast_abbrev = Qnil;
|
|
647 Vlast_abbrev_text = Qnil;
|
|
648 last_abbrev_point = 0;
|
|
649
|
39988
|
650 DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location,
|
|
651 doc: /* Buffer position for `expand-abbrev' to use as the start of the abbrev.
|
44851
|
652 When nil, use the word before point as the abbrev.
|
39960
|
653 Calling `expand-abbrev' sets this to nil. */);
|
146
|
654 Vabbrev_start_location = Qnil;
|
|
655
|
39988
|
656 DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer,
|
|
657 doc: /* Buffer that `abbrev-start-location' has been set for.
|
39960
|
658 Trying to expand an abbrev in any other buffer clears `abbrev-start-location'. */);
|
146
|
659 Vabbrev_start_location_buffer = Qnil;
|
|
660
|
39988
|
661 DEFVAR_PER_BUFFER ("local-abbrev-table", ¤t_buffer->abbrev_table, Qnil,
|
|
662 doc: /* Local (mode-specific) abbrev table of current buffer. */);
|
146
|
663
|
39988
|
664 DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed,
|
|
665 doc: /* Set non-nil by defining or altering any word abbrevs.
|
39960
|
666 This causes `save-some-buffers' to offer to save the abbrevs. */);
|
146
|
667 abbrevs_changed = 0;
|
|
668
|
39988
|
669 DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps,
|
|
670 doc: /* *Set non-nil means expand multi-word abbrevs all caps if abbrev was so. */);
|
146
|
671 abbrev_all_caps = 0;
|
|
672
|
39988
|
673 DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook,
|
|
674 doc: /* Function or functions to be called before abbrev expansion is done.
|
39960
|
675 This is the first thing that `expand-abbrev' does, and so this may change
|
|
676 the current abbrev table before abbrev lookup happens. */);
|
458
|
677 Vpre_abbrev_expand_hook = Qnil;
|
|
678 Qpre_abbrev_expand_hook = intern ("pre-abbrev-expand-hook");
|
|
679 staticpro (&Qpre_abbrev_expand_hook);
|
|
680
|
146
|
681 defsubr (&Smake_abbrev_table);
|
|
682 defsubr (&Sclear_abbrev_table);
|
|
683 defsubr (&Sdefine_abbrev);
|
|
684 defsubr (&Sdefine_global_abbrev);
|
|
685 defsubr (&Sdefine_mode_abbrev);
|
|
686 defsubr (&Sabbrev_expansion);
|
|
687 defsubr (&Sabbrev_symbol);
|
|
688 defsubr (&Sexpand_abbrev);
|
|
689 defsubr (&Sunexpand_abbrev);
|
|
690 defsubr (&Sinsert_abbrev_table_description);
|
|
691 defsubr (&Sdefine_abbrev_table);
|
|
692 }
|