diff options
| author | Paul Eggert | 2012-04-23 15:46:35 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-04-23 15:46:35 -0700 |
| commit | 89a438bd861e9b80e8f80a23955624c74782921a (patch) | |
| tree | 5f1a72549a39cb2ad2d00ac32af303b115b3ef73 /src/buffer.c | |
| parent | 7511ded8c94e37aea836e3c13ccc9a5f77b07857 (diff) | |
| download | emacs-89a438bd861e9b80e8f80a23955624c74782921a.tar.gz emacs-89a438bd861e9b80e8f80a23955624c74782921a.zip | |
Do not create empty overlays with the evaporate property (Bug#9642).
* buffer.c (Fmove_overlay): Delete an evaporating overlay
if it becomes empty after its bounds are adjusted to fit within
its buffer. Without this fix, in a nonempty buffer (let ((o
(make-overlay 1 2))) (overlay-put o 'evaporate t) (move-overlay o 0 1))
yields an empty overlay that has the evaporate property, which is
not supposed to happen.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/src/buffer.c b/src/buffer.c index 9bac3ec742b..6c2e21c8125 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -3682,6 +3682,7 @@ buffer. */) | |||
| 3682 | struct buffer *b, *ob; | 3682 | struct buffer *b, *ob; |
| 3683 | Lisp_Object obuffer; | 3683 | Lisp_Object obuffer; |
| 3684 | int count = SPECPDL_INDEX (); | 3684 | int count = SPECPDL_INDEX (); |
| 3685 | ptrdiff_t n_beg, n_end; | ||
| 3685 | 3686 | ||
| 3686 | CHECK_OVERLAY (overlay); | 3687 | CHECK_OVERLAY (overlay); |
| 3687 | if (NILP (buffer)) | 3688 | if (NILP (buffer)) |
| @@ -3700,15 +3701,23 @@ buffer. */) | |||
| 3700 | CHECK_NUMBER_COERCE_MARKER (beg); | 3701 | CHECK_NUMBER_COERCE_MARKER (beg); |
| 3701 | CHECK_NUMBER_COERCE_MARKER (end); | 3702 | CHECK_NUMBER_COERCE_MARKER (end); |
| 3702 | 3703 | ||
| 3703 | if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate))) | ||
| 3704 | return Fdelete_overlay (overlay); | ||
| 3705 | |||
| 3706 | if (XINT (beg) > XINT (end)) | 3704 | if (XINT (beg) > XINT (end)) |
| 3707 | { | 3705 | { |
| 3708 | Lisp_Object temp; | 3706 | Lisp_Object temp; |
| 3709 | temp = beg; beg = end; end = temp; | 3707 | temp = beg; beg = end; end = temp; |
| 3710 | } | 3708 | } |
| 3711 | 3709 | ||
| 3710 | /* First set the overlay boundaries, which may clip them. */ | ||
| 3711 | Fset_marker (OVERLAY_START (overlay), beg, buffer); | ||
| 3712 | Fset_marker (OVERLAY_END (overlay), end, buffer); | ||
| 3713 | n_beg = marker_position (OVERLAY_START (overlay)); | ||
| 3714 | n_end = marker_position (OVERLAY_END (overlay)); | ||
| 3715 | |||
| 3716 | /* Now, delete the overlay if it is empty after clipping and has the | ||
| 3717 | evaporate property. */ | ||
| 3718 | if (n_beg == n_end && ! NILP (Foverlay_get (overlay, Qevaporate))) | ||
| 3719 | return Fdelete_overlay (overlay); | ||
| 3720 | |||
| 3712 | specbind (Qinhibit_quit, Qt); | 3721 | specbind (Qinhibit_quit, Qt); |
| 3713 | 3722 | ||
| 3714 | obuffer = Fmarker_buffer (OVERLAY_START (overlay)); | 3723 | obuffer = Fmarker_buffer (OVERLAY_START (overlay)); |
| @@ -3731,7 +3740,7 @@ buffer. */) | |||
| 3731 | } | 3740 | } |
| 3732 | 3741 | ||
| 3733 | /* Redisplay where the overlay is going to be. */ | 3742 | /* Redisplay where the overlay is going to be. */ |
| 3734 | modify_overlay (b, XINT (beg), XINT (end)); | 3743 | modify_overlay (b, n_beg, n_end); |
| 3735 | } | 3744 | } |
| 3736 | else | 3745 | else |
| 3737 | /* Redisplay the area the overlay has just left, or just enclosed. */ | 3746 | /* Redisplay the area the overlay has just left, or just enclosed. */ |
| @@ -3741,16 +3750,12 @@ buffer. */) | |||
| 3741 | o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3750 | o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3742 | o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3751 | o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3743 | 3752 | ||
| 3744 | if (o_beg == XINT (beg)) | 3753 | if (o_beg == n_beg) |
| 3745 | modify_overlay (b, o_end, XINT (end)); | 3754 | modify_overlay (b, o_end, n_end); |
| 3746 | else if (o_end == XINT (end)) | 3755 | else if (o_end == n_end) |
| 3747 | modify_overlay (b, o_beg, XINT (beg)); | 3756 | modify_overlay (b, o_beg, n_beg); |
| 3748 | else | 3757 | else |
| 3749 | { | 3758 | modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end)); |
| 3750 | if (XINT (beg) < o_beg) o_beg = XINT (beg); | ||
| 3751 | if (XINT (end) > o_end) o_end = XINT (end); | ||
| 3752 | modify_overlay (b, o_beg, o_end); | ||
| 3753 | } | ||
| 3754 | } | 3759 | } |
| 3755 | 3760 | ||
| 3756 | if (!NILP (obuffer)) | 3761 | if (!NILP (obuffer)) |
| @@ -3762,12 +3767,8 @@ buffer. */) | |||
| 3762 | eassert (XOVERLAY (overlay)->next == NULL); | 3767 | eassert (XOVERLAY (overlay)->next == NULL); |
| 3763 | } | 3768 | } |
| 3764 | 3769 | ||
| 3765 | Fset_marker (OVERLAY_START (overlay), beg, buffer); | ||
| 3766 | Fset_marker (OVERLAY_END (overlay), end, buffer); | ||
| 3767 | |||
| 3768 | /* Put the overlay on the wrong list. */ | 3770 | /* Put the overlay on the wrong list. */ |
| 3769 | end = OVERLAY_END (overlay); | 3771 | if (n_end < b->overlay_center) |
| 3770 | if (OVERLAY_POSITION (end) < b->overlay_center) | ||
| 3771 | { | 3772 | { |
| 3772 | XOVERLAY (overlay)->next = b->overlays_after; | 3773 | XOVERLAY (overlay)->next = b->overlays_after; |
| 3773 | b->overlays_after = XOVERLAY (overlay); | 3774 | b->overlays_after = XOVERLAY (overlay); |