diff options
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 174 |
1 files changed, 170 insertions, 4 deletions
diff --git a/src/buffer.c b/src/buffer.c index 6c797aef744..f1334c0b6a0 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1693,7 +1693,138 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr) | |||
| 1693 | *prev_ptr = prev; | 1693 | *prev_ptr = prev; |
| 1694 | return idx; | 1694 | return idx; |
| 1695 | } | 1695 | } |
| 1696 | |||
| 1697 | /* Find all the overlays in the current buffer that overlap the range BEG-END | ||
| 1698 | plus empty overlays anywhere from BEG to END. | ||
| 1699 | Return the number found, and store them in a vector in *VEC_PTR. | ||
| 1700 | Store in *LEN_PTR the size allocated for the vector. | ||
| 1701 | Store in *NEXT_PTR the next position after POS where an overlay starts, | ||
| 1702 | or ZV if there are no more overlays. | ||
| 1703 | Store in *PREV_PTR the previous position before POS where an overlay ends, | ||
| 1704 | or BEGV if there are no previous overlays. | ||
| 1705 | NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info. | ||
| 1706 | |||
| 1707 | *VEC_PTR and *LEN_PTR should contain a valid vector and size | ||
| 1708 | when this function is called. | ||
| 1709 | |||
| 1710 | If EXTEND is non-zero, we make the vector bigger if necessary. | ||
| 1711 | If EXTEND is zero, we never extend the vector, | ||
| 1712 | and we store only as many overlays as will fit. | ||
| 1713 | But we still return the total number of overlays. */ | ||
| 1714 | |||
| 1715 | int | ||
| 1716 | overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr) | ||
| 1717 | int beg, end; | ||
| 1718 | int extend; | ||
| 1719 | Lisp_Object **vec_ptr; | ||
| 1720 | int *len_ptr; | ||
| 1721 | int *next_ptr; | ||
| 1722 | int *prev_ptr; | ||
| 1723 | { | ||
| 1724 | Lisp_Object tail, overlay, ostart, oend, result; | ||
| 1725 | int idx = 0; | ||
| 1726 | int len = *len_ptr; | ||
| 1727 | Lisp_Object *vec = *vec_ptr; | ||
| 1728 | int next = ZV; | ||
| 1729 | int prev = BEGV; | ||
| 1730 | int inhibit_storing = 0; | ||
| 1731 | |||
| 1732 | for (tail = current_buffer->overlays_before; | ||
| 1733 | GC_CONSP (tail); | ||
| 1734 | tail = XCONS (tail)->cdr) | ||
| 1735 | { | ||
| 1736 | int startpos, endpos; | ||
| 1737 | |||
| 1738 | overlay = XCONS (tail)->car; | ||
| 1739 | |||
| 1740 | ostart = OVERLAY_START (overlay); | ||
| 1741 | oend = OVERLAY_END (overlay); | ||
| 1742 | endpos = OVERLAY_POSITION (oend); | ||
| 1743 | if (endpos < beg) | ||
| 1744 | { | ||
| 1745 | if (prev < endpos) | ||
| 1746 | prev = endpos; | ||
| 1747 | break; | ||
| 1748 | } | ||
| 1749 | startpos = OVERLAY_POSITION (ostart); | ||
| 1750 | /* Count an interval if it either overlaps the range | ||
| 1751 | or is empty at either end of the range. */ | ||
| 1752 | if ((beg < endpos && startpos < end) | ||
| 1753 | || (startpos == endpos && beg == startpos) | ||
| 1754 | || (startpos == endpos && end == startpos)) | ||
| 1755 | { | ||
| 1756 | if (idx == len) | ||
| 1757 | { | ||
| 1758 | /* The supplied vector is full. | ||
| 1759 | Either make it bigger, or don't store any more in it. */ | ||
| 1760 | if (extend) | ||
| 1761 | { | ||
| 1762 | *len_ptr = len *= 2; | ||
| 1763 | vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); | ||
| 1764 | *vec_ptr = vec; | ||
| 1765 | } | ||
| 1766 | else | ||
| 1767 | inhibit_storing = 1; | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | if (!inhibit_storing) | ||
| 1771 | vec[idx] = overlay; | ||
| 1772 | /* Keep counting overlays even if we can't return them all. */ | ||
| 1773 | idx++; | ||
| 1774 | } | ||
| 1775 | else if (startpos < next) | ||
| 1776 | next = startpos; | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | for (tail = current_buffer->overlays_after; | ||
| 1780 | GC_CONSP (tail); | ||
| 1781 | tail = XCONS (tail)->cdr) | ||
| 1782 | { | ||
| 1783 | int startpos, endpos; | ||
| 1784 | |||
| 1785 | overlay = XCONS (tail)->car; | ||
| 1786 | |||
| 1787 | ostart = OVERLAY_START (overlay); | ||
| 1788 | oend = OVERLAY_END (overlay); | ||
| 1789 | startpos = OVERLAY_POSITION (ostart); | ||
| 1790 | if (end < startpos) | ||
| 1791 | { | ||
| 1792 | if (startpos < next) | ||
| 1793 | next = startpos; | ||
| 1794 | break; | ||
| 1795 | } | ||
| 1796 | endpos = OVERLAY_POSITION (oend); | ||
| 1797 | if ((beg < endpos && startpos < end) | ||
| 1798 | || (startpos == endpos && beg == startpos) | ||
| 1799 | || (startpos == endpos && end == startpos)) | ||
| 1800 | { | ||
| 1801 | if (idx == len) | ||
| 1802 | { | ||
| 1803 | if (extend) | ||
| 1804 | { | ||
| 1805 | *len_ptr = len *= 2; | ||
| 1806 | vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); | ||
| 1807 | *vec_ptr = vec; | ||
| 1808 | } | ||
| 1809 | else | ||
| 1810 | inhibit_storing = 1; | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | if (!inhibit_storing) | ||
| 1814 | vec[idx] = overlay; | ||
| 1815 | idx++; | ||
| 1816 | } | ||
| 1817 | else if (endpos < beg && endpos > prev) | ||
| 1818 | prev = endpos; | ||
| 1819 | } | ||
| 1696 | 1820 | ||
| 1821 | if (next_ptr) | ||
| 1822 | *next_ptr = next; | ||
| 1823 | if (prev_ptr) | ||
| 1824 | *prev_ptr = prev; | ||
| 1825 | return idx; | ||
| 1826 | } | ||
| 1827 | |||
| 1697 | /* Fast function to just test if we're at an overlay boundary. */ | 1828 | /* Fast function to just test if we're at an overlay boundary. */ |
| 1698 | int | 1829 | int |
| 1699 | overlay_touches_p (pos) | 1830 | overlay_touches_p (pos) |
| @@ -1894,7 +2025,8 @@ overlay_strings (pos, w, pstr) | |||
| 1894 | { | 2025 | { |
| 1895 | overlay_tails_len *= 2; | 2026 | overlay_tails_len *= 2; |
| 1896 | overlay_tails = ((struct sortstr *) | 2027 | overlay_tails = ((struct sortstr *) |
| 1897 | xrealloc ((overlay_tails_len | 2028 | xrealloc (overlay_tails, |
| 2029 | (overlay_tails_len | ||
| 1898 | * sizeof (struct sortstr)))); | 2030 | * sizeof (struct sortstr)))); |
| 1899 | } | 2031 | } |
| 1900 | } | 2032 | } |
| @@ -1923,7 +2055,8 @@ overlay_strings (pos, w, pstr) | |||
| 1923 | { | 2055 | { |
| 1924 | overlay_heads_len *= 2; | 2056 | overlay_heads_len *= 2; |
| 1925 | overlay_heads = ((struct sortstr *) | 2057 | overlay_heads = ((struct sortstr *) |
| 1926 | xrealloc ((overlay_heads_len | 2058 | xrealloc (overlay_heads, |
| 2059 | (overlay_heads_len | ||
| 1927 | * sizeof (struct sortstr)))); | 2060 | * sizeof (struct sortstr)))); |
| 1928 | } | 2061 | } |
| 1929 | } | 2062 | } |
| @@ -1963,7 +2096,8 @@ overlay_strings (pos, w, pstr) | |||
| 1963 | { | 2096 | { |
| 1964 | overlay_tails_len *= 2; | 2097 | overlay_tails_len *= 2; |
| 1965 | overlay_tails = ((struct sortstr *) | 2098 | overlay_tails = ((struct sortstr *) |
| 1966 | xrealloc ((overlay_tails_len | 2099 | xrealloc (overlay_tails, |
| 2100 | (overlay_tails_len | ||
| 1967 | * sizeof (struct sortstr)))); | 2101 | * sizeof (struct sortstr)))); |
| 1968 | } | 2102 | } |
| 1969 | } | 2103 | } |
| @@ -1992,7 +2126,8 @@ overlay_strings (pos, w, pstr) | |||
| 1992 | { | 2126 | { |
| 1993 | overlay_heads_len *= 2; | 2127 | overlay_heads_len *= 2; |
| 1994 | overlay_heads = ((struct sortstr *) | 2128 | overlay_heads = ((struct sortstr *) |
| 1995 | xrealloc ((overlay_heads_len | 2129 | xrealloc (overlay_heads, |
| 2130 | (overlay_heads_len | ||
| 1996 | * sizeof (struct sortstr)))); | 2131 | * sizeof (struct sortstr)))); |
| 1997 | } | 2132 | } |
| 1998 | } | 2133 | } |
| @@ -2619,6 +2754,36 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, | |||
| 2619 | return result; | 2754 | return result; |
| 2620 | } | 2755 | } |
| 2621 | 2756 | ||
| 2757 | DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0, | ||
| 2758 | "Return a list of the overlays that overlap region BEG ... END.\n\ | ||
| 2759 | This includes empty overlays at BEG or END (as well as empty overlays\n\ | ||
| 2760 | within the range.") | ||
| 2761 | (beg, end) | ||
| 2762 | Lisp_Object beg, end; | ||
| 2763 | { | ||
| 2764 | int noverlays; | ||
| 2765 | Lisp_Object *overlay_vec; | ||
| 2766 | int len; | ||
| 2767 | Lisp_Object result; | ||
| 2768 | |||
| 2769 | CHECK_NUMBER_COERCE_MARKER (beg, 0); | ||
| 2770 | CHECK_NUMBER_COERCE_MARKER (end, 0); | ||
| 2771 | |||
| 2772 | len = 10; | ||
| 2773 | overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); | ||
| 2774 | |||
| 2775 | /* Put all the overlays we want in a vector in overlay_vec. | ||
| 2776 | Store the length in len. */ | ||
| 2777 | noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, | ||
| 2778 | (int *) 0, (int *) 0); | ||
| 2779 | |||
| 2780 | /* Make a list of them all. */ | ||
| 2781 | result = Flist (noverlays, overlay_vec); | ||
| 2782 | |||
| 2783 | xfree (overlay_vec); | ||
| 2784 | return result; | ||
| 2785 | } | ||
| 2786 | |||
| 2622 | DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change, | 2787 | DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change, |
| 2623 | 1, 1, 0, | 2788 | 1, 1, 0, |
| 2624 | "Return the next position after POS where an overlay starts or ends.\n\ | 2789 | "Return the next position after POS where an overlay starts or ends.\n\ |
| @@ -3713,6 +3878,7 @@ is a member of the list."); | |||
| 3713 | defsubr (&Soverlay_buffer); | 3878 | defsubr (&Soverlay_buffer); |
| 3714 | defsubr (&Soverlay_properties); | 3879 | defsubr (&Soverlay_properties); |
| 3715 | defsubr (&Soverlays_at); | 3880 | defsubr (&Soverlays_at); |
| 3881 | defsubr (&Soverlays_in); | ||
| 3716 | defsubr (&Snext_overlay_change); | 3882 | defsubr (&Snext_overlay_change); |
| 3717 | defsubr (&Sprevious_overlay_change); | 3883 | defsubr (&Sprevious_overlay_change); |
| 3718 | defsubr (&Soverlay_recenter); | 3884 | defsubr (&Soverlay_recenter); |