diff options
-rw-r--r-- | src/ChangeLog | 5 | ||||
-rw-r--r-- | src/xdisp.c | 47 | ||||
-rw-r--r-- | test/ChangeLog | 4 | ||||
-rw-r--r-- | test/redisplay-testsuite.el | 95 |
4 files changed, 135 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 28143d43b23..beb47d6c998 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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). diff --git a/src/xdisp.c b/src/xdisp.c index 03fb94ca1b3..ff74af98304 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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; } diff --git a/test/ChangeLog b/test/ChangeLog index f1bf458f812..cd7e9fd7ccc 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -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. diff --git a/test/redisplay-testsuite.el b/test/redisplay-testsuite.el index f080b6db4f1..99924daa3d9 100644 --- a/test/redisplay-testsuite.el +++ b/test/redisplay-testsuite.el @@ -113,7 +113,7 @@ (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)))) |