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