diff options
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 238 |
1 files changed, 234 insertions, 4 deletions
diff --git a/src/buffer.c b/src/buffer.c index 6ba82668549..6cf2aea4b9d 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -141,7 +141,7 @@ Lisp_Object Qget_file_buffer; | |||
| 141 | 141 | ||
| 142 | Lisp_Object Qoverlayp; | 142 | Lisp_Object Qoverlayp; |
| 143 | 143 | ||
| 144 | Lisp_Object Qpriority, Qwindow, Qevaporate; | 144 | Lisp_Object Qpriority, Qwindow, Qevaporate, Qbefore_string, Qafter_string; |
| 145 | 145 | ||
| 146 | Lisp_Object Qmodification_hooks; | 146 | Lisp_Object Qmodification_hooks; |
| 147 | Lisp_Object Qinsert_in_front_hooks; | 147 | Lisp_Object Qinsert_in_front_hooks; |
| @@ -1274,7 +1274,7 @@ set_buffer_internal (b) | |||
| 1274 | } | 1274 | } |
| 1275 | 1275 | ||
| 1276 | /* Switch to buffer B temporarily for redisplay purposes. | 1276 | /* Switch to buffer B temporarily for redisplay purposes. |
| 1277 | This avoids certain things thatdon't need to be done within redisplay. */ | 1277 | This avoids certain things that don't need to be done within redisplay. */ |
| 1278 | 1278 | ||
| 1279 | void | 1279 | void |
| 1280 | set_buffer_temp (b) | 1280 | set_buffer_temp (b) |
| @@ -1534,7 +1534,7 @@ swap_out_buffer_local_variables (b) | |||
| 1534 | Store in *LEN_PTR the size allocated for the vector. | 1534 | Store in *LEN_PTR the size allocated for the vector. |
| 1535 | Store in *NEXT_PTR the next position after POS where an overlay starts, | 1535 | Store in *NEXT_PTR the next position after POS where an overlay starts, |
| 1536 | or ZV if there are no more overlays. | 1536 | or ZV if there are no more overlays. |
| 1537 | Store in *PREV_PTR the previous position after POS where an overlay ends, | 1537 | Store in *PREV_PTR the previous position before POS where an overlay ends, |
| 1538 | or BEGV if there are no previous overlays. | 1538 | or BEGV if there are no previous overlays. |
| 1539 | NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info. | 1539 | NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info. |
| 1540 | 1540 | ||
| @@ -1776,6 +1776,232 @@ sort_overlays (overlay_vec, noverlays, w) | |||
| 1776 | return (noverlays); | 1776 | return (noverlays); |
| 1777 | } | 1777 | } |
| 1778 | 1778 | ||
| 1779 | struct sortstr | ||
| 1780 | { | ||
| 1781 | Lisp_Object string; | ||
| 1782 | int size; | ||
| 1783 | int priority; | ||
| 1784 | }; | ||
| 1785 | |||
| 1786 | /* A comparison function suitable for passing to qsort. */ | ||
| 1787 | static int | ||
| 1788 | cmp_for_strings (as1, as2) | ||
| 1789 | char *as1, *as2; | ||
| 1790 | { | ||
| 1791 | struct sortstr *s1 = (struct sortstr *)as1; | ||
| 1792 | struct sortstr *s2 = (struct sortstr *)as2; | ||
| 1793 | if (s1->size != s2->size) | ||
| 1794 | return s2->size - s1->size; | ||
| 1795 | if (s1->priority != s2->priority) | ||
| 1796 | return s1->priority - s2->priority; | ||
| 1797 | return 0; | ||
| 1798 | } | ||
| 1799 | |||
| 1800 | /* Buffers for storing the overlays touching a given position. | ||
| 1801 | These are expanded as needed, but never freed. */ | ||
| 1802 | static struct sortstr *overlay_heads, *overlay_tails; | ||
| 1803 | static char *overlay_str_buf; | ||
| 1804 | |||
| 1805 | /* Allocated length of those buffers. */ | ||
| 1806 | static int overlay_heads_len, overlay_tails_len, overlay_str_len; | ||
| 1807 | |||
| 1808 | /* Return the concatenation of the strings associated with overlays that | ||
| 1809 | begin or end at POS, ignoring overlays that are specific to a window | ||
| 1810 | other than W. The strings are concatenated in the appropriate order: | ||
| 1811 | shorter overlays nest inside longer ones, and higher priority inside | ||
| 1812 | lower. Returns the string length, and stores the contents indirectly | ||
| 1813 | through PSTR, if that variable is non-null. The string may be | ||
| 1814 | overwritten by subsequent calls. */ | ||
| 1815 | int | ||
| 1816 | overlay_strings (pos, w, pstr) | ||
| 1817 | int pos; | ||
| 1818 | struct window *w; | ||
| 1819 | char **pstr; | ||
| 1820 | { | ||
| 1821 | Lisp_Object ov, overlay, window, str, tem; | ||
| 1822 | int ntail = 0, nhead = 0; | ||
| 1823 | int total = 0; | ||
| 1824 | int startpos, endpos; | ||
| 1825 | |||
| 1826 | for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr) | ||
| 1827 | { | ||
| 1828 | overlay = XCONS (ov)->car; | ||
| 1829 | if (!OVERLAYP (overlay)) | ||
| 1830 | abort (); | ||
| 1831 | |||
| 1832 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 1833 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 1834 | if (endpos < pos) | ||
| 1835 | break; | ||
| 1836 | if (endpos != pos && startpos != pos) | ||
| 1837 | continue; | ||
| 1838 | window = Foverlay_get (overlay, Qwindow); | ||
| 1839 | if (WINDOWP (window) && XWINDOW (window) != w) | ||
| 1840 | continue; | ||
| 1841 | if (endpos == pos) | ||
| 1842 | { | ||
| 1843 | str = Foverlay_get (overlay, Qafter_string); | ||
| 1844 | if (STRINGP (str)) | ||
| 1845 | { | ||
| 1846 | if (ntail == overlay_tails_len) | ||
| 1847 | { | ||
| 1848 | if (! overlay_tails) | ||
| 1849 | { | ||
| 1850 | overlay_tails_len = 5; | ||
| 1851 | overlay_tails = ((struct sortstr *) | ||
| 1852 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 1853 | } | ||
| 1854 | else | ||
| 1855 | { | ||
| 1856 | overlay_tails_len *= 2; | ||
| 1857 | overlay_tails = ((struct sortstr *) | ||
| 1858 | xrealloc ((overlay_tails_len | ||
| 1859 | * sizeof (struct sortstr)))); | ||
| 1860 | } | ||
| 1861 | } | ||
| 1862 | overlay_tails[ntail].string = str; | ||
| 1863 | overlay_tails[ntail].size = endpos - startpos; | ||
| 1864 | tem = Foverlay_get (overlay, Qpriority); | ||
| 1865 | overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 1866 | ntail++; | ||
| 1867 | total += XSTRING (str)->size; | ||
| 1868 | } | ||
| 1869 | } | ||
| 1870 | if (startpos == pos) | ||
| 1871 | { | ||
| 1872 | str = Foverlay_get (overlay, Qbefore_string); | ||
| 1873 | if (STRINGP (str)) | ||
| 1874 | { | ||
| 1875 | if (nhead == overlay_heads_len) | ||
| 1876 | { | ||
| 1877 | if (! overlay_heads) | ||
| 1878 | { | ||
| 1879 | overlay_heads_len = 5; | ||
| 1880 | overlay_heads = ((struct sortstr *) | ||
| 1881 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 1882 | } | ||
| 1883 | else | ||
| 1884 | { | ||
| 1885 | overlay_heads_len *= 2; | ||
| 1886 | overlay_heads = ((struct sortstr *) | ||
| 1887 | xrealloc ((overlay_heads_len | ||
| 1888 | * sizeof (struct sortstr)))); | ||
| 1889 | } | ||
| 1890 | } | ||
| 1891 | overlay_heads[nhead].string = str; | ||
| 1892 | overlay_heads[nhead].size = endpos - startpos; | ||
| 1893 | tem = Foverlay_get (overlay, Qpriority); | ||
| 1894 | overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 1895 | nhead++; | ||
| 1896 | total += XSTRING (str)->size; | ||
| 1897 | } | ||
| 1898 | } | ||
| 1899 | } | ||
| 1900 | for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr) | ||
| 1901 | { | ||
| 1902 | overlay = XCONS (ov)->car; | ||
| 1903 | if (!OVERLAYP (overlay)) | ||
| 1904 | abort (); | ||
| 1905 | |||
| 1906 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 1907 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 1908 | if (startpos > pos) | ||
| 1909 | break; | ||
| 1910 | if (endpos == pos) | ||
| 1911 | { | ||
| 1912 | str = Foverlay_get (overlay, Qafter_string); | ||
| 1913 | if (STRINGP (str)) | ||
| 1914 | { | ||
| 1915 | if (ntail == overlay_tails_len) | ||
| 1916 | { | ||
| 1917 | if (! overlay_tails) | ||
| 1918 | { | ||
| 1919 | overlay_tails_len = 5; | ||
| 1920 | overlay_tails = ((struct sortstr *) | ||
| 1921 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 1922 | } | ||
| 1923 | else | ||
| 1924 | { | ||
| 1925 | overlay_tails_len *= 2; | ||
| 1926 | overlay_tails = ((struct sortstr *) | ||
| 1927 | xrealloc ((overlay_tails_len | ||
| 1928 | * sizeof (struct sortstr)))); | ||
| 1929 | } | ||
| 1930 | } | ||
| 1931 | overlay_tails[ntail].string = str; | ||
| 1932 | overlay_tails[ntail].size = endpos - startpos; | ||
| 1933 | tem = Foverlay_get (overlay, Qpriority); | ||
| 1934 | overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 1935 | ntail++; | ||
| 1936 | total += XSTRING (str)->size; | ||
| 1937 | } | ||
| 1938 | } | ||
| 1939 | if (startpos == pos) | ||
| 1940 | { | ||
| 1941 | str = Foverlay_get (overlay, Qbefore_string); | ||
| 1942 | if (STRINGP (str)) | ||
| 1943 | { | ||
| 1944 | if (nhead == overlay_heads_len) | ||
| 1945 | { | ||
| 1946 | if (! overlay_heads) | ||
| 1947 | { | ||
| 1948 | overlay_heads_len = 5; | ||
| 1949 | overlay_heads = ((struct sortstr *) | ||
| 1950 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 1951 | } | ||
| 1952 | else | ||
| 1953 | { | ||
| 1954 | overlay_heads_len *= 2; | ||
| 1955 | overlay_heads = ((struct sortstr *) | ||
| 1956 | xrealloc ((overlay_heads_len | ||
| 1957 | * sizeof (struct sortstr)))); | ||
| 1958 | } | ||
| 1959 | } | ||
| 1960 | overlay_heads[nhead].string = str; | ||
| 1961 | overlay_heads[nhead].size = endpos - startpos; | ||
| 1962 | tem = Foverlay_get (overlay, Qpriority); | ||
| 1963 | overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 1964 | nhead++; | ||
| 1965 | total += XSTRING (str)->size; | ||
| 1966 | } | ||
| 1967 | } | ||
| 1968 | } | ||
| 1969 | if (ntail > 1) | ||
| 1970 | qsort (overlay_tails, ntail, sizeof (struct sortstr), cmp_for_strings); | ||
| 1971 | if (nhead > 1) | ||
| 1972 | qsort (overlay_heads, nhead, sizeof (struct sortstr), cmp_for_strings); | ||
| 1973 | if (total) | ||
| 1974 | { | ||
| 1975 | int i; | ||
| 1976 | char *p; | ||
| 1977 | |||
| 1978 | if (total > overlay_str_len) | ||
| 1979 | { | ||
| 1980 | if (! overlay_str_buf) | ||
| 1981 | overlay_str_buf = (char *)xmalloc (total); | ||
| 1982 | else | ||
| 1983 | overlay_str_buf = (char *)xrealloc (overlay_str_buf, total); | ||
| 1984 | overlay_str_len = total; | ||
| 1985 | } | ||
| 1986 | p = overlay_str_buf; | ||
| 1987 | for (i = ntail; --i >= 0;) | ||
| 1988 | { | ||
| 1989 | tem = overlay_tails[i].string; | ||
| 1990 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); | ||
| 1991 | p += XSTRING (tem)->size; | ||
| 1992 | } | ||
| 1993 | for (i = 0; i < nhead; ++i) | ||
| 1994 | { | ||
| 1995 | tem = overlay_heads[i].string; | ||
| 1996 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); | ||
| 1997 | p += XSTRING (tem)->size; | ||
| 1998 | } | ||
| 1999 | if (pstr) | ||
| 2000 | *pstr = overlay_str_buf; | ||
| 2001 | } | ||
| 2002 | return total; | ||
| 2003 | } | ||
| 2004 | |||
| 1779 | /* Shift overlays in BUF's overlay lists, to center the lists at POS. */ | 2005 | /* Shift overlays in BUF's overlay lists, to center the lists at POS. */ |
| 1780 | 2006 | ||
| 1781 | void | 2007 | void |
| @@ -2796,7 +3022,7 @@ init_buffer_once () | |||
| 2796 | buffer_defaults.file_format = Qnil; | 3022 | buffer_defaults.file_format = Qnil; |
| 2797 | buffer_defaults.overlays_before = Qnil; | 3023 | buffer_defaults.overlays_before = Qnil; |
| 2798 | buffer_defaults.overlays_after = Qnil; | 3024 | buffer_defaults.overlays_after = Qnil; |
| 2799 | XSETFASTINT (buffer_defaults.overlay_center, 1); | 3025 | XSETFASTINT (buffer_defaults.overlay_center, BEG); |
| 2800 | 3026 | ||
| 2801 | XSETFASTINT (buffer_defaults.tab_width, 8); | 3027 | XSETFASTINT (buffer_defaults.tab_width, 8); |
| 2802 | buffer_defaults.truncate_lines = Qnil; | 3028 | buffer_defaults.truncate_lines = Qnil; |
| @@ -2948,6 +3174,10 @@ syms_of_buffer () | |||
| 2948 | staticpro (&Qpriority); | 3174 | staticpro (&Qpriority); |
| 2949 | Qwindow = intern ("window"); | 3175 | Qwindow = intern ("window"); |
| 2950 | staticpro (&Qwindow); | 3176 | staticpro (&Qwindow); |
| 3177 | Qbefore_string = intern ("before-string"); | ||
| 3178 | staticpro (&Qbefore_string); | ||
| 3179 | Qafter_string = intern ("after-string"); | ||
| 3180 | staticpro (&Qafter_string); | ||
| 2951 | 3181 | ||
| 2952 | Qoverlayp = intern ("overlayp"); | 3182 | Qoverlayp = intern ("overlayp"); |
| 2953 | 3183 | ||