This is abbrev.c in view mode; [Download] [Up]
/* Primitives for word-abbrev mode. Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc. This file is part of XEmacs. XEmacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Synched up with: FSF 19.28. Note that there are many more functions in FSF's abbrev.c. These have been moved into Lisp in XEmacs. */ /* This file has been Mule-ized. */ #include <config.h> #include "lisp.h" #include "commands.h" #include "buffer.h" #include "window.h" #include "insdel.h" /* An abbrev table is an obarray. Each defined abbrev is represented by a symbol in that obarray whose print name is the abbreviation. The symbol's value is a string which is the expansion. If its function definition is non-nil, it is called after the expansion is done. The plist slot of the abbrev symbol is its usage count. */ /* The table of global abbrevs. These are in effect in any buffer in which abbrev mode is turned on. */ Lisp_Object Vglobal_abbrev_table; int abbrev_all_caps; /* Non-nil => use this location as the start of abbrev to expand (rather than taking the word before point as the abbrev) */ Lisp_Object Vabbrev_start_location; /* Buffer that Vabbrev_start_location applies to */ Lisp_Object Vabbrev_start_location_buffer; /* The symbol representing the abbrev most recently expanded */ Lisp_Object Vlast_abbrev; /* A string for the actual text of the abbrev most recently expanded. This has more info than Vlast_abbrev since case is significant. */ Lisp_Object Vlast_abbrev_text; /* Character address of start of last abbrev expanded */ int last_abbrev_point; /* Hook to run before expanding any abbrev. */ Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook; /* Expand the word before point, if it is an abbrev. Returns Qt if an expansion is done. */ DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "", "Expand the abbrev before point, if there is an abbrev there.\n\ Effective when explicitly called even when `abbrev-mode' is nil.\n\ Returns t if expansion took place.") () { /* This function can GC */ REGISTER Bufbyte *buffer, *p; REGISTER Bufpos wordstart, wordend, idx; Charcount whitecnt; Charcount uccount = 0, lccount = 0; REGISTER Lisp_Object sym; Lisp_Object expansion, hook, value; struct buffer *buf = current_buffer; Lisp_Object lbuf; int oldmodiff = BUF_MODIFF (buf); XSETBUFFER (lbuf, buf); if (!NILP (Vrun_hooks)) call1 (Vrun_hooks, Qpre_abbrev_expand_hook); /* If the hook changes the buffer, treat that as having "done an expansion". */ value = (BUF_MODIFF (buf) != oldmodiff ? Qt : Qnil); if (!BUFFERP (Vabbrev_start_location_buffer) || XBUFFER (Vabbrev_start_location_buffer) != buf) Vabbrev_start_location = Qnil; if (!NILP (Vabbrev_start_location)) { wordstart = get_bufpos (buf, Vabbrev_start_location, GB_COERCE_RANGE); Vabbrev_start_location = Qnil; if (BUF_FETCH_CHAR (buf, wordstart) == '-') buffer_delete_range (buf, wordstart, wordstart + 1, 0); } else wordstart = scan_words (buf, BUF_PT (buf), -1); if (!wordstart) return value; wordend = scan_words (buf, wordstart, 1); if (!wordend) return value; if (wordend > BUF_PT (buf)) wordend = BUF_PT (buf); whitecnt = BUF_PT (buf) - wordend; if (wordend <= wordstart) return value; p = buffer = (Bufbyte *) alloca (MAX_EMCHAR_LEN*(wordend - wordstart)); for (idx = wordstart; idx < wordend; idx++) { REGISTER Emchar c = BUF_FETCH_CHAR (buf, idx); if (UPPERCASEP (buf, c)) c = DOWNCASE (buf, c), uccount++; else if (! NOCASEP (buf, c)) lccount++; p += emchar_to_charptr (c, p); } if (VECTORP (buf->abbrev_table)) sym = oblookup (buf->abbrev_table, buffer, p - buffer); else sym = Qzero; if (INTP (sym) || NILP (XSYMBOL (sym)->value)) sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); if (INTP (sym) || NILP (XSYMBOL (sym)->value)) return value; if (INTERACTIVE && !EQ (minibuf_window, Fselected_window (Qnil))) { BUF_SET_PT (buf, wordend); Fundo_boundary (); } BUF_SET_PT (buf, wordstart); Vlast_abbrev_text = make_string_from_buffer (buf, wordstart, wordend - wordstart); buffer_delete_range (buf, wordstart, wordend, 0); /* Now sym is the abbrev symbol. */ Vlast_abbrev = sym; last_abbrev_point = wordstart; if (INTP (XSYMBOL (sym)->plist)) XSETINT (XSYMBOL (sym)->plist, XINT (XSYMBOL (sym)->plist) + 1); /* Increment use count */ expansion = XSYMBOL (sym)->value; buffer_insert_lisp_string (buf, expansion); BUF_SET_PT (buf, BUF_PT (buf) + whitecnt); if (uccount && !lccount) { /* Abbrev was all caps */ /* If expansion is multiple words, normally capitalize each word */ /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase but Megatest 68000 compiler can't handle that */ if (!abbrev_all_caps) if (scan_words (buf, BUF_PT (buf), -1) > scan_words (buf, wordstart, 1)) { upcase_initials_region (buf, make_number (wordstart), make_number (BUF_PT (buf))); goto caped; } /* If expansion is one word, or if user says so, upcase it all. */ Fupcase_region (make_number (wordstart), make_number (BUF_PT (buf)), lbuf); caped: ; } else if (uccount) { /* Abbrev included some caps. Cap first initial of expansion */ int speccount = specpdl_depth (); Bufpos old_pt = BUF_PT (buf); /* Don't let Fcapitalize_word operate on text after point. */ record_unwind_protect (save_restriction_restore, save_restriction_save ()); Fnarrow_to_region (make_number (BUF_BEGV (buf)), make_number (BUF_PT (buf)), lbuf); BUF_SET_PT (buf, wordstart); Fcapitalize_word (make_number (1), lbuf); BUF_SET_PT (buf, old_pt); unbind_to (speccount, Qnil); } hook = XSYMBOL (sym)->function; if (!NILP (hook) && !EQ (hook, Qunbound)) call0 (hook); return Qt; } void syms_of_abbrev (void) { defsymbol (&Qpre_abbrev_expand_hook, "pre-abbrev-expand-hook"); defsubr (&Sexpand_abbrev); } void vars_of_abbrev (void) { DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table, "The abbrev table whose abbrevs affect all buffers.\n\ Each buffer may also have a local abbrev table.\n\ If it does, the local table overrides the global one\n\ for any particular abbrev defined in both."); Vglobal_abbrev_table = Qnil; /* setup by Lisp code */ DEFVAR_LISP ("last-abbrev", &Vlast_abbrev, "The abbrev-symbol of the last abbrev expanded.\n\ See the function `abbrev-symbol'."); DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text, "The exact text of the last abbrev expanded.\n\ nil if the abbrev has already been unexpanded."); DEFVAR_INT ("last-abbrev-location", &last_abbrev_point, "The location of the start of the last abbrev expanded."); Vlast_abbrev = Qnil; Vlast_abbrev_text = Qnil; last_abbrev_point = 0; DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location, "Buffer position for `expand-abbrev' to use as the start of the abbrev.\n\ nil means use the word before point as the abbrev.\n\ Calling `expand-abbrev' sets this to nil."); Vabbrev_start_location = Qnil; DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer, "Buffer that `abbrev-start-location' has been set for.\n\ Trying to expand an abbrev in any other buffer clears `abbrev-start-location'."); Vabbrev_start_location_buffer = Qnil; DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps, "*Set non-nil means expand multi-word abbrevs all caps if abbrev was so."); abbrev_all_caps = 0; DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook, "Function or functions to be called before abbrev expansion is done.\n\ This is the first thing that `expand-abbrev' does, and so this may change\n\ the current abbrev table before abbrev lookup happens."); Vpre_abbrev_expand_hook = Qnil; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.