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 @@ | |||
| 1 | 2012-08-18 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (handle_invisible_prop): Obey TEXT_PROP_MEANS_INVISIBLE | ||
| 4 | for the string case (Bug#3874). | ||
| 5 | |||
| 1 | 2012-08-18 Paul Eggert <eggert@cs.ucla.edu> | 6 | 2012-08-18 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 7 | ||
| 3 | * buffer.h (BSET): Remove (Bug#12215). | 8 | * 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 | |||
| 4069 | handle_invisible_prop (struct it *it) | 4069 | handle_invisible_prop (struct it *it) |
| 4070 | { | 4070 | { |
| 4071 | enum prop_handled handled = HANDLED_NORMALLY; | 4071 | enum prop_handled handled = HANDLED_NORMALLY; |
| 4072 | int invis_p; | ||
| 4073 | Lisp_Object prop; | ||
| 4072 | 4074 | ||
| 4073 | if (STRINGP (it->string)) | 4075 | if (STRINGP (it->string)) |
| 4074 | { | 4076 | { |
| 4075 | Lisp_Object prop, end_charpos, limit, charpos; | 4077 | Lisp_Object end_charpos, limit, charpos; |
| 4076 | 4078 | ||
| 4077 | /* Get the value of the invisible text property at the | 4079 | /* Get the value of the invisible text property at the |
| 4078 | current position. Value will be nil if there is no such | 4080 | current position. Value will be nil if there is no such |
| 4079 | property. */ | 4081 | property. */ |
| 4080 | charpos = make_number (IT_STRING_CHARPOS (*it)); | 4082 | charpos = make_number (IT_STRING_CHARPOS (*it)); |
| 4081 | prop = Fget_text_property (charpos, Qinvisible, it->string); | 4083 | prop = Fget_text_property (charpos, Qinvisible, it->string); |
| 4084 | invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); | ||
| 4082 | 4085 | ||
| 4083 | if (!NILP (prop) | 4086 | if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos) |
| 4084 | && IT_STRING_CHARPOS (*it) < it->end_charpos) | ||
| 4085 | { | 4087 | { |
| 4088 | /* Record whether we have to display an ellipsis for the | ||
| 4089 | invisible text. */ | ||
| 4090 | int display_ellipsis_p = (invis_p == 2); | ||
| 4086 | ptrdiff_t endpos; | 4091 | ptrdiff_t endpos; |
| 4087 | 4092 | ||
| 4088 | handled = HANDLED_RECOMPUTE_PROPS; | 4093 | handled = HANDLED_RECOMPUTE_PROPS; |
| 4089 | 4094 | ||
| 4090 | /* Get the position at which the next change of the | 4095 | /* Get the position at which the next visible text can be |
| 4091 | invisible text property can be found in IT->string. | 4096 | found in IT->string, if any. */ |
| 4092 | Value will be nil if the property value is the same for | ||
| 4093 | all the rest of IT->string. */ | ||
| 4094 | XSETINT (limit, SCHARS (it->string)); | 4097 | XSETINT (limit, SCHARS (it->string)); |
| 4095 | end_charpos = Fnext_single_property_change (charpos, Qinvisible, | 4098 | do |
| 4096 | it->string, limit); | 4099 | { |
| 4100 | end_charpos = Fnext_single_property_change (charpos, Qinvisible, | ||
| 4101 | it->string, limit); | ||
| 4102 | if (!NILP (end_charpos)) | ||
| 4103 | { | ||
| 4104 | prop = Fget_text_property (end_charpos, Qinvisible, it->string); | ||
| 4105 | invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); | ||
| 4106 | if (invis_p == 2) | ||
| 4107 | display_ellipsis_p = 1; | ||
| 4108 | } | ||
| 4109 | } | ||
| 4110 | while (!NILP (end_charpos) && invis_p); | ||
| 4111 | |||
| 4112 | if (display_ellipsis_p) | ||
| 4113 | { | ||
| 4114 | it->ellipsis_p = 1; | ||
| 4115 | handled = HANDLED_RETURN; | ||
| 4116 | } | ||
| 4097 | 4117 | ||
| 4098 | /* Text at current position is invisible. The next | ||
| 4099 | change in the property is at position end_charpos. | ||
| 4100 | Move IT's current position to that position. */ | ||
| 4101 | if (INTEGERP (end_charpos) | 4118 | if (INTEGERP (end_charpos) |
| 4102 | && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit)) | 4119 | && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit)) |
| 4103 | { | 4120 | { |
| 4121 | /* Text at END_CHARPOS is visible. Move IT there. */ | ||
| 4104 | struct text_pos old; | 4122 | struct text_pos old; |
| 4105 | ptrdiff_t oldpos; | 4123 | ptrdiff_t oldpos; |
| 4106 | 4124 | ||
| @@ -4153,9 +4171,8 @@ handle_invisible_prop (struct it *it) | |||
| 4153 | } | 4171 | } |
| 4154 | else | 4172 | else |
| 4155 | { | 4173 | { |
| 4156 | int invis_p; | ||
| 4157 | ptrdiff_t newpos, next_stop, start_charpos, tem; | 4174 | ptrdiff_t newpos, next_stop, start_charpos, tem; |
| 4158 | Lisp_Object pos, prop, overlay; | 4175 | Lisp_Object pos, overlay; |
| 4159 | 4176 | ||
| 4160 | /* First of all, is there invisible text at this position? */ | 4177 | /* First of all, is there invisible text at this position? */ |
| 4161 | tem = start_charpos = IT_CHARPOS (*it); | 4178 | tem = start_charpos = IT_CHARPOS (*it); |
| @@ -6032,7 +6049,7 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 6032 | { | 6049 | { |
| 6033 | Lisp_Object prop; | 6050 | Lisp_Object prop; |
| 6034 | prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1), | 6051 | prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1), |
| 6035 | Qinvisible, it->window); | 6052 | Qinvisible, it->window); |
| 6036 | if (TEXT_PROP_MEANS_INVISIBLE (prop)) | 6053 | if (TEXT_PROP_MEANS_INVISIBLE (prop)) |
| 6037 | continue; | 6054 | continue; |
| 6038 | } | 6055 | } |
diff --git a/test/ChangeLog b/test/ChangeLog index f1bf458f812..cd7e9fd7ccc 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2012-08-18 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * redisplay-testsuite.el (test-redisplay-4): New test (Bug#3874). | ||
| 4 | |||
| 1 | 2012-08-14 Dmitry Gutov <dgutov@yandex.ru> | 5 | 2012-08-14 Dmitry Gutov <dgutov@yandex.ru> |
| 2 | 6 | ||
| 3 | * indent/ruby.rb: Rearrange examples, add new ones. | 7 | * 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 @@ | |||
| 113 | (insert "\n\n")) | 113 | (insert "\n\n")) |
| 114 | 114 | ||
| 115 | (defun test-redisplay-3 () | 115 | (defun test-redisplay-3 () |
| 116 | (insert "Test 3: Overlay with before/after strings and images:\n\n") | 116 | (insert "Test 3: Overlay with strings and images:\n\n") |
| 117 | (let ((img-data "#define x_width 8 | 117 | (let ((img-data "#define x_width 8 |
| 118 | #define x_height 8 | 118 | #define x_height 8 |
| 119 | static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff };")) | 119 | 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 | |||
| 165 | (overlay-put ov2 'before-string "C") | 165 | (overlay-put ov2 'before-string "C") |
| 166 | (overlay-put ov3 'display `(image :data ,img-data :type xbm)))))) | 166 | (overlay-put ov3 'display `(image :data ,img-data :type xbm)))))) |
| 167 | 167 | ||
| 168 | (defun test-redisplay-4 () | ||
| 169 | (insert "Test 4: Overlay strings and invisibility:\n\n") | ||
| 170 | ;; Before and after strings with non-nil `invisibility'. | ||
| 171 | (insert " Expected: ABC\n") | ||
| 172 | (insert " Result: ") | ||
| 173 | (let ((opoint (point))) | ||
| 174 | (insert "ABC\n") | ||
| 175 | (let ((ov (make-overlay (1+ opoint) (+ 2 opoint)))) | ||
| 176 | (overlay-put ov 'before-string | ||
| 177 | (propertize "XX" 'invisible | ||
| 178 | 'test-redisplay--simple-invis)) | ||
| 179 | (overlay-put ov 'after-string | ||
| 180 | (propertize "XX" 'invisible | ||
| 181 | 'test-redisplay--simple-invis)))) | ||
| 182 | |||
| 183 | ;; Before and after strings bogus `invisibility' property (value is | ||
| 184 | ;; not listed in `buffer-invisibility-spec'). | ||
| 185 | (insert "\n Expected: ABC") | ||
| 186 | (insert "\n Result: ") | ||
| 187 | (let ((opoint (point))) | ||
| 188 | (insert "B\n") | ||
| 189 | (let ((ov (make-overlay opoint (1+ opoint)))) | ||
| 190 | (overlay-put ov 'before-string | ||
| 191 | (propertize "A" 'invisible 'bogus-invis-spec)) | ||
| 192 | (overlay-put ov 'after-string | ||
| 193 | (propertize "C" 'invisible 'bogus-invis-spec)))) | ||
| 194 | |||
| 195 | ;; Before/after string with ellipsis `invisibility' property. | ||
| 196 | (insert "\n Expected: ...B...") | ||
| 197 | (insert "\n Result: ") | ||
| 198 | (let ((opoint (point))) | ||
| 199 | (insert "B\n") | ||
| 200 | (let ((ov (make-overlay opoint (1+ opoint)))) | ||
| 201 | (overlay-put ov 'before-string | ||
| 202 | (propertize "A" 'invisible 'test-redisplay--ellipsis-invis)) | ||
| 203 | (overlay-put ov 'after-string | ||
| 204 | (propertize "C" 'invisible 'test-redisplay--ellipsis-invis)))) | ||
| 205 | |||
| 206 | ;; Before/after string with partial ellipsis `invisibility' property. | ||
| 207 | (insert "\n Expected: A...ABC...C") | ||
| 208 | (insert "\n Result: ") | ||
| 209 | (let ((opoint (point))) | ||
| 210 | (insert "B\n") | ||
| 211 | (let ((ov (make-overlay opoint (1+ opoint))) | ||
| 212 | (a "AAA") | ||
| 213 | (c "CCC")) | ||
| 214 | (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis a) | ||
| 215 | (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis c) | ||
| 216 | (overlay-put ov 'before-string a) | ||
| 217 | (overlay-put ov 'after-string c))) | ||
| 218 | |||
| 219 | ;; Display string with `invisibility' property. | ||
| 220 | (insert "\n Expected: ABC") | ||
| 221 | (insert "\n Result: ") | ||
| 222 | (let ((opoint (point))) | ||
| 223 | (insert "AYBC\n") | ||
| 224 | (let ((ov (make-overlay (1+ opoint) (+ 2 opoint)))) | ||
| 225 | (overlay-put ov 'display | ||
| 226 | (propertize "XX" 'invisible | ||
| 227 | 'test-redisplay--simple-invis)))) | ||
| 228 | ;; Display string with bogus `invisibility' property. | ||
| 229 | (insert "\n Expected: ABC") | ||
| 230 | (insert "\n Result: ") | ||
| 231 | (let ((opoint (point))) | ||
| 232 | (insert "AXC\n") | ||
| 233 | (let ((ov (make-overlay (1+ opoint) (+ 2 opoint)))) | ||
| 234 | (overlay-put ov 'display | ||
| 235 | (propertize "B" 'invisible 'bogus-invis-spec)))) | ||
| 236 | ;; Display string with ellipsis `invisibility' property. | ||
| 237 | (insert "\n Expected: A...C") | ||
| 238 | (insert "\n Result: ") | ||
| 239 | (let ((opoint (point))) | ||
| 240 | (insert "AXC\n") | ||
| 241 | (let ((ov (make-overlay (1+ opoint) (+ 2 opoint)))) | ||
| 242 | (overlay-put ov 'display | ||
| 243 | (propertize "B" 'invisible | ||
| 244 | 'test-redisplay--ellipsis-invis)))) | ||
| 245 | ;; Display string with partial `invisibility' property. | ||
| 246 | (insert "\n Expected: A...C") | ||
| 247 | (insert "\n Result: ") | ||
| 248 | (let ((opoint (point))) | ||
| 249 | (insert "X\n") | ||
| 250 | (let ((ov (make-overlay opoint (1+ opoint))) | ||
| 251 | (str "ABC")) | ||
| 252 | (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis str) | ||
| 253 | (overlay-put ov 'display str))) | ||
| 254 | |||
| 255 | (insert "\n")) | ||
| 256 | |||
| 168 | 257 | ||
| 169 | (defun test-redisplay () | 258 | (defun test-redisplay () |
| 170 | (interactive) | 259 | (interactive) |
| @@ -173,8 +262,12 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff | |||
| 173 | (kill-buffer buf)) | 262 | (kill-buffer buf)) |
| 174 | (pop-to-buffer (get-buffer-create "*Redisplay Test*")) | 263 | (pop-to-buffer (get-buffer-create "*Redisplay Test*")) |
| 175 | (erase-buffer) | 264 | (erase-buffer) |
| 265 | (setq buffer-invisibility-spec | ||
| 266 | '(test-redisplay--simple-invis | ||
| 267 | (test-redisplay--ellipsis-invis . t))) | ||
| 176 | (test-redisplay-1) | 268 | (test-redisplay-1) |
| 177 | (test-redisplay-2) | 269 | (test-redisplay-2) |
| 178 | (test-redisplay-3) | 270 | (test-redisplay-3) |
| 271 | (test-redisplay-4) | ||
| 179 | (goto-char (point-min)))) | 272 | (goto-char (point-min)))) |
| 180 | 273 | ||