Subject: bug#27525: 25.1; Line wrapping of bidi paragraphs

From: Itai Berli <[email-masked]>
Date: Thu, 29 Jun 2017 10:23:15 +0300

The line-wrapping algorithm for formatting multi-lingual paragraphs
containing text in languages of opposite directionality (e.g. English
and Hebrew) is inconsistent with other text editing applications
(including Gmail, Google Docs, Libre Writer, MS-Word, Pages, and
TextEdit), as well as with Emacs itself!

Consider as an example the following paragraph that starts with two
Hebrew words followed by the opening of Lincoln's Gettysburg Address.

נאום גטיסבורג Four score and seven years ago our fathers brought forth
on this continent, a new nation, conceived in Liberty, and dedicated to
the proposition that all men are created equal.

When I type this inside the `M-x report-emacs-bug` buffer, and press
`RET`, the paragraph lines wrap as follows, similar to how the other
applications mentioned above handle it.

ILLUSTRATION: A correct way to line-wrap a bidi paragraph
http://imgur.com/9VDZFz0

If I now copy this paragraph and paste it in a new buffer, the line
wrapping is preserved.

However, when I *type* the same paragraph inside a new buffer, (as well as
when I finish typing the paragraph insie the `M-x report-emacs-bug`
buffer, just before pressing `RET`), the lines wrap as follows.

ILLUSTRATION: An incorrect way to line-wrap a bidi paragraph
http://imgur.com/Bckn7zP

Observe that the English text flows from the bottom of the paragraph to
the top, which makes no sense, since the words of the paragraph have a
natural, logical ordering within the paragraph that is independent of their
directionality, but the way the lines are wrapped in the last screenshot
disrupts this logical order by placing the last word ('equal') on the
same line as the first two words (the Hebrew words), whereas the third
word ('Four') is positioned two lines apart.

In GNU Emacs 25.1.1 (x86_64-apple-darwin13.4.0, NS appkit-1265.21
Version 10.9.5 (Build 13F1911))
 of 2016-09-21 built on builder10-9.porkrind.org
Windowing system distributor 'Apple', version 10.3.1504
Configured using:
 'configure --with-ns '--enable-locallisppath=/Library/Application
 Support/Emacs/${version}/site-lisp:/Library/Application
 Support/Emacs/site-lisp' --with-modules'

Configured features:
NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Fundamental

Minor modes in effect:
  ivy-mode: t
  shell-dirtrack-mode: t
  projectile-mode: t
  helm-descbinds-mode: t
  async-bytecomp-package-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent messages:
ad-handle-definition: ‘ibuffer’ got redefined
Turn on helm-projectile key bindings
For information about GNU Emacs and the GNU system, type C-h C-a.

Load-path shadows:
/Users/itaiberli/.emacs.d/elpa/seq-2.20/seq hides
/Applications/Emacs.app/Contents/Resources/lisp/emacs-lisp/seq

Features:
(shadow sort mail-extr emacsbug message rfc822 mml mml-sec epg mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums mail-utils colir color counsel
jka-compr esh-util etags xref project swiper reftex reftex-vars
two-column ivy delsel ivy-overlay helm-projectile helm-files rx
image-dired tramp tramp-compat tramp-loaddefs trampver shell pcomplete
format-spec dired-x dired-aux ffap helm-tags helm-bookmark helm-adaptive
helm-info bookmark pp helm-external helm-net browse-url xml url
url-proxy url-privacy url-expand url-methods url-history url-cookie
url-domsuf url-util url-parse auth-source gnus-util mm-util help-fns
mail-prsvr password-cache url-vars mailcap helm-buffers helm-grep
helm-regexp helm-utils helm-locate helm-help helm-types projectile grep
compile comint ansi-color ring ibuf-ext ibuffer thingatpt helm-descbinds
helm easy-mmode helm-source cl-seq eieio-compat eieio eieio-core
helm-multi-match helm-lib dired helm-config helm-easymenu cl-macs
async-bytecomp async advice edmacro kmacro finder-inf tex-site info
package epg-config seq byte-opt gv bytecomp byte-compile cl-extra
help-mode easymenu cconv cl-loaddefs pcase cl-lib time-date mule-util
tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type
mwheel ns-win ucs-normalize term/common-win tool-bar dnd fontset image
regexp-opt fringe tabulated-list newcomment elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cl-generic cham
georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese charscript case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote kqueue cocoa ns multi-tty
make-network-process emacs)

Memory information:
((conses 16 312113 14836)
 (symbols 48 30403 0)
 (miscs 40 88 163)
 (strings 32 51779 9508)
 (string-bytes 1 1669823)
 (vectors 16 50217)
 (vector-slots 8 844607 6040)
 (floats 8 564 139)
 (intervals 56 243 0)
 (buffers 976 18))