Function: current-bidi-paragraph-direction
current-bidi-paragraph-direction is a function defined in xdisp.c.
Signature
(current-bidi-paragraph-direction &optional BUFFER)
Documentation
Return paragraph direction at point in BUFFER.
Value is either left-to-right or right-to-left.
If BUFFER is omitted or nil, it defaults to the current buffer.
Paragraph direction determines how the text in the paragraph is displayed. In left-to-right paragraphs, text begins at the left margin of the window and the reading direction is generally left to right. In right-to-left paragraphs, text begins at the right margin and is read from right to left.
See also bidi-paragraph-direction.
Probably introduced at or before Emacs version 24.1.
Source Code
// Defined in /usr/src/emacs/src/xdisp.c
{
struct buffer *buf = current_buffer;
struct buffer *old = buf;
if (! NILP (buffer))
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
}
if (NILP (BVAR (buf, bidi_display_reordering))
|| NILP (BVAR (buf, enable_multibyte_characters))
/* When we are loading loadup.el, the character property tables
needed for bidi iteration are not yet available. */
|| redisplay__inhibit_bidi)
return Qleft_to_right;
else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
return BVAR (buf, bidi_paragraph_direction);
else
{
/* Determine the direction from buffer text. We could try to
use current_matrix if it is up to date, but this seems fast
enough as it is. */
struct bidi_it itb;
ptrdiff_t pos = BUF_PT (buf);
ptrdiff_t bytepos = BUF_PT_BYTE (buf);
int c;
void *itb_data = bidi_shelve_cache ();
set_buffer_temp (buf);
/* bidi_paragraph_init finds the base direction of the paragraph
by searching forward from paragraph start. We need the base
direction of the current or _previous_ paragraph, so we need
to make sure we are within that paragraph. To that end, find
the previous non-empty line. */
if (pos >= ZV && pos > BEGV)
dec_both (&pos, &bytepos);
AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
if (fast_looking_at (trailing_white_space,
pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
{
while ((c = FETCH_BYTE (bytepos)) == '\n'
|| c == ' ' || c == '\t' || c == '\f')
{
if (bytepos <= BEGV_BYTE)
break;
bytepos--;
pos--;
}
while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
bytepos--;
}
bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
itb.paragraph_dir = NEUTRAL_DIR;
itb.string.s = NULL;
itb.string.lstring = Qnil;
itb.string.bufpos = 0;
itb.string.from_disp_str = false;
itb.string.unibyte = false;
/* We have no window to use here for ignoring window-specific
overlays. Using NULL for window pointer will cause
compute_display_string_pos to use the current buffer. */
itb.w = NULL;
bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
bidi_unshelve_cache (itb_data, false);
set_buffer_temp (old);
switch (itb.paragraph_dir)
{
case L2R:
return Qleft_to_right;
break;
case R2L:
return Qright_to_left;
break;
default:
emacs_abort ();
}
}
}