diff options
| author | Karl Heuer | 1994-05-17 03:30:40 +0000 |
|---|---|---|
| committer | Karl Heuer | 1994-05-17 03:30:40 +0000 |
| commit | 2b1bdf65a991dda471e5217acadc5919a4c76d62 (patch) | |
| tree | 9d0abbb416d139bcc56157d693af9799d0904453 /src/buffer.c | |
| parent | 8de1d5f084ebf5ca165fd6bfe9a9ec72144ce9ee (diff) | |
| download | emacs-2b1bdf65a991dda471e5217acadc5919a4c76d62.tar.gz emacs-2b1bdf65a991dda471e5217acadc5919a4c76d62.zip | |
(fix_overlays_in_range): New function.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/buffer.c b/src/buffer.c index 038c5aee4bb..1293b1590e9 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1635,6 +1635,109 @@ recenter_overlay_lists (buf, pos) | |||
| 1635 | 1635 | ||
| 1636 | XFASTINT (buf->overlay_center) = pos; | 1636 | XFASTINT (buf->overlay_center) = pos; |
| 1637 | } | 1637 | } |
| 1638 | |||
| 1639 | /* Fix up overlays that were garbled as a result of permuting markers | ||
| 1640 | in the range START through END. Any overlay with at least one | ||
| 1641 | endpoint in this range will need to be unlinked from the overlay | ||
| 1642 | list and reinserted in its proper place. | ||
| 1643 | Such an overlay might even have negative size at this point. | ||
| 1644 | If so, we'll reverse the endpoints. Can you think of anything | ||
| 1645 | better to do in this situation? */ | ||
| 1646 | void | ||
| 1647 | fix_overlays_in_range (start, end) | ||
| 1648 | register int start, end; | ||
| 1649 | { | ||
| 1650 | Lisp_Object tem, overlay; | ||
| 1651 | Lisp_Object before_list, after_list; | ||
| 1652 | Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list; | ||
| 1653 | int startpos, endpos; | ||
| 1654 | |||
| 1655 | /* This algorithm shifts links around instead of consing and GCing. | ||
| 1656 | The loop invariant is that before_list (resp. after_list) is a | ||
| 1657 | well-formed list except that its last element, the one that | ||
| 1658 | *pbefore (resp. *pafter) points to, is still uninitialized. | ||
| 1659 | So it's not a bug that before_list isn't initialized, although | ||
| 1660 | it may look strange. */ | ||
| 1661 | for (ptail = ¤t_buffer->overlays_before; CONSP (*ptail);) | ||
| 1662 | { | ||
| 1663 | overlay = XCONS (*ptail)->car; | ||
| 1664 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 1665 | if (endpos < start) | ||
| 1666 | break; | ||
| 1667 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 1668 | if (endpos < end | ||
| 1669 | || (startpos >= start && startpos < end)) | ||
| 1670 | { | ||
| 1671 | /* If the overlay is backwards, fix that now. */ | ||
| 1672 | if (startpos > endpos) | ||
| 1673 | { | ||
| 1674 | int tem; | ||
| 1675 | Fset_marker (OVERLAY_START (overlay), endpos, Qnil); | ||
| 1676 | Fset_marker (OVERLAY_END (overlay), startpos, Qnil); | ||
| 1677 | tem = startpos; startpos = endpos; endpos = tem; | ||
| 1678 | } | ||
| 1679 | /* Add it to the end of the wrong list. Later on, | ||
| 1680 | recenter_overlay_lists will move it to the right place. */ | ||
| 1681 | if (endpos < XINT (current_buffer->overlay_center)) | ||
| 1682 | { | ||
| 1683 | *pafter = *ptail; | ||
| 1684 | pafter = &XCONS (*ptail)->cdr; | ||
| 1685 | } | ||
| 1686 | else | ||
| 1687 | { | ||
| 1688 | *pbefore = *ptail; | ||
| 1689 | pbefore = &XCONS (*ptail)->cdr; | ||
| 1690 | } | ||
| 1691 | *ptail = XCONS (*ptail)->cdr; | ||
| 1692 | } | ||
| 1693 | else | ||
| 1694 | ptail = &XCONS (*ptail)->cdr; | ||
| 1695 | } | ||
| 1696 | for (ptail = ¤t_buffer->overlays_after; CONSP (*ptail);) | ||
| 1697 | { | ||
| 1698 | overlay = XCONS (*ptail)->car; | ||
| 1699 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 1700 | if (startpos >= end) | ||
| 1701 | break; | ||
| 1702 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 1703 | if (startpos >= start | ||
| 1704 | || (endpos >= start && endpos < end)) | ||
| 1705 | { | ||
| 1706 | if (startpos > endpos) | ||
| 1707 | { | ||
| 1708 | int tem; | ||
| 1709 | Fset_marker (OVERLAY_START (overlay), endpos, Qnil); | ||
| 1710 | Fset_marker (OVERLAY_END (overlay), startpos, Qnil); | ||
| 1711 | tem = startpos; startpos = endpos; endpos = tem; | ||
| 1712 | } | ||
| 1713 | if (endpos < XINT (current_buffer->overlay_center)) | ||
| 1714 | { | ||
| 1715 | *pafter = *ptail; | ||
| 1716 | pafter = &XCONS (*ptail)->cdr; | ||
| 1717 | } | ||
| 1718 | else | ||
| 1719 | { | ||
| 1720 | *pbefore = *ptail; | ||
| 1721 | pbefore = &XCONS (*ptail)->cdr; | ||
| 1722 | } | ||
| 1723 | *ptail = XCONS (*ptail)->cdr; | ||
| 1724 | } | ||
| 1725 | else | ||
| 1726 | ptail = &XCONS (*ptail)->cdr; | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | /* Splice the constructed (wrong) lists into the buffer's lists, | ||
| 1730 | and let the recenter function make it sane again. */ | ||
| 1731 | *pbefore = current_buffer->overlays_before; | ||
| 1732 | current_buffer->overlays_before = before_list; | ||
| 1733 | recenter_overlay_lists (current_buffer, | ||
| 1734 | XINT (current_buffer->overlay_center)); | ||
| 1735 | |||
| 1736 | *pafter = current_buffer->overlays_after; | ||
| 1737 | current_buffer->overlays_after = after_list; | ||
| 1738 | recenter_overlay_lists (current_buffer, | ||
| 1739 | XINT (current_buffer->overlay_center)); | ||
| 1740 | } | ||
| 1638 | 1741 | ||
| 1639 | DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, | 1742 | DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, |
| 1640 | "Return t if OBJECT is an overlay.") | 1743 | "Return t if OBJECT is an overlay.") |