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:
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:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44: Lisp_Object Vabbrev_table_name_list;
45:
46:
47:
48:
49: Lisp_Object Vglobal_abbrev_table;
50:
51:
52:
53: Lisp_Object Vfundamental_mode_abbrev_table;
54:
55:
56:
57: int abbrevs_changed;
58:
59: int abbrev_all_caps;
60:
61:
62:
63:
64: Lisp_Object Vabbrev_start_location;
65:
66:
67: Lisp_Object Vabbrev_start_location_buffer;
68:
69:
70:
71: Lisp_Object Vlast_abbrev;
72:
73:
74:
75:
76: Lisp_Object Vlast_abbrev_text;
77:
78:
79:
80: EMACS_INT last_abbrev_point;
81:
82:
83:
84: Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
85:
86: Lisp_Object Qsystem_type, Qcount, Qforce;
87: ^L
88: DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
89: doc: )
90: ()
91: {
92:
93: return Fmake_vector (make_number (59), make_number (0));
94: }
95:
96: DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0,
97: doc: )
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:
111: DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 6, 0,
112: doc:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128: )
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:
137:
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: DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2,
176: "sDefine global abbrev: \nsExpansion for %s: ",
177: doc: )
178: (abbrev, expansion)
179: Lisp_Object abbrev, expansion;
180: {
181: Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
182: expansion, Qnil, make_number (0), Qnil);
183: return abbrev;
184: }
185:
186: DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
187: "sDefine mode abbrev: \nsExpansion for %s: ",
188: doc: )
189: (abbrev, expansion)
190: Lisp_Object abbrev, expansion;
191: {
192: if (NILP (current_buffer->abbrev_table))
193: error ("Major mode has no abbrev table");
194:
195: Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
196: expansion, Qnil, make_number (0), Qnil);
197: return abbrev;
198: }
199:
200: DEFUN ("abbrev-symbol", Fabbrev_symbol, Sabbrev_symbol, 1, 2, 0,
201: doc:
202:
203:
204:
205:
206: )
207: (abbrev, table)
208: Lisp_Object abbrev, table;
209: {
210: Lisp_Object sym;
211: CHECK_STRING (abbrev);
212: if (!NILP (table))
213: sym = Fintern_soft (abbrev, table);
214: else
215: {
216: sym = Qnil;
217: if (!NILP (current_buffer->abbrev_table))
218: sym = Fintern_soft (abbrev, current_buffer->abbrev_table);
219: if (NILP (SYMBOL_VALUE (sym)))
220: sym = Qnil;
221: if (NILP (sym))
222: sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
223: }
224: if (NILP (SYMBOL_VALUE (sym)))
225: return Qnil;
226: return sym;
227: }
228:
229: DEFUN ("abbrev-expansion", Fabbrev_expansion, Sabbrev_expansion, 1, 2, 0,
230: doc:
231:
232: )
233: (abbrev, table)
234: Lisp_Object abbrev, table;
235: {
236: Lisp_Object sym;
237: sym = Fabbrev_symbol (abbrev, table);
238: if (NILP (sym)) return sym;
239: return Fsymbol_value (sym);
240: }
241: ^L
242:
243:
244:
245: DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "",
246: doc:
247:
248: )
249: ()
250: {
251: register char *buffer, *p;
252: int wordstart, wordend;
253: register int wordstart_byte, wordend_byte, idx, idx_byte;
254: int whitecnt;
255: int uccount = 0, lccount = 0;
256: register Lisp_Object sym;
257: Lisp_Object expansion, hook, tem;
258: Lisp_Object value;
259: int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
260:
261: value = Qnil;
262:
263: Frun_hooks (1, &Qpre_abbrev_expand_hook);
264:
265: wordstart = 0;
266: if (!(BUFFERP (Vabbrev_start_location_buffer)
267: && XBUFFER (Vabbrev_start_location_buffer) == current_buffer))
268: Vabbrev_start_location = Qnil;
269: if (!NILP (Vabbrev_start_location))
270: {
271: tem = Vabbrev_start_location;
272: CHECK_NUMBER_COERCE_MARKER (tem);
273: wordstart = XINT (tem);
274: Vabbrev_start_location = Qnil;
275: if (wordstart < BEGV || wordstart > ZV)
276: wordstart = 0;
277: if (wordstart && wordstart != ZV)
278: {
279: wordstart_byte = CHAR_TO_BYTE (wordstart);
280: if (FETCH_BYTE (wordstart_byte) == '-')
281: del_range (wordstart, wordstart + 1);
282: }
283: }
284: if (!wordstart)
285: wordstart = scan_words (PT, -1);
286:
287: if (!wordstart)
288: return value;
289:
290: wordstart_byte = CHAR_TO_BYTE (wordstart);
291: wordend = scan_words (wordstart, 1);
292: if (!wordend)
293: return value;
294:
295: if (wordend > PT)
296: wordend = PT;
297:
298: wordend_byte = CHAR_TO_BYTE (wordend);
299: whitecnt = PT - wordend;
300: if (wordend <= wordstart)
301: return value;
302:
303: p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
304:
305: for (idx = wordstart, idx_byte = wordstart_byte; idx < wordend; )
306: {
307: register int c;
308:
309: if (multibyte)
310: {
311: FETCH_CHAR_ADVANCE (c, idx, idx_byte);
312: }
313: else
314: {
315: c = FETCH_BYTE (idx_byte);
316: idx++, idx_byte++;
317: }
318:
319: if (UPPERCASEP (c))
320: c = DOWNCASE (c), uccount++;
321: else if (! NOCASEP (c))
322: lccount++;
323: if (multibyte)
324: p += CHAR_STRING (c, p);
325: else
326: *p++ = c;
327: }
328:
329: if (VECTORP (current_buffer->abbrev_table))
330: sym = oblookup (current_buffer->abbrev_table, buffer,
331: wordend - wordstart, p - buffer);
332: else
333: XSETFASTINT (sym, 0);
334:
335: if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
336: sym = oblookup (Vglobal_abbrev_table, buffer,
337: wordend - wordstart, p - buffer);
338: if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
339: return value;
340:
341: if (INTERACTIVE && !EQ (minibuf_window, selected_window))
342: {
343:
344:
345: SET_PT (wordend);
346: Fundo_boundary ();
347: }
348:
349: Vlast_abbrev_text
350: = Fbuffer_substring (make_number (wordstart), make_number (wordend));
351:
352:
353: Vlast_abbrev = sym;
354: value = sym;
355: last_abbrev_point = wordstart;
356:
357:
358: if (INTEGERP (XSYMBOL (sym)->plist))
359: XSETINT (XSYMBOL (sym)->plist,
360: XINT (XSYMBOL (sym)->plist) + 1);
361: else if (INTEGERP (tem = Fget (sym, Qcount)))
362: Fput (sym, Qcount, make_number (XINT (tem) + 1));
363:
364:
365:
366: expansion = SYMBOL_VALUE (sym);
367: if (STRINGP (expansion))
368: {
369: SET_PT (wordstart);
370:
371: insert_from_string (expansion, 0, 0, SCHARS (expansion),
372: SBYTES (expansion), 1);
373: del_range_both (PT, PT_BYTE,
374: wordend + (PT - wordstart),
375: wordend_byte + (PT_BYTE - wordstart_byte),
376: 1);
377:
378: SET_PT (PT + whitecnt);
379:
380: if (uccount && !lccount)
381: {
382:
383:
384:
385:
386: if (!abbrev_all_caps)
387: if (scan_words (PT, -1) > scan_words (wordstart, 1))
388: {
389: Fupcase_initials_region (make_number (wordstart),
390: make_number (PT));
391: goto caped;
392: }
393:
394: Fupcase_region (make_number (wordstart), make_number (PT));
395: caped: ;
396: }
397: else if (uccount)
398: {
399:
400: int pos = wordstart_byte;
401:
402:
403: while (pos < PT_BYTE
404: && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword)
405: pos++;
406:
407:
408: pos = BYTE_TO_CHAR (pos);
409: Fupcase_initials_region (make_number (pos), make_number (pos + 1));
410: }
411: }
412:
413: hook = XSYMBOL (sym)->function;
414: if (!NILP (hook))
415: {
416: Lisp_Object expanded, prop;
417:
418:
419: expanded = call0 (hook);
420:
421:
422:
423:
424:
425:
426: if (SYMBOLP (hook)
427: && NILP (expanded)
428: && (prop = Fget (hook, intern ("no-self-insert")),
429: !NILP (prop)))
430: value = Qnil;
431: }
432:
433: return value;
434: }
435:
436: DEFUN ("unexpand-abbrev", Funexpand_abbrev, Sunexpand_abbrev, 0, 0, "",
437: doc:
438:
439: )
440: ()
441: {
442: int opoint = PT;
443: int adjust = 0;
444: if (last_abbrev_point < BEGV
445: || last_abbrev_point > ZV)
446: return Qnil;
447: SET_PT (last_abbrev_point);
448: if (STRINGP (Vlast_abbrev_text))
449: {
450:
451:
452: Lisp_Object val;
453: int zv_before;
454:
455: val = SYMBOL_VALUE (Vlast_abbrev);
456: if (!STRINGP (val))
457: error ("Value of `abbrev-symbol' must be a string");
458: zv_before = ZV;
459: del_range_byte (PT_BYTE, PT_BYTE + SBYTES (val), 1);
460:
461: insert_from_string (Vlast_abbrev_text, 0, 0,
462: SCHARS (Vlast_abbrev_text),
463: SBYTES (Vlast_abbrev_text), 0);
464: Vlast_abbrev_text = Qnil;
465:
466: adjust = ZV - zv_before;
467: }
468: SET_PT (last_abbrev_point < opoint ? opoint + adjust : opoint);
469: return Qnil;
470: }
471: ^L
472: static void
473: write_abbrev (sym, stream)
474: Lisp_Object sym, stream;
475: {
476: Lisp_Object name, count, system_flag;
477:
478: if (INTEGERP (XSYMBOL (sym)->plist))
479: {
480: count = XSYMBOL (sym)->plist;
481: system_flag = Qnil;
482: }
483: else
484: {
485: count = Fget (sym, Qcount);
486: system_flag = Fget (sym, Qsystem_type);
487: }
488:
489: if (NILP (SYMBOL_VALUE (sym)) || ! NILP (system_flag))
490: return;
491:
492: insert (" (", 5);
493: name = SYMBOL_NAME (sym);
494: Fprin1 (name, stream);
495: insert (" ", 1);
496: Fprin1 (SYMBOL_VALUE (sym), stream);
497: insert (" ", 1);
498: Fprin1 (XSYMBOL (sym)->function, stream);
499: insert (" ", 1);
500: Fprin1 (count, stream);
501: insert (")\n", 2);
502: }
503:
504: static void
505: describe_abbrev (sym, stream)
506: Lisp_Object sym, stream;
507: {
508: Lisp_Object one, count, system_flag;
509:
510: if (INTEGERP (XSYMBOL (sym)->plist))
511: {
512: count = XSYMBOL (sym)->plist;
513: system_flag = Qnil;
514: }
515: else
516: {
517: count = Fget (sym, Qcount);
518: system_flag = Fget (sym, Qsystem_type);
519: }
520:
521: if (NILP (SYMBOL_VALUE (sym)))
522: return;
523:
524: one = make_number (1);
525: Fprin1 (Fsymbol_name (sym), stream);
526:
527: if (!NILP (system_flag))
528: {
529: insert_string (" (sys)");
530: Findent_to (make_number (20), one);
531: }
532: else
533: Findent_to (make_number (15), one);
534:
535: Fprin1 (count, stream);
536: Findent_to (make_number (20), one);
537: Fprin1 (SYMBOL_VALUE (sym), stream);
538: if (!NILP (XSYMBOL (sym)->function))
539: {
540: Findent_to (make_number (45), one);
541: Fprin1 (XSYMBOL (sym)->function, stream);
542: }
543: Fterpri (stream);
544: }
545:
546: static void
547: record_symbol (sym, list)
548: Lisp_Object sym, list;
549: {
550: XSETCDR (list, Fcons (sym, XCDR (list)));
551: }
552:
553: DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description,
554: Sinsert_abbrev_table_description, 1, 2, 0,
555: doc:
556:
557:
558:
559:
560:
561:
562:
563: )
564: (name, readable)
565: Lisp_Object name, readable;
566: {
567: Lisp_Object table;
568: Lisp_Object symbols;
569: Lisp_Object stream;
570:
571: CHECK_SYMBOL (name);
572: table = Fsymbol_value (name);
573: CHECK_VECTOR (table);
574:
575: XSETBUFFER (stream, current_buffer);
576:
577: symbols = Fcons (Qnil, Qnil);
578: map_obarray (table, record_symbol, symbols);
579: symbols = XCDR (symbols);
580: symbols = Fsort (symbols, Qstring_lessp);
581:
582: if (!NILP (readable))
583: {
584: insert_string ("(");
585: Fprin1 (name, stream);
586: insert_string (")\n\n");
587: while (! NILP (symbols))
588: {
589: describe_abbrev (XCAR (symbols), stream);
590: symbols = XCDR (symbols);
591: }
592:
593: insert_string ("\n\n");
594: }
595: else
596: {
597: insert_string ("(define-abbrev-table '");
598: Fprin1 (name, stream);
599: insert_string (" '(\n");
600: while (! NILP (symbols))
601: {
602: write_abbrev (XCAR (symbols), stream);
603: symbols = XCDR (symbols);
604: }
605: insert_string (" ))\n\n");
606: }
607:
608: return Qnil;
609: