]> git.eshelyaron.com Git - emacs.git/commitdiff
Make display strings obey buffer-invisibility-spec.
authorChong Yidong <cyd@gnu.org>
Sat, 18 Aug 2012 07:23:30 +0000 (15:23 +0800)
committerChong Yidong <cyd@gnu.org>
Sat, 18 Aug 2012 07:23:30 +0000 (15:23 +0800)
* src/xdisp.c (handle_invisible_prop): Obey TEXT_PROP_MEANS_INVISIBLE
for the string case.

* redisplay-testsuite.el (test-redisplay-4): New test.

Fixes: debbugs:3874
src/ChangeLog
src/xdisp.c
test/ChangeLog
test/redisplay-testsuite.el

index 28143d43b236b122cfd3e7e3e0a0056c7ad85e93..beb47d6c998cda164e6e7e2e87e8d16b1847623e 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-18  Chong Yidong  <cyd@gnu.org>
+
+       * xdisp.c (handle_invisible_prop): Obey TEXT_PROP_MEANS_INVISIBLE
+       for the string case (Bug#3874).
+
 2012-08-18  Paul Eggert  <eggert@cs.ucla.edu>
 
        * buffer.h (BSET): Remove (Bug#12215).
index 03fb94ca1b3e2fd338912592499050236817e721..ff74af983047b05fb87252f0fcff18aeac80073b 100644 (file)
@@ -4069,38 +4069,56 @@ static enum prop_handled
 handle_invisible_prop (struct it *it)
 {
   enum prop_handled handled = HANDLED_NORMALLY;
+  int invis_p;
+  Lisp_Object prop;
 
   if (STRINGP (it->string))
     {
-      Lisp_Object prop, end_charpos, limit, charpos;
+      Lisp_Object end_charpos, limit, charpos;
 
       /* Get the value of the invisible text property at the
         current position.  Value will be nil if there is no such
         property.  */
       charpos = make_number (IT_STRING_CHARPOS (*it));
       prop = Fget_text_property (charpos, Qinvisible, it->string);
+      invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
 
-      if (!NILP (prop)
-         && IT_STRING_CHARPOS (*it) < it->end_charpos)
+      if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
        {
+         /* Record whether we have to display an ellipsis for the
+            invisible text.  */
+         int display_ellipsis_p = (invis_p == 2);
          ptrdiff_t endpos;
 
          handled = HANDLED_RECOMPUTE_PROPS;
 
-         /* Get the position at which the next change of the
-            invisible text property can be found in IT->string.
-            Value will be nil if the property value is the same for
-            all the rest of IT->string.  */
+         /* Get the position at which the next visible text can be
+            found in IT->string, if any.  */
          XSETINT (limit, SCHARS (it->string));
-         end_charpos = Fnext_single_property_change (charpos, Qinvisible,
-                                                     it->string, limit);
+         do
+           {
+             end_charpos = Fnext_single_property_change (charpos, Qinvisible,
+                                                         it->string, limit);
+             if (!NILP (end_charpos))
+               {
+                 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
+                 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
+                 if (invis_p == 2)
+                   display_ellipsis_p = 1;
+               }
+           }
+         while (!NILP (end_charpos) && invis_p);
+
+         if (display_ellipsis_p)
+           {
+             it->ellipsis_p = 1;
+             handled = HANDLED_RETURN;
+           }
 
-         /* Text at current position is invisible.  The next
-            change in the property is at position end_charpos.
-            Move IT's current position to that position.  */
          if (INTEGERP (end_charpos)
              && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
            {
+             /* Text at END_CHARPOS is visible.  Move IT there.  */
              struct text_pos old;
              ptrdiff_t oldpos;
 
@@ -4153,9 +4171,8 @@ handle_invisible_prop (struct it *it)
     }
   else
     {
-      int invis_p;
       ptrdiff_t newpos, next_stop, start_charpos, tem;
-      Lisp_Object pos, prop, overlay;
+      Lisp_Object pos, overlay;
 
       /* First of all, is there invisible text at this position?  */
       tem = start_charpos = IT_CHARPOS (*it);
@@ -6032,7 +6049,7 @@ back_to_previous_visible_line_start (struct it *it)
       {
        Lisp_Object prop;
        prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
-                                    Qinvisible, it->window);
+                                  Qinvisible, it->window);
        if (TEXT_PROP_MEANS_INVISIBLE (prop))
          continue;
       }
index f1bf458f8122a010ae553a4a2e27dc9e1f5103c2..cd7e9fd7cccb3eada7f79acfba57d029ca87a693 100644 (file)
@@ -1,3 +1,7 @@
+2012-08-18  Chong Yidong  <cyd@gnu.org>
+
+       * redisplay-testsuite.el (test-redisplay-4): New test (Bug#3874).
+
 2012-08-14  Dmitry Gutov  <dgutov@yandex.ru>
 
        * indent/ruby.rb: Rearrange examples, add new ones.
index f080b6db4f135531626f09d6890947c38147531f..99924daa3d99a53a5fa2472b1c9600cd5b0562f4 100644 (file)
   (insert "\n\n"))
 
 (defun test-redisplay-3 ()
-  (insert "Test 3: Overlay with before/after strings and images:\n\n")
+  (insert "Test 3: Overlay with strings and images:\n\n")
   (let ((img-data "#define x_width 8
 #define x_height 8
 static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff };"))
@@ -165,6 +165,95 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff
        (overlay-put ov2 'before-string "C")
        (overlay-put ov3 'display `(image :data ,img-data :type xbm))))))
 
+(defun test-redisplay-4 ()
+  (insert "Test 4: Overlay strings and invisibility:\n\n")
+  ;; Before and after strings with non-nil `invisibility'.
+  (insert "  Expected: ABC\n")
+  (insert "    Result: ")
+  (let ((opoint (point)))
+    (insert "ABC\n")
+    (let ((ov (make-overlay (1+ opoint) (+ 2 opoint))))
+      (overlay-put ov 'before-string
+                  (propertize "XX" 'invisible
+                              'test-redisplay--simple-invis))
+      (overlay-put ov 'after-string
+                  (propertize "XX" 'invisible
+                              'test-redisplay--simple-invis))))
+
+  ;; Before and after strings bogus `invisibility' property (value is
+  ;; not listed in `buffer-invisibility-spec').
+  (insert "\n  Expected: ABC")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "B\n")
+    (let ((ov (make-overlay opoint (1+ opoint))))
+      (overlay-put ov 'before-string
+                  (propertize "A" 'invisible 'bogus-invis-spec))
+      (overlay-put ov 'after-string
+                  (propertize "C" 'invisible 'bogus-invis-spec))))
+
+  ;; Before/after string with ellipsis `invisibility' property.
+  (insert "\n  Expected: ...B...")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "B\n")
+    (let ((ov (make-overlay opoint (1+ opoint))))
+      (overlay-put ov 'before-string
+                  (propertize "A" 'invisible 'test-redisplay--ellipsis-invis))
+      (overlay-put ov 'after-string
+                  (propertize "C" 'invisible 'test-redisplay--ellipsis-invis))))
+
+  ;; Before/after string with partial ellipsis `invisibility' property.
+  (insert "\n  Expected: A...ABC...C")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "B\n")
+    (let ((ov (make-overlay opoint (1+ opoint)))
+         (a "AAA")
+         (c "CCC"))
+      (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis a)
+      (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis c)
+      (overlay-put ov 'before-string a)
+      (overlay-put ov 'after-string  c)))
+
+  ;; Display string with `invisibility' property.
+  (insert "\n  Expected: ABC")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "AYBC\n")
+    (let ((ov (make-overlay (1+ opoint) (+ 2 opoint))))
+      (overlay-put ov 'display
+                  (propertize "XX" 'invisible
+                              'test-redisplay--simple-invis))))
+  ;; Display string with bogus `invisibility' property.
+  (insert "\n  Expected: ABC")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "AXC\n")
+    (let ((ov (make-overlay (1+ opoint) (+ 2 opoint))))
+      (overlay-put ov 'display
+                  (propertize "B" 'invisible 'bogus-invis-spec))))
+  ;; Display string with ellipsis `invisibility' property.
+  (insert "\n  Expected: A...C")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "AXC\n")
+    (let ((ov (make-overlay (1+ opoint) (+ 2 opoint))))
+      (overlay-put ov 'display
+                  (propertize "B" 'invisible
+                              'test-redisplay--ellipsis-invis))))
+  ;; Display string with partial `invisibility' property.
+  (insert "\n  Expected: A...C")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "X\n")
+    (let ((ov  (make-overlay opoint (1+ opoint)))
+         (str "ABC"))
+      (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis str)
+      (overlay-put ov 'display str)))
+
+  (insert "\n"))
+
 
 (defun test-redisplay ()
   (interactive)
@@ -173,8 +262,12 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff
        (kill-buffer buf))
     (pop-to-buffer (get-buffer-create "*Redisplay Test*"))
     (erase-buffer)
+    (setq buffer-invisibility-spec
+         '(test-redisplay--simple-invis
+           (test-redisplay--ellipsis-invis . t)))
     (test-redisplay-1)
     (test-redisplay-2)
     (test-redisplay-3)
+    (test-redisplay-4)
     (goto-char (point-min))))