aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2007-10-28 02:41:00 +0000
committerStefan Monnier2007-10-28 02:41:00 +0000
commite047f448837314fb158e0571813e79fbac677cc7 (patch)
treee14390dd2f4cb89d066b1dd1decef1d57cae8942 /src
parenta034393c29917271c100c3d55dff2a23ffcffeb4 (diff)
downloademacs-e047f448837314fb158e0571813e79fbac677cc7.tar.gz
emacs-e047f448837314fb158e0571813e79fbac677cc7.zip
Rewrite abbrev.c in Elisp.
* image.c (Qcount): Don't declare as extern. (syms_of_image): Initialize and staticpro `Qcount'. * puresize.h (BASE_PURESIZE): Increase for the new abbrev.el functions. * emacs.c (main): Don't call syms_of_abbrev. * Makefile.in (obj): Remove abbrev.o. (abbrev.o): Remove. * abbrev.c: Remove. Rewrite abbrev.c in Elisp. * abbrev.el (abbrev-mode): Move custom group from cus-edit.el. (abbrev-table-get, abbrev-table-put, abbrev-get) (abbrev-put, make-abbrev-table, abbrev-table-p, clear-abbrev-table) (define-abbrev, abbrev--check-chars, define-global-abbrev) (define-mode-abbrev, abbrev--active-tables, abbrev-symbol) (abbrev-expansion, abbrev--before-point, expand-abbrev) (unexpand-abbrev, abbrev--write, abbrev--describe) (insert-abbrev-table-description, define-abbrev-table): New funs, largely transcribed from abbrev.c. (abbrev-with-wrapper-hook): New macro. (abbrev-table-name-list, global-abbrev-table) (abbrev-minor-mode-table-alist, fundamental-mode-abbrev-table) (abbrevs-changed, abbrev-all-caps, abbrev-start-location) (abbrev-start-location-buffer, last-abbrev, last-abbrev-text) (last-abbrev-location, pre-abbrev-expand-hook, abbrev-expand-function): New vars, largely transcribed from abbrev.c. * cus-edit.el (abbrev-mode): Remove. Move to abbrev.el. * cus-start.el: Remove abbrev-all-caps and pre-abbrev-expand-hook. * loadup.el: Load "abbrev.el" before "lisp-mode.el".
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/Makefile.in6
-rw-r--r--src/abbrev.c803
-rw-r--r--src/emacs.c1
-rw-r--r--src/image.c7
-rw-r--r--src/puresize.h2
6 files changed, 19 insertions, 811 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 36e6ca3b00d..d4f70731562 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12007-10-28 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Rewrite abbrev.c in Elisp.
4 * image.c (Qcount): Don't declare as extern.
5 (syms_of_image): Initialize and staticpro `Qcount'.
6 * puresize.h (BASE_PURESIZE): Increase for the new abbrev.el functions.
7 * emacs.c (main): Don't call syms_of_abbrev.
8 * Makefile.in (obj): Remove abbrev.o.
9 (abbrev.o): Remove.
10 * abbrev.c: Remove.
11
12007-10-26 Martin Rudalics <rudalics@gmx.at> 122007-10-26 Martin Rudalics <rudalics@gmx.at>
2 13
3 * window.c (window_min_size_2): Don't count header-line. 14 * window.c (window_min_size_2): Don't count header-line.
diff --git a/src/Makefile.in b/src/Makefile.in
index 7119f94c8d2..56e8a7c49a5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -603,7 +603,7 @@ obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \
603 cmds.o casetab.o casefiddle.o indent.o search.o regex.o undo.o \ 603 cmds.o casetab.o casefiddle.o indent.o search.o regex.o undo.o \
604 alloc.o data.o doc.o editfns.o callint.o \ 604 alloc.o data.o doc.o editfns.o callint.o \
605 eval.o floatfns.o fns.o print.o lread.o \ 605 eval.o floatfns.o fns.o print.o lread.o \
606 abbrev.o syntax.o UNEXEC bytecode.o \ 606 syntax.o UNEXEC bytecode.o \
607 process.o callproc.o \ 607 process.o callproc.o \
608 region-cache.o sound.o atimer.o \ 608 region-cache.o sound.o atimer.o \
609 doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \ 609 doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \
@@ -1094,8 +1094,6 @@ stamp-oldxmenu:
1094 it is so often changed in ways that do not require any recompilation 1094 it is so often changed in ways that do not require any recompilation
1095 and so rarely changed in ways that do require any. */ 1095 and so rarely changed in ways that do require any. */
1096 1096
1097abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h charset.h \
1098 syntax.h $(config_h)
1099buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \ 1097buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
1100 dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h charset.h \ 1098 dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h charset.h \
1101 $(config_h) 1099 $(config_h)
@@ -1279,7 +1277,7 @@ composite.o: composite.c buffer.h charset.h $(INTERVAL_SRC) $(config_h)
1279sunfns.o: sunfns.c buffer.h window.h dispextern.h termhooks.h $(config_h) 1277sunfns.o: sunfns.c buffer.h window.h dispextern.h termhooks.h $(config_h)
1280 1278
1281#ifdef HAVE_CARBON 1279#ifdef HAVE_CARBON
1282abbrev.o buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \ 1280buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
1283 fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \ 1281 fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
1284 scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \ 1282 scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
1285 xterm.o xselect.o sound.o: macgui.h 1283 xterm.o xselect.o sound.o: macgui.h
diff --git a/src/abbrev.c b/src/abbrev.c
deleted file mode 100644
index 403afdb99a7..00000000000
--- a/src/abbrev.c
+++ /dev/null
@@ -1,803 +0,0 @@
1/* Primitives for word-abbrev mode.
2 Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007 Free Software Foundation, Inc.
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
9the Free Software Foundation; either version 3, or (at your option)
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
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
21
22
23#include <config.h>
24#include <stdio.h>
25
26#include "lisp.h"
27#include "commands.h"
28#include "buffer.h"
29#include "window.h"
30#include "charset.h"
31#include "syntax.h"
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
80EMACS_INT last_abbrev_point;
81
82/* Hook to run before expanding any abbrev. */
83
84Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
85
86Lisp_Object Qsystem_type, Qcount, Qforce;
87
88DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
89 doc: /* Create a new, empty abbrev table object. */)
90 ()
91{
92 /* The value 59 is arbitrary chosen prime number. */
93 return Fmake_vector (make_number (59), make_number (0));
94}
95
96DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0,
97 doc: /* Undefine all abbrevs in abbrev table TABLE, leaving it empty. */)
98 (table)
99 Lisp_Object table;
100{
101 int i, size;
102
103 CHECK_VECTOR (table);
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
111DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 6, 0,
112 doc: /* Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK.
113NAME must be a string, and should be lower-case.
114EXPANSION should usually be a string.
115To undefine an abbrev, define it with EXPANSION = nil.
116If HOOK is non-nil, it should be a function of no arguments;
117it is called after EXPANSION is inserted.
118If EXPANSION is not a string, the abbrev is a special one,
119 which does not expand in the usual way but only runs HOOK.
120
121COUNT, if specified, gives the initial value for the abbrev's
122usage-count, which is incremented each time the abbrev is used.
123\(The default is zero.)
124
125SYSTEM-FLAG, if non-nil, says that this is a "system" abbreviation
126which should not be saved in the user's abbreviation file.
127Unless SYSTEM-FLAG is `force', a system abbreviation will not
128overwrite a non-system abbreviation of the same name. */)
129 (table, name, expansion, hook, count, system_flag)
130 Lisp_Object table, name, expansion, hook, count, system_flag;
131{
132 Lisp_Object sym, oexp, ohook, tem;
133 CHECK_VECTOR (table);
134 CHECK_STRING (name);
135
136 /* If defining a system abbrev, do not overwrite a non-system abbrev
137 of the same name, unless 'force is used. */
138 if (!NILP (system_flag) && !EQ (system_flag, Qforce))
139 {
140 sym = Fintern_soft (name, table);
141
142 if (!NILP (SYMBOL_VALUE (sym)) &&
143 NILP (Fplist_get (XSYMBOL (sym)->plist, Qsystem_type))) return Qnil;
144 }
145
146 if (NILP (count))
147 count = make_number (0);
148 else
149 CHECK_NUMBER (count);
150
151 sym = Fintern (name, table);
152
153 oexp = SYMBOL_VALUE (sym);
154 ohook = XSYMBOL (sym)->function;
155 if (!((EQ (oexp, expansion)
156 || (STRINGP (oexp) && STRINGP (expansion)
157 && (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
158 &&
159 (EQ (ohook, hook)
160 || (tem = Fequal (ohook, hook), !NILP (tem))))
161 && NILP (system_flag))
162 abbrevs_changed = 1;
163
164 Fset (sym, expansion);
165 Ffset (sym, hook);
166
167 if (! NILP (system_flag))
168 Fsetplist (sym, list4 (Qcount, count, Qsystem_type, system_flag));
169 else
170 Fsetplist (sym, count);
171
172 return name;
173}
174
175/* Check if the characters in ABBREV have word syntax in either the
176 * current (if global == 0) or standard syntax table. */
177static void
178abbrev_check_chars (abbrev, global)
179 Lisp_Object abbrev;
180 int global;
181{
182 int i, i_byte, len, nbad = 0;
183 int j, found, nuniq = 0;
184 char *badchars, *baduniq;
185
186 CHECK_STRING (abbrev);
187 len = SCHARS (abbrev);
188
189 badchars = (char *) alloca (len + 1);
190
191 for (i = 0, i_byte = 0; i < len; )
192 {
193 int c;
194
195 FETCH_STRING_CHAR_ADVANCE (c, abbrev, i, i_byte);
196
197 if (global)
198 {
199 /* Copied from SYNTAX in syntax.h, except using FOLLOW_PARENT. */
200 Lisp_Object syntax_temp
201 = SYNTAX_ENTRY_FOLLOW_PARENT (Vstandard_syntax_table, c);
202 if ( (CONSP (syntax_temp)
203 ? (enum syntaxcode) (XINT (XCAR (syntax_temp)) & 0xff)
204 : Swhitespace) != Sword ) badchars[nbad++] = c;
205 }
206 else if (SYNTAX (c) != Sword)
207 badchars[nbad++] = c;
208 }
209
210 if (nbad == 0) return;
211
212 baduniq = (char *) alloca (nbad + 1);
213
214 for (i = 0; i < nbad; i++)
215 {
216 found = 0;
217
218 for (j = 0; j < nuniq; j++)
219 {
220 if (badchars[i] == baduniq[j])
221 {
222 found = 1;
223 break;
224 }
225 }
226
227 if (found) continue ;
228
229 baduniq[nuniq++] = badchars[i];
230 }
231
232 baduniq[nuniq] = '\0';
233
234 error ("Some abbrev characters (%s) are not word constituents %s",
235 baduniq, global ? "in the standard syntax" : "in this mode" );
236}
237
238DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2,
239 "sDefine global abbrev: \nsExpansion for %s: ",
240 doc: /* Define ABBREV as a global abbreviation for EXPANSION.
241The characters in ABBREV must all be word constituents in the standard
242syntax table. */)
243 (abbrev, expansion)
244 Lisp_Object abbrev, expansion;
245{
246 abbrev_check_chars (abbrev, 1);
247
248 Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
249 expansion, Qnil, make_number (0), Qnil);
250 return abbrev;
251}
252
253DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
254 "sDefine mode abbrev: \nsExpansion for %s: ",
255 doc: /* Define ABBREV as a mode-specific abbreviation for EXPANSION.
256The characters in ABBREV must all be word-constituents in the current mode. */)
257 (abbrev, expansion)
258 Lisp_Object abbrev, expansion;
259{
260 if (NILP (current_buffer->abbrev_table))
261 error ("Major mode has no abbrev table");
262
263 abbrev_check_chars (abbrev, 0);
264
265 Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
266 expansion, Qnil, make_number (0), Qnil);
267 return abbrev;
268}
269
270DEFUN ("abbrev-symbol", Fabbrev_symbol, Sabbrev_symbol, 1, 2, 0,
271 doc: /* Return the symbol representing abbrev named ABBREV.
272This symbol's name is ABBREV, but it is not the canonical symbol of that name;
273it is interned in an abbrev-table rather than the normal obarray.
274The value is nil if that abbrev is not defined.
275Optional second arg TABLE is abbrev table to look it up in.
276The default is to try buffer's mode-specific abbrev table, then global table. */)
277 (abbrev, table)
278 Lisp_Object abbrev, table;
279{
280 Lisp_Object sym;
281 CHECK_STRING (abbrev);
282 if (!NILP (table))
283 sym = Fintern_soft (abbrev, table);
284 else
285 {
286 sym = Qnil;
287 if (!NILP (current_buffer->abbrev_table))
288 sym = Fintern_soft (abbrev, current_buffer->abbrev_table);
289 if (NILP (SYMBOL_VALUE (sym)))
290 sym = Qnil;
291 if (NILP (sym))
292 sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
293 }
294 if (NILP (SYMBOL_VALUE (sym)))
295 return Qnil;
296 return sym;
297}
298
299DEFUN ("abbrev-expansion", Fabbrev_expansion, Sabbrev_expansion, 1, 2, 0,
300 doc: /* Return the string that ABBREV expands into in the current buffer.
301Optionally specify an abbrev table as second arg;
302then ABBREV is looked up in that table only. */)
303 (abbrev, table)
304 Lisp_Object abbrev, table;
305{
306 Lisp_Object sym;
307 sym = Fabbrev_symbol (abbrev, table);
308 if (NILP (sym)) return sym;
309 return Fsymbol_value (sym);
310}
311
312/* Expand the word before point, if it is an abbrev.
313 Returns 1 if an expansion is done. */
314
315DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "",
316 doc: /* Expand the abbrev before point, if there is an abbrev there.
317Effective when explicitly called even when `abbrev-mode' is nil.
318Returns the abbrev symbol, if expansion took place. */)
319 ()
320{
321 register char *buffer, *p;
322 int wordstart, wordend;
323 register int wordstart_byte, wordend_byte, idx, idx_byte;
324 int whitecnt;
325 int uccount = 0, lccount = 0;
326 register Lisp_Object sym;
327 Lisp_Object expansion, hook, tem;
328 Lisp_Object value;
329 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
330
331 value = Qnil;
332
333 Frun_hooks (1, &Qpre_abbrev_expand_hook);
334
335 wordstart = 0;
336 if (!(BUFFERP (Vabbrev_start_location_buffer)
337 && XBUFFER (Vabbrev_start_location_buffer) == current_buffer))
338 Vabbrev_start_location = Qnil;
339 if (!NILP (Vabbrev_start_location))
340 {
341 tem = Vabbrev_start_location;
342 CHECK_NUMBER_COERCE_MARKER (tem);
343 wordstart = XINT (tem);
344 Vabbrev_start_location = Qnil;
345 if (wordstart < BEGV || wordstart > ZV)
346 wordstart = 0;
347 if (wordstart && wordstart != ZV)
348 {
349 wordstart_byte = CHAR_TO_BYTE (wordstart);
350 if (FETCH_BYTE (wordstart_byte) == '-')
351 del_range (wordstart, wordstart + 1);
352 }
353 }
354 if (!wordstart)
355 wordstart = scan_words (PT, -1);
356
357 if (!wordstart)
358 return value;
359
360 wordstart_byte = CHAR_TO_BYTE (wordstart);
361 wordend = scan_words (wordstart, 1);
362 if (!wordend)
363 return value;
364
365 if (wordend > PT)
366 wordend = PT;
367
368 wordend_byte = CHAR_TO_BYTE (wordend);
369 whitecnt = PT - wordend;
370 if (wordend <= wordstart)
371 return value;
372
373 p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
374
375 for (idx = wordstart, idx_byte = wordstart_byte; idx < wordend; )
376 {
377 register int c;
378
379 if (multibyte)
380 {
381 FETCH_CHAR_ADVANCE (c, idx, idx_byte);
382 }
383 else
384 {
385 c = FETCH_BYTE (idx_byte);
386 idx++, idx_byte++;
387 }
388
389 if (UPPERCASEP (c))
390 c = DOWNCASE (c), uccount++;
391 else if (! NOCASEP (c))
392 lccount++;
393 if (multibyte)
394 p += CHAR_STRING (c, p);
395 else
396 *p++ = c;
397 }
398
399 if (VECTORP (current_buffer->abbrev_table))
400 sym = oblookup (current_buffer->abbrev_table, buffer,
401 wordend - wordstart, p - buffer);
402 else
403 XSETFASTINT (sym, 0);
404
405 if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
406 sym = oblookup (Vglobal_abbrev_table, buffer,
407 wordend - wordstart, p - buffer);
408 if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
409 return value;
410
411 if (INTERACTIVE && !EQ (minibuf_window, selected_window))
412 {
413 /* Add an undo boundary, in case we are doing this for
414 a self-inserting command which has avoided making one so far. */
415 SET_PT (wordend);
416 Fundo_boundary ();
417 }
418
419 Vlast_abbrev_text
420 = Fbuffer_substring (make_number (wordstart), make_number (wordend));
421
422 /* Now sym is the abbrev symbol. */
423 Vlast_abbrev = sym;
424 value = sym;
425 last_abbrev_point = wordstart;
426
427 /* Increment use count. */
428 if (INTEGERP (XSYMBOL (sym)->plist))
429 XSETINT (XSYMBOL (sym)->plist,
430 XINT (XSYMBOL (sym)->plist) + 1);
431 else if (INTEGERP (tem = Fget (sym, Qcount)))
432 Fput (sym, Qcount, make_number (XINT (tem) + 1));
433
434 /* If this abbrev has an expansion, delete the abbrev
435 and insert the expansion. */
436 expansion = SYMBOL_VALUE (sym);
437 if (STRINGP (expansion))
438 {
439 SET_PT (wordstart);
440
441 insert_from_string (expansion, 0, 0, SCHARS (expansion),
442 SBYTES (expansion), 1);
443 del_range_both (PT, PT_BYTE,
444 wordend + (PT - wordstart),
445 wordend_byte + (PT_BYTE - wordstart_byte),
446 1);
447
448 SET_PT (PT + whitecnt);
449
450 if (uccount && !lccount)
451 {
452 /* Abbrev was all caps */
453 /* If expansion is multiple words, normally capitalize each word */
454 /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
455 but Megatest 68000 compiler can't handle that */
456 if (!abbrev_all_caps)
457 if (scan_words (PT, -1) > scan_words (wordstart, 1))
458 {
459 Fupcase_initials_region (make_number (wordstart),
460 make_number (PT));
461 goto caped;
462 }
463 /* If expansion is one word, or if user says so, upcase it all. */
464 Fupcase_region (make_number (wordstart), make_number (PT));
465 caped: ;
466 }
467 else if (uccount)
468 {
469 /* Abbrev included some caps. Cap first initial of expansion */
470 int pos = wordstart_byte;
471
472 /* Find the initial. */
473 while (pos < PT_BYTE
474 && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword)
475 pos++;
476
477 /* Change just that. */
478 pos = BYTE_TO_CHAR (pos);
479 Fupcase_initials_region (make_number (pos), make_number (pos + 1));
480 }
481 }
482
483 hook = XSYMBOL (sym)->function;
484 if (!NILP (hook))
485 {
486 Lisp_Object expanded, prop;
487
488 /* If the abbrev has a hook function, run it. */
489 expanded = call0 (hook);
490
491 /* In addition, if the hook function is a symbol with
492 a non-nil `no-self-insert' property, let the value it returned
493 specify whether we consider that an expansion took place. If
494 it returns nil, no expansion has been done. */
495
496 if (SYMBOLP (hook)
497 && NILP (expanded)
498 && (prop = Fget (hook, intern ("no-self-insert")),
499 !NILP (prop)))
500 value = Qnil;
501 }
502
503 return value;
504}
505
506DEFUN ("unexpand-abbrev", Funexpand_abbrev, Sunexpand_abbrev, 0, 0, "",
507 doc: /* Undo the expansion of the last abbrev that expanded.
508This differs from ordinary undo in that other editing done since then
509is not undone. */)
510 ()
511{
512 int opoint = PT;
513 int adjust = 0;
514 if (last_abbrev_point < BEGV
515 || last_abbrev_point > ZV)
516 return Qnil;
517 SET_PT (last_abbrev_point);
518 if (STRINGP (Vlast_abbrev_text))
519 {
520 /* This isn't correct if Vlast_abbrev->function was used
521 to do the expansion */
522 Lisp_Object val;
523 int zv_before;
524
525 val = SYMBOL_VALUE (Vlast_abbrev);
526 if (!STRINGP (val))
527 error ("Value of `abbrev-symbol' must be a string");
528 zv_before = ZV;
529 del_range_byte (PT_BYTE, PT_BYTE + SBYTES (val), 1);
530 /* Don't inherit properties here; just copy from old contents. */
531 insert_from_string (Vlast_abbrev_text, 0, 0,
532 SCHARS (Vlast_abbrev_text),
533 SBYTES (Vlast_abbrev_text), 0);
534 Vlast_abbrev_text = Qnil;
535 /* Total number of characters deleted. */
536 adjust = ZV - zv_before;
537 }
538 SET_PT (last_abbrev_point < opoint ? opoint + adjust : opoint);
539 return Qnil;
540}
541
542static void
543write_abbrev (sym, stream)
544 Lisp_Object sym, stream;
545{
546 Lisp_Object name, count, system_flag;
547
548 if (INTEGERP (XSYMBOL (sym)->plist))
549 {
550 count = XSYMBOL (sym)->plist;
551 system_flag = Qnil;
552 }
553 else
554 {
555 count = Fget (sym, Qcount);
556 system_flag = Fget (sym, Qsystem_type);
557 }
558
559 if (NILP (SYMBOL_VALUE (sym)) || ! NILP (system_flag))
560 return;
561
562 insert (" (", 5);
563 name = SYMBOL_NAME (sym);
564 Fprin1 (name, stream);
565 insert (" ", 1);
566 Fprin1 (SYMBOL_VALUE (sym), stream);
567 insert (" ", 1);
568 Fprin1 (XSYMBOL (sym)->function, stream);
569 insert (" ", 1);
570 Fprin1 (count, stream);
571 insert (")\n", 2);
572}
573
574static void
575describe_abbrev (sym, stream)
576 Lisp_Object sym, stream;
577{
578 Lisp_Object one, count, system_flag;
579
580 if (INTEGERP (XSYMBOL (sym)->plist))
581 {
582 count = XSYMBOL (sym)->plist;
583 system_flag = Qnil;
584 }
585 else
586 {
587 count = Fget (sym, Qcount);
588 system_flag = Fget (sym, Qsystem_type);
589 }
590
591 if (NILP (SYMBOL_VALUE (sym)))
592 return;
593
594 one = make_number (1);
595 Fprin1 (Fsymbol_name (sym), stream);
596
597 if (!NILP (system_flag))
598 {
599 insert_string (" (sys)");
600 Findent_to (make_number (20), one);
601 }
602 else
603 Findent_to (make_number (15), one);
604
605 Fprin1 (count, stream);
606 Findent_to (make_number (20), one);
607 Fprin1 (SYMBOL_VALUE (sym), stream);
608 if (!NILP (XSYMBOL (sym)->function))
609 {
610 Findent_to (make_number (45), one);
611 Fprin1 (XSYMBOL (sym)->function, stream);
612 }
613 Fterpri (stream);
614}
615
616static void
617record_symbol (sym, list)
618 Lisp_Object sym, list;
619{
620 XSETCDR (list, Fcons (sym, XCDR (list)));
621}
622
623DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description,
624 Sinsert_abbrev_table_description, 1, 2, 0,
625 doc: /* Insert before point a full description of abbrev table named NAME.
626NAME is a symbol whose value is an abbrev table.
627If optional 2nd arg READABLE is non-nil, a human-readable description
628is inserted. Otherwise the description is an expression,
629a call to `define-abbrev-table', which would
630define the abbrev table NAME exactly as it is currently defined.
631
632Abbrevs marked as "system abbrevs" are normally omitted. However, if
633READABLE is non-nil, they are listed. */)
634 (name, readable)
635 Lisp_Object name, readable;
636{
637 Lisp_Object table;
638 Lisp_Object symbols;
639 Lisp_Object stream;
640
641 CHECK_SYMBOL (name);
642 table = Fsymbol_value (name);
643 CHECK_VECTOR (table);
644
645 XSETBUFFER (stream, current_buffer);
646
647 symbols = Fcons (Qnil, Qnil);
648 map_obarray (table, record_symbol, symbols);
649 symbols = XCDR (symbols);
650 symbols = Fsort (symbols, Qstring_lessp);
651
652 if (!NILP (readable))
653 {
654 insert_string ("(");
655 Fprin1 (name, stream);
656 insert_string (")\n\n");
657 while (! NILP (symbols))
658 {
659 describe_abbrev (XCAR (symbols), stream);
660 symbols = XCDR (symbols);
661 }
662
663 insert_string ("\n\n");
664 }
665 else
666 {
667 insert_string ("(define-abbrev-table '");
668 Fprin1 (name, stream);
669 insert_string (" '(\n");
670 while (! NILP (symbols))
671 {
672 write_abbrev (XCAR (symbols), stream);
673 symbols = XCDR (symbols);
674 }
675 insert_string (" ))\n\n");
676 }
677
678 return Qnil;
679}
680
681DEFUN ("define-abbrev-table", Fdefine_abbrev_table, Sdefine_abbrev_table,
682 2, 2, 0,
683 doc: /* Define TABLENAME (a symbol) as an abbrev table name.
684Define abbrevs in it according to DEFINITIONS, which is a list of elements
685of the form (ABBREVNAME EXPANSION HOOK USECOUNT SYSTEMFLAG).
686\(If the list is shorter than that, omitted elements default to nil). */)
687 (tablename, definitions)
688 Lisp_Object tablename, definitions;
689{
690 Lisp_Object name, exp, hook, count;
691 Lisp_Object table, elt, sys;
692
693 CHECK_SYMBOL (tablename);
694 table = Fboundp (tablename);
695 if (NILP (table) || (table = Fsymbol_value (tablename), NILP (table)))
696 {
697 table = Fmake_abbrev_table ();
698 Fset (tablename, table);
699 Vabbrev_table_name_list = Fcons (tablename, Vabbrev_table_name_list);
700 }
701 CHECK_VECTOR (table);
702
703 for (; CONSP (definitions); definitions = XCDR (definitions))
704 {
705 elt = XCAR (definitions);
706 name = Fcar (elt); elt = Fcdr (elt);
707 exp = Fcar (elt); elt = Fcdr (elt);
708 hook = Fcar (elt); elt = Fcdr (elt);
709 count = Fcar (elt); elt = Fcdr (elt);
710 sys = Fcar (elt);
711 Fdefine_abbrev (table, name, exp, hook, count, sys);
712 }
713 return Qnil;
714}
715
716void
717syms_of_abbrev ()
718{
719 Qsystem_type = intern ("system-type");
720 staticpro (&Qsystem_type);
721
722 Qcount = intern ("count");
723 staticpro (&Qcount);
724
725 Qforce = intern ("force");
726 staticpro (&Qforce);
727
728 DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
729 doc: /* List of symbols whose values are abbrev tables. */);
730 Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
731 Fcons (intern ("global-abbrev-table"),
732 Qnil));
733
734 DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table,
735 doc: /* The abbrev table whose abbrevs affect all buffers.
736Each buffer may also have a local abbrev table.
737If it does, the local table overrides the global one
738for any particular abbrev defined in both. */);
739 Vglobal_abbrev_table = Fmake_abbrev_table ();
740
741 DEFVAR_LISP ("fundamental-mode-abbrev-table", &Vfundamental_mode_abbrev_table,
742 doc: /* The abbrev table of mode-specific abbrevs for Fundamental Mode. */);
743 Vfundamental_mode_abbrev_table = Fmake_abbrev_table ();
744 current_buffer->abbrev_table = Vfundamental_mode_abbrev_table;
745 buffer_defaults.abbrev_table = Vfundamental_mode_abbrev_table;
746
747 DEFVAR_LISP ("last-abbrev", &Vlast_abbrev,
748 doc: /* The abbrev-symbol of the last abbrev expanded. See `abbrev-symbol'. */);
749
750 DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text,
751 doc: /* The exact text of the last abbrev expanded.
752A value of nil means the abbrev has already been unexpanded. */);
753
754 DEFVAR_INT ("last-abbrev-location", &last_abbrev_point,
755 doc: /* The location of the start of the last abbrev expanded. */);
756
757 Vlast_abbrev = Qnil;
758 Vlast_abbrev_text = Qnil;
759 last_abbrev_point = 0;
760
761 DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location,
762 doc: /* Buffer position for `expand-abbrev' to use as the start of the abbrev.
763When nil, use the word before point as the abbrev.
764Calling `expand-abbrev' sets this to nil. */);
765 Vabbrev_start_location = Qnil;
766
767 DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer,
768 doc: /* Buffer that `abbrev-start-location' has been set for.
769Trying to expand an abbrev in any other buffer clears `abbrev-start-location'. */);
770 Vabbrev_start_location_buffer = Qnil;
771
772 DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed,
773 doc: /* Set non-nil by defining or altering any word abbrevs.
774This causes `save-some-buffers' to offer to save the abbrevs. */);
775 abbrevs_changed = 0;
776
777 DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps,
778 doc: /* *Set non-nil means expand multi-word abbrevs all caps if abbrev was so. */);
779 abbrev_all_caps = 0;
780
781 DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook,
782 doc: /* Function or functions to be called before abbrev expansion is done.
783This is the first thing that `expand-abbrev' does, and so this may change
784the current abbrev table before abbrev lookup happens. */);
785 Vpre_abbrev_expand_hook = Qnil;
786 Qpre_abbrev_expand_hook = intern ("pre-abbrev-expand-hook");
787 staticpro (&Qpre_abbrev_expand_hook);
788
789 defsubr (&Smake_abbrev_table);
790 defsubr (&Sclear_abbrev_table);
791 defsubr (&Sdefine_abbrev);
792 defsubr (&Sdefine_global_abbrev);
793 defsubr (&Sdefine_mode_abbrev);
794 defsubr (&Sabbrev_expansion);
795 defsubr (&Sabbrev_symbol);
796 defsubr (&Sexpand_abbrev);
797 defsubr (&Sunexpand_abbrev);
798 defsubr (&Sinsert_abbrev_table_description);
799 defsubr (&Sdefine_abbrev_table);
800}
801
802/* arch-tag: b721db69-f633-44a8-a361-c275acbdad7d
803 (do not change this comment) */
diff --git a/src/emacs.c b/src/emacs.c
index 9fbb0b32707..2d47114e16d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1543,7 +1543,6 @@ main (argc, argv
1543 syms_of_fns (); 1543 syms_of_fns ();
1544 syms_of_floatfns (); 1544 syms_of_floatfns ();
1545 1545
1546 syms_of_abbrev ();
1547 syms_of_buffer (); 1546 syms_of_buffer ();
1548 syms_of_bytecode (); 1547 syms_of_bytecode ();
1549 syms_of_callint (); 1548 syms_of_callint ();
diff --git a/src/image.c b/src/image.c
index 33d5e1a9b2d..91be3f4b57e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -733,9 +733,9 @@ Lisp_Object Qxbm;
733/* Keywords. */ 733/* Keywords. */
734 734
735extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile; 735extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
736extern Lisp_Object QCdata, QCtype, Qcount; 736extern Lisp_Object QCdata, QCtype;
737extern Lisp_Object Qcenter; 737extern Lisp_Object Qcenter;
738Lisp_Object QCascent, QCmargin, QCrelief; 738Lisp_Object QCascent, QCmargin, QCrelief, Qcount;
739Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; 739Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
740Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; 740Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
741 741
@@ -9089,6 +9089,9 @@ non-numeric, there is no explicit limit on the size of images. */);
9089 define_image_type (&xbm_type, 1); 9089 define_image_type (&xbm_type, 1);
9090 define_image_type (&pbm_type, 1); 9090 define_image_type (&pbm_type, 1);
9091 9091
9092 Qcount = intern ("count");
9093 staticpro (&Qcount);
9094
9092 QCascent = intern (":ascent"); 9095 QCascent = intern (":ascent");
9093 staticpro (&QCascent); 9096 staticpro (&QCascent);
9094 QCmargin = intern (":margin"); 9097 QCmargin = intern (":margin");
diff --git a/src/puresize.h b/src/puresize.h
index f5b675055b8..bf4971a0b5f 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -43,7 +43,7 @@ Boston, MA 02110-1301, USA. */
43#endif 43#endif
44 44
45#ifndef BASE_PURESIZE 45#ifndef BASE_PURESIZE
46#define BASE_PURESIZE (1170000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) 46#define BASE_PURESIZE (1180000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
47#endif 47#endif
48 48
49/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ 49/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */