aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 06:22:52 -0500
committerEli Zaretskii2010-01-01 06:22:52 -0500
commitb44d9321f299626113e7b2e15371b20f7ad38892 (patch)
treeb0078c8e083dd9ef6bc6bb338fd9fbb505a76da8 /src
parentbe39f003e91ecb81161e5cf14ec0b635a6dc229d (diff)
downloademacs-b44d9321f299626113e7b2e15371b20f7ad38892.tar.gz
emacs-b44d9321f299626113e7b2e15371b20f7ad38892.zip
Retrospective commit from 2009-10-05.
Continue working on paragraph base direction. Support per-buffer default paragraph direction. buffer.h (struct buffer): New member paragraph_direction. buffer.c (init_buffer_once): Initialize it. (syms_of_buffer): Declare Lisp variables default-paragraph-direction and paragraph-direction. dispextern.h (struct it): New member paragraph_embedding. xdisp.c (init_iterator): Initialize it from the buffer's value of paragraph-direction. <Qright_to_left, Qleft_to_right>: New variables. (syms_of_xdisp): Initialize and staticpro them. (set_iterator_to_next, next_element_from_buffer): Use the value of paragraph_embedding to determine the paragraph direction. bidi.c (bidi_line_init): Fix second argument to bidi_set_sor_type. (bidi_init_it): Initialize paragraph_dir to NEUTRAL_DIR. (bidi_get_next_char_visually): Record the last character of the separator in separator_limit, not the character after that. (bidi_find_paragraph_start): Accept character and byte positions instead of the whole iterator stricture. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog.bidi23
-rw-r--r--src/bidi.c66
-rw-r--r--src/buffer.c19
-rw-r--r--src/buffer.h4
-rw-r--r--src/dispextern.h1
-rw-r--r--src/xdisp.c26
6 files changed, 104 insertions, 35 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi
index e581be7dc5b..db1d6c5bce0 100644
--- a/src/ChangeLog.bidi
+++ b/src/ChangeLog.bidi
@@ -1,3 +1,26 @@
12009-10-05 Eli Zaretskii <eliz@gnu.org>
2
3 * buffer.h (struct buffer): New member paragraph_direction.
4 * buffer.c (init_buffer_once): Initialize it.
5 (syms_of_buffer): Declare Lisp variables
6 default-paragraph-direction and paragraph-direction.
7
8 * dispextern.h (struct it): New member paragraph_embedding.
9 * xdisp.c (init_iterator): Initialize it from the buffer's value
10 of paragraph-direction.
11 <Qright_to_left, Qleft_to_right>: New variables.
12 (syms_of_xdisp): Initialize and staticpro them.
13 (set_iterator_to_next, next_element_from_buffer): Use the value of
14 paragraph_embedding to determine the paragraph direction.
15
16 * bidi.c (bidi_line_init): Fix second argument to
17 bidi_set_sor_type.
18 (bidi_init_it): Initialize paragraph_dir to NEUTRAL_DIR.
19 (bidi_get_next_char_visually): Record the last character of the
20 separator in separator_limit, not the character after that.
21 (bidi_find_paragraph_start): Accept character and byte positions
22 instead of the whole iterator stricture. All callers changed.
23
12009-10-04 Eli Zaretskii <eliz@gnu.org> 242009-10-04 Eli Zaretskii <eliz@gnu.org>
2 25
3 * bidi.c (bidi_at_paragraph_end): Check for paragraph-start if 26 * bidi.c (bidi_at_paragraph_end): Check for paragraph-start if
diff --git a/src/bidi.c b/src/bidi.c
index 8d9e32d5c3b..fc7e326cfb5 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -807,7 +807,8 @@ bidi_line_init (struct bidi_it *bidi_it)
807 bidi_it->invalid_rl_levels = -1; 807 bidi_it->invalid_rl_levels = -1;
808 bidi_it->next_en_pos = -1; 808 bidi_it->next_en_pos = -1;
809 bidi_it->next_for_ws.type = UNKNOWN_BT; 809 bidi_it->next_for_ws.type = UNKNOWN_BT;
810 bidi_set_sor_type (bidi_it, bidi_it->paragraph_dir, 810 bidi_set_sor_type (bidi_it,
811 bidi_it->paragraph_dir == R2L ? 1 : 0,
811 bidi_it->level_stack[0].level); /* X10 */ 812 bidi_it->level_stack[0].level); /* X10 */
812 813
813 bidi_cache_reset (); 814 bidi_cache_reset ();
@@ -816,11 +817,9 @@ bidi_line_init (struct bidi_it *bidi_it)
816/* Find the beginning of this paragraph by looking back in the buffer. 817/* Find the beginning of this paragraph by looking back in the buffer.
817 Value is the byte position of the paragraph's beginning. */ 818 Value is the byte position of the paragraph's beginning. */
818static EMACS_INT 819static EMACS_INT
819bidi_find_paragraph_start (struct bidi_it *bidi_it) 820bidi_find_paragraph_start (EMACS_INT pos, EMACS_INT pos_byte)
820{ 821{
821 Lisp_Object re = Fbuffer_local_value (Qparagraph_start, Fcurrent_buffer ()); 822 Lisp_Object re = Fbuffer_local_value (Qparagraph_start, Fcurrent_buffer ());
822 EMACS_INT pos = bidi_it->charpos;
823 EMACS_INT pos_byte = bidi_it->bytepos;
824 EMACS_INT limit = ZV, limit_byte = ZV_BYTE; 823 EMACS_INT limit = ZV, limit_byte = ZV_BYTE;
825 824
826 if (!STRINGP (re)) 825 if (!STRINGP (re))
@@ -835,7 +834,13 @@ bidi_find_paragraph_start (struct bidi_it *bidi_it)
835} 834}
836 835
837/* Determine the direction, a.k.a. base embedding level, of the 836/* Determine the direction, a.k.a. base embedding level, of the
838 paragraph we are about to iterate through. */ 837 paragraph we are about to iterate through. If DIR is either L2R or
838 R2L, just use that. Otherwise, determine the paragraph direction
839 from the first strong character of the paragraph.
840
841 Note that this gives the paragraph separator the same direction as
842 the preceding paragraph, even though Emacs generally views the
843 separartor as not belonging to any paragraph. */
839void 844void
840bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) 845bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
841{ 846{
@@ -868,24 +873,21 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
868 if (bidi_it->charpos < bidi_it->separator_limit) 873 if (bidi_it->charpos < bidi_it->separator_limit)
869 return; 874 return;
870 875
871 /* If we are before another paragraph separator, continue 876 /* If we are on a newline, get past it to where the next
872 through that with the previous paragraph direction. */ 877 paragraph might start. */
873 sep_len = bidi_at_paragraph_end (bidi_it->charpos, bytepos); 878 if (FETCH_CHAR (bytepos) == '\n')
874 if (sep_len >= 0)
875 { 879 {
876 bidi_it->separator_limit += sep_len + 1; 880 bytepos++;
877 return; 881 pos = bidi_it->charpos + 1;
878 } 882 }
879 else if (sep_len == -2) 883
880 /* We are in the middle of a paragraph. Search back to where 884 /* We are either at the beginning of a paragraph or in the
881 this paragraph starts. */ 885 middle of it. Find where this paragraph starts. */
882 bytepos = bidi_find_paragraph_start (bidi_it); 886 bytepos = bidi_find_paragraph_start (pos, bytepos);
883 887
884 /* We should always be at the beginning of a new line at this 888 /* We should always be at the beginning of a new line at this
885 point. */ 889 point. */
886 if (!(bytepos == BEGV_BYTE 890 if (!(bytepos == BEGV_BYTE || FETCH_CHAR (bytepos - 1) == '\n'))
887 || FETCH_CHAR (bytepos) == '\n'
888 || FETCH_CHAR (bytepos - 1) == '\n'))
889 abort (); 891 abort ();
890 892
891 bidi_it->separator_limit = -1; 893 bidi_it->separator_limit = -1;
@@ -918,14 +920,15 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
918 else 920 else
919 abort (); 921 abort ();
920 922
921 /* Contrary to UAX#9 clause P3, we only default to L2R if we have no 923 /* Contrary to UAX#9 clause P3, we only default the paragraph
922 previous usable paragraph direction. */ 924 direction to L2R if we have no previous usable paragraph
925 direction. */
923 if (bidi_it->paragraph_dir == NEUTRAL_DIR) 926 if (bidi_it->paragraph_dir == NEUTRAL_DIR)
924 bidi_it->paragraph_dir = L2R; /* P3 */ 927 bidi_it->paragraph_dir = L2R; /* P3 and ``higher protocols'' */
925 if (bidi_it->paragraph_dir == R2L) 928 if (bidi_it->paragraph_dir == R2L)
926 bidi_it->level_stack[0].level == 1; 929 bidi_it->level_stack[0].level = 1;
927 else 930 else
928 bidi_it->level_stack[0].level == 0; 931 bidi_it->level_stack[0].level = 0;
929 932
930 bidi_line_init (bidi_it); 933 bidi_line_init (bidi_it);
931} 934}
@@ -953,6 +956,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, struct bidi_it *bidi_it)
953 bidi_set_paragraph_end (bidi_it); 956 bidi_set_paragraph_end (bidi_it);
954 bidi_it->new_paragraph = 1; 957 bidi_it->new_paragraph = 1;
955 bidi_it->separator_limit = -1; 958 bidi_it->separator_limit = -1;
959 bidi_it->paragraph_dir = NEUTRAL_DIR;
956 bidi_it->type = NEUTRAL_B; 960 bidi_it->type = NEUTRAL_B;
957 bidi_it->type_after_w1 = UNKNOWN_BT; 961 bidi_it->type_after_w1 = UNKNOWN_BT;
958 bidi_it->orig_type = UNKNOWN_BT; 962 bidi_it->orig_type = UNKNOWN_BT;
@@ -1943,9 +1947,13 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
1943 next_level = bidi_level_of_next_char (bidi_it); 1947 next_level = bidi_level_of_next_char (bidi_it);
1944 } 1948 }
1945 1949
1946 /* Take note when we are at the end of the paragraph. The next time 1950 /* Take note when we have just processed the newline that precedes
1947 we are about to be called, set_iterator_to_next will 1951 the end of the paragraph. The next time we are about to be
1948 automatically reinit the paragraph direction, if needed. */ 1952 called, set_iterator_to_next will automatically reinit the
1953 paragraph direction, if needed. We do this at the newline before
1954 the paragraph separator, because the next character might not be
1955 the first character of the next paragraph, due to the bidi
1956 reordering. */
1949 if (bidi_it->scan_dir == 1 1957 if (bidi_it->scan_dir == 1
1950 && bidi_it->orig_type == NEUTRAL_B 1958 && bidi_it->orig_type == NEUTRAL_B
1951 && bidi_it->bytepos < ZV_BYTE) 1959 && bidi_it->bytepos < ZV_BYTE)
@@ -1956,9 +1964,9 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
1956 if (sep_len >= 0) 1964 if (sep_len >= 0)
1957 { 1965 {
1958 bidi_it->new_paragraph = 1; 1966 bidi_it->new_paragraph = 1;
1959 /* Record the buffer position of the first character after 1967 /* Record the buffer position of the last character of the
1960 the paragraph separator. */ 1968 paragraph separator. */
1961 bidi_it->separator_limit = bidi_it->charpos + 1 + sep_len + 1; 1969 bidi_it->separator_limit = bidi_it->charpos + 1 + sep_len;
1962 } 1970 }
1963 } 1971 }
1964 1972
diff --git a/src/buffer.c b/src/buffer.c
index 2930465834d..8484abcdbb5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5188,6 +5188,7 @@ init_buffer_once ()
5188 buffer_defaults.ctl_arrow = Qt; 5188 buffer_defaults.ctl_arrow = Qt;
5189 buffer_defaults.bidi_display_reordering = Qnil; 5189 buffer_defaults.bidi_display_reordering = Qnil;
5190 buffer_defaults.direction_reversed = Qnil; 5190 buffer_defaults.direction_reversed = Qnil;
5191 buffer_defaults.paragraph_direction = Qnil;
5191 buffer_defaults.cursor_type = Qt; 5192 buffer_defaults.cursor_type = Qt;
5192 buffer_defaults.extra_line_spacing = Qnil; 5193 buffer_defaults.extra_line_spacing = Qnil;
5193 buffer_defaults.cursor_in_non_selected_windows = Qt; 5194 buffer_defaults.cursor_in_non_selected_windows = Qt;
@@ -5274,6 +5275,7 @@ init_buffer_once ()
5274 XSETFASTINT (buffer_local_flags.category_table, idx); ++idx; 5275 XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
5275 XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx; 5276 XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx;
5276 XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx; 5277 XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
5278 XSETFASTINT (buffer_local_flags.paragraph_direction, idx); ++idx;
5277 XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx); 5279 XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
5278 /* Make this one a permanent local. */ 5280 /* Make this one a permanent local. */
5279 buffer_permanent_local_flags[idx++] = 1; 5281 buffer_permanent_local_flags[idx++] = 1;
@@ -5545,6 +5547,11 @@ This is the same as (default-value 'direction-reversed). */);
5545 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it. 5547 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
5546This is the same as (default-value 'enable-multibyte-characters). */); 5548This is the same as (default-value 'enable-multibyte-characters). */);
5547 5549
5550 DEFVAR_LISP_NOPRO ("default-paragraph-direction",
5551 &buffer_defaults.paragraph_direction,
5552 doc: /* Default value of `paragraph-direction' for buffers that do not override it.
5553This is the same as (default-value 'paragraph-direction). */);
5554
5548 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system", 5555 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
5549 &buffer_defaults.buffer_file_coding_system, 5556 &buffer_defaults.buffer_file_coding_system,
5550 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it. 5557 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
@@ -5806,6 +5813,18 @@ See also the variable `bidi-display-reordering'. */);
5806 doc: /*Non-nil means reorder bidirectional text for display in the visual order. 5813 doc: /*Non-nil means reorder bidirectional text for display in the visual order.
5807See also the variable `direction-reversed'. */); 5814See also the variable `direction-reversed'. */);
5808 5815
5816 DEFVAR_PER_BUFFER ("paragraph-direction",
5817 &current_buffer->paragraph_direction, Qnil,
5818 doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
5819
5820If this is nil (the default), the direction of each paragraph is
5821determined by the first strong directional character of its text.
5822The values of `right-to-left' and `left-to-right' override that.
5823Any other value is treated as nil.
5824
5825This variable has no effect unless the buffer's value of
5826\`bidi-display-reordering' is non-nil. */);
5827
5809 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil, 5828 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
5810 doc: /* *Non-nil means do not display continuation lines. 5829 doc: /* *Non-nil means do not display continuation lines.
5811Instead, give each line of text just one screen line. 5830Instead, give each line of text just one screen line.
diff --git a/src/buffer.h b/src/buffer.h
index c870f923e87..205bf865879 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -664,6 +664,10 @@ struct buffer
664 /* Non-nil means set beginning of lines at the right edge of 664 /* Non-nil means set beginning of lines at the right edge of
665 windows. */ 665 windows. */
666 Lisp_Object direction_reversed; 666 Lisp_Object direction_reversed;
667 /* If non-nil, specifies which direction of text to force in each
668 paragraph. Nil means determine paragraph direction dynamically
669 for each paragraph. */
670 Lisp_Object paragraph_direction;
667 /* Non-nil means do selective display; 671 /* Non-nil means do selective display;
668 see doc string in syms_of_buffer (buffer.c) for details. */ 672 see doc string in syms_of_buffer (buffer.c) for details. */
669 Lisp_Object selective_display; 673 Lisp_Object selective_display;
diff --git a/src/dispextern.h b/src/dispextern.h
index 6928d8ae1b8..d07b70df6cc 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2327,6 +2327,7 @@ struct it
2327 2327
2328 /* For iterating over bidirectional text. */ 2328 /* For iterating over bidirectional text. */
2329 struct bidi_it bidi_it; 2329 struct bidi_it bidi_it;
2330 bidi_dir_t paragraph_embedding;
2330}; 2331};
2331 2332
2332 2333
diff --git a/src/xdisp.c b/src/xdisp.c
index 7597b2c98ed..e8eb21c4e5a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -248,6 +248,7 @@ Lisp_Object Qfontified;
248Lisp_Object Qgrow_only; 248Lisp_Object Qgrow_only;
249Lisp_Object Qinhibit_eval_during_redisplay; 249Lisp_Object Qinhibit_eval_during_redisplay;
250Lisp_Object Qbuffer_position, Qposition, Qobject; 250Lisp_Object Qbuffer_position, Qposition, Qobject;
251Lisp_Object Qright_to_left, Qleft_to_right;
251 252
252/* Cursor shapes */ 253/* Cursor shapes */
253Lisp_Object Qbar, Qhbar, Qbox, Qhollow; 254Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
@@ -2809,7 +2810,17 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2809 /* If we are to reorder bidirectional text, init the bidi 2810 /* If we are to reorder bidirectional text, init the bidi
2810 iterator. */ 2811 iterator. */
2811 if (it->bidi_p) 2812 if (it->bidi_p)
2812 bidi_init_it (charpos, bytepos, &it->bidi_it); 2813 {
2814 /* Note the paragraph direction that this buffer wants to
2815 use. */
2816 if (EQ (current_buffer->paragraph_direction, Qleft_to_right))
2817 it->paragraph_embedding = L2R;
2818 else if (EQ (current_buffer->paragraph_direction, Qright_to_left))
2819 it->paragraph_embedding = R2L;
2820 else
2821 it->paragraph_embedding = NEUTRAL_DIR;
2822 bidi_init_it (charpos, bytepos, &it->bidi_it);
2823 }
2813 2824
2814 /* If a buffer position was specified, set the iterator there, 2825 /* If a buffer position was specified, set the iterator there,
2815 getting overlays and face properties from that position. */ 2826 getting overlays and face properties from that position. */
@@ -6106,7 +6117,7 @@ set_iterator_to_next (it, reseat_p)
6106 /* If this is a new paragraph, determine its base 6117 /* If this is a new paragraph, determine its base
6107 direction (a.k.a. its base embedding level). */ 6118 direction (a.k.a. its base embedding level). */
6108 if (it->bidi_it.new_paragraph) 6119 if (it->bidi_it.new_paragraph)
6109 bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it); 6120 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6110 bidi_get_next_char_visually (&it->bidi_it); 6121 bidi_get_next_char_visually (&it->bidi_it);
6111 IT_BYTEPOS (*it) = it->bidi_it.bytepos; 6122 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6112 IT_CHARPOS (*it) = it->bidi_it.charpos; 6123 IT_CHARPOS (*it) = it->bidi_it.charpos;
@@ -6527,9 +6538,7 @@ next_element_from_buffer (it)
6527 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' 6538 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6528 || FETCH_CHAR (it->bidi_it.bytepos) == '\n') 6539 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6529 { 6540 {
6530 /* FIXME: NEUTRAL_DIR below should be user-definable and/or 6541 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6531 come from some ``higher protocol''. */
6532 bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it);
6533 bidi_get_next_char_visually (&it->bidi_it); 6542 bidi_get_next_char_visually (&it->bidi_it);
6534 } 6543 }
6535 else 6544 else
@@ -6543,7 +6552,7 @@ next_element_from_buffer (it)
6543 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); 6552 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6544 it->bidi_it.charpos = IT_CHARPOS (*it); 6553 it->bidi_it.charpos = IT_CHARPOS (*it);
6545 it->bidi_it.bytepos = IT_BYTEPOS (*it); 6554 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6546 bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it); 6555 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6547 do { 6556 do {
6548 /* Now return to buffer position where we were asked to 6557 /* Now return to buffer position where we were asked to
6549 get the next display element, and produce that. */ 6558 get the next display element, and produce that. */
@@ -24956,6 +24965,11 @@ syms_of_xdisp ()
24956 staticpro (&previous_help_echo_string); 24965 staticpro (&previous_help_echo_string);
24957 help_echo_pos = -1; 24966 help_echo_pos = -1;
24958 24967
24968 Qright_to_left = intern ("right-to-left");
24969 staticpro (&Qright_to_left);
24970 Qleft_to_right = intern ("left-to-right");
24971 staticpro (&Qleft_to_right);
24972
24959#ifdef HAVE_WINDOW_SYSTEM 24973#ifdef HAVE_WINDOW_SYSTEM
24960 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p, 24974 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24961 doc: /* *Non-nil means draw block cursor as wide as the glyph under it. 24975 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.