diff options
| author | Eli Zaretskii | 2010-03-30 05:13:07 -0400 |
|---|---|---|
| committer | Eli Zaretskii | 2010-03-30 05:13:07 -0400 |
| commit | a7b028203499410a9f4bebe8220be8f3a9ce598b (patch) | |
| tree | 085ffc8adee85e9d1e55eace47a2bf13da81098c /src/buffer.c | |
| parent | 82fc79808b345b43efc20c064baec63cc14df8a5 (diff) | |
| parent | 4d6ea387e7527aa73d7664e98bfd2e2c24b1628d (diff) | |
| download | emacs-a7b028203499410a9f4bebe8220be8f3a9ce598b.tar.gz emacs-a7b028203499410a9f4bebe8220be8f3a9ce598b.zip | |
Initial support for bidirectional editing.
Makefile.in (obj): Include bidi.o.
(bidi.o): New target.
makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O).
($(BLD)/bidi.$(O)): New target.
bidi.c: New file.
buffer.h (struct buffer): New members bidi_display_reordering
and bidi_paragraph_direction.
buffer.c (init_buffer_once): Initialize bidi_display_reordering
and bidi_paragraph_direction.
(syms_of_buffer): Declare Lisp variables bidi-display-reordering
and bidi-paragraph-direction.
(Fbuffer_swap_text): Swap the values of
bidi_display_reordering and bidi_paragraph_direction.
dispextern.h (BIDI_MAXLEVEL, BIDI_AT_BASE_LEVEL): New macros.
(bidi_type_t, bidi_dir_t): New types.
(bidi_saved_info, bidi_stack, bidi_it): New structures.
(struct it): New members bidi_p, bidi_it, paragraph_embedding,
prev_stop, base_level_stop, and eol_pos.
(bidi_init_it, bidi_get_next_char_visually): New prototypes.
(IT_STACK_SIZE): Enlarge to 5.
(struct glyph_row): New member reversed_p.
<string_buffer_position>: Update prototype.
(PRODUCE_GLYPHS): Set the reversed_p flag in the iterator's
glyph_row if bidi_it.paragraph_dir == R2L.
(struct glyph): New members resolved_level and bidi_type.
dispnew.c (direct_output_forward_char): Give up if we need bidi
processing or buffer's direction is right-to-left.
(prepare_desired_row): Preserve the reversed_p flag.
(row_equal_p): Compare the reversed_p attributes as well.
xdisp.c (init_iterator): Initialize it->bidi_p. Call
bidi_init_it and set it->paragraph_embedding from the current
buffer's value of bidi_paragraph_direction.
(reseat_1): Initialize bidi_it.first_elt.
(set_iterator_to_next, next_element_from_buffer): Use the value of
paragraph_embedding to determine the paragraph direction.
(set_iterator_to_next): Under bidi reordering, call
bidi_get_next_char_visually. Call bidi_paragraph_init if the
new_paragraph flag is set in the bidi iterator.
(next_element_from_buffer): If bidi_it.first_elt is set,
initialize paragraph direction and find the first character to
display in the visual order. If reseated to a middle of a line,
prime the bidi iterator starting at the line's beginning. Handle
the situation where we overstepped stop_charpos due to
non-linearity of the bidi iteration. Likewise for when we back up
beyond the previous stop_charpos. When moving across stop_charpos,
record it in prev_stop.
(display_line): Set row->end and it->start for the next row to the
next character in logical order. Always extend reversed_p rows to
the end of line, even if they end at ZV. Copy the reversed_p flag
to the next glyph row. Keep calling set_cursor_from_row for
bidi-reordered rows even if we already have a possible candidate
for cursor position. Set row_end after all the row's glyphs have
been produced, by looping over the glyphs. Record the position
after EOL in it->eol_pos, and use it to set end_pos of the last
row produced for a continued line.
<Qright_to_left, Qleft_to_right>: New variables.
(syms_of_xdisp): Initialize and staticpro them.
(string_buffer_position_lim): New function.
(string_buffer_position): Most of code moved to
string_buffer_position_lim. Last argument and return value are
now EMACS_INT; all callers changed.
(set_cursor_from_row): Rewritten to support bidirectional text and
reversed glyph rows.
(text_outside_line_unchanged_p, try_window_id): Disable
optimizations if we are reordering bidirectional text and the
paragraph direction can be affected by the change.
(append_glyph, append_composite_glyph)
(produce_image_glyph, append_stretch_glyph): Set the
resolved_level and bidi_type members of each glyph.
(append_glyph): If the glyph row is reversed, prepend the glyph
rather than appending it.
(handle_stop_backwards): New function.
(reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
(reseat): call handle_stop_backwards to recompute prev_stop and
base_level_stop for the new position.
(handle_invisible_prop): Under bidi iteration, skip invisible text
using bidi_get_next_char_visually. If we are `reseat'ed, init the
paragraph direction. Update IT->prev_stop after skipping
invisible text.
(move_it_in_display_line_to): New variables prev_method
and prev_pos. Compare for strict equality in
BUFFER_POS_REACHED_P.
(try_cursor_movement): Examine all the candidate rows that occlude
point, to return the best match. If rows are bidi-reordered
and point moved backwards, back up to the row that is not a
continuation line, and start looking for a suitable row from
there.
term.c (append_glyph): Reverse glyphs by pre-pending them,
rather than appending, if the glyph_row's reversed_p flag is set.
Set the resolved_level and bidi_type members of each glyph.
.gdbinit (pbiditype): New command.
(pgx): Use it to display bidi level and type of the glyph.
(pitx): Display some bidi information about the iterator.
(prowlims, pmtxrows): New commands.
files.el: Make bidi-display-reordering safe variable for boolean
values.
mule.texi (International): Mention support of bidirectional editing.
(Bidirectional Editing): New section.
HELLO: Reorder Arabic and Hebrew into logical order, and
insert RLM before the opening paren, to make the display more
reasonable. Add setting for bidi-display-reordering in the local
variables section.
NEWS: Mention initial support for bidirectional editing.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/src/buffer.c b/src/buffer.c index a0acad309af..0c6e57d45be 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2279,6 +2279,8 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | |||
| 2279 | swapfield (undo_list, Lisp_Object); | 2279 | swapfield (undo_list, Lisp_Object); |
| 2280 | swapfield (mark, Lisp_Object); | 2280 | swapfield (mark, Lisp_Object); |
| 2281 | swapfield (enable_multibyte_characters, Lisp_Object); | 2281 | swapfield (enable_multibyte_characters, Lisp_Object); |
| 2282 | swapfield (bidi_display_reordering, Lisp_Object); | ||
| 2283 | swapfield (bidi_paragraph_direction, Lisp_Object); | ||
| 2282 | /* FIXME: Not sure what we should do with these *_marker fields. | 2284 | /* FIXME: Not sure what we should do with these *_marker fields. |
| 2283 | Hopefully they're just nil anyway. */ | 2285 | Hopefully they're just nil anyway. */ |
| 2284 | swapfield (pt_marker, Lisp_Object); | 2286 | swapfield (pt_marker, Lisp_Object); |
| @@ -5206,7 +5208,9 @@ init_buffer_once () | |||
| 5206 | buffer_defaults.truncate_lines = Qnil; | 5208 | buffer_defaults.truncate_lines = Qnil; |
| 5207 | buffer_defaults.word_wrap = Qnil; | 5209 | buffer_defaults.word_wrap = Qnil; |
| 5208 | buffer_defaults.ctl_arrow = Qt; | 5210 | buffer_defaults.ctl_arrow = Qt; |
| 5211 | buffer_defaults.bidi_display_reordering = Qnil; | ||
| 5209 | buffer_defaults.direction_reversed = Qnil; | 5212 | buffer_defaults.direction_reversed = Qnil; |
| 5213 | buffer_defaults.bidi_paragraph_direction = Qnil; | ||
| 5210 | buffer_defaults.cursor_type = Qt; | 5214 | buffer_defaults.cursor_type = Qt; |
| 5211 | buffer_defaults.extra_line_spacing = Qnil; | 5215 | buffer_defaults.extra_line_spacing = Qnil; |
| 5212 | buffer_defaults.cursor_in_non_selected_windows = Qt; | 5216 | buffer_defaults.cursor_in_non_selected_windows = Qt; |
| @@ -5291,7 +5295,9 @@ init_buffer_once () | |||
| 5291 | XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx; | 5295 | XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx; |
| 5292 | XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx; | 5296 | XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx; |
| 5293 | XSETFASTINT (buffer_local_flags.category_table, idx); ++idx; | 5297 | XSETFASTINT (buffer_local_flags.category_table, idx); ++idx; |
| 5298 | XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx; | ||
| 5294 | XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx; | 5299 | XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx; |
| 5300 | XSETFASTINT (buffer_local_flags.bidi_paragraph_direction, idx); ++idx; | ||
| 5295 | XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx); | 5301 | XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx); |
| 5296 | /* Make this one a permanent local. */ | 5302 | /* Make this one a permanent local. */ |
| 5297 | buffer_permanent_local_flags[idx++] = 1; | 5303 | buffer_permanent_local_flags[idx++] = 1; |
| @@ -5548,11 +5554,6 @@ This is the same as (default-value 'abbrev-mode). */); | |||
| 5548 | doc: /* Default value of `ctl-arrow' for buffers that do not override it. | 5554 | doc: /* Default value of `ctl-arrow' for buffers that do not override it. |
| 5549 | This is the same as (default-value 'ctl-arrow). */); | 5555 | This is the same as (default-value 'ctl-arrow). */); |
| 5550 | 5556 | ||
| 5551 | DEFVAR_LISP_NOPRO ("default-direction-reversed", | ||
| 5552 | &buffer_defaults.direction_reversed, | ||
| 5553 | doc: /* Default value of `direction-reversed' for buffers that do not override it. | ||
| 5554 | This is the same as (default-value 'direction-reversed). */); | ||
| 5555 | |||
| 5556 | DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters", | 5557 | DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters", |
| 5557 | &buffer_defaults.enable_multibyte_characters, | 5558 | &buffer_defaults.enable_multibyte_characters, |
| 5558 | doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it. | 5559 | doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it. |
| @@ -5809,11 +5810,29 @@ The variable `coding-system-for-write', if non-nil, overrides this variable. | |||
| 5809 | 5810 | ||
| 5810 | This variable is never applied to a way of decoding a file while reading it. */); | 5811 | This variable is never applied to a way of decoding a file while reading it. */); |
| 5811 | 5812 | ||
| 5812 | DEFVAR_PER_BUFFER ("direction-reversed", ¤t_buffer->direction_reversed, | 5813 | DEFVAR_PER_BUFFER ("direction-reversed", |
| 5813 | Qnil, | 5814 | ¤t_buffer->direction_reversed, Qnil, |
| 5814 | doc: /* *Non-nil means lines in the buffer are displayed right to left. */); | 5815 | doc: /* Non-nil means set beginning of lines at the right edge of the window. |
| 5815 | 5816 | See also the variable `bidi-display-reordering'. */); | |
| 5816 | DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil, | 5817 | |
| 5818 | DEFVAR_PER_BUFFER ("bidi-display-reordering", | ||
| 5819 | ¤t_buffer->bidi_display_reordering, Qnil, | ||
| 5820 | doc: /* Non-nil means reorder bidirectional text for display in the visual order. | ||
| 5821 | See also the variable `direction-reversed'. */); | ||
| 5822 | |||
| 5823 | DEFVAR_PER_BUFFER ("bidi-paragraph-direction", | ||
| 5824 | ¤t_buffer->bidi_paragraph_direction, Qnil, | ||
| 5825 | doc: /* *If non-nil, forces directionality of text paragraphs in the buffer. | ||
| 5826 | |||
| 5827 | If this is nil (the default), the direction of each paragraph is | ||
| 5828 | determined by the first strong directional character of its text. | ||
| 5829 | The values of `right-to-left' and `left-to-right' override that. | ||
| 5830 | Any other value is treated as nil. | ||
| 5831 | |||
| 5832 | This variable has no effect unless the buffer's value of | ||
| 5833 | \`bidi-display-reordering' is non-nil. */); | ||
| 5834 | |||
| 5835 | DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil, | ||
| 5817 | doc: /* *Non-nil means do not display continuation lines. | 5836 | doc: /* *Non-nil means do not display continuation lines. |
| 5818 | Instead, give each line of text just one screen line. | 5837 | Instead, give each line of text just one screen line. |
| 5819 | 5838 | ||