comparison src/xdisp.c @ 71337:7128a9839095

(init_from_display_pos): Don't set it->method and overlay_string_index after pop_it. Add asserts. (handle_stop): Look for overlay strings around a display string, image, or composition. Handle properties on those strings. (next_overlay_string): Don't set string, pos or method after pop_it. (get_overlay_strings_1): Split from get_overlay_strings; don't modify it if no overlay strings are found. (get_overlay_strings): Use get_overlay_strings_1. Always set it->string and it->method. (push_it): Push it->image_id and it->method. Push it->object instead of it->string if method is GET_FROM_IMAGE. (pop_it): Pop it->image_id and it->method. Ppo it->object instead of it->string if method is GET_FROM_IMAGE. Reset it->current.string_pos if popped it->string is nil. (reseat_1): Remove comment dated 19 May 2003. It expressed doubt whether a given change was correct; but the change is correct. Clear it->string_from_display_prop_p. (set_iterator_to_next): Rely on it->method and it->image_id from iterator stack, instead of setting them explicitly after pop_it.
author Kim F. Storm <storm@cua.dk>
date Tue, 13 Jun 2006 22:45:00 +0000
parents 938915517680
children 50899a9ba412
comparison
equal deleted inserted replaced
71336:6844a4a9691c 71337:7128a9839095
914 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object, 914 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
915 int, int, struct it *, int, int, int, int)); 915 int, int, struct it *, int, int, int, int));
916 static void compute_line_metrics P_ ((struct it *)); 916 static void compute_line_metrics P_ ((struct it *));
917 static void run_redisplay_end_trigger_hook P_ ((struct it *)); 917 static void run_redisplay_end_trigger_hook P_ ((struct it *));
918 static int get_overlay_strings P_ ((struct it *, int)); 918 static int get_overlay_strings P_ ((struct it *, int));
919 static int get_overlay_strings_1 P_ ((struct it *, int, int));
919 static void next_overlay_string P_ ((struct it *)); 920 static void next_overlay_string P_ ((struct it *));
920 static void reseat P_ ((struct it *, struct text_pos, int)); 921 static void reseat P_ ((struct it *, struct text_pos, int));
921 static void reseat_1 P_ ((struct it *, struct text_pos, int)); 922 static void reseat_1 P_ ((struct it *, struct text_pos, int));
922 static void back_to_previous_visible_line_start P_ ((struct it *)); 923 static void back_to_previous_visible_line_start P_ ((struct it *));
923 void reseat_at_previous_visible_line_start P_ ((struct it *)); 924 void reseat_at_previous_visible_line_start P_ ((struct it *));
2907 POS, make sure to pop the iterator because it will be in 2908 POS, make sure to pop the iterator because it will be in
2908 front of that overlay string. When POS is ZV, we've thereby 2909 front of that overlay string. When POS is ZV, we've thereby
2909 also ``processed'' overlay strings at ZV. */ 2910 also ``processed'' overlay strings at ZV. */
2910 while (it->sp) 2911 while (it->sp)
2911 pop_it (it); 2912 pop_it (it);
2912 it->current.overlay_string_index = -1; 2913 xassert (it->current.overlay_string_index == -1);
2913 it->method = GET_FROM_BUFFER; 2914 xassert (it->method == GET_FROM_BUFFER);
2914 if (CHARPOS (pos->pos) == ZV) 2915 if (CHARPOS (pos->pos) == ZV)
2915 it->overlay_strings_at_end_processed_p = 1; 2916 it->overlay_strings_at_end_processed_p = 1;
2916 } 2917 }
2917 #endif /* 0 */ 2918 #endif /* 0 */
2918 2919
3019 handled = p->handler (it); 3020 handled = p->handler (it);
3020 3021
3021 if (handled == HANDLED_RECOMPUTE_PROPS) 3022 if (handled == HANDLED_RECOMPUTE_PROPS)
3022 break; 3023 break;
3023 else if (handled == HANDLED_RETURN) 3024 else if (handled == HANDLED_RETURN)
3024 return; 3025 {
3026 /* We still want to show before and after strings from
3027 overlays even if the actual buffer text is replaced. */
3028 if (!handle_overlay_change_p || it->sp > 1)
3029 return;
3030 if (!get_overlay_strings_1 (it, 0, 0))
3031 return;
3032 it->string_from_display_prop_p = 0;
3033 handle_overlay_change_p = 0;
3034 handled = HANDLED_RECOMPUTE_PROPS;
3035 break;
3036 }
3025 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED) 3037 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3026 handle_overlay_change_p = 0; 3038 handle_overlay_change_p = 0;
3027 } 3039 }
3028 3040
3029 if (handled != HANDLED_RECOMPUTE_PROPS) 3041 if (handled != HANDLED_RECOMPUTE_PROPS)
4541 they were before overlay strings were processed, and 4553 they were before overlay strings were processed, and
4542 continue to deliver from current_buffer. */ 4554 continue to deliver from current_buffer. */
4543 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p; 4555 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4544 4556
4545 pop_it (it); 4557 pop_it (it);
4546 xassert (it->stop_charpos >= BEGV 4558 xassert (it->sp > 0
4547 && it->stop_charpos <= it->end_charpos); 4559 || (NILP (it->string)
4548 it->string = Qnil; 4560 && it->method == GET_FROM_BUFFER
4561 && it->stop_charpos >= BEGV
4562 && it->stop_charpos <= it->end_charpos));
4549 it->current.overlay_string_index = -1; 4563 it->current.overlay_string_index = -1;
4550 SET_TEXT_POS (it->current.string_pos, -1, -1);
4551 it->n_overlay_strings = 0; 4564 it->n_overlay_strings = 0;
4552 it->method = GET_FROM_BUFFER;
4553 4565
4554 /* If we're at the end of the buffer, record that we have 4566 /* If we're at the end of the buffer, record that we have
4555 processed the overlay strings there already, so that 4567 processed the overlay strings there already, so that
4556 next_element_from_buffer doesn't try it again. */ 4568 next_element_from_buffer doesn't try it again. */
4557 if (IT_CHARPOS (*it) >= it->end_charpos) 4569 if (IT_CHARPOS (*it) >= it->end_charpos)
4803 /* Get the first chunk of overlay strings at IT's current buffer 4815 /* Get the first chunk of overlay strings at IT's current buffer
4804 position, or at CHARPOS if that is > 0. Value is non-zero if at 4816 position, or at CHARPOS if that is > 0. Value is non-zero if at
4805 least one overlay string was found. */ 4817 least one overlay string was found. */
4806 4818
4807 static int 4819 static int
4808 get_overlay_strings (it, charpos) 4820 get_overlay_strings_1 (it, charpos, compute_stop_p)
4809 struct it *it; 4821 struct it *it;
4810 int charpos; 4822 int charpos;
4811 { 4823 {
4812 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to 4824 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4813 process. This fills IT->overlay_strings with strings, and sets 4825 process. This fills IT->overlay_strings with strings, and sets
4825 if (it->n_overlay_strings) 4837 if (it->n_overlay_strings)
4826 { 4838 {
4827 /* Make sure we know settings in current_buffer, so that we can 4839 /* Make sure we know settings in current_buffer, so that we can
4828 restore meaningful values when we're done with the overlay 4840 restore meaningful values when we're done with the overlay
4829 strings. */ 4841 strings. */
4830 compute_stop_pos (it); 4842 if (compute_stop_p)
4843 compute_stop_pos (it);
4831 xassert (it->face_id >= 0); 4844 xassert (it->face_id >= 0);
4832 4845
4833 /* Save IT's settings. They are restored after all overlay 4846 /* Save IT's settings. They are restored after all overlay
4834 strings have been processed. */ 4847 strings have been processed. */
4835 xassert (it->sp == 0); 4848 xassert (!compute_stop_p || it->sp == 0);
4836 push_it (it); 4849 push_it (it);
4837 4850
4838 /* Set up IT to deliver display elements from the first overlay 4851 /* Set up IT to deliver display elements from the first overlay
4839 string. */ 4852 string. */
4840 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; 4853 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4842 it->stop_charpos = 0; 4855 it->stop_charpos = 0;
4843 xassert (STRINGP (it->string)); 4856 xassert (STRINGP (it->string));
4844 it->end_charpos = SCHARS (it->string); 4857 it->end_charpos = SCHARS (it->string);
4845 it->multibyte_p = STRING_MULTIBYTE (it->string); 4858 it->multibyte_p = STRING_MULTIBYTE (it->string);
4846 it->method = GET_FROM_STRING; 4859 it->method = GET_FROM_STRING;
4847 } 4860 return 1;
4848 else 4861 }
4849 { 4862
4850 it->string = Qnil; 4863 it->current.overlay_string_index = -1;
4851 it->current.overlay_string_index = -1; 4864 return 0;
4852 it->method = GET_FROM_BUFFER; 4865 }
4853 } 4866
4867 static int
4868 get_overlay_strings (it, charpos)
4869 struct it *it;
4870 int charpos;
4871 {
4872 it->string = Qnil;
4873 it->method = GET_FROM_BUFFER;
4874
4875 (void) get_overlay_strings_1 (it, charpos, 1);
4854 4876
4855 CHECK_IT (it); 4877 CHECK_IT (it);
4856 4878
4857 /* Value is non-zero if we found at least one overlay string. */ 4879 /* Value is non-zero if we found at least one overlay string. */
4858 return STRINGP (it->string); 4880 return STRINGP (it->string);
4873 push_it (it) 4895 push_it (it)
4874 struct it *it; 4896 struct it *it;
4875 { 4897 {
4876 struct iterator_stack_entry *p; 4898 struct iterator_stack_entry *p;
4877 4899
4878 xassert (it->sp < 2); 4900 xassert (it->sp < IT_STACK_SIZE);
4879 p = it->stack + it->sp; 4901 p = it->stack + it->sp;
4880 4902
4881 p->stop_charpos = it->stop_charpos; 4903 p->stop_charpos = it->stop_charpos;
4882 xassert (it->face_id >= 0); 4904 xassert (it->face_id >= 0);
4883 p->face_id = it->face_id; 4905 p->face_id = it->face_id;
4884 p->string = it->string; 4906 p->image_id = it->image_id;
4907 p->method = it->method;
4908 if (it->method == GET_FROM_IMAGE)
4909 p->string = it->object;
4910 else
4911 p->string = it->string;
4885 p->pos = it->current; 4912 p->pos = it->current;
4886 p->end_charpos = it->end_charpos; 4913 p->end_charpos = it->end_charpos;
4887 p->string_nchars = it->string_nchars; 4914 p->string_nchars = it->string_nchars;
4888 p->area = it->area; 4915 p->area = it->area;
4889 p->multibyte_p = it->multibyte_p; 4916 p->multibyte_p = it->multibyte_p;
4912 xassert (it->sp > 0); 4939 xassert (it->sp > 0);
4913 --it->sp; 4940 --it->sp;
4914 p = it->stack + it->sp; 4941 p = it->stack + it->sp;
4915 it->stop_charpos = p->stop_charpos; 4942 it->stop_charpos = p->stop_charpos;
4916 it->face_id = p->face_id; 4943 it->face_id = p->face_id;
4917 it->string = p->string; 4944 it->method = p->method;
4945 it->image_id = p->image_id;
4918 it->current = p->pos; 4946 it->current = p->pos;
4947 if (it->method == GET_FROM_IMAGE)
4948 {
4949 it->object = it->string;
4950 it->string = Qnil;
4951 }
4952 else
4953 it->string = p->string;
4954 if (NILP (it->string))
4955 SET_TEXT_POS (it->current.string_pos, -1, -1);
4919 it->end_charpos = p->end_charpos; 4956 it->end_charpos = p->end_charpos;
4920 it->string_nchars = p->string_nchars; 4957 it->string_nchars = p->string_nchars;
4921 it->area = p->area; 4958 it->area = p->area;
4922 it->multibyte_p = p->multibyte_p; 4959 it->multibyte_p = p->multibyte_p;
4923 it->slice = p->slice; 4960 it->slice = p->slice;
5231 it->current.overlay_string_index = -1; 5268 it->current.overlay_string_index = -1;
5232 IT_STRING_CHARPOS (*it) = -1; 5269 IT_STRING_CHARPOS (*it) = -1;
5233 IT_STRING_BYTEPOS (*it) = -1; 5270 IT_STRING_BYTEPOS (*it) = -1;
5234 it->string = Qnil; 5271 it->string = Qnil;
5235 it->method = GET_FROM_BUFFER; 5272 it->method = GET_FROM_BUFFER;
5236 /* RMS: I added this to fix a bug in move_it_vertically_backward
5237 where it->area continued to relate to the starting point
5238 for the backward motion. Bug report from
5239 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
5240 However, I am not sure whether reseat still does the right thing
5241 in general after this change. */
5242 it->area = TEXT_AREA; 5273 it->area = TEXT_AREA;
5243 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); 5274 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5244 it->sp = 0; 5275 it->sp = 0;
5276 it->string_from_display_prop_p = 0;
5245 it->face_before_selective_p = 0; 5277 it->face_before_selective_p = 0;
5246 5278
5247 if (set_stop_p) 5279 if (set_stop_p)
5248 it->stop_charpos = CHARPOS (pos); 5280 it->stop_charpos = CHARPOS (pos);
5249 } 5281 }
5807 string, this time an overlay string, or a buffer. */ 5839 string, this time an overlay string, or a buffer. */
5808 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string) 5840 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5809 && it->sp > 0) 5841 && it->sp > 0)
5810 { 5842 {
5811 pop_it (it); 5843 pop_it (it);
5812 if (STRINGP (it->string)) 5844 if (it->method == GET_FROM_STRING)
5813 goto consider_string_end; 5845 goto consider_string_end;
5814 it->method = GET_FROM_BUFFER;
5815 } 5846 }
5816 } 5847 }
5817 break; 5848 break;
5818 5849
5819 case GET_FROM_IMAGE: 5850 case GET_FROM_IMAGE:
5821 /* The position etc with which we have to proceed are on 5852 /* The position etc with which we have to proceed are on
5822 the stack. The position may be at the end of a string, 5853 the stack. The position may be at the end of a string,
5823 if the `display' property takes up the whole string. */ 5854 if the `display' property takes up the whole string. */
5824 xassert (it->sp > 0); 5855 xassert (it->sp > 0);
5825 pop_it (it); 5856 pop_it (it);
5826 it->image_id = 0; 5857 if (it->method == GET_FROM_STRING)
5827 if (STRINGP (it->string)) 5858 goto consider_string_end;
5828 {
5829 it->method = GET_FROM_STRING;
5830 goto consider_string_end;
5831 }
5832 it->method = GET_FROM_BUFFER;
5833 break; 5859 break;
5834 5860
5835 default: 5861 default:
5836 /* There are no other methods defined, so this should be a bug. */ 5862 /* There are no other methods defined, so this should be a bug. */
5837 abort (); 5863 abort ();