Annotation of 43BSDReno/contrib/emacs-18.55/src/abbrev.c, revision 1.1.1.1

1.1       root        1: /* Primitives for word-abbrev mode.
                      2:    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: GNU Emacs General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU Emacs so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: #include <stdio.h>
                     24: #undef NULL
                     25: #include "lisp.h"
                     26: #include "commands.h"
                     27: #include "buffer.h"
                     28: #include "window.h"
                     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: 
                     41: Lisp_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: 
                     46: Lisp_Object Vglobal_abbrev_table;
                     47: 
                     48: /* The local abbrev table used by default (in Fundamental Mode buffers) */
                     49: 
                     50: Lisp_Object Vfundamental_mode_abbrev_table;
                     51: 
                     52: /* Set nonzero when an abbrev definition is changed */
                     53: 
                     54: int abbrevs_changed;
                     55: 
                     56: int 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: 
                     61: Lisp_Object Vabbrev_start_location;
                     62: 
                     63: /* Buffer that Vabbrev_start_location applies to */
                     64: Lisp_Object Vabbrev_start_location_buffer;
                     65: 
                     66: /* The symbol representing the abbrev most recently expanded */
                     67: 
                     68: Lisp_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: 
                     73: Lisp_Object Vlast_abbrev_text;
                     74: 
                     75: /* Character address of start of last abbrev expanded */
                     76: 
                     77: int last_abbrev_point;
                     78: 
                     79: extern Lisp_Object oblookup ();
                     80: 
                     81: DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
                     82:   "Create a new, empty abbrev table object.")
                     83:   ()
                     84: {
                     85:   return Fmake_vector (make_number (59), make_number (0));
                     86: }
                     87: 
                     88: DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0,
                     89:   "Undefine all abbrevs in abbrev table TABLE, leaving it empty.")
                     90:   (table)
                     91:      Lisp_Object table;
                     92: {
                     93:   int i, size;
                     94: 
                     95:   CHECK_VECTOR (table, 0);
                     96:   size = XVECTOR (table)->size;
                     97:   abbrevs_changed = 1;
                     98:   for (i = 0; i < size; i++)
                     99:     XVECTOR (table)->contents[i] = make_number (0);
                    100:   return Qnil;
                    101: }
                    102: 
                    103: DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 5, 0,
                    104:   "Define an abbrev in TABLE named NAME, to expand to EXPANSION or call HOOK.\n\
                    105: NAME and EXPANSION are strings.  HOOK is a function or nil.\n\
                    106: To undefine an abbrev, define it with EXPANSION = nil")
                    107:   (table, name, expansion, hook, count)
                    108:      Lisp_Object table, name, expansion, hook, count;
                    109: {
                    110:   Lisp_Object sym, oexp, ohook, tem;
                    111:   CHECK_VECTOR (table, 0);
                    112:   CHECK_STRING (name, 1);
                    113:   CHECK_STRING (expansion, 2);
                    114:   if (NULL (count))
                    115:     count = make_number (0);
                    116:   else
                    117:     CHECK_NUMBER (count, 0);
                    118: 
                    119:   sym = Fintern (name, table);
                    120: 
                    121:   oexp = XSYMBOL (sym)->value;
                    122:   ohook = XSYMBOL (sym)->function;
                    123:   if (!((EQ (oexp, expansion)
                    124:         || (XTYPE (oexp) == Lisp_String
                    125:             && (tem = Fstring_equal (oexp, expansion), !NULL (tem))))
                    126:        &&
                    127:        (EQ (ohook, hook)
                    128:         || (tem = Fequal (ohook, hook), !NULL (tem)))))
                    129:     abbrevs_changed = 1;
                    130: 
                    131:   Fset (sym, expansion);
                    132:   Ffset (sym, hook);
                    133:   Fsetplist (sym, count);
                    134: 
                    135:   return name;
                    136: }
                    137: 
                    138: DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2,
                    139:   "sDefine global abbrev: \nsExpansion for %s: ",
                    140:   "Define ABBREV as a global abbreviation for EXPANSION.")
                    141:   (name, expansion)
                    142:      Lisp_Object name, expansion;
                    143: {
                    144:   Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (name),
                    145:                  expansion, Qnil, make_number (0));
                    146:   return name;
                    147: }
                    148: 
                    149: DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
                    150:   "sDefine mode abbrev: \nsExpansion for %s: ",
                    151:   "Define ABBREV as a mode-specific abbreviation for EXPANSION.")
                    152:   (name, expansion)
                    153:      Lisp_Object name, expansion;
                    154: {
                    155:   if (NULL (bf_cur->abbrev_table))
                    156:     error ("No local abbrev table associated with this buffer");
                    157: 
                    158:   Fdefine_abbrev (bf_cur->abbrev_table, Fdowncase (name),
                    159:                  expansion, Qnil, make_number (0));
                    160:   return name;
                    161: }
                    162: 
                    163: DEFUN ("abbrev-symbol", Fabbrev_symbol, Sabbrev_symbol, 1, 2, 0,
                    164:   "Return the symbol representing abbrev named ABBREV.\n\
                    165: Value is nil if that abbrev is not defined.\n\
                    166: Optional second arg TABLE is abbrev table to look it up in.\n\
                    167: Default is try buffer's mode-specific abbrev table, then global table.")
                    168:   (abbrev, table)
                    169:      Lisp_Object abbrev, table;
                    170: {
                    171:   Lisp_Object sym;
                    172:   CHECK_STRING (abbrev, 0);
                    173:   if (!NULL (table))
                    174:     sym = Fintern_soft (abbrev, table);
                    175:   else
                    176:     {
                    177:       sym = Qnil;
                    178:       if (!NULL (bf_cur->abbrev_table))
                    179:        sym = Fintern_soft (abbrev, bf_cur->abbrev_table);
                    180:       if (NULL (XSYMBOL (sym)->value))
                    181:        sym = Qnil;
                    182:       if (NULL (sym))
                    183:        sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
                    184:     }
                    185:   if (NULL (XSYMBOL (sym)->value)) return Qnil;
                    186:   return sym;
                    187: }
                    188: 
                    189: DEFUN ("abbrev-expansion", Fabbrev_expansion, Sabbrev_expansion, 1, 2, 0,
                    190:   "Return the string that ABBREV expands into in the current buffer.\n\
                    191: Optionally specify an abbrev table; then ABBREV is looked up in that table only.")
                    192:   (abbrev, table)
                    193:      Lisp_Object abbrev, table;
                    194: {
                    195:   Lisp_Object sym;
                    196:   sym = Fabbrev_symbol (abbrev, table);
                    197:   if (NULL (sym)) return sym;
                    198:   return Fsymbol_value (sym);
                    199: }
                    200: 
                    201: /* Expand the word before point, if it is an abbrev.
                    202:   Returns 1 if an expansion is done. */
                    203: 
                    204: DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "",
                    205:   "Expand the abbrev before point, if it is an abbrev.\n\
                    206: Effective when explicitly called even when abbrev-mode is not enabled.\n\
                    207: Returns t if expansion took place.")
                    208:   ()
                    209: {
                    210:   char buffer[200];
                    211:   register char *p = buffer;
                    212:   register int wordstart, idx;
                    213:   int uccount = 0, lccount = 0;
                    214:   register Lisp_Object sym;
                    215:   Lisp_Object expansion, hook, tem;
                    216: 
                    217:   if (XBUFFER (Vabbrev_start_location_buffer) != bf_cur)
                    218:     Vabbrev_start_location = Qnil;
                    219:   if (!NULL (Vabbrev_start_location))
                    220:     {
                    221:       tem = Vabbrev_start_location;
                    222:       CHECK_NUMBER_COERCE_MARKER (tem, 0);
                    223:       wordstart = XINT (tem);
                    224:       Vabbrev_start_location = Qnil;
                    225:       if (CharAt (wordstart) == '-')
                    226:        del_range (wordstart, wordstart + 1);
                    227:     }
                    228:   else
                    229:     wordstart = scan_words (point, -1);
                    230: 
                    231:   if (!wordstart || point - wordstart >= sizeof buffer || point <= wordstart)
                    232:     return Qnil;
                    233: 
                    234:   for (idx = wordstart; idx < point; idx++)
                    235:     {
                    236:       register int c = CharAt (idx);
                    237:       if (UPPERCASEP (c))
                    238:        c = DOWNCASE (c), uccount++;
                    239:       else if (! NOCASEP (c))
                    240:        lccount++;
                    241:       *p++ = c;
                    242:     }
                    243: 
                    244:   if (XTYPE (bf_cur->abbrev_table) == Lisp_Vector)
                    245:     sym = oblookup (bf_cur->abbrev_table, buffer, p - buffer);
                    246:   else
                    247:     XFASTINT (sym) = 0;
                    248:   if (XTYPE (sym) == Lisp_Int ||
                    249:       NULL (XSYMBOL (sym)->value))
                    250:     sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer);
                    251:   if (XTYPE (sym) == Lisp_Int ||
                    252:       NULL (XSYMBOL (sym)->value))
                    253:     return Qnil;
                    254: 
                    255:   if (INTERACTIVE && !EQ (minibuf_window, selected_window))
                    256:     {
                    257:       SetPoint (wordstart + p - buffer);
                    258:       Fundo_boundary ();
                    259:     }
                    260:   SetPoint (wordstart);
                    261:   Vlast_abbrev_text
                    262:     = Fbuffer_substring (make_number (point),
                    263:                         make_number (point + (p - buffer)));
                    264:   del_range (point, point + (p - buffer));
                    265: 
                    266:   /* Now sym is the abbrev symbol. */
                    267:   Vlast_abbrev = sym;
                    268:   last_abbrev_point = point;
                    269: 
                    270:   if (XTYPE (XSYMBOL (sym)->plist) == Lisp_Int)
                    271:     XSETINT (XSYMBOL (sym)->plist,
                    272:             XINT (XSYMBOL (sym)->plist) + 1);  /* Increment use count */
                    273: 
                    274:   expansion = XSYMBOL (sym)->value;
                    275:   InsCStr (XSTRING (expansion)->data, XSTRING (expansion)->size);
                    276: 
                    277:   if (uccount && !lccount)
                    278:     {
                    279:       /* Abbrev was all caps */
                    280:       /* If expansion is multiple words, normally capitalize each word */
                    281:       /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
                    282:         but Megatest 68000 compiler can't handle that */
                    283:       if (!abbrev_all_caps)
                    284:        if (scan_words (point, -1) > scan_words (wordstart, 1))
                    285:          {
                    286:            upcase_initials_region (make_number (wordstart),
                    287:                                    make_number (point));
                    288:            goto caped;
                    289:          }
                    290:       /* If expansion is one word, or if user says so, upcase it all. */
                    291:       Fupcase_region (make_number (wordstart), make_number (point));
                    292:     caped: ;
                    293:     }
                    294:   else if (uccount)
                    295:     {
                    296:       /* Abbrev included some caps.  Cap first initial of expansion */
                    297:       idx = point;
                    298:       SetPoint (wordstart);
                    299:       Fcapitalize_word (make_number (1));
                    300:       SetPoint (idx);
                    301:     }
                    302: 
                    303:   hook = XSYMBOL (sym)->function;
                    304:   if (!NULL (hook))
                    305:     call0 (hook);
                    306: 
                    307:   return Qt;
                    308: }
                    309: 
                    310: DEFUN ("unexpand-abbrev", Funexpand_abbrev, Sunexpand_abbrev, 0, 0, "",
                    311:   "Undo the expansion of the last abbrev that expanded.")
                    312:   ()
                    313: {
                    314:   int opoint = point;
                    315:   int adjust = 0;
                    316:   if (last_abbrev_point < FirstCharacter
                    317:       || last_abbrev_point > NumCharacters)
                    318:     return Qnil;
                    319:   SetPoint (last_abbrev_point);
                    320:   if (XTYPE (Vlast_abbrev_text) == Lisp_String)
                    321:     {
                    322:       /* This isn't correct if Vlast_abbrev->function was used
                    323:          to do the expansion */
                    324:       Lisp_Object val;
                    325:       XSET (val, Lisp_String, XSYMBOL (Vlast_abbrev)->value);
                    326:       adjust = XSTRING (val)->size;
                    327:       del_range (point, point + adjust);
                    328:       InsCStr (XSTRING (Vlast_abbrev_text)->data,
                    329:               XSTRING (Vlast_abbrev_text)->size);
                    330:       adjust -= XSTRING (Vlast_abbrev_text)->size;
                    331:       Vlast_abbrev_text = Qnil;
                    332:     }
                    333:   SetPoint (last_abbrev_point < opoint ? opoint - adjust : opoint);
                    334:   return Qnil;
                    335: }
                    336: 
                    337: static
                    338: write_abbrev (sym, stream)
                    339:      Lisp_Object sym, stream;
                    340: {
                    341:   Lisp_Object name;
                    342:   if (NULL (XSYMBOL (sym)->value))
                    343:     return;
                    344:   InsCStr ("    (", 5);
                    345:   XSET (name, Lisp_String, XSYMBOL (sym)->name);
                    346:   Fprin1 (name, stream);
                    347:   InsCStr (" ", 1);
                    348:   Fprin1 (XSYMBOL (sym)->value, stream);
                    349:   InsCStr (" ", 1);
                    350:   Fprin1 (XSYMBOL (sym)->function, stream);
                    351:   InsCStr (" ", 1);
                    352:   Fprin1 (XSYMBOL (sym)->plist, stream);
                    353:   InsCStr (")\n", 2);
                    354: }
                    355: 
                    356: static
                    357: describe_abbrev (sym, stream)
                    358:      Lisp_Object sym, stream;
                    359: {
                    360:   Lisp_Object one;
                    361: 
                    362:   if (NULL (XSYMBOL (sym)->value))
                    363:     return;
                    364:   one = make_number (1);
                    365:   Fprin1 (Fsymbol_name (sym), stream);
                    366:   Findent_to (make_number (15), one);
                    367:   Fprin1 (XSYMBOL (sym)->plist, stream);
                    368:   Findent_to (make_number (20), one);
                    369:   Fprin1 (XSYMBOL (sym)->value, stream);
                    370:   if (!NULL (XSYMBOL (sym)->function))
                    371:     {
                    372:       Findent_to (make_number (45), one);
                    373:       Fprin1 (XSYMBOL (sym)->function, stream);
                    374:     }
                    375:   Fterpri (stream);
                    376: }
                    377: 
                    378: DEFUN ("insert-abbrev-table-description",
                    379:   Finsert_abbrev_table_description, Sinsert_abbrev_table_description,
                    380:   2, 2, 0,
                    381:   "Insert before point a description of abbrev table named NAME.\n\
                    382: NAME is a symbol whose value is an abbrev table.\n\
                    383: If 2nd arg READABLE is non-nil, a readable description is inserted.\n\
                    384: Otherwise description is an expression,\n\
                    385: a call to define-abbrev-table which would\n\
                    386: define NAME exactly as it is currently defined.")
                    387:   (name, readable)
                    388:      Lisp_Object name, readable;
                    389: {
                    390:   Lisp_Object table;
                    391:   Lisp_Object stream;
                    392: 
                    393:   CHECK_SYMBOL (name, 0);
                    394:   table = Fsymbol_value (name);
                    395:   CHECK_VECTOR (table, 0);
                    396: 
                    397:   XSET (stream, Lisp_Buffer, bf_cur);
                    398: 
                    399:   if (!NULL (readable))
                    400:     {
                    401:       InsStr ("(");
                    402:       Fprin1 (name, stream);
                    403:       InsStr (")\n\n");
                    404:       map_obarray (table, describe_abbrev, stream);
                    405:       InsStr ("\n\n");
                    406:     }
                    407:   else
                    408:     {
                    409:       InsStr ("(define-abbrev-table '");
                    410:       Fprin1 (name, stream);
                    411:       InsStr (" '(\n");
                    412:       map_obarray (table, write_abbrev, stream);
                    413:       InsStr ("    ))\n\n");
                    414:     }
                    415: 
                    416:   return Qnil;
                    417: }
                    418: 
                    419: DEFUN ("define-abbrev-table", Fdefine_abbrev_table, Sdefine_abbrev_table,
                    420:        2, 2, 0,
                    421:   "Define TABNAME (a symbol) as an abbrev table name.\n\
                    422: Define abbrevs in it according to DEFINITIONS, a list of elements\n\
                    423: of the form (ABBREVNAME EXPANSION HOOK USECOUNT).")
                    424:   (tabname, defns)
                    425:      Lisp_Object tabname, defns;
                    426: {
                    427:   Lisp_Object name, exp, hook, count;
                    428:   Lisp_Object table, elt;
                    429: 
                    430:   CHECK_SYMBOL (tabname, 0);
                    431:   table = Fboundp (tabname);
                    432:   if (NULL (table) || (table = Fsymbol_value (tabname), NULL (table)))
                    433:     {
                    434:       table = Fmake_abbrev_table ();
                    435:       Fset (tabname, table);
                    436:       Vabbrev_table_name_list =
                    437:        Fcons (tabname, Vabbrev_table_name_list);
                    438:     }
                    439:   CHECK_VECTOR (table, 0);
                    440: 
                    441:   for (;!NULL (defns); defns = Fcdr (defns))
                    442:     {
                    443:       elt = Fcar (defns);
                    444:       name = Fcar (elt);
                    445:       elt = Fcdr (elt);
                    446:       exp = Fcar (elt);
                    447:       elt = Fcdr (elt);
                    448:       hook = Fcar (elt);
                    449:       elt = Fcdr (elt);
                    450:       count = Fcar (elt);
                    451:       Fdefine_abbrev (table, name, exp, hook, count);
                    452:     }
                    453:   return Qnil;
                    454: }
                    455: 
                    456: syms_of_abbrev ()
                    457: {
                    458:   DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
                    459:     "List of symbols whose values are  abbrev tables.");
                    460:   Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
                    461:                                   Fcons (intern ("global-abbrev-table"),
                    462:                                          Qnil));
                    463: 
                    464:   DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table,
                    465:     "The abbrev table whose abbrevs affect all buffers.\n\
                    466: Each buffer may also have a local abbrev table.\n\
                    467: If it does, the local table overrides the global one\n\
                    468: for any particular abbrev defined in both.");
                    469:   Vglobal_abbrev_table = Fmake_abbrev_table ();
                    470: 
                    471:   DEFVAR_LISP ("fundamental-mode-abbrev-table", &Vfundamental_mode_abbrev_table,
                    472:     "The abbrev table of mode-specific abbrevs for Fundamental Mode.");
                    473:   Vfundamental_mode_abbrev_table = Fmake_abbrev_table ();
                    474:   bf_cur->abbrev_table = Vfundamental_mode_abbrev_table;
                    475: 
                    476:   DEFVAR_LISP ("last-abbrev", &Vlast_abbrev,
                    477:     "The abbrev-symbol of the last abbrev expanded.");
                    478: 
                    479:   DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text,
                    480:     "The exact text of the last abbrev expanded.\n\
                    481: nil if the abbrev has already been unexpanded.");
                    482: 
                    483:   DEFVAR_INT ("last-abbrev-location", &last_abbrev_point,
                    484:     "The location of the last abbrev expanded.");
                    485: 
                    486:   Vlast_abbrev = Qnil;
                    487:   Vlast_abbrev_text = Qnil;
                    488:   last_abbrev_point = 0;
                    489: 
                    490:   DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location,
                    491:     "Buffer position for expand-abbrev to use as the start of the abbrev.\n\
                    492: nil means use the word before point as the abbrev.\n\
                    493: Set to nil each time expand-abbrev is called.");
                    494:   Vabbrev_start_location = Qnil;
                    495: 
                    496:   DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer,
                    497:     "Buffer that abbrev-start-location has been set for.\n\
                    498: Trying to expand an abbrev in any other buffer clears abbrev-start-location.");
                    499:   Vabbrev_start_location_buffer = Qnil;
                    500: 
                    501:   DEFVAR_PER_BUFFER ("local-abbrev-table", &bf_cur->abbrev_table,
                    502:     "Local (mode-specific) abbrev table of current buffer.");
                    503: 
                    504:   DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed,
                    505:     "Set non-nil by defining or altering any word abbrevs.");
                    506:   abbrevs_changed = 0;
                    507: 
                    508:   DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps,
                    509:     "*Set non-nil means expand multi-word abbrevs all caps if abbrev was so.");
                    510:   abbrev_all_caps = 0;
                    511: 
                    512:   defsubr (&Smake_abbrev_table);
                    513:   defsubr (&Sclear_abbrev_table);
                    514:   defsubr (&Sdefine_abbrev);
                    515:   defsubr (&Sdefine_global_abbrev);
                    516:   defsubr (&Sdefine_mode_abbrev);
                    517:   defsubr (&Sabbrev_expansion);
                    518:   defsubr (&Sabbrev_symbol);
                    519:   defsubr (&Sexpand_abbrev);
                    520:   defsubr (&Sunexpand_abbrev);
                    521:   defsubr (&Sinsert_abbrev_table_description);
                    522:   defsubr (&Sdefine_abbrev_table);
                    523: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.