From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.devel Subject: Re: Line wrap reconsidered Date: Sat, 15 Aug 2020 13:34:58 -0400 Message-ID: <2E390DEE-47E6-418A-8FD2-27C6D69262DC@gmail.com> References: <83tux4jmup.fsf@gnu.org> <83lfigj6tt.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.1\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_0310FD01-2DF4-4AB5-AB7A-1089C32845D7" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="2077"; mail-complaints-to="usenet@ciao.gmane.io" Cc: larsi@gnus.org, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Aug 15 19:35:45 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k705o-0000Pd-5n for ged-emacs-devel@m.gmane-mx.org; Sat, 15 Aug 2020 19:35:44 +0200 Original-Received: from localhost ([::1]:60862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k705n-0006qV-6v for ged-emacs-devel@m.gmane-mx.org; Sat, 15 Aug 2020 13:35:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47520) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k705B-0006LL-0m for emacs-devel@gnu.org; Sat, 15 Aug 2020 13:35:05 -0400 Original-Received: from mail-qt1-x82e.google.com ([2607:f8b0:4864:20::82e]:33572) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1k7059-0004BH-E1; Sat, 15 Aug 2020 13:35:04 -0400 Original-Received: by mail-qt1-x82e.google.com with SMTP id 6so9400708qtt.0; Sat, 15 Aug 2020 10:35:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=Q3vXeLJaIZL8f8zT0x1sq78xzRqnvzeMA1NFLuvyYFc=; b=O/NmALs/NGUO2bmXsvT36IP+XZ5t9tyoIuiw/9AYDGs5aGmp5E1spwszBSLlr93bpx gNlhQMIeDLjCrgY1FO256VqM/lIpRd5tFS1wjJfrqdI/BoFE0n39DUHbdz6dWm3/uW6l QR6/+CYz9sYYzJNixjiPD1WrXdvyIo2yu9ffg2hMc7b/rfjmqJPyAEUspbpjvPm3SpiV FBNFcAuMC5S0K7lqRyP+A2s3LcS+e4DSskVpG62WjYGXZX6W5DG9igvKNmNn/OgP8Awk +c9ZBDSGscrdlzR/3FhaM2s/Sg2ynRm5KFnmqaHR4kCMvnJ8dhUfwacR6GA0qG+jkZua lGhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=Q3vXeLJaIZL8f8zT0x1sq78xzRqnvzeMA1NFLuvyYFc=; b=Vr42V/ISTU9Q7UoTzY0UCT0xb2XEIzEvhDNOWcgW0xjIUfYYhZowudPaCT/QJkRxkf /ufTs3a14xNZnhblwTKUOytLySBH7sQfSZimhCcZlXIdOhJv1WyKEKopLo2fZJopt5qE QnhgvXMyRre3rksVAOF6HBdV72JwBGYRAOsa7NBCCv8a4Rid1Q2RsIs39vjKSxl8RBLh QCPHuV4fFJ0mc/R6hinNZ66c7GhTrSE1dP4panDqjf7z8GrkY5WJ9xUQ9+2xoha7q5/B g5ma0G8AeiW5QBywRQaULpR1KFsUd1wFp0NLijJOyzHwVsBAvLUoJVGHzdfry7eoLYrd jv7g== X-Gm-Message-State: AOAM531nWtQ+rB8B/KkfSzcLrUcbImbqpJp4g124K5WZwEHuzm5f7kSc P3dilgacLhivXNolyGr5yfbDkfnQ3etEIQ== X-Google-Smtp-Source: ABdhPJx1MUe5LQgEHRI8ECXgR8QQvBubiQdJTTzx6ZFiWPSghzFu+5dUWCZTgUR7dbKxtpZRNPHcFA== X-Received: by 2002:ac8:4b52:: with SMTP id e18mr7053688qts.231.1597512901841; Sat, 15 Aug 2020 10:35:01 -0700 (PDT) Original-Received: from ?IPv6:2601:98a:4200:9210:bd2e:d88a:e4e3:3a76? ([2601:98a:4200:9210:bd2e:d88a:e4e3:3a76]) by smtp.gmail.com with ESMTPSA id y3sm14243051qtj.55.2020.08.15.10.35.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 15 Aug 2020 10:35:01 -0700 (PDT) In-Reply-To: <83lfigj6tt.fsf@gnu.org> X-Mailer: Apple Mail (2.3608.120.23.2.1) Received-SPF: pass client-ip=2607:f8b0:4864:20::82e; envelope-from=casouri@gmail.com; helo=mail-qt1-x82e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:253807 Archived-At: --Apple-Mail=_0310FD01-2DF4-4AB5-AB7A-1089C32845D7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Aug 15, 2020, at 10:56 AM, Eli Zaretskii wrote: >=20 >> From: Fu Yuan >> Date: Sat, 15 Aug 2020 09:10:06 -0400 >> Cc: larsi@gnus.org, emacs-devel@gnu.org >>=20 >>> I think word-wrap-by-character-category is better. >>>=20 >>=20 >> That=E2=80=99s kinda long, how about word-wrap-by-category? >=20 > Let's try that. Here is the patch. I don=E2=80=99t think we are supposed to say =E2=80=9C(= load =E2=80=9Ckinsoku.el)=E2=80=9D in Emacs User Manual, so I created a = new command load-kinsoku in simple.el. I hope that=E2=80=99s ok? Yuan --Apple-Mail=_0310FD01-2DF4-4AB5-AB7A-1089C32845D7 Content-Disposition: attachment; filename=word-wrap.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="word-wrap.patch" Content-Transfer-Encoding: quoted-printable =46rom=203f82a9320729ed2248622e9875d5272b835adcb6=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Tue,=20= 26=20May=202020=2022:47:27=20-0400=0ASubject:=20[PATCH]=20Improve=20word=20= wrapping=20for=20CJK=20characters=0A=0ANote=20about=20the=20change=20= around=20line=209257=20and=2023372:=0A=0ABefore,=20the=20test=20for=20= whitespace=20checks=20for=20can_wrap_before=20and=0Acan_wrap_after=20= simutaniously.=20=20Now=20we=20separate=20these=20two=20checks,=20and=0A= the=20logic=20needs=20to=20change=20a=20little=20bit.=20=20However,=20= when=20we=20don't=20enable=0Athe=20new=20wrapping=20feature,=20= 'can_wrap_after'=20is=20equivalent=20to=0A'IT_DISPLAYING_WHITESPACE'=20= and=20'can_wrap_before'=20is=20equivalent=20to=0A= '!IT_DISPLAYING_WHITESPACE'.=20=20And=20the=20new=20logic=20is=20= equivalent=20with=20the=0Aold=20one=20in=20that=20case.=0A=0AOld=20= logic:=0A=0A=20=20=20=20if=20(whitespace)=20/*=20Which=20means=20can=20= wrap=20after=20&&=20can't=20wrap=0A=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20before.=20=20*/=0A=20=20=20=20=20=20= may_wrap=20=3D=20true;=0A=0A=20=20=20=20else=20if=20(may_wrap)=20/*=20= aka=20(!whitespace=20&&=20may_wrap)=0A=20=20=20=20=20=20(set=20wrap=20= point)=20=20*=20aka=20(can't=20wrap=20after=20&&=20can=20wrap=20before=0A= =20=20=20=20=20=20may_wrap=20=3D=20false=20=20*=20=20=20=20=20=20&&=20= may_wrap)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20*/=0A=0ANew=20logic:=0A=0A=20=20=20=20if=20(can_wrap_after)=0A=20= =20=20=20=20=20next_may_wrap=20=3D=20true=0A=20=20=20=20else=0A=20=20=20=20= =20=20next_may_wrap=20=3D=20false;=0A=0A=20=20=20=20if=20(may_wrap=20&&=20= can_wrap_before)=0A=20=20=20=20=20=20(set=20wrap=20point)=0A=0A=20=20=20=20= /*=20Update=20may_wrap.=20=20*/=0A=20=20=20=20may_wrap=20=3D=20= next_may_wrap;=0A=0A*=20src/xdisp.c=20(it_char_has_category,=20= char_can_wrap_before,=0Achar_can_wrap_after):=20New=20functions.=0A= (move_it_in_display_line_to,=20display_line):=20Replace=0A= 'IT_DISPLAYING_WHITESPACE'=20with=20either=20'char_can_wrap_before'=20or=0A= 'char_can_wrap_after'.=0A(word-wrap-by-category):=20New=20variable.=0A*=20= doc/emacs/display.texi=20(Visual=20Line=20Mode):=20Add=20a=20paragraph=20= about=20the=0Anew=20feature.=0A*=20etc/NEWS:=20Add=20a=20news=20entry.=0A= *=20lisp/cus-start.el=20(minibuffer-prompt-properties--setter):=20Add=0A= 'word-wrap-by-category'=20as=20a=20custom=20variable.=0A*=20= lisp/simple.el=20(load-kinsoku):=20New=20function.=0A---=0A=20= doc/emacs/display.texi=20|=20=2013=20+++=0A=20etc/NEWS=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=2010=20+++=0A=20lisp/cus-start.el=20=20=20=20= =20=20|=20=20=201=20+=0A=20lisp/simple.el=20=20=20=20=20=20=20=20=20|=20=20= =206=20++=0A=20src/xdisp.c=20=20=20=20=20=20=20=20=20=20=20=20|=20185=20= ++++++++++++++++++++++++++++++++---------=0A=205=20files=20changed,=20= 177=20insertions(+),=2038=20deletions(-)=0A=0Adiff=20--git=20= a/doc/emacs/display.texi=20b/doc/emacs/display.texi=0Aindex=20= 536f4cb5da..8ddc717c97=20100644=0A---=20a/doc/emacs/display.texi=0A+++=20= b/doc/emacs/display.texi=0A@@=20-1801,6=20+1801,19=20@@=20Visual=20Line=20= Mode=0A=20would=20be=20visually=20distracting.=20=20You=20can=20change=20= this=20by=20customizing=20the=0A=20variable=20= @code{visual-line-fringe-indicators}.=0A=20=0A= +@vindex{word-wrap-by-category}=0A+@findex{load-kinsoku}=0A+=20=20By=20= default,=20Emacs=20only=20breaks=20lines=20after=20whitespace=0A= +characters.=20That=20strategy=20produces=20bad=20results=20when=20CJK=20= and=20Latin=20text=0A+are=20mixed=20together=20(because=20CJK=20= characters=20don't=20use=20whitespace=20to=0A+separate=20words).=20=20= You=20can=20customize=20@code{word-wrap-by-category}=20to=0A+allow=20= Emacs=20to=20break=20lines=20after=20more=20characters.=20That=20way=0A= +word-wrapping=20for=20CJK-Latin=20text=20works=20right.=20=20You=20can=20= type=20@kbd{M-x=0A+load-kinsoku}=20to=20enable=20more=20advanced=20= line-breaking=20strategies:=20some=0A+characters=20don't=20appear=20at=20= the=20beginning=20of=20a=20line=20(e.g.,=20FULLWIDTH=0A+COMMA),=20and=20= some=20don't=20appear=20at=20the=20end=20of=20a=20line=20(e.g.,=20LEFT=20= DOUBLE=0A+ANGLE=20BRACKET).=0A+=0A=20@node=20Display=20Custom=0A=20= @section=20Customization=20of=20Display=0A=20=0Adiff=20--git=20= a/etc/NEWS=20b/etc/NEWS=0Aindex=20e97755a454..d84936c1ed=20100644=0A---=20= a/etc/NEWS=0A+++=20b/etc/NEWS=0A@@=20-70,6=20+70,16=20@@=20specify=20= 'cursor-type'=20to=20be=20'(box=20.=20SIZE)',=20the=20cursor=20becomes=20= a=20hollow=0A=20box=20if=20the=20point=20is=20on=20an=20image=20larger=20= than=20'SIZE'=20pixels=20in=20any=0A=20dimension.=0A=20=0A+**=20New=20= custom=20option=20'word-wrap-by-category'.=0A+=0A+When=20word-wrap=20is=20= enabled,=20this=20option=20allows=20Emacs=20to=20break=20lines=0A+after=20= more=20characters=20(instead=20of=20just=20whitespace=20characters),=20= that=0A+means=20word-wrapping=20for=20CJK=20text=20mixed=20with=20Latin=20= text=20are=20improved.=0A+Also,=20there=20is=20a=20new=20command=20= 'enable-kinsoku'=20that=20when=20called,=0A+enables=20advanced=20= wrapping=20strategies=20that=20prohibits=20certain=20character=0A+to=20= appear=20at=20the=20beginning=20of=20a=20line,=20and=20some=20others=20= at=20the=20end=20of=20a=0A+line.=0A+=0A=20=0C=0A=20*=20Editing=20Changes=20= in=20Emacs=2028.1=0A=20=0Adiff=20--git=20a/lisp/cus-start.el=20= b/lisp/cus-start.el=0Aindex=206632687da4..f260573219=20100644=0A---=20= a/lisp/cus-start.el=0A+++=20b/lisp/cus-start.el=0A@@=20-98,6=20+98,7=20= @@=20minibuffer-prompt-properties--setter=0A=20=09=20=20=20=20=20= (ctl-arrow=20display=20boolean)=0A=20=09=20=20=20=20=20(truncate-lines=20= display=20boolean)=0A=20=09=20=20=20=20=20(word-wrap=20display=20= boolean)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (word-wrap-by-category=20display=20boolean)=0A=20=09=20=20=20=20=20= (selective-display-ellipses=20display=20boolean)=0A=20=09=20=20=20=20=20= (indicate-empty-lines=20fringe=20boolean)=0A=20=09=20=20=20=20=20= (indicate-buffer-boundaries=0Adiff=20--git=20a/lisp/simple.el=20= b/lisp/simple.el=0Aindex=20111afa69d1..923d964850=20100644=0A---=20= a/lisp/simple.el=0A+++=20b/lisp/simple.el=0A@@=20-7148,6=20+7148,12=20@@=20= visual-line-mode=0A=20(defun=20turn-on-visual-line-mode=20()=0A=20=20=20= (visual-line-mode=201))=0A=20=0A+(defun=20load-kinsoku=20()=0A+=20=20= "Load=20kinsoku=20features.=0A+See=20`word-wrap-by-category'=20for=20= more=20information."=0A+=20=20(interactive)=0A+=20=20(load=20= "kinsoku.el"))=0A+=0A=20(define-globalized-minor-mode=20= global-visual-line-mode=0A=20=20=20visual-line-mode=20= turn-on-visual-line-mode)=0A=20=0Adiff=20--git=20a/src/xdisp.c=20= b/src/xdisp.c=0Aindex=20cf15f579b5..6551087375=20100644=0A---=20= a/src/xdisp.c=0A+++=20b/src/xdisp.c=0A@@=20-447,6=20+447,7=20@@=20= Copyright=20(C)=201985-1988,=201993-1995,=201997-2020=20Free=20Software=20= Foundation,=0A=20#include=20"termchar.h"=0A=20#include=20"dispextern.h"=0A= =20#include=20"character.h"=0A+#include=20"category.h"=0A=20#include=20= "buffer.h"=0A=20#include=20"charset.h"=0A=20#include=20"indent.h"=0A@@=20= -508,6=20+509,77=20@@=20#define=20IT_DISPLAYING_WHITESPACE(it)=09=09=09=09= =09\=0A=20=09=20=20=20&&=20(*BYTE_POS_ADDR=20(IT_BYTEPOS=20(*it))=20=3D=3D= =20'=20'=09=09=09\=0A=20=09=20=20=20=20=20=20=20||=20*BYTE_POS_ADDR=20= (IT_BYTEPOS=20(*it))=20=3D=3D=20'\t'))))=0A=20=0A+/*=20These=20are=20the=20= category=20sets=20we=20use.=20=20They=20are=20defined=20by=0A+=20=20=20= kinsoku.el=20and=20chracters.el.=20=20*/=0A+#define=20NOT_AT_EOL=20'<'=0A= +#define=20NOT_AT_BOL=20'>'=0A+#define=20LINE_BREAKABLE=20'|'=0A+=0A= +static=20bool=20it_char_has_category(struct=20it=20*it,=20int=20cat)=0A= +{=0A+=20=20int=20ch=20=3D=200;=0A+=20=20if=20(it->what=20=3D=3D=20= IT_CHARACTER)=0A+=20=20=20=20ch=20=3D=20it->c;=0A+=20=20else=20if=20= (STRINGP=20(it->string))=0A+=20=20=20=20ch=20=3D=20SREF=20(it->string,=20= IT_STRING_BYTEPOS=20(*it));=0A+=20=20else=20if=20(it->s)=0A+=20=20=20=20= ch=20=3D=20it->s[IT_BYTEPOS=20(*it)];=0A+=20=20else=20if=20(IT_BYTEPOS=20= (*it)=20<=20ZV_BYTE)=0A+=20=20=20=20ch=20=3D=20*BYTE_POS_ADDR=20= (IT_BYTEPOS=20(*it));=0A+=0A+=20=20if=20(ch=20=3D=3D=200)=0A+=20=20=20=20= return=20false;=0A+=20=20else=0A+=20=20=20=20return=20CHAR_HAS_CATEGORY=20= (ch,=20cat);=0A+}=0A+=0A+/*=20Return=20true=20if=20the=20current=20= character=20allows=20wrapping=20before=20it.=20=20=20*/=0A+static=20bool=20= char_can_wrap_before=20(struct=20it=20*it)=0A+{=0A+=20=20if=20= (!Vword_wrap_by_category)=0A+=20=20=20=20return=20= !IT_DISPLAYING_WHITESPACE=20(it);=0A+=0A+=20=20/*=20For=20CJK=20(LTR)=20= text=20in=20RTL=20paragraph,=20EOL=20and=20BOL=20are=20flipped.=0A+=20=20= =20=20=20Because=20in=20RTL=20paragraph,=20each=20glyph=20is=20prepended=20= to=20the=20last=0A+=20=20=20=20=20one,=20effectively=20drawing=20right=20= to=20left.=20=20*/=0A+=20=20int=20not_at_bol;=0A+=20=20if=20= (it->glyph_row=20&&=20it->glyph_row->reversed_p)=0A+=20=20=20=20= not_at_bol=20=3D=20NOT_AT_EOL;=0A+=20=20else=0A+=20=20=20=20not_at_bol=20= =3D=20NOT_AT_BOL;=0A+=20=20/*=20You=20cannot=20wrap=20before=20a=20space=20= or=20tab=20because=20that=20way=20you'll=0A+=20=20=20=20=20have=20space=20= and=20tab=20at=20the=20beginning=20of=20next=20line.=20=20*/=0A+=20=20= return=20(!IT_DISPLAYING_WHITESPACE=20(it)=0A+=09=20=20/*=20Can=20be=20= at=20BOL.=20=20*/=0A+=09=20=20&&=20!it_char_has_category=20(it,=20= not_at_bol));=0A+}=0A+=0A+/*=20Return=20true=20if=20the=20current=20= character=20allows=20wrapping=20after=20it.=20=20=20*/=0A+static=20bool=20= char_can_wrap_after=20(struct=20it=20*it)=0A+{=0A+=20=20if=20= (!Vword_wrap_by_category)=0A+=20=20=20=20return=20= IT_DISPLAYING_WHITESPACE=20(it);=0A+=0A+=20=20/*=20For=20CJK=20(LTR)=20= text=20in=20RTL=20paragraph,=20EOL=20and=20BOL=20are=20flipped.=0A+=20=20= =20=20=20Because=20in=20RTL=20paragraph,=20each=20glyph=20is=20prepended=20= to=20the=20last=0A+=20=20=20=20=20one,=20effectively=20drawing=20right=20= to=20left.=20=20*/=0A+=20=20int=20not_at_eol;=0A+=20=20if=20= (it->glyph_row=20&&=20it->glyph_row->reversed_p)=0A+=20=20=20=20= not_at_eol=20=3D=20NOT_AT_BOL;=0A+=20=20else=0A+=20=20=20=20not_at_eol=20= =3D=20NOT_AT_EOL;=0A+=0A+=20=20return=20(IT_DISPLAYING_WHITESPACE=20(it)=0A= +=09=20=20/*=20Can=20break=20after=20&&=20can=20be=20at=20EOL.=20=20*/=0A= +=09=20=20||=20(it_char_has_category=20(it,=20LINE_BREAKABLE)=0A+=09=20=20= =20=20=20=20&&=20!it_char_has_category=20(it,=20not_at_eol)));=0A+}=0A+=0A= +#undef=20IT_DISPLAYING_WHITESPACE=0A+#undef=20NOT_AT_EOL=0A+#undef=20= NOT_AT_BOL=0A+#undef=20LINE_BREAKABLE=0A+=0A=20/*=20If=20all=20the=20= conditions=20needed=20to=20print=20the=20fill=20column=20indicator=20are=0A= =20=20=20=20met,=20return=20the=20(nonnegative)=20column=20number,=20= else=20return=20a=20negative=0A=20=20=20=20value.=20=20*/=0A@@=20= -9185,13=20+9257,20=20@@=20#define=20IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09= \=0A=20=09{=0A=20=09=20=20if=20(it->line_wrap=20=3D=3D=20WORD_WRAP=20&&=20= it->area=20=3D=3D=20TEXT_AREA)=0A=20=09=20=20=20=20{=0A-=09=20=20=20=20=20= =20if=20(IT_DISPLAYING_WHITESPACE=20(it))=0A-=09=09may_wrap=20=3D=20= true;=0A-=09=20=20=20=20=20=20else=20if=20(may_wrap)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20bool=20next_may_wrap=20=3D=20may_wrap;=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20/*=20Can=20we=20wrap=20after=20this=20= character?=20=20*/=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (char_can_wrap_after=20(it))=0A+=09=09next_may_wrap=20=3D=20true;=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20else=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20next_may_wrap=20=3D=20false;=0A+=09=20=20=20=20=20=20= /*=20Can=20we=20wrap=20here?=20*/=0A+=09=20=20=20=20=20=20if=20(may_wrap=20= &&=20char_can_wrap_before=20(it))=0A=20=09=09{=0A=20=09=09=20=20/*=20We=20= have=20reached=20a=20glyph=20that=20follows=20one=20or=20more=0A-=09=09=20= =20=20=20=20whitespace=20characters.=20=20If=20the=20position=20is=0A-=09= =09=20=20=20=20=20already=20found,=20we=20are=20done.=20=20*/=0A+=09=09=20= =20=20=20=20whitespace=20characters=20or=20a=20character=20that=20allows=0A= +=09=09=20=20=20=20=20wrapping=20after=20it.=20=20If=20this=20character=20= allows=0A+=09=09=20=20=20=20=20wrapping=20before=20it,=20save=20this=20= position=20as=20a=0A+=09=09=20=20=20=20=20wrapping=20point.=20=20*/=0A=20= =09=09=20=20if=20(atpos_it.sp=20>=3D=200)=0A=20=09=09=20=20=20=20{=0A=20=09= =09=20=20=20=20=20=20RESTORE_IT=20(it,=20&atpos_it,=20atpos_data);=0A@@=20= -9206,8=20+9285,10=20@@=20#define=20IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09= \=0A=20=09=09=20=20=20=20}=0A=20=09=09=20=20/*=20Otherwise,=20we=20can=20= wrap=20here.=20=20*/=0A=20=09=09=20=20SAVE_IT=20(wrap_it,=20*it,=20= wrap_data);=0A-=09=09=20=20may_wrap=20=3D=20false;=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20next_may_wrap=20=3D=20false;=0A=20=09=09= }=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20/*=20Update=20may_wrap=20= for=20the=20next=20iteration.=20=20*/=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20may_wrap=20=3D=20next_may_wrap;=0A=20=09=20=20=20=20}=0A=20=09}=0A= =20=0A@@=20-9335,10=20+9416,10=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09=09=09=20=20=20=20{=0A=20= =09=09=09=20=20=20=20=20=20bool=20can_wrap=20=3D=20true;=0A=20=0A-=09=09=09= =20=20=20=20=20=20/*=20If=20we=20are=20at=20a=20whitespace=20character=0A= -=09=09=09=09=20that=20barely=20fits=20on=20this=20screen=20line,=0A-=09=09= =09=09=20but=20the=20next=20character=20is=20also=0A-=09=09=09=09=20= whitespace,=20we=20cannot=20wrap=20here.=20=20*/=0A+=09=09=09=20=20=20=20= =20=20/*=20If=20the=20previous=20character=20says=20we=20can=0A+=09=09=09= =09=20wrap=20after=20it,=20but=20the=20current=0A+=09=09=09=09=20= character=20says=20we=20can't=20wrap=20before=0A+=09=09=09=09=20it,=20= then=20we=20can't=20wrap=20here.=20=20*/=0A=20=09=09=09=20=20=20=20=20=20= if=20(it->line_wrap=20=3D=3D=20WORD_WRAP=0A=20=09=09=09=09=20=20&&=20= wrap_it.sp=20>=3D=200=0A=20=09=09=09=09=20=20&&=20may_wrap=0A@@=20= -9350,7=20+9431,7=20@@=20#define=20IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09= \=0A=20=09=09=09=09=20=20SAVE_IT=20(tem_it,=20*it,=20tem_data);=0A=20=09=09= =09=09=20=20set_iterator_to_next=20(it,=20true);=0A=20=09=09=09=09=20=20= if=20(get_next_display_element=20(it)=0A-=09=09=09=09=20=20=20=20=20=20= &&=20IT_DISPLAYING_WHITESPACE=20(it))=0A+=09=09=09=09=20=20=20=20=20=20= &&=20!char_can_wrap_before=20(it))=0A=20=09=09=09=09=20=20=20=20can_wrap=20= =3D=20false;=0A=20=09=09=09=09=20=20RESTORE_IT=20(it,=20&tem_it,=20= tem_data);=0A=20=09=09=09=09}=0A@@=20-9429,19=20+9510,18=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09=09=20=20else=0A=20=09=09= =20=20=20=20IT_RESET_X_ASCENT_DESCENT=20(it);=0A=20=0A-=09=09=20=20/*=20= If=20the=20screen=20line=20ends=20with=20whitespace,=20and=20we=0A-=09=09= =20=20=20=20=20are=20under=20word-wrap,=20don't=20use=20wrap_it:=20it=20= is=20no=0A-=09=09=20=20=20=20=20longer=20relevant,=20but=20we=20won't=20= have=20an=20opportunity=0A-=09=09=20=20=20=20=20to=20update=20it,=20= since=20we=20are=20done=20with=20this=20screen=0A-=09=09=20=20=20=20=20= line.=20=20*/=0A+=09=09=20=20/*=20If=20the=20screen=20line=20ends=20with=20= whitespace=20(or=0A+=09=09=20=20=20=20=20wrap-able=20character),=20and=20= we=20are=20under=20word-wrap,=0A+=09=09=20=20=20=20=20don't=20use=20= wrap_it:=20it=20is=20no=20longer=20relevant,=20but=0A+=09=09=20=20=20=20=20= we=20won't=20have=20an=20opportunity=20to=20update=20it,=20since=0A+=09=09= =20=20=20=20=20we=20are=20done=20with=20this=20screen=20line.=20=20*/=0A=20= =09=09=20=20if=20(may_wrap=20&&=20IT_OVERFLOW_NEWLINE_INTO_FRINGE=20(it)=0A= =20=09=09=20=20=20=20=20=20/*=20If=20the=20character=20after=20the=20one=20= which=20set=20the=0A-=09=09=09=20may_wrap=20flag=20is=20also=20= whitespace,=20we=20can't=0A-=09=09=09=20wrap=20here,=20since=20the=20= screen=20line=20cannot=20be=0A-=09=09=09=20wrapped=20in=20the=20middle=20= of=20whitespace.=0A-=09=09=09=20Therefore,=20wrap_it=20_is_=20relevant=20= in=20that=0A-=09=09=09=20case.=20=20*/=0A-=09=09=20=20=20=20=20=20&&=20= !(moved_forward=20&&=20IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=20= may_wrap=20flag=20says=20we=20can't=20wrap=20before=20it,=0A+=09=09=09=20= we=20can't=20wrap=20here.=20=20Therefore,=20wrap_it=0A+=09=09=09=20= (previously=20found=20wrap-point)=20_is_=20relevant=0A+=09=09=09=20in=20= that=20case.=20=20*/=0A+=09=09=20=20=20=20=20=20&&=20!(moved_forward=20= &&=20char_can_wrap_before=20(it)))=0A=20=09=09=20=20=20=20{=0A=20=09=09=20= =20=20=20=20=20/*=20If=20we've=20found=20TO_X,=20go=20back=20there,=20as=20= we=20now=0A=20=09=09=09=20know=20the=20last=20word=20fits=20on=20this=20= screen=20line.=20=20*/=0A@@=20-23292,9=20+23372,14=20@@=20#define=20= RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=0A=20=09=20=20if=20= (it->line_wrap=20=3D=3D=20WORD_WRAP=20&&=20it->area=20=3D=3D=20= TEXT_AREA)=0A=20=09=20=20=20=20{=0A-=09=20=20=20=20=20=20if=20= (IT_DISPLAYING_WHITESPACE=20(it))=0A-=09=09may_wrap=20=3D=20true;=0A-=09=20= =20=20=20=20=20else=20if=20(may_wrap)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20bool=20next_may_wrap=20=3D=20may_wrap;=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20/*=20Can=20we=20wrap=20after=20this=20character?=20=20= */=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (char_can_wrap_after=20(it))=0A+=09=09next_may_wrap=20=3D=20true;=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20else=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20next_may_wrap=20=3D=20false;=0A+=09=20=20=20=20=20=20= /*=20Can=20we=20wrap=20here?=20*/=0A+=09=20=20=20=20=20=20if=20(may_wrap=20= &&=20char_can_wrap_before=20(it))=0A=20=09=09{=0A=20=09=09=20=20SAVE_IT=20= (wrap_it,=20*it,=20wrap_data);=0A=20=09=09=20=20wrap_x=20=3D=20x;=0A@@=20= -23308,8=20+23393,9=20@@=20#define=20RECORD_MAX_MIN_POS(IT)=09=09=09=09=09= \=0A=20=09=09=20=20wrap_row_min_bpos=20=3D=20min_bpos;=0A=20=09=09=20=20= wrap_row_max_pos=20=3D=20max_pos;=0A=20=09=09=20=20wrap_row_max_bpos=20=3D= =20max_bpos;=0A-=09=09=20=20may_wrap=20=3D=20false;=0A=20=09=09}=0A+=09=20= =20=20=20=20=20/*=20Update=20may_wrap=20for=20the=20next=20iteration.=20=20= */=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20may_wrap=20=3D=20= next_may_wrap;=0A=20=09=20=20=20=20}=0A=20=09}=0A=20=0A@@=20-23433,14=20= +23519,18=20@@=20#define=20RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=09= =09=09=20=20/*=20If=20line-wrap=20is=20on,=20check=20if=20a=20previous=0A= =20=09=09=09=20=20=20=20=20wrap=20point=20was=20found.=20=20*/=0A=20=09=09= =09=20=20if=20(!IT_OVERFLOW_NEWLINE_INTO_FRINGE=20(it)=0A-=09=09=09=20=20= =20=20=20=20&&=20wrap_row_used=20>=200=0A+=09=09=09=20=20=20=20=20=20&&=20= wrap_row_used=20>=200=20/*=20Found.=20=20*/=0A=20=09=09=09=20=20=20=20=20= =20/*=20Even=20if=20there=20is=20a=20previous=20wrap=0A=20=09=09=09=09=20= point,=20continue=20the=20line=20here=20as=0A=20=09=09=09=09=20usual,=20= if=20(i)=20the=20previous=20character=0A-=09=09=09=09=20was=20a=20space=20= or=20tab=20AND=20(ii)=20the=0A-=09=09=09=09=20current=20character=20is=20= not.=20=20*/=0A-=09=09=09=20=20=20=20=20=20&&=20(!may_wrap=0A-=09=09=09=09= =20=20||=20IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=09=20allows=20= wrapping=20after=20it,=20AND=20(ii)=0A+=09=09=09=09=20the=20current=20= character=20allows=20wrapping=0A+=09=09=09=09=20before=20it.=20=20= Because=20this=20is=20a=20valid=0A+=09=09=09=09=20break=20point,=20we=20= can=20just=20continue=20to=0A+=09=09=09=09=20the=20next=20line=20at=20= here,=20there=20is=20no=0A+=09=09=09=09=20need=20to=20wrap=20early=20at=20= the=20previous=0A+=09=09=09=09=20wrap=20point.=20=20*/=0A+=09=09=09=20=20= =20=20=20=20&&=20(!may_wrap=20||=20!char_can_wrap_before=20(it)))=0A=20=09= =09=09=20=20=20=20goto=20back_to_wrap;=0A=20=0A=20=09=09=09=20=20/*=20= Record=20the=20maximum=20and=20minimum=20buffer=0A@@=20-23468,13=20= +23558,16=20@@=20#define=20RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=09= =09=09=20=20=20=20=20=20/*=20If=20line-wrap=20is=20on,=20check=20if=20a=0A= =20=09=09=09=09=20previous=20wrap=20point=20was=20found.=20=20*/=0A=20=09= =09=09=20=20=20=20=20=20else=20if=20(wrap_row_used=20>=200=0A-=09=09=09=09= =20=20=20=20=20=20=20/*=20Even=20if=20there=20is=20a=20previous=20wrap=0A= -=09=09=09=09=09=20=20point,=20continue=20the=20line=20here=20as=0A-=09=09= =09=09=09=20=20usual,=20if=20(i)=20the=20previous=20character=0A-=09=09=09= =09=09=20=20was=20a=20space=20or=20tab=20AND=20(ii)=20the=0A-=09=09=09=09= =09=20=20current=20character=20is=20not.=20=20*/=0A-=09=09=09=09=20=20=20= =20=20=20=20&&=20(!may_wrap=0A-=09=09=09=09=09=20=20=20||=20= IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=09=20=20=20=20=20=20=20/*=20= Even=20if=20there=20is=20a=20previous=0A+=09=09=09=09=09=20=20wrap=20= point,=20continue=20the=0A+=09=09=09=09=09=20=20line=20here=20as=20= usual,=20if=20(i)=0A+=09=09=09=09=09=20=20the=20previous=20character=20= was=20a=0A+=09=09=09=09=09=20=20space=20or=20tab=20AND=20(ii)=20the=0A+=09= =09=09=09=09=20=20current=20character=20is=20not,=0A+=09=09=09=09=09=20=20= AND=20(iii)=20the=20current=0A+=09=09=09=09=09=20=20character=20allows=20= wrapping=0A+=09=09=09=09=09=20=20before=20it.=20=20*/=0A+=09=09=09=09=20=20= =20=20=20=20=20&&=20(!may_wrap=20||=20!char_can_wrap_before=20(it)))=0A=20= =09=09=09=09goto=20back_to_wrap;=0A=20=0A=20=09=09=09=20=20=20=20}=0A@@=20= -34594,6=20+34687,22=20@@=20syms_of_xdisp=20(void)=0A=20If=20`word-wrap'=20= is=20enabled,=20you=20might=20want=20to=20reduce=20this.=20=20*/);=0A=20=20= =20Vtruncate_partial_width_windows=20=3D=20make_fixnum=20(50);=0A=20=0A+=20= =20DEFVAR_BOOL("word-wrap-by-category",=20Vword_wrap_by_category,=0A+=20=20= =20=20doc:=20/*=20=20Non-nil=20means=20also=20wrap=20after=20characters=20= of=20a=20certain=20category.=0A+Normally=20when=20`word-wrap'=20is=20on,=20= Emacs=20only=20breaks=20lines=20after=0A+whitespace=20characters.=20=20= When=20this=20option=20is=20turned=20on,=20Emacs=20also=0A+breaks=20= lines=20after=20characters=20that=20have=20the=20"|"=20category=20= (defined=20in=0A+characters.el).=20=20This=20is=20useful=20for=20= allowing=20breaking=20after=20CJK=0A+characters=20and=20improves=20the=20= word-wrapping=20for=20CJK=20text=20mixed=20with=0A+Latin=20text.=0A+=0A= +If=20kinsoku.el=20is=20loaded,=20Emacs=20also=20respects=20kinsoku=20= rules=20when=0A+breaking=20lines.=20=20That=20means=20some=20characters=20= don't=20appear=20at=20the=0A+beginning=20of=20a=20line=20(e.g.,=20= FULLWIDTH=20COMMA),=20and=20some=20don't=20appear=20at=0A+the=20end=20of=20= a=20line=20(e.g.,=20LEFT=20DOUBLE=20ANGLE=20BRACKET).=20=20You=20can=20= load=0A+kinsoku.el=20with=20`load-kinsoku'.=20=20*/);=0A+=20=20= Vword_wrap_by_category=20=3D=20false;=0A+=0A=20=20=20DEFVAR_LISP=20= ("line-number-display-limit",=20Vline_number_display_limit,=0A=20=20=20=20= =20doc:=20/*=20Maximum=20buffer=20size=20for=20which=20line=20number=20= should=20be=20displayed.=0A=20If=20the=20buffer=20is=20bigger=20than=20= this,=20the=20line=20number=20does=20not=20appear=0A--=20=0A2.27.0=0A=0A= --Apple-Mail=_0310FD01-2DF4-4AB5-AB7A-1089C32845D7--