Mercurial > emacs
comparison src/intervals.c @ 43898:8b2a2bd229c3
(adjust_for_invis_intang): New function.
(set_point_both): Use `adjust_for_invis_intang' to do most of the work
for dealing with invisible+intangible regions. Do so before and after
both forward and backward movements, to handle both front-sticky and
rear-sticky cases.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Thu, 14 Mar 2002 08:11:46 +0000 |
parents | 3af09e7320c0 |
children | b9f2c8b7c60e |
comparison
equal
deleted
inserted
replaced
43897:46cd50d89b5b | 43898:8b2a2bd229c3 |
---|---|
1 /* Code for doing intervals. | 1 /* Code for doing intervals. |
2 Copyright (C) 1993, 1994, 1995, 1997, 1998 Free Software Foundation, Inc. | 2 Copyright (C) 1993, 1994, 1995, 1997, 1998, 2002 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GNU Emacs. | 4 This file is part of GNU Emacs. |
5 | 5 |
6 GNU Emacs is free software; you can redistribute it and/or modify | 6 GNU Emacs is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
1881 register int charpos; | 1881 register int charpos; |
1882 { | 1882 { |
1883 set_point_both (buffer, charpos, buf_charpos_to_bytepos (buffer, charpos)); | 1883 set_point_both (buffer, charpos, buf_charpos_to_bytepos (buffer, charpos)); |
1884 } | 1884 } |
1885 | 1885 |
1886 /* If there's an invisible character at position POS + TEST_OFFS in the | |
1887 current buffer, and the invisible property has a `stickiness' such that | |
1888 inserting a character at position POS would inherit the property it, | |
1889 return POS + ADJ, otherwise return POS. If TEST_INTANG is non-zero, | |
1890 then intangibility is required as well as invisibleness. | |
1891 | |
1892 TEST_OFFS should be either 0 or -1, and ADJ should be either 1 or -1. | |
1893 | |
1894 Note that `stickiness' is determined by overlay marker insertion types, | |
1895 if the invisible property comes from an overlay. */ | |
1896 | |
1897 static int | |
1898 adjust_for_invis_intang (pos, test_offs, adj, test_intang) | |
1899 int pos, test_offs, adj, test_intang; | |
1900 { | |
1901 Lisp_Object invis_propval, invis_overlay; | |
1902 Lisp_Object test_pos; | |
1903 | |
1904 if ((adj < 0 && pos + adj < BEGV) || (adj > 0 && pos + adj > ZV)) | |
1905 /* POS + ADJ would be beyond the buffer bounds, so do no adjustment. */ | |
1906 return pos; | |
1907 | |
1908 test_pos = make_number (pos + test_offs); | |
1909 | |
1910 invis_propval | |
1911 = get_char_property_and_overlay (test_pos, Qinvisible, Qnil, | |
1912 &invis_overlay); | |
1913 | |
1914 if ((!test_intang | |
1915 || ! NILP (Fget_char_property (test_pos, Qintangible, Qnil))) | |
1916 && TEXT_PROP_MEANS_INVISIBLE (invis_propval) | |
1917 /* This next test is true if the invisible property has a stickiness | |
1918 such that an insertion at POS would inherit it. */ | |
1919 && (NILP (invis_overlay) | |
1920 /* Invisible property is from a text-property. */ | |
1921 ? (text_property_stickiness (Qinvisible, make_number (pos)) | |
1922 == (test_offs == 0 ? 1 : -1)) | |
1923 /* Invisible property is from an overlay. */ | |
1924 : (test_offs == 0 | |
1925 ? XMARKER (OVERLAY_START (invis_overlay))->insertion_type == 0 | |
1926 : XMARKER (OVERLAY_END (invis_overlay))->insertion_type == 1))) | |
1927 pos += adj; | |
1928 | |
1929 return pos; | |
1930 } | |
1931 | |
1886 /* Set point in BUFFER to CHARPOS, which corresponds to byte | 1932 /* Set point in BUFFER to CHARPOS, which corresponds to byte |
1887 position BYTEPOS. If the target position is | 1933 position BYTEPOS. If the target position is |
1888 before an intangible character, move to an ok place. */ | 1934 before an intangible character, move to an ok place. */ |
1889 | 1935 |
1890 void | 1936 void |
1973 || have_overlays) | 2019 || have_overlays) |
1974 /* Intangibility never stops us from positioning at the beginning | 2020 /* Intangibility never stops us from positioning at the beginning |
1975 or end of the buffer, so don't bother checking in that case. */ | 2021 or end of the buffer, so don't bother checking in that case. */ |
1976 && charpos != BEGV && charpos != ZV) | 2022 && charpos != BEGV && charpos != ZV) |
1977 { | 2023 { |
1978 Lisp_Object intangible_propval, invisible_propval; | |
1979 Lisp_Object pos; | 2024 Lisp_Object pos; |
1980 int invis_p; | 2025 Lisp_Object intangible_propval; |
1981 | |
1982 XSETINT (pos, charpos); | |
1983 | 2026 |
1984 if (backwards) | 2027 if (backwards) |
1985 { | 2028 { |
1986 /* If the preceding char is both invisible and intangible, | 2029 /* If the preceeding character is both intangible and invisible, |
1987 start backing up from just before that one. */ | 2030 and the invisible property is `rear-sticky', perturb it so |
1988 | 2031 that the search starts one character earlier -- this ensures |
1989 intangible_propval | 2032 that point can never move to the end of an invisible/ |
1990 = Fget_char_property (make_number (charpos - 1), | 2033 intangible/rear-sticky region. */ |
1991 Qintangible, Qnil); | 2034 charpos = adjust_for_invis_intang (charpos, -1, -1, 1); |
1992 invisible_propval | 2035 |
1993 = Fget_char_property (make_number (charpos - 1), Qinvisible, Qnil); | 2036 XSETINT (pos, charpos); |
1994 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible_propval); | |
1995 | |
1996 if (! NILP (intangible_propval) && invis_p) | |
1997 XSETINT (pos, --charpos); | |
1998 | 2037 |
1999 /* If following char is intangible, | 2038 /* If following char is intangible, |
2000 skip back over all chars with matching intangible property. */ | 2039 skip back over all chars with matching intangible property. */ |
2001 | 2040 |
2002 intangible_propval = Fget_char_property (pos, Qintangible, Qnil); | 2041 intangible_propval = Fget_char_property (pos, Qintangible, Qnil); |
2006 while (XINT (pos) > BUF_BEGV (buffer) | 2045 while (XINT (pos) > BUF_BEGV (buffer) |
2007 && EQ (Fget_char_property (make_number (XINT (pos) - 1), | 2046 && EQ (Fget_char_property (make_number (XINT (pos) - 1), |
2008 Qintangible, Qnil), | 2047 Qintangible, Qnil), |
2009 intangible_propval)) | 2048 intangible_propval)) |
2010 pos = Fprevious_char_property_change (pos, Qnil); | 2049 pos = Fprevious_char_property_change (pos, Qnil); |
2050 | |
2051 /* Set CHARPOS from POS, and if the final intangible character | |
2052 that we skipped over is also invisible, and the invisible | |
2053 property is `front-sticky', perturb it to be one character | |
2054 earlier -- this ensures that point can never move to the | |
2055 beginning of an invisible/intangible/front-sticky region. */ | |
2056 charpos = adjust_for_invis_intang (XINT (pos), 0, -1, 0); | |
2011 } | 2057 } |
2012 } | 2058 } |
2013 else | 2059 else |
2014 { | 2060 { |
2061 /* If the following character is both intangible and invisible, | |
2062 and the invisible property is `front-sticky', perturb it so | |
2063 that the search starts one character later -- this ensures | |
2064 that point can never move to the beginning of an | |
2065 invisible/intangible/front-sticky region. */ | |
2066 charpos = adjust_for_invis_intang (charpos, 0, 1, 1); | |
2067 | |
2068 XSETINT (pos, charpos); | |
2069 | |
2015 /* If preceding char is intangible, | 2070 /* If preceding char is intangible, |
2016 skip forward over all chars with matching intangible property. */ | 2071 skip forward over all chars with matching intangible property. */ |
2017 | 2072 |
2018 intangible_propval = Fget_char_property (make_number (charpos - 1), | 2073 intangible_propval = Fget_char_property (make_number (charpos - 1), |
2019 Qintangible, Qnil); | 2074 Qintangible, Qnil); |
2023 while (XINT (pos) < BUF_ZV (buffer) | 2078 while (XINT (pos) < BUF_ZV (buffer) |
2024 && EQ (Fget_char_property (pos, Qintangible, Qnil), | 2079 && EQ (Fget_char_property (pos, Qintangible, Qnil), |
2025 intangible_propval)) | 2080 intangible_propval)) |
2026 pos = Fnext_char_property_change (pos, Qnil); | 2081 pos = Fnext_char_property_change (pos, Qnil); |
2027 | 2082 |
2028 /* Is the last one invisible as well as intangible? */ | 2083 /* Set CHARPOS from POS, and if the final intangible character |
2029 | 2084 that we skipped over is also invisible, and the invisible |
2030 invisible_propval | 2085 property is `rear-sticky', perturb it to be one character |
2031 = Fget_char_property (make_number (XINT (pos) - 1), | 2086 later -- this ensures that point can never move to the |
2032 Qinvisible, Qnil); | 2087 end of an invisible/intangible/rear-sticky region. */ |
2033 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible_propval); | 2088 charpos = adjust_for_invis_intang (XINT (pos), -1, 1, 0); |
2034 | |
2035 /* If so, advance one character more: | |
2036 don't stop after an invisible, intangible character. */ | |
2037 | |
2038 if (invis_p && XINT (pos) < BUF_ZV (buffer)) | |
2039 XSETINT (pos, XINT (pos) + 1); | |
2040 } | 2089 } |
2041 } | 2090 } |
2042 | 2091 |
2043 charpos = XINT (pos); | |
2044 bytepos = buf_charpos_to_bytepos (buffer, charpos); | 2092 bytepos = buf_charpos_to_bytepos (buffer, charpos); |
2045 } | 2093 } |
2046 | 2094 |
2047 if (charpos != original_position) | 2095 if (charpos != original_position) |
2048 { | 2096 { |