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