Mercurial > emacs
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) |