/* Primitives for word-abbrev mode.
- Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1996, 1998 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "commands.h"
#include "buffer.h"
#include "window.h"
+#include "charset.h"
#include "syntax.h"
/* An abbrev table is an obarray.
If HOOK is non-nil, it should be a function of no arguments;\n\
it is called after EXPANSION is inserted.\n\
If EXPANSION is not a string, the abbrev is a special one,\n\
- which does not expand in the usual way but only runs HOOK.")
+ which does not expand in the usual way but only runs HOOK.\n\
+COUNT, if specified, initializes the abbrev's usage-count\n\
+which is incremented each time the abbrev is used.")
(table, name, expansion, hook, count)
Lisp_Object table, name, expansion, hook, count;
{
()
{
register char *buffer, *p;
- register int wordstart, wordend, idx;
+ int wordstart, wordend;
+ register int wordstart_byte, wordend_byte, idx;
int whitecnt;
int uccount = 0, lccount = 0;
register Lisp_Object sym;
Lisp_Object expansion, hook, tem;
- int oldmodiff = MODIFF;
Lisp_Object value;
value = Qnil;
Vabbrev_start_location = Qnil;
if (wordstart < BEGV || wordstart > ZV)
wordstart = 0;
- if (wordstart && wordstart != ZV && FETCH_BYTE (wordstart) == '-')
- del_range (wordstart, wordstart + 1);
+ if (wordstart && wordstart != ZV)
+ {
+ wordstart_byte = CHAR_TO_BYTE (wordstart);
+ if (FETCH_BYTE (wordstart_byte) == '-')
+ del_range (wordstart, wordstart + 1);
+ }
}
if (!wordstart)
wordstart = scan_words (PT, -1);
if (!wordstart)
return value;
+ wordstart_byte = CHAR_TO_BYTE (wordstart);
wordend = scan_words (wordstart, 1);
if (!wordend)
return value;
if (wordend > PT)
wordend = PT;
+
+ wordend_byte = CHAR_TO_BYTE (wordend);
whitecnt = PT - wordend;
if (wordend <= wordstart)
return value;
- p = buffer = (char *) alloca (wordend - wordstart);
+ p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
- for (idx = wordstart; idx < wordend; idx++)
+ for (idx = wordstart_byte; idx < wordend_byte; idx++)
{
+ /* ??? This loop needs to go by characters! */
register int c = FETCH_BYTE (idx);
if (UPPERCASEP (c))
c = DOWNCASE (c), uccount++;
}
if (VECTORP (current_buffer->abbrev_table))
- sym = oblookup (current_buffer->abbrev_table, buffer, p - buffer);
+ sym = oblookup (current_buffer->abbrev_table, buffer,
+ wordend - wordstart, wordend_byte - wordstart_byte);
else
XSETFASTINT (sym, 0);
if (INTEGERP (sym) || NILP (XSYMBOL (sym)->value))
- sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer);
+ sym = oblookup (Vglobal_abbrev_table, buffer,
+ wordend - wordstart, wordend_byte - wordstart_byte);
if (INTEGERP (sym) || NILP (XSYMBOL (sym)->value))
return value;
{
SET_PT (wordstart);
- del_range (wordstart, wordend);
+ del_range_both (wordstart, wordstart_byte, wordend, wordend_byte, 1);
- insert_from_string (expansion, 0, XSTRING (expansion)->size, 1);
+ insert_from_string (expansion, 0, 0, XSTRING (expansion)->size,
+ STRING_BYTES (XSTRING (expansion)), 1);
SET_PT (PT + whitecnt);
if (uccount && !lccount)
else if (uccount)
{
/* Abbrev included some caps. Cap first initial of expansion */
- int pos = wordstart;
+ int pos = wordstart_byte;
/* Find the initial. */
- while (pos < PT
- && SYNTAX (*BUF_CHAR_ADDRESS (current_buffer, pos)) != Sword)
+ while (pos < PT_BYTE
+ && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword)
pos++;
/* Change just that. */
+ pos = BYTE_TO_CHAR (pos);
Fupcase_initials_region (make_number (pos), make_number (pos + 1));
}
}
hook = XSYMBOL (sym)->function;
if (!NILP (hook))
- call0 (hook);
+ {
+ Lisp_Object expanded, prop;
+
+ /* If the abbrev has a hook function, run it. */
+ expanded = call0 (hook);
+
+ /* In addition, if the hook function is a symbol with a a
+ non-nil `no-self-insert' property, let the value it returned
+ specify whether we consider that an expansion took place. If
+ it returns nil, no expansion has been done. */
+
+ if (SYMBOLP (hook)
+ && NILP (expanded)
+ && (prop = Fget (hook, intern ("no-self-insert")),
+ !NILP (prop)))
+ value = Qnil;
+ }
return value;
}
/* This isn't correct if Vlast_abbrev->function was used
to do the expansion */
Lisp_Object val;
+ int zv_before;
+
val = XSYMBOL (Vlast_abbrev)->value;
if (!STRINGP (val))
error ("value of abbrev-symbol must be a string");
- adjust = XSTRING (val)->size;
- del_range (PT, PT + adjust);
+ zv_before = ZV;
+ del_range_byte (PT_BYTE, PT_BYTE + STRING_BYTES (XSTRING (val)), 1);
/* Don't inherit properties here; just copy from old contents. */
- insert_from_string (Vlast_abbrev_text, 0,
- XSTRING (Vlast_abbrev_text)->size, 0);
- adjust -= XSTRING (Vlast_abbrev_text)->size;
+ insert_from_string (Vlast_abbrev_text, 0, 0,
+ XSTRING (Vlast_abbrev_text)->size,
+ STRING_BYTES (XSTRING (Vlast_abbrev_text)), 0);
Vlast_abbrev_text = Qnil;
+ /* Total number of characters deleted. */
+ adjust = ZV - zv_before;
}
- SET_PT (last_abbrev_point < opoint ? opoint - adjust : opoint);
+ SET_PT (last_abbrev_point < opoint ? opoint + adjust : opoint);
return Qnil;
}
\f
-static
+static void
write_abbrev (sym, stream)
Lisp_Object sym, stream;
{
insert (")\n", 2);
}
-static
+static void
describe_abbrev (sym, stream)
Lisp_Object sym, stream;
{
return Qnil;
}
\f
+void
syms_of_abbrev ()
{
DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
"The abbrev table of mode-specific abbrevs for Fundamental Mode.");
Vfundamental_mode_abbrev_table = Fmake_abbrev_table ();
current_buffer->abbrev_table = Vfundamental_mode_abbrev_table;
+ buffer_defaults.abbrev_table = Vfundamental_mode_abbrev_table;
DEFVAR_LISP ("last-abbrev", &Vlast_abbrev,
"The abbrev-symbol of the last abbrev expanded. See `abbrev-symbol'.");