aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa1999-12-15 00:14:44 +0000
committerKenichi Handa1999-12-15 00:14:44 +0000
commitf56b42ac9e43c1f77ecd782ceab46a65c10604fe (patch)
tree16990cc466743dd598cc02c4797830ec925b6e32 /src
parenta5ecc8a3152f0d49340b51e2b906598413eb660c (diff)
downloademacs-f56b42ac9e43c1f77ecd782ceab46a65c10604fe.tar.gz
emacs-f56b42ac9e43c1f77ecd782ceab46a65c10604fe.zip
(adjust_intervals_for_insertion): To check stickines
of properties, pay attention to text-property-default-nonsticky. (merge_properties_sticky): Likewise. (get_property_and_range): New function.
Diffstat (limited to 'src')
-rw-r--r--src/intervals.c169
1 files changed, 140 insertions, 29 deletions
diff --git a/src/intervals.c b/src/intervals.c
index 2699c71ee07..bba25d7de8c 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -853,39 +853,69 @@ adjust_intervals_for_insertion (tree, position, length)
853 853
854 /* If in middle of an interval which is not sticky either way, 854 /* If in middle of an interval which is not sticky either way,
855 we must not just give its properties to the insertion. 855 we must not just give its properties to the insertion.
856 So split this interval at the insertion point. */ 856 So split this interval at the insertion point.
857 if (! (position == i->position || eobp) 857
858 && END_NONSTICKY_P (i) 858 Originally, the if condition here was this:
859 && FRONT_NONSTICKY_P (i)) 859 (! (position == i->position || eobp)
860 && END_NONSTICKY_P (i)
861 && FRONT_NONSTICKY_P (i))
862 But, these macros are now unreliable because of introduction of
863 Vtext_property_default_nonsticky. So, we always check properties
864 one by one if POSITION is in middle of an interval. */
865 if (! (position == i->position || eobp))
860 { 866 {
861 Lisp_Object tail; 867 Lisp_Object tail;
862 Lisp_Object front, rear; 868 Lisp_Object front, rear;
863 869
870 tail = i->plist;
871
872 /* Properties font-sticky and rear-nonsticky override
873 Vtext_property_default_nonsticky. So, if they are t, we can
874 skip one by one checking of properties. */
875 rear = textget (i->plist, Qrear_nonsticky);
876 if (! CONSP (rear) && ! NILP (rear))
877 {
878 /* All properties are nonsticky. We split the interval. */
879 goto check_done;
880 }
864 front = textget (i->plist, Qfront_sticky); 881 front = textget (i->plist, Qfront_sticky);
865 rear = textget (i->plist, Qrear_nonsticky); 882 if (! CONSP (front) && ! NILP (front))
883 {
884 /* All properties are sticky. We don't split the interval. */
885 tail = Qnil;
886 goto check_done;
887 }
866 888
867 /* Does any actual property pose an actual problem? */ 889 /* Does any actual property pose an actual problem? We break
868 for (tail = i->plist; ! NILP (tail); tail = Fcdr (Fcdr (tail))) 890 the loop if we find a nonsticky property. */
891 for (; CONSP (tail); tail = Fcdr (XCDR (tail)))
869 { 892 {
870 Lisp_Object prop; 893 Lisp_Object prop, tmp;
871 prop = XCAR (tail); 894 prop = XCAR (tail);
872 895
873 /* Is this particular property rear-sticky? 896 /* Is this particular property front-sticky? */
874 Note, if REAR isn't a cons, it must be non-nil,
875 which means that all properties are rear-nonsticky. */
876 if (CONSP (rear) && NILP (Fmemq (prop, rear)))
877 continue;
878
879 /* Is this particular property front-sticky?
880 Note, if FRONT isn't a cons, it must be nil,
881 which means that all properties are front-nonsticky. */
882 if (CONSP (front) && ! NILP (Fmemq (prop, front))) 897 if (CONSP (front) && ! NILP (Fmemq (prop, front)))
883 continue; 898 continue;
884 899
885 /* PROP isn't sticky on either side => it is a real problem. */ 900 /* Is this particular property rear-nonsticky? */
886 break; 901 if (CONSP (rear) && ! NILP (Fmemq (prop, rear)))
902 break;
903
904 /* Is this particular property recorded as sticky or
905 nonsticky in Vtext_property_default_nonsticky? */
906 tmp = Fassq (prop, Vtext_property_default_nonsticky);
907 if (CONSP (tmp))
908 {
909 if (NILP (tmp))
910 continue;
911 break;
912 }
913
914 /* By default, a text property is rear-sticky, thus we
915 continue the loop. */
887 } 916 }
888 917
918 check_done:
889 /* If any property is a real problem, split the interval. */ 919 /* If any property is a real problem, split the interval. */
890 if (! NILP (tail)) 920 if (! NILP (tail))
891 { 921 {
@@ -921,8 +951,16 @@ adjust_intervals_for_insertion (tree, position, length)
921 } 951 }
922 952
923 /* If at least one interval has sticky properties, 953 /* If at least one interval has sticky properties,
924 we check the stickiness property by property. */ 954 we check the stickiness property by property.
925 if (END_NONSTICKY_P (prev) || FRONT_STICKY_P (i)) 955
956 Originally, the if condition here was this:
957 (END_NONSTICKY_P (prev) || FRONT_STICKY_P (i))
958 But, these macros are now unreliable because of introduction
959 of Vtext_property_default_nonsticky. So, we always have to
960 check stickiness of properties one by one. If cache of
961 stickiness is implemented in the future, we may be able to
962 use those macros again. */
963 if (1)
926 { 964 {
927 Lisp_Object pleft, pright; 965 Lisp_Object pleft, pright;
928 struct interval newi; 966 struct interval newi;
@@ -1030,8 +1068,10 @@ merge_properties_sticky (pleft, pright)
1030 rrear = textget (pright, Qrear_nonsticky); 1068 rrear = textget (pright, Qrear_nonsticky);
1031 1069
1032 /* Go through each element of PRIGHT. */ 1070 /* Go through each element of PRIGHT. */
1033 for (tail1 = pright; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1))) 1071 for (tail1 = pright; CONSP (tail1); tail1 = Fcdr (Fcdr (tail1)))
1034 { 1072 {
1073 Lisp_Object tmp;
1074
1035 sym = Fcar (tail1); 1075 sym = Fcar (tail1);
1036 1076
1037 /* Sticky properties get special treatment. */ 1077 /* Sticky properties get special treatment. */
@@ -1039,7 +1079,7 @@ merge_properties_sticky (pleft, pright)
1039 continue; 1079 continue;
1040 1080
1041 rval = Fcar (Fcdr (tail1)); 1081 rval = Fcar (Fcdr (tail1));
1042 for (tail2 = pleft; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2))) 1082 for (tail2 = pleft; CONSP (tail2); tail2 = Fcdr (Fcdr (tail2)))
1043 if (EQ (sym, Fcar (tail2))) 1083 if (EQ (sym, Fcar (tail2)))
1044 break; 1084 break;
1045 1085
@@ -1049,8 +1089,15 @@ merge_properties_sticky (pleft, pright)
1049 lpresent = ! NILP (tail2); 1089 lpresent = ! NILP (tail2);
1050 lval = (NILP (tail2) ? Qnil : Fcar (Fcdr (tail2))); 1090 lval = (NILP (tail2) ? Qnil : Fcar (Fcdr (tail2)));
1051 1091
1052 use_left = ! TMEM (sym, lrear) && lpresent; 1092 /* Even if lrear or rfront say nothing about the stickiness of
1053 use_right = TMEM (sym, rfront); 1093 SYM, Vtext_property_default_nonsticky may give default
1094 stickiness to SYM. */
1095 tmp = Fassq (sym, Vtext_property_default_nonsticky);
1096 use_left = (lpresent
1097 && ! (TMEM (sym, lrear)
1098 || CONSP (tmp) && ! NILP (XCDR (tmp))));
1099 use_right = (TMEM (sym, rfront)
1100 || (CONSP (tmp) && NILP (XCDR (tmp))));
1054 if (use_left && use_right) 1101 if (use_left && use_right)
1055 { 1102 {
1056 if (NILP (lval)) 1103 if (NILP (lval))
@@ -1079,8 +1126,10 @@ merge_properties_sticky (pleft, pright)
1079 } 1126 }
1080 1127
1081 /* Now go through each element of PLEFT. */ 1128 /* Now go through each element of PLEFT. */
1082 for (tail2 = pleft; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2))) 1129 for (tail2 = pleft; CONSP (tail2); tail2 = Fcdr (Fcdr (tail2)))
1083 { 1130 {
1131 Lisp_Object tmp;
1132
1084 sym = Fcar (tail2); 1133 sym = Fcar (tail2);
1085 1134
1086 /* Sticky properties get special treatment. */ 1135 /* Sticky properties get special treatment. */
@@ -1088,7 +1137,7 @@ merge_properties_sticky (pleft, pright)
1088 continue; 1137 continue;
1089 1138
1090 /* If sym is in PRIGHT, we've already considered it. */ 1139 /* If sym is in PRIGHT, we've already considered it. */
1091 for (tail1 = pright; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1))) 1140 for (tail1 = pright; CONSP (tail1); tail1 = Fcdr (Fcdr (tail1)))
1092 if (EQ (sym, Fcar (tail1))) 1141 if (EQ (sym, Fcar (tail1)))
1093 break; 1142 break;
1094 if (! NILP (tail1)) 1143 if (! NILP (tail1))
@@ -1096,14 +1145,19 @@ merge_properties_sticky (pleft, pright)
1096 1145
1097 lval = Fcar (Fcdr (tail2)); 1146 lval = Fcar (Fcdr (tail2));
1098 1147
1148 /* Even if lrear or rfront say nothing about the stickiness of
1149 SYM, Vtext_property_default_nonsticky may give default
1150 stickiness to SYM. */
1151 tmp = Fassq (sym, Vtext_property_default_nonsticky);
1152
1099 /* Since rval is known to be nil in this loop, the test simplifies. */ 1153 /* Since rval is known to be nil in this loop, the test simplifies. */
1100 if (! TMEM (sym, lrear)) 1154 if (! (TMEM (sym, lrear) || (CONSP (tmp) && ! NILP (XCDR (tmp)))))
1101 { 1155 {
1102 props = Fcons (lval, Fcons (sym, props)); 1156 props = Fcons (lval, Fcons (sym, props));
1103 if (TMEM (sym, lfront)) 1157 if (TMEM (sym, lfront))
1104 front = Fcons (sym, front); 1158 front = Fcons (sym, front);
1105 } 1159 }
1106 else if (TMEM (sym, rfront)) 1160 else if (TMEM (sym, rfront) || (CONSP (tmp) && NILP (XCDR (tmp))))
1107 { 1161 {
1108 /* The value is nil, but we still inherit the stickiness 1162 /* The value is nil, but we still inherit the stickiness
1109 from the right. */ 1163 from the right. */
@@ -1648,14 +1702,24 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1648 = split_interval_left (this, position - under->position); 1702 = split_interval_left (this, position - under->position);
1649 copy_properties (under, end_unchanged); 1703 copy_properties (under, end_unchanged);
1650 under->position = position; 1704 under->position = position;
1705#if 0
1706 /* This code has no effect. */
1651 prev = 0; 1707 prev = 0;
1652 middle = 1; 1708 middle = 1;
1709#endif /* 0 */
1653 } 1710 }
1654 else 1711 else
1655 { 1712 {
1713 /* This call may have some effect because previous_interval may
1714 update `position' fields of intervals. Thus, don't ignore it
1715 for the moment. Someone please tell me the truth (K.Handa). */
1656 prev = previous_interval (under); 1716 prev = previous_interval (under);
1717#if 0
1718 /* But, this code surely has no effect. And, anyway,
1719 END_NONSTICKY_P is unreliable now. */
1657 if (prev && !END_NONSTICKY_P (prev)) 1720 if (prev && !END_NONSTICKY_P (prev))
1658 prev = 0; 1721 prev = 0;
1722#endif /* 0 */
1659 } 1723 }
1660 1724
1661 /* Insertion is now at beginning of UNDER. */ 1725 /* Insertion is now at beginning of UNDER. */
@@ -2017,6 +2081,53 @@ move_if_not_intangible (position)
2017 SET_PT (position); 2081 SET_PT (position);
2018} 2082}
2019 2083
2084/* If text at position POS has property PROP, set *VAL to the property
2085 value, *START and *END to the beginning and end of a region that
2086 has the same property, and return 1. Otherwise return 0.
2087
2088 OBJECT is the string or buffer to look for the property in;
2089 nil means the current buffer. */
2090
2091int
2092get_property_and_range (pos, prop, val, start, end, object)
2093 int pos;
2094 Lisp_Object prop, *val;
2095 int *start, *end;
2096 Lisp_Object object;
2097{
2098 INTERVAL i, prev, next;
2099
2100 if (NILP (object))
2101 i = find_interval (BUF_INTERVALS (current_buffer), pos);
2102 else if (BUFFERP (object))
2103 i = find_interval (BUF_INTERVALS (XBUFFER (object)), pos);
2104 else if (STRINGP (object))
2105 i = find_interval (XSTRING (object)->intervals, pos);
2106 else
2107 abort ();
2108
2109 if (NULL_INTERVAL_P (i) || (i->position + LENGTH (i) <= pos))
2110 return 0;
2111 *val = textget (i->plist, prop);
2112 if (NILP (*val))
2113 return 0;
2114
2115 next = i; /* remember it in advance */
2116 prev = previous_interval (i);
2117 while (! NULL_INTERVAL_P (prev)
2118 && EQ (*val, textget (prev->plist, prop)))
2119 i = prev, prev = previous_interval (prev);
2120 *start = i->position;
2121
2122 next = next_interval (i);
2123 while (! NULL_INTERVAL_P (next)
2124 && EQ (*val, textget (next->plist, prop)))
2125 i = next, next = next_interval (next);
2126 *end = i->position + LENGTH (i);
2127
2128 return 1;
2129}
2130
2020/* Return the proper local map for position POSITION in BUFFER. 2131/* Return the proper local map for position POSITION in BUFFER.
2021 Use the map specified by the local-map property, if any. 2132 Use the map specified by the local-map property, if any.
2022 Otherwise, use BUFFER's local map. */ 2133 Otherwise, use BUFFER's local map. */