comparison src/intervals.c @ 13028:49df58305295

(call_mod_hooks, verify_interval_modification): Functions moved to textprop.c.
author Richard M. Stallman <rms@gnu.org>
date Tue, 12 Sep 1995 17:37:53 +0000
parents 7c7519c2a45a
children 621a575db6f7
comparison
equal deleted inserted replaced
13027:48358e0fa98e 13028:49df58305295
1793 return prop; 1793 return prop;
1794 1794
1795 return buffer->keymap; 1795 return buffer->keymap;
1796 } 1796 }
1797 1797
1798 /* Call the modification hook functions in LIST, each with START and END. */
1799
1800 static void
1801 call_mod_hooks (list, start, end)
1802 Lisp_Object list, start, end;
1803 {
1804 struct gcpro gcpro1;
1805 GCPRO1 (list);
1806 while (!NILP (list))
1807 {
1808 call2 (Fcar (list), start, end);
1809 list = Fcdr (list);
1810 }
1811 UNGCPRO;
1812 }
1813
1814 /* Check for read-only intervals and signal an error if we find one.
1815 Then check for any modification hooks in the range START up to
1816 (but not including) END. Create a list of all these hooks in
1817 lexicographic order, eliminating consecutive extra copies of the
1818 same hook. Then call those hooks in order, with START and END - 1
1819 as arguments. */
1820
1821 void
1822 verify_interval_modification (buf, start, end)
1823 struct buffer *buf;
1824 int start, end;
1825 {
1826 register INTERVAL intervals = BUF_INTERVALS (buf);
1827 register INTERVAL i, prev;
1828 Lisp_Object hooks;
1829 register Lisp_Object prev_mod_hooks;
1830 Lisp_Object mod_hooks;
1831 struct gcpro gcpro1;
1832
1833 hooks = Qnil;
1834 prev_mod_hooks = Qnil;
1835 mod_hooks = Qnil;
1836
1837 if (NULL_INTERVAL_P (intervals))
1838 return;
1839
1840 if (start > end)
1841 {
1842 int temp = start;
1843 start = end;
1844 end = temp;
1845 }
1846
1847 /* For an insert operation, check the two chars around the position. */
1848 if (start == end)
1849 {
1850 INTERVAL prev;
1851 Lisp_Object before, after;
1852
1853 /* Set I to the interval containing the char after START,
1854 and PREV to the interval containing the char before START.
1855 Either one may be null. They may be equal. */
1856 i = find_interval (intervals, start);
1857
1858 if (start == BUF_BEGV (buf))
1859 prev = 0;
1860 else if (i->position == start)
1861 prev = previous_interval (i);
1862 else if (i->position < start)
1863 prev = i;
1864 if (start == BUF_ZV (buf))
1865 i = 0;
1866
1867 /* If Vinhibit_read_only is set and is not a list, we can
1868 skip the read_only checks. */
1869 if (NILP (Vinhibit_read_only) || CONSP (Vinhibit_read_only))
1870 {
1871 /* If I and PREV differ we need to check for the read-only
1872 property together with its stickyness. If either I or
1873 PREV are 0, this check is all we need.
1874 We have to take special care, since read-only may be
1875 indirectly defined via the category property. */
1876 if (i != prev)
1877 {
1878 if (! NULL_INTERVAL_P (i))
1879 {
1880 after = textget (i->plist, Qread_only);
1881
1882 /* If interval I is read-only and read-only is
1883 front-sticky, inhibit insertion.
1884 Check for read-only as well as category. */
1885 if (! NILP (after)
1886 && NILP (Fmemq (after, Vinhibit_read_only)))
1887 {
1888 Lisp_Object tem;
1889
1890 tem = textget (i->plist, Qfront_sticky);
1891 if (TMEM (Qread_only, tem)
1892 || (NILP (Fplist_get (i->plist, Qread_only))
1893 && TMEM (Qcategory, tem)))
1894 error ("Attempt to insert within read-only text");
1895 }
1896 }
1897
1898 if (! NULL_INTERVAL_P (prev))
1899 {
1900 before = textget (prev->plist, Qread_only);
1901
1902 /* If interval PREV is read-only and read-only isn't
1903 rear-nonsticky, inhibit insertion.
1904 Check for read-only as well as category. */
1905 if (! NILP (before)
1906 && NILP (Fmemq (before, Vinhibit_read_only)))
1907 {
1908 Lisp_Object tem;
1909
1910 tem = textget (prev->plist, Qrear_nonsticky);
1911 if (! TMEM (Qread_only, tem)
1912 && (! NILP (Fplist_get (prev->plist,Qread_only))
1913 || ! TMEM (Qcategory, tem)))
1914 error ("Attempt to insert within read-only text");
1915 }
1916 }
1917 }
1918 else if (! NULL_INTERVAL_P (i))
1919 {
1920 after = textget (i->plist, Qread_only);
1921
1922 /* If interval I is read-only and read-only is
1923 front-sticky, inhibit insertion.
1924 Check for read-only as well as category. */
1925 if (! NILP (after) && NILP (Fmemq (after, Vinhibit_read_only)))
1926 {
1927 Lisp_Object tem;
1928
1929 tem = textget (i->plist, Qfront_sticky);
1930 if (TMEM (Qread_only, tem)
1931 || (NILP (Fplist_get (i->plist, Qread_only))
1932 && TMEM (Qcategory, tem)))
1933 error ("Attempt to insert within read-only text");
1934
1935 tem = textget (prev->plist, Qrear_nonsticky);
1936 if (! TMEM (Qread_only, tem)
1937 && (! NILP (Fplist_get (prev->plist, Qread_only))
1938 || ! TMEM (Qcategory, tem)))
1939 error ("Attempt to insert within read-only text");
1940 }
1941 }
1942 }
1943
1944 /* Run both insert hooks (just once if they're the same). */
1945 if (!NULL_INTERVAL_P (prev))
1946 prev_mod_hooks = textget (prev->plist, Qinsert_behind_hooks);
1947 if (!NULL_INTERVAL_P (i))
1948 mod_hooks = textget (i->plist, Qinsert_in_front_hooks);
1949 GCPRO1 (mod_hooks);
1950 if (! NILP (prev_mod_hooks))
1951 call_mod_hooks (prev_mod_hooks, make_number (start),
1952 make_number (end));
1953 UNGCPRO;
1954 if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks))
1955 call_mod_hooks (mod_hooks, make_number (start), make_number (end));
1956 }
1957 else
1958 {
1959 /* Loop over intervals on or next to START...END,
1960 collecting their hooks. */
1961
1962 i = find_interval (intervals, start);
1963 do
1964 {
1965 if (! INTERVAL_WRITABLE_P (i))
1966 error ("Attempt to modify read-only text");
1967
1968 mod_hooks = textget (i->plist, Qmodification_hooks);
1969 if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks))
1970 {
1971 hooks = Fcons (mod_hooks, hooks);
1972 prev_mod_hooks = mod_hooks;
1973 }
1974
1975 i = next_interval (i);
1976 }
1977 /* Keep going thru the interval containing the char before END. */
1978 while (! NULL_INTERVAL_P (i) && i->position < end);
1979
1980 GCPRO1 (hooks);
1981 hooks = Fnreverse (hooks);
1982 while (! EQ (hooks, Qnil))
1983 {
1984 call_mod_hooks (Fcar (hooks), make_number (start),
1985 make_number (end));
1986 hooks = Fcdr (hooks);
1987 }
1988 UNGCPRO;
1989 }
1990 }
1991
1992 /* Produce an interval tree reflecting the intervals in 1798 /* Produce an interval tree reflecting the intervals in
1993 TREE from START to START + LENGTH. */ 1799 TREE from START to START + LENGTH. */
1994 1800
1995 INTERVAL 1801 INTERVAL
1996 copy_intervals (tree, start, length) 1802 copy_intervals (tree, start, length)