Message headers in right-to-left mode in Emacs notmuch-show-mode

Subject: Message headers in right-to-left mode in Emacs notmuch-show-mode

Date: Mon, 03 Aug 2020 09:13:35 +0300



From: Teemu Likonen

Emacs uses setting bidi-paragraph-direction=nil by default which means
that paragraph's text direction can change automatically, for example:
right-to-left. A quote from the variable's description:

    If this is nil (the default), the direction of each paragraph is
    determined by the first strong directional character of its text.

So, in notmuch-show-mode the message header paragraph is switched to
right-to-left mode if headers contain a "strong directional"
right-to-left character.

The result can be seen in the attached jpg image which displays part of
the message <>

I think message headers should always be in left-to-right mode but
message contents should follow the Emacs default (choose automatically
from the content). I believe the header part can be switched to
left-to-right mode by using function bidi-string-mark-left-to-right.
Below is a relevant quote from Emacs Lisp reference manual.

Unfortunately I don't know Notmuch Emacs code (at least not yet). So
this message is mainly for documenting the current behavior.

Emacs Lisp reference manual, section "Bidirectional Display".

    Bidirectional reordering can have surprising and unpleasant effects
    when two strings with bidirectional content are juxtaposed in a
    buffer, or otherwise programmatically concatenated into a string of
    text. A typical problematic case is when a buffer consists of
    sequences of text fields separated by whitespace or punctuation
    characters, like Buffer Menu mode or Rmail Summary Mode. Because the
    punctuation characters used as separators have “weak
    directionality”, they take on the directionality of surrounding
    text. As result, a numeric field that follows a field with
    bidirectional content can be displayed _to the left_ of the
    preceding field, messing up the expected layout. There are several
    ways to avoid this problem:

       − Append the special character U+200E LEFT-TO-RIGHT MARK, or LRM,
         to the end of each field that may have bidirectional content,
         or prepend it to the beginning of the following field. The
         function ‘bidi-string-mark-left-to-right’, described below,
         comes in handy for this purpose. (In a right-to-left paragraph,
         use U+200F RIGHT-TO-LEFT MARK, or RLM, instead.) This is one of
         the solutions recommended by the UBA.

       − Include the tab character in the field separator. The tab
         character plays the role of “segment separator” in
         bidirectional reordering, causing the text on either side to be
         reordered separately.

       − Separate fields with a ‘display’ property or overlay with a
         property value of the form ‘(space . PROPS)’ (*note Specified
         Space::). Emacs treats this display specification as a
         “paragraph separator”, and reorders the text on either side

     -- Function: bidi-string-mark-left-to-right string

         This function returns its argument STRING, possibly modified,
         such that the result can be safely concatenated with another
         string, or juxtaposed with another string in a buffer, without
         disrupting the relative layout of this string and the next one
         on display. If the string returned by this function is
         displayed as part of a left-to-right paragraph, it will always
         appear on display to the left of the text that follows it. The
         function works by examining the characters of its argument, and
         if any of those characters could cause reordering on display,
         the function appends the LRM character to the string. The
         appended LRM character is made invisible by giving it an
         ‘invisible’ text property of ‘t’ (*note Invisible Text::).

/// Teemu Likonen - .-..
// OpenPGP: 4E1055DC84E9DFF613D78557719D69D324539450
signature.asc (application/pgp-signature)
notmuch mailing list --
To unsubscribe send an email to