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