From f6614a4770f298ad6ccdf6995adb706cc4d03c11 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 23 Mar 2014 18:30:47 -0400 Subject: [PATCH] * lisp/simple.el (redisplay-highlight-region-function): Increase priority of overlay to make sure boundaries are visible. * src/buffer.c (struct sortvec): Add field `spriority'. (compare_overlays): Use it. (sort_overlays): Set it. Fixes: debbugs:15899 --- lisp/ChangeLog | 5 +++++ lisp/simple.el | 5 +++++ src/ChangeLog | 6 ++++++ src/buffer.c | 49 ++++++++++++++++++++++++++++++++++++------------- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 943a5e8da7..f0705e5edd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-03-23 Stefan Monnier + + * simple.el (redisplay-highlight-region-function): Increase priority of + overlay to make sure boundaries are visible (bug#15899). + 2014-03-23 Juanma Barranquero * frameset.el (frameset-restore): Compare display strings with equal. diff --git a/lisp/simple.el b/lisp/simple.el index d77de2f567..c8350005ac 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4476,6 +4476,11 @@ also checks the value of `use-empty-active-region'." (funcall redisplay-unhighlight-region-function rol) (overlay-put nrol 'window window) (overlay-put nrol 'face 'region) + ;; Normal priority so that a large region doesn't hide all the + ;; overlays within it, but high secondary priority so that if it + ;; ends/starts in the middle of a small overlay, that small overlay + ;; won't hide the region's boundaries. + (overlay-put nrol 'priority '(nil . 100)) nrol) (unless (and (eq (overlay-buffer rol) (current-buffer)) (eq (overlay-start rol) start) diff --git a/src/ChangeLog b/src/ChangeLog index ad6df5e7ae..1510e4e158 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-03-23 Stefan Monnier + + * buffer.c (struct sortvec): Add field `spriority'. + (compare_overlays): Use it. + (sort_overlays): Set it. + 2014-03-23 Eli Zaretskii * xdisp.c (redisplay_window): If all previous attempts to find the diff --git a/src/buffer.c b/src/buffer.c index daafbcef0e..a167895198 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3147,6 +3147,7 @@ struct sortvec Lisp_Object overlay; ptrdiff_t beg, end; EMACS_INT priority; + EMACS_INT spriority; /* Secondary priority. */ }; static int @@ -3154,19 +3155,28 @@ compare_overlays (const void *v1, const void *v2) { const struct sortvec *s1 = v1; const struct sortvec *s2 = v2; + /* Return 1 if s1 should take precedence, -1 if v2 should take precedence, + and 0 if they're equal. */ if (s1->priority != s2->priority) return s1->priority < s2->priority ? -1 : 1; - if (s1->beg != s2->beg) - return s1->beg < s2->beg ? -1 : 1; - if (s1->end != s2->end) + /* If the priority is equal, give precedence to the one not covered by the + other. If neither covers the other, obey spriority. */ + else if (s1->beg < s2->beg) + return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1); + else if (s1->beg > s2->beg) + return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1); + else if (s1->end != s2->end) return s2->end < s1->end ? -1 : 1; - /* Avoid the non-determinism of qsort by choosing an arbitrary ordering - between "equal" overlays. The result can still change between - invocations of Emacs, but it won't change in the middle of - `find_field' (bug#6830). */ - if (!EQ (s1->overlay, s2->overlay)) + else if (s1->spriority != s2->spriority) + return (s1->spriority < s2->spriority ? -1 : 1); + else if (EQ (s1->overlay, s2->overlay)) + return 0; + else + /* Avoid the non-determinism of qsort by choosing an arbitrary ordering + between "equal" overlays. The result can still change between + invocations of Emacs, but it won't change in the middle of + `find_field' (bug#6830). */ return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; - return 0; } /* Sort an array of overlays by priority. The array is modified in place. @@ -3209,10 +3219,23 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); tem = Foverlay_get (overlay, Qpriority); - if (INTEGERP (tem)) - sortvec[j].priority = XINT (tem); - else - sortvec[j].priority = 0; + if (NILP (tem)) + { + sortvec[j].priority = 0; + sortvec[j].spriority = 0; + } + else if (INTEGERP (tem)) + { + sortvec[j].priority = XINT (tem); + sortvec[j].spriority = 0; + } + else if (CONSP (tem)) + { + Lisp_Object car = XCAR (tem); + Lisp_Object cdr = XCDR (tem); + sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0; + sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0; + } j++; } } -- 2.20.1