aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 5e923d26f3f..a22c6d7dd54 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3142,6 +3142,7 @@ struct sortvec
3142 Lisp_Object overlay; 3142 Lisp_Object overlay;
3143 ptrdiff_t beg, end; 3143 ptrdiff_t beg, end;
3144 EMACS_INT priority; 3144 EMACS_INT priority;
3145 EMACS_INT spriority; /* Secondary priority. */
3145}; 3146};
3146 3147
3147static int 3148static int
@@ -3149,19 +3150,28 @@ compare_overlays (const void *v1, const void *v2)
3149{ 3150{
3150 const struct sortvec *s1 = v1; 3151 const struct sortvec *s1 = v1;
3151 const struct sortvec *s2 = v2; 3152 const struct sortvec *s2 = v2;
3153 /* Return 1 if s1 should take precedence, -1 if v2 should take precedence,
3154 and 0 if they're equal. */
3152 if (s1->priority != s2->priority) 3155 if (s1->priority != s2->priority)
3153 return s1->priority < s2->priority ? -1 : 1; 3156 return s1->priority < s2->priority ? -1 : 1;
3154 if (s1->beg != s2->beg) 3157 /* If the priority is equal, give precedence to the one not covered by the
3155 return s1->beg < s2->beg ? -1 : 1; 3158 other. If neither covers the other, obey spriority. */
3156 if (s1->end != s2->end) 3159 else if (s1->beg < s2->beg)
3160 return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1);
3161 else if (s1->beg > s2->beg)
3162 return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1);
3163 else if (s1->end != s2->end)
3157 return s2->end < s1->end ? -1 : 1; 3164 return s2->end < s1->end ? -1 : 1;
3158 /* Avoid the non-determinism of qsort by choosing an arbitrary ordering 3165 else if (s1->spriority != s2->spriority)
3159 between "equal" overlays. The result can still change between 3166 return (s1->spriority < s2->spriority ? -1 : 1);
3160 invocations of Emacs, but it won't change in the middle of 3167 else if (EQ (s1->overlay, s2->overlay))
3161 `find_field' (bug#6830). */ 3168 return 0;
3162 if (!EQ (s1->overlay, s2->overlay)) 3169 else
3170 /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
3171 between "equal" overlays. The result can still change between
3172 invocations of Emacs, but it won't change in the middle of
3173 `find_field' (bug#6830). */
3163 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; 3174 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3164 return 0;
3165} 3175}
3166 3176
3167/* Sort an array of overlays by priority. The array is modified in place. 3177/* Sort an array of overlays by priority. The array is modified in place.
@@ -3204,10 +3214,23 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3204 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); 3214 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3205 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3215 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3206 tem = Foverlay_get (overlay, Qpriority); 3216 tem = Foverlay_get (overlay, Qpriority);
3207 if (INTEGERP (tem)) 3217 if (NILP (tem))
3208 sortvec[j].priority = XINT (tem); 3218 {
3209 else 3219 sortvec[j].priority = 0;
3210 sortvec[j].priority = 0; 3220 sortvec[j].spriority = 0;
3221 }
3222 else if (INTEGERP (tem))
3223 {
3224 sortvec[j].priority = XINT (tem);
3225 sortvec[j].spriority = 0;
3226 }
3227 else if (CONSP (tem))
3228 {
3229 Lisp_Object car = XCAR (tem);
3230 Lisp_Object cdr = XCDR (tem);
3231 sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
3232 sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
3233 }
3211 j++; 3234 j++;
3212 } 3235 }
3213 } 3236 }