mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-12 09:28:24 +00:00
(call_mod_hooks, verify_interval_modification):
Functions moved to textprop.c.
This commit is contained in:
parent
318d2fa869
commit
40648b6832
194
src/intervals.c
194
src/intervals.c
@ -1795,200 +1795,6 @@ get_local_map (position, buffer)
|
||||
return buffer->keymap;
|
||||
}
|
||||
|
||||
/* Call the modification hook functions in LIST, each with START and END. */
|
||||
|
||||
static void
|
||||
call_mod_hooks (list, start, end)
|
||||
Lisp_Object list, start, end;
|
||||
{
|
||||
struct gcpro gcpro1;
|
||||
GCPRO1 (list);
|
||||
while (!NILP (list))
|
||||
{
|
||||
call2 (Fcar (list), start, end);
|
||||
list = Fcdr (list);
|
||||
}
|
||||
UNGCPRO;
|
||||
}
|
||||
|
||||
/* Check for read-only intervals and signal an error if we find one.
|
||||
Then check for any modification hooks in the range START up to
|
||||
(but not including) END. Create a list of all these hooks in
|
||||
lexicographic order, eliminating consecutive extra copies of the
|
||||
same hook. Then call those hooks in order, with START and END - 1
|
||||
as arguments. */
|
||||
|
||||
void
|
||||
verify_interval_modification (buf, start, end)
|
||||
struct buffer *buf;
|
||||
int start, end;
|
||||
{
|
||||
register INTERVAL intervals = BUF_INTERVALS (buf);
|
||||
register INTERVAL i, prev;
|
||||
Lisp_Object hooks;
|
||||
register Lisp_Object prev_mod_hooks;
|
||||
Lisp_Object mod_hooks;
|
||||
struct gcpro gcpro1;
|
||||
|
||||
hooks = Qnil;
|
||||
prev_mod_hooks = Qnil;
|
||||
mod_hooks = Qnil;
|
||||
|
||||
if (NULL_INTERVAL_P (intervals))
|
||||
return;
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
int temp = start;
|
||||
start = end;
|
||||
end = temp;
|
||||
}
|
||||
|
||||
/* For an insert operation, check the two chars around the position. */
|
||||
if (start == end)
|
||||
{
|
||||
INTERVAL prev;
|
||||
Lisp_Object before, after;
|
||||
|
||||
/* Set I to the interval containing the char after START,
|
||||
and PREV to the interval containing the char before START.
|
||||
Either one may be null. They may be equal. */
|
||||
i = find_interval (intervals, start);
|
||||
|
||||
if (start == BUF_BEGV (buf))
|
||||
prev = 0;
|
||||
else if (i->position == start)
|
||||
prev = previous_interval (i);
|
||||
else if (i->position < start)
|
||||
prev = i;
|
||||
if (start == BUF_ZV (buf))
|
||||
i = 0;
|
||||
|
||||
/* If Vinhibit_read_only is set and is not a list, we can
|
||||
skip the read_only checks. */
|
||||
if (NILP (Vinhibit_read_only) || CONSP (Vinhibit_read_only))
|
||||
{
|
||||
/* If I and PREV differ we need to check for the read-only
|
||||
property together with its stickyness. If either I or
|
||||
PREV are 0, this check is all we need.
|
||||
We have to take special care, since read-only may be
|
||||
indirectly defined via the category property. */
|
||||
if (i != prev)
|
||||
{
|
||||
if (! NULL_INTERVAL_P (i))
|
||||
{
|
||||
after = textget (i->plist, Qread_only);
|
||||
|
||||
/* If interval I is read-only and read-only is
|
||||
front-sticky, inhibit insertion.
|
||||
Check for read-only as well as category. */
|
||||
if (! NILP (after)
|
||||
&& NILP (Fmemq (after, Vinhibit_read_only)))
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
tem = textget (i->plist, Qfront_sticky);
|
||||
if (TMEM (Qread_only, tem)
|
||||
|| (NILP (Fplist_get (i->plist, Qread_only))
|
||||
&& TMEM (Qcategory, tem)))
|
||||
error ("Attempt to insert within read-only text");
|
||||
}
|
||||
}
|
||||
|
||||
if (! NULL_INTERVAL_P (prev))
|
||||
{
|
||||
before = textget (prev->plist, Qread_only);
|
||||
|
||||
/* If interval PREV is read-only and read-only isn't
|
||||
rear-nonsticky, inhibit insertion.
|
||||
Check for read-only as well as category. */
|
||||
if (! NILP (before)
|
||||
&& NILP (Fmemq (before, Vinhibit_read_only)))
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
tem = textget (prev->plist, Qrear_nonsticky);
|
||||
if (! TMEM (Qread_only, tem)
|
||||
&& (! NILP (Fplist_get (prev->plist,Qread_only))
|
||||
|| ! TMEM (Qcategory, tem)))
|
||||
error ("Attempt to insert within read-only text");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (! NULL_INTERVAL_P (i))
|
||||
{
|
||||
after = textget (i->plist, Qread_only);
|
||||
|
||||
/* If interval I is read-only and read-only is
|
||||
front-sticky, inhibit insertion.
|
||||
Check for read-only as well as category. */
|
||||
if (! NILP (after) && NILP (Fmemq (after, Vinhibit_read_only)))
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
tem = textget (i->plist, Qfront_sticky);
|
||||
if (TMEM (Qread_only, tem)
|
||||
|| (NILP (Fplist_get (i->plist, Qread_only))
|
||||
&& TMEM (Qcategory, tem)))
|
||||
error ("Attempt to insert within read-only text");
|
||||
|
||||
tem = textget (prev->plist, Qrear_nonsticky);
|
||||
if (! TMEM (Qread_only, tem)
|
||||
&& (! NILP (Fplist_get (prev->plist, Qread_only))
|
||||
|| ! TMEM (Qcategory, tem)))
|
||||
error ("Attempt to insert within read-only text");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Run both insert hooks (just once if they're the same). */
|
||||
if (!NULL_INTERVAL_P (prev))
|
||||
prev_mod_hooks = textget (prev->plist, Qinsert_behind_hooks);
|
||||
if (!NULL_INTERVAL_P (i))
|
||||
mod_hooks = textget (i->plist, Qinsert_in_front_hooks);
|
||||
GCPRO1 (mod_hooks);
|
||||
if (! NILP (prev_mod_hooks))
|
||||
call_mod_hooks (prev_mod_hooks, make_number (start),
|
||||
make_number (end));
|
||||
UNGCPRO;
|
||||
if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks))
|
||||
call_mod_hooks (mod_hooks, make_number (start), make_number (end));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Loop over intervals on or next to START...END,
|
||||
collecting their hooks. */
|
||||
|
||||
i = find_interval (intervals, start);
|
||||
do
|
||||
{
|
||||
if (! INTERVAL_WRITABLE_P (i))
|
||||
error ("Attempt to modify read-only text");
|
||||
|
||||
mod_hooks = textget (i->plist, Qmodification_hooks);
|
||||
if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks))
|
||||
{
|
||||
hooks = Fcons (mod_hooks, hooks);
|
||||
prev_mod_hooks = mod_hooks;
|
||||
}
|
||||
|
||||
i = next_interval (i);
|
||||
}
|
||||
/* Keep going thru the interval containing the char before END. */
|
||||
while (! NULL_INTERVAL_P (i) && i->position < end);
|
||||
|
||||
GCPRO1 (hooks);
|
||||
hooks = Fnreverse (hooks);
|
||||
while (! EQ (hooks, Qnil))
|
||||
{
|
||||
call_mod_hooks (Fcar (hooks), make_number (start),
|
||||
make_number (end));
|
||||
hooks = Fcdr (hooks);
|
||||
}
|
||||
UNGCPRO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Produce an interval tree reflecting the intervals in
|
||||
TREE from START to START + LENGTH. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user