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