aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-07-17 17:50:37 +0300
committerEli Zaretskii2017-07-17 17:50:37 +0300
commitd7f7fef1c1cdef206860a7075873de7d6c521d8d (patch)
treeabc7489210594cfdd4324404f1fe8155dfd58953 /src
parent5e2ae74df54d4090c591c79ab13e7713c6654b9c (diff)
downloademacs-d7f7fef1c1cdef206860a7075873de7d6c521d8d.tar.gz
emacs-d7f7fef1c1cdef206860a7075873de7d6c521d8d.zip
Allow user control on what starts and ends a paragraph for bidi
* src/buffer.h (struct buffer): New members bidi_paragraph_separate_re_ and bidi_paragraph_start_re_. * src/buffer.c (bset_bidi_paragraph_start_re) (bset_bidi_paragraph_separate_re): New setters/ (Fbuffer_swap_text): Swap the values of bidi-paragraph-start-re and bidi-paragraph-separate-re. (init_buffer_once): Init the values of bidi-paragraph-start-re and bidi-paragraph-separate-re. (syms_of_buffer) <bidi-paragraph-start-re, bidi-paragraph-separate-re>: New per-buffer variables. * src/bidi.c (bidi_at_paragraph_end, bidi_find_paragraph_start): Support bidi-paragraph-start-re and bidi-paragraph-separate-re. (bidi_move_to_visually_next): Handle correctly the case when the separator matches an empty string. (Bug#27526) * doc/emacs/mule.texi (Bidirectional Editing): * doc/lispref/display.texi (Bidirectional Display): Document bidi-paragraph-start-re and bidi-paragraph-separate-re. * etc/NEWS: Mention bidi-paragraph-start-re and bidi-paragraph-separate-re.
Diffstat (limited to 'src')
-rw-r--r--src/bidi.c29
-rw-r--r--src/buffer.c59
-rw-r--r--src/buffer.h6
3 files changed, 87 insertions, 7 deletions
diff --git a/src/bidi.c b/src/bidi.c
index e34da778ba0..763797488b0 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1448,8 +1448,14 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos)
1448 Lisp_Object start_re; 1448 Lisp_Object start_re;
1449 ptrdiff_t val; 1449 ptrdiff_t val;
1450 1450
1451 sep_re = paragraph_separate_re; 1451 if (STRINGP (BVAR (current_buffer, bidi_paragraph_separate_re)))
1452 start_re = paragraph_start_re; 1452 sep_re = BVAR (current_buffer, bidi_paragraph_separate_re);
1453 else
1454 sep_re = paragraph_separate_re;
1455 if (STRINGP (BVAR (current_buffer, bidi_paragraph_start_re)))
1456 start_re = BVAR (current_buffer, bidi_paragraph_start_re);
1457 else
1458 start_re = paragraph_start_re;
1453 1459
1454 val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil); 1460 val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
1455 if (val < 0) 1461 if (val < 0)
@@ -1523,7 +1529,10 @@ bidi_paragraph_cache_on_off (void)
1523static ptrdiff_t 1529static ptrdiff_t
1524bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) 1530bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1525{ 1531{
1526 Lisp_Object re = paragraph_start_re; 1532 Lisp_Object re =
1533 STRINGP (BVAR (current_buffer, bidi_paragraph_start_re))
1534 ? BVAR (current_buffer, bidi_paragraph_start_re)
1535 : paragraph_start_re;
1527 ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; 1536 ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
1528 struct region_cache *bpc = bidi_paragraph_cache_on_off (); 1537 struct region_cache *bpc = bidi_paragraph_cache_on_off ();
1529 ptrdiff_t n = 0, oldpos = pos, next; 1538 ptrdiff_t n = 0, oldpos = pos, next;
@@ -3498,10 +3507,16 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
3498 if (sep_len >= 0) 3507 if (sep_len >= 0)
3499 { 3508 {
3500 bidi_it->new_paragraph = 1; 3509 bidi_it->new_paragraph = 1;
3501 /* Record the buffer position of the last character of the 3510 /* Record the buffer position of the last character of
3502 paragraph separator. */ 3511 the paragraph separator. If the paragraph separator
3503 bidi_it->separator_limit 3512 is an empty string (e.g., the regex is "^"), the
3504 = bidi_it->charpos + bidi_it->nchars + sep_len; 3513 newline that precedes the end of the paragraph is
3514 that last character. */
3515 if (sep_len > 0)
3516 bidi_it->separator_limit
3517 = bidi_it->charpos + bidi_it->nchars + sep_len;
3518 else
3519 bidi_it->separator_limit = bidi_it->charpos;
3505 } 3520 }
3506 } 3521 }
3507 } 3522 }
diff --git a/src/buffer.c b/src/buffer.c
index e0972aac33c..649ddbe1839 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -173,6 +173,16 @@ bset_bidi_display_reordering (struct buffer *b, Lisp_Object val)
173 b->bidi_display_reordering_ = val; 173 b->bidi_display_reordering_ = val;
174} 174}
175static void 175static void
176bset_bidi_paragraph_start_re (struct buffer *b, Lisp_Object val)
177{
178 b->bidi_paragraph_start_re_ = val;
179}
180static void
181bset_bidi_paragraph_separate_re (struct buffer *b, Lisp_Object val)
182{
183 b->bidi_paragraph_separate_re_ = val;
184}
185static void
176bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) 186bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
177{ 187{
178 b->buffer_file_coding_system_ = val; 188 b->buffer_file_coding_system_ = val;
@@ -2322,6 +2332,8 @@ results, see Info node `(elisp)Swapping Text'. */)
2322 swapfield_ (enable_multibyte_characters, Lisp_Object); 2332 swapfield_ (enable_multibyte_characters, Lisp_Object);
2323 swapfield_ (bidi_display_reordering, Lisp_Object); 2333 swapfield_ (bidi_display_reordering, Lisp_Object);
2324 swapfield_ (bidi_paragraph_direction, Lisp_Object); 2334 swapfield_ (bidi_paragraph_direction, Lisp_Object);
2335 swapfield_ (bidi_paragraph_separate_re, Lisp_Object);
2336 swapfield_ (bidi_paragraph_start_re, Lisp_Object);
2325 /* FIXME: Not sure what we should do with these *_marker fields. 2337 /* FIXME: Not sure what we should do with these *_marker fields.
2326 Hopefully they're just nil anyway. */ 2338 Hopefully they're just nil anyway. */
2327 swapfield_ (pt_marker, Lisp_Object); 2339 swapfield_ (pt_marker, Lisp_Object);
@@ -5121,6 +5133,8 @@ init_buffer_once (void)
5121 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; 5133 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
5122 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; 5134 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx;
5123 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; 5135 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx;
5136 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_separate_re), idx); ++idx;
5137 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_start_re), idx); ++idx;
5124 XSETFASTINT (BVAR (&buffer_local_flags, buffer_file_coding_system), idx); 5138 XSETFASTINT (BVAR (&buffer_local_flags, buffer_file_coding_system), idx);
5125 /* Make this one a permanent local. */ 5139 /* Make this one a permanent local. */
5126 buffer_permanent_local_flags[idx++] = 1; 5140 buffer_permanent_local_flags[idx++] = 1;
@@ -5202,6 +5216,8 @@ init_buffer_once (void)
5202 bset_ctl_arrow (&buffer_defaults, Qt); 5216 bset_ctl_arrow (&buffer_defaults, Qt);
5203 bset_bidi_display_reordering (&buffer_defaults, Qt); 5217 bset_bidi_display_reordering (&buffer_defaults, Qt);
5204 bset_bidi_paragraph_direction (&buffer_defaults, Qnil); 5218 bset_bidi_paragraph_direction (&buffer_defaults, Qnil);
5219 bset_bidi_paragraph_start_re (&buffer_defaults, Qnil);
5220 bset_bidi_paragraph_separate_re (&buffer_defaults, Qnil);
5205 bset_cursor_type (&buffer_defaults, Qt); 5221 bset_cursor_type (&buffer_defaults, Qt);
5206 bset_extra_line_spacing (&buffer_defaults, Qnil); 5222 bset_extra_line_spacing (&buffer_defaults, Qnil);
5207 bset_cursor_in_non_selected_windows (&buffer_defaults, Qt); 5223 bset_cursor_in_non_selected_windows (&buffer_defaults, Qt);
@@ -5616,6 +5632,49 @@ This variable is never applied to a way of decoding a file while reading it. */
5616 &BVAR (current_buffer, bidi_display_reordering), Qnil, 5632 &BVAR (current_buffer, bidi_display_reordering), Qnil,
5617 doc: /* Non-nil means reorder bidirectional text for display in the visual order. */); 5633 doc: /* Non-nil means reorder bidirectional text for display in the visual order. */);
5618 5634
5635 DEFVAR_PER_BUFFER ("bidi-paragraph-start-re",
5636 &BVAR (current_buffer, bidi_paragraph_start_re), Qnil,
5637 doc: /* If non-nil, a regexp matching a line that starts OR separates paragraphs.
5638
5639The value of nil means to use empty lines as lines that start and
5640separate paragraphs.
5641
5642When Emacs displays bidirectional text, it by default computes
5643the base paragraph direction separately for each paragraph.
5644Setting this variable changes the places where paragraph base
5645direction is recomputed.
5646
5647The regexp is always matched after a newline, so it is best to
5648anchor it by beginning it with a "^".
5649
5650If you change the value of this variable, be sure to change
5651the value of `bidi-paragraph-separate-re' accordingly. For
5652example, to have a single newline behave as a paragraph separator,
5653set both these variables to "^".
5654
5655See also `bidi-paragraph-direction'. */);
5656
5657 DEFVAR_PER_BUFFER ("bidi-paragraph-separate-re",
5658 &BVAR (current_buffer, bidi_paragraph_separate_re), Qnil,
5659 doc: /* If non-nil, a regexp matching a line that separates paragraphs.
5660
5661The value of nil means to use empty lines as paragraph separators.
5662
5663When Emacs displays bidirectional text, it by default computes
5664the base paragraph direction separately for each paragraph.
5665Setting this variable changes the places where paragraph base
5666direction is recomputed.
5667
5668The regexp is always matched after a newline, so it is best to
5669anchor it by beginning it with a "^".
5670
5671If you change the value of this variable, be sure to change
5672the value of `bidi-paragraph-start-re' accordingly. For
5673example, to have a single newline behave as a paragraph separator,
5674set both these variables to "^".
5675
5676See also `bidi-paragraph-direction'. */);
5677
5619 DEFVAR_PER_BUFFER ("bidi-paragraph-direction", 5678 DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
5620 &BVAR (current_buffer, bidi_paragraph_direction), Qnil, 5679 &BVAR (current_buffer, bidi_paragraph_direction), Qnil,
5621 doc: /* If non-nil, forces directionality of text paragraphs in the buffer. 5680 doc: /* If non-nil, forces directionality of text paragraphs in the buffer.
diff --git a/src/buffer.h b/src/buffer.h
index be270fe4823..46ca6aa7384 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -611,6 +611,12 @@ struct buffer
611 direction dynamically for each paragraph. */ 611 direction dynamically for each paragraph. */
612 Lisp_Object bidi_paragraph_direction_; 612 Lisp_Object bidi_paragraph_direction_;
613 613
614 /* If non-nil, a regular expression for bidi paragraph separator. */
615 Lisp_Object bidi_paragraph_separate_re_;
616
617 /* If non-nil, a regular expression for bidi paragraph start. */
618 Lisp_Object bidi_paragraph_start_re_;
619
614 /* Non-nil means do selective display; 620 /* Non-nil means do selective display;
615 see doc string in syms_of_buffer (buffer.c) for details. */ 621 see doc string in syms_of_buffer (buffer.c) for details. */
616 Lisp_Object selective_display_; 622 Lisp_Object selective_display_;