From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.devel Subject: Re: Word wrap for non-whitespace-seperated language Date: Sat, 7 Mar 2020 12:30:48 -0500 Message-ID: <30842691-B627-4773-BE6C-27E7D04A9971@gmail.com> References: <838skgvu2l.fsf@gnu.org> <3692AB81-B291-4D14-BEDE-924F020D94ED@gmail.com> <837e00vsk9.fsf@gnu.org> <9737C398-80FC-4377-91BA-C0891BD5A0F5@gmail.com> <835zfjwgyb.fsf@gnu.org> <6DE83788-5296-4C4F-A265-88B33A43DC93@gmail.com> <4E3669DB-4012-4E56-9517-F1BEB0D97A78@gmail.com> <83wo7wa86t.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 13.0 \(3608.60.0.2.5\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_433FF1E4-46CE-4266-86B6-8E41E007BB73" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="32805"; mail-complaints-to="usenet@ciao.gmane.io" Cc: rms@gnu.org, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Mar 07 18:31:44 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 1jAdId-0008SD-7Q for ged-emacs-devel@m.gmane-mx.org; Sat, 07 Mar 2020 18:31:43 +0100 Original-Received: from localhost ([::1]:51144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jAdIc-0006iP-AF for ged-emacs-devel@m.gmane-mx.org; Sat, 07 Mar 2020 12:31:42 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:53399) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jAdHt-0005w3-K1 for emacs-devel@gnu.org; Sat, 07 Mar 2020 12:30:58 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jAdHs-0002v8-O1 for emacs-devel@gnu.org; Sat, 07 Mar 2020 12:30:57 -0500 Original-Received: from mail-qk1-x72e.google.com ([2607:f8b0:4864:20::72e]:33353) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jAdHp-0002ce-TG; Sat, 07 Mar 2020 12:30:54 -0500 Original-Received: by mail-qk1-x72e.google.com with SMTP id p62so5485107qkb.0; Sat, 07 Mar 2020 09:30:53 -0800 (PST) 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=BaUWbkPlKLOquj5Hs0ua7FMi+yKR7YlfMj10fUygbcs=; b=WYC8u6/vti+Nu4VstHXx+rld2KaKInl6cEqDeNTAankspvbTaWKiFZa9aJi03AmG82 NhkOhky1eOBlQu7QKbwjRCQ1isCQK8mPwOGGRH1l6TOdydLUuSYyxv8ev7DMMiGHOcjt f8h0bxCgVqsiwKGSrTn7/i+BlofgCsbvOAnCYDnNjel672SpkGlD8DZlnUMhoQtGIiZJ aSRvXy2d+XiYdNQx1uhU43iJykYZqF3VFk/e9ghy2wiYEQ+gQs2TX1tpmtE18NCqIYye CNlW0ajhX4+oUylJgbZqiNFeBb8u94oPlQwd5kr4HMbg4OoB03bC2+r2NcQaSC2yyqL+ /wcA== 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=BaUWbkPlKLOquj5Hs0ua7FMi+yKR7YlfMj10fUygbcs=; b=R+orBYE9KmtBzQoCejXFX2p3567hpsY6VBLsQwPcx9Xio9w2M/8XjFwW3HoL0KF99V g5vqMu5h7IDV5HizQp4iWXbzyGwDUT6jBJlXuicusPpA2YJWJ/2+jSn8Vou4lPwc/Chl S0g2tmbntFkpnBObfPZsMCZUudeq8SnzromMwVItiUuGIOPg6WOqgfSExTqG8Hm0a5CE otiRAP/10aGX4h3OsZAEwkEQQgVkapxzlHtKgxecDkhtne1mSE5C2tK4hi1aH405Bfti kvhGMPEPVl0rIttoQtGsqcGsvdf6DCs1+sZ/0t6cfouB6Wz//suAv2QMvKdCDZenbNbH A/lQ== X-Gm-Message-State: ANhLgQ0F3/NVZKwi2dT0y6M5VZdUW8QDFBnPbi9rQh2JjD2iyaDI1OrZ A2ww49PjvKQ/c+uyvoqx7wgPYUMj5eu2AA== X-Google-Smtp-Source: ADFU+vsKOEg+O50NitikvCLno8zGqRBXp/Mal+dxPxB1xHiWRJ395aRQ2h8fKLheJbTUiHFapqXS1g== X-Received: by 2002:a05:620a:112c:: with SMTP id p12mr6570223qkk.307.1583602252732; Sat, 07 Mar 2020 09:30:52 -0800 (PST) Original-Received: from [192.168.1.5] (c-174-60-229-153.hsd1.pa.comcast.net. [174.60.229.153]) by smtp.gmail.com with ESMTPSA id o35sm4709842qtk.5.2020.03.07.09.30.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Mar 2020 09:30:52 -0800 (PST) In-Reply-To: <83wo7wa86t.fsf@gnu.org> X-Mailer: Apple Mail (2.3608.60.0.2.5) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::72e 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:245320 Archived-At: --Apple-Mail=_433FF1E4-46CE-4266-86B6-8E41E007BB73 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > Thank you for your work, but I don't think this is what Richard was > asking for. A properly filled text according to what Richard wants > should have the right edge of the text almost completely justified to > the same pixel. I see, sfill.el is more wrapping than filling, maybe the name is = misleading... Anyway it would be nice if sfill can be included in Emacs = as it provides a nicer wrapping that is same as what you get in a = WYSIWYG editor. It can be a (more capable but less efficient) = alternative to the word-wrap feature. WDYT? Btw I=E2=80=99ve sorted out my previous question about a faster way to = get the point around column x. I seem to be incapable of solving a = problem before asking it out loud in public, sorry for the noise. Now it = is reasonably fast for daily use. Yuan --Apple-Mail=_433FF1E4-46CE-4266-86B6-8E41E007BB73 Content-Disposition: attachment; filename=sfill.el Content-Type: application/octet-stream; x-unix-mode=0644; name="sfill.el" Content-Transfer-Encoding: quoted-printable ;;;=20sfill.el=20---=20Soft=20and=20smart=20fill=20=20=20=20=20=20-*-=20= lexical-binding:=20t;=20-*-=0A=0A;;=20Author:=20Yuan=20Fu=20= =0A=0A;;;=20This=20file=20is=20NOT=20part=20of=20GNU=20= Emacs=0A=0A;;;=20Commentary:=0A;;=0A;;=20This=20package=20gives=20you=20= word=20wrapping=20with=20more=20precision=20than=20the=0A;;=20default=20= one.=20The=20default=20word=20wrapping=20(=E2=80=98toggle-word-wrap=E2=80=99= )=20can=0A;;=20only=20wrap=20on=20white=20spaces=20and=20tabs,=20thus=20= is=20unable=20to=20wrap=20text=0A;;=20with=20both=20CJK=20characters=20= and=20latin=20characters=20properly.=20Also=20it=0A;;=20can=E2=80=99t=20= wrap=20on=20arbitrary=20columns.=20On=20the=20other=20hand,=0A;;=20= =E2=80=98fill-paragraph=E2=80=99=20can=20only=20work=20with=20mono=20= spaced=20fonts,=20filling=0A;;=20variable=20pitch=20font=20usually=20= gives=20sub-optimal=20result.=20(And,=20of=0A;;=20course,=20it=20= destructively=20insert=20newlines,=20which=20may=20not=20be=20what=20you=0A= ;;=20want.)=0A;;=0A;;=20This=20package=20solves=20above=20problems.=20It=20= wraps=20lines=20correctly=20no=0A;;=20matter=20the=20text=20is=20latin=20= or=20CJK=20or=20both,=20and=20no=20matter=20it=E2=80=99s=20mono=0A;;=20= spaces=20or=20variable=20pitch.=20It=20wraps=20on=20arbitrary=20columns=20= and=20it=0A;;=20handles=20kinsoku=20correctly=20(thanks=20to=20= kinsoku.el).=0A;;=0A;;=20=20=20Usage=0A;;=0A;;=20=09M-x=20sfill-mode=20= RET=0A;;=0A;;=20=20=20Customization=0A;;=0A;;=20=E2=80=98sfill-column=E2=80= =99.=0A=0A;;;=20Code:=0A;;=0A=0A(require=20'subr-x)=0A(require=20= 'cl-lib)=0A=0A(defvar-local=20sfill-column=2070=0A=20=20"Fill=20Column=20= for=20sfill.")=0A=0A(defface=20sfill-debug-face=20(let=20((spec=20= '(:inherit=20highlight))=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=20=20=20=20=20=20=20=20(display=20t))=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=20=20=20=20= `((,display=20.=20,spec)))=0A=20=20"Face=20for=20highlighting=20sfill=20= overlays."=0A=20=20:group=20'sfill)=0A=0A(define-minor-mode=20= sfill-debug-mode=0A=20=20"Toggle=20debug=20mode=20for=20sfill."=0A=20=20= :lighter=20""=0A=20=20:global=20t=0A=20=20(sfill-region=20nil=20nil=20= t))=0A=0A(defun=20sfill-insert-newline=20()=0A=20=20"Insert=20newline=20= at=20point=20by=20overlay."=0A=20=20;;=20We=20shouldn=E2=80=99t=20need=20= to=20break=20line=20at=20point-max.=0A=20=20(if=20(or=20(eq=20(point)=20= (point-max)))=0A=20=20=20=20=20=20(error=20"Cannot=20insert=20at=20the=20= end=20of=20visible=20buffer")=0A=20=20=20=20(let*=20((beg=20(point))=0A=20= =20=20=20=20=20=20=20=20=20=20(end=20(1+=20(point)))=0A=20=20=20=20=20=20= =20=20=20=20=20(ov=20(make-overlay=20beg=20end=20nil=20t)))=0A=20=20=20=20= =20=20(overlay-put=20ov=20'sfill=20t)=0A=20=20=20=20=20=20(overlay-put=20= ov=20'before-string=20"\n")=0A=20=20=20=20=20=20(overlay-put=20ov=20= 'evaporate=20t)=0A=20=20=20=20=20=20(when=20sfill-debug-mode=0A=20=20=20=20= =20=20=20=20(overlay-put=20ov=20'face=20'sfill-debug-face)))))=0A=0A= (defun=20sfill-clear-overlay=20(beg=20end)=0A=20=20"Clear=20overlays=20= that=20`soft-insert'=20made=20between=20BEG=20and=20END."=0A=20=20(let=20= ((overlay-list=20(overlays-in=20beg=20end)))=0A=20=20=20=20(dolist=20(ov=20= overlay-list)=0A=20=20=20=20=20=20(when=20(overlay-get=20ov=20'sfill)=0A=20= =20=20=20=20=20=20=20(delete-overlay=20ov)))))=0A=0A(defun=20= sfill-delete-overlay-at=20(point)=0A=20=20"Delete=20sfill=20overlay=20at=20= POINT."=0A=20=20(sfill-clear-overlay=20point=20(1+=20point)))=0A=0A= (defun=20sfill-clear-newline=20(beg=20end)=0A=20=20"Remove=20newlines=20= in=20the=20region=20from=20BEG=20to=20END."=0A=20=20(save-excursion=0A=20= =20=20=20(goto-char=20beg)=0A=20=20=20=20(while=20(re-search-forward=20= "\n"=20end=20t)=0A=20=20=20=20=20=20;;=20I=20can=20be=20more=20= intelligent=20here,=20but=20since=20the=20break=20point=0A=20=20=20=20=20= =20;;=20function=20is=20from=20fill.el,=20better=20keep=20in=20sync=20= with=20it.=0A=20=20=20=20=20=20;;=20(see=20= =E2=80=98fill-move-to-break-point=E2=80=99)=0A=20=20=20=20=20=20(if=20= (and=20(eq=20(char-charset=20(char-before=20(1-=20(point))))=20'ascii)=0A= =09=20=20=20=20=20=20=20(eq=20(char-charset=20(char-after=20(point)))=20= 'ascii))=0A=20=20=20=20=20=20=20=20=20=20(replace-match=20"=20")=0A=20=20= =20=20=20=20=20=20(replace-match=20"")))=0A=20=20=20=20= (put-text-property=20beg=20end=20'sfill-bol=20nil)))=0A=0A(defun=20= sfill-forward-column=20(column)=0A=20=20"Forward=20COLUMN=20columns.=0A=0A= This=20only=20works=20correctly=20in=20mono=20space=20setting."=0A=20=20= (condition-case=20nil=0A=20=20=20=20=20=20(while=20(>=3D=20column=200)=0A= =20=20=20=20=20=20=20=20(forward-char)=0A=20=20=20=20=20=20=20=20(setq=20= column=20(-=20column=20(char-width=20(char-before)))))=0A=20=20=20=20= ('end-of-buffer=20nil)))=0A=0A(defun=20sfill-forward-column-visual=20= (column)=0A=20=20"Forward=20COLUMN=20columns=20and=20return=20point.=0A=0A= Works=20for=20both=20mono=20space=20and=20variable=20pitch."=0A=20=20;;=20= =E2=80=98column-x-pos=E2=80=99=20is=20the=20x=20offset=20from=20= widow=E2=80=99s=20left=20edge=20in=20pixels.=0A=20=20;;=20We=20want=20to=20= break=20around=20this=20position.=0A=20=20(condition-case=20nil=0A=20=20=20= =20=20=20(let=20((column-x-pos=20(*=20column=20(window-font-width))))=0A=20= =20=20=20=20=20=20=20(while=20(>=3D=20column-x-pos=200)=0A=20=20=20=20=20= =20=20=20=20=20(forward-char)=0A=20=20=20=20=20=20=20=20=20=20(setq=20= column-x-pos=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(-=20= column-x-pos=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (car=20(mapcar=20(lambda=20(glyph)=20(aref=20glyph=204))=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=20=20=20=20=20=20= =20=20(font-get-glyphs=20(font-at=20(1-=20(point)))=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=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(1-=20= (point))(point)))))))=0A=20=20=20=20=20=20=20=20(point))=0A=20=20=20=20= ('end-of-buffer=20(point))))=0A=0A(defun=20sfill-go-to-break-point=20= (linebeg=20bound)=0A=20=20"Move=20to=20the=20position=20where=20the=20= line=20should=20be=20broken.=0ALINEBEG=20is=20the=20beginning=20of=20= current=20visual=20line.=0AWe=20don=E2=80=99t=20go=20beyond=20BOUND."=0A=20= =20(if=20(display-multi-font-p)=0A=20=20=20=20=20=20= (sfill-forward-column-visual=20sfill-column)=0A=20=20=20=20= (sfill-forward-column=20sfill-column))=0A=20=20(if=20(>=20(point)=20= bound)=0A=20=20=20=20=20=20(goto-char=20bound))=0A=20=20;;=20If=20this=20= (visual)=20line=20is=20the=20last=20line=20of=20the=20(visual)=20= paragraph,=0A=20=20;;=20(point)=20would=20be=20equal=20to=20bound,=20and=20= we=20want=20to=20stay=20there,=20so=0A=20=20;;=20that=20later=20we=20= don=E2=80=99t=20insert=20newline=20incorrectly.=0A=20=20(unless=20(>=3D=20= (point)=20bound)=0A=20=20=20=20(fill-move-to-break-point=20linebeg)=0A=20= =20=20=20(skip-chars-forward=20"=20\t")))=0A=0A(defsubst=20= sfill-next-break=20(point=20bound)=0A=20=20"Return=20the=20position=20of=20= the=20first=20line=20break=20after=20POINT.=0ADon=E2=80=99t=20go=20= beyond=20BOUND."=0A=20=20(next-single-char-property-change=0A=20=20=20= (1+=20point)=0A=20=20=20'sfill=20nil=20bound))=0A=0A(defsubst=20= sfill-at-break=20(point)=0A=20=20"Return=20non-nil=20if=20POINT=20is=20= at=20a=20line=20break."=0A=20=20(plist-get=20(text-properties-at=20= point)=20'sfill-bol))=0A=0A(defsubst=20sfill-prev-break=20(point=20= bound)=0A=20=20"Return=20the=20position=20of=20the=20first=20line=20= break=20before=20POINT.=0ADon=E2=80=99t=20go=20beyond=20BOUND."=0A=20=20= (1-=20(previous-single-char-property-change=0A=20=20=20=20=20=20=20point=20= 'sfill=20nil=0A=20=20=20=20=20=20=20(1+=20bound))))=0A=0A(defun=20= sfill-line=20(point=20&optional=20force)=0A=20=20"Fill=20the=20line=20in=20= where=20POINT=20is.=0AReturn=20(BEG=20END)=20where=20the=20text=20is=20= filled.=20BEG=20is=20the=20visual=0Abeginning=20of=20current=20live.=20= END=20is=20the=20actual=20end=20of=20line.=20If=0AFORCE=20is=20non-nil,=20= update=20the=20whole=20line."=0A=20=20(catch=20'early-termination=0A=20=20= =20=20(save-window-excursion=0A=20=20=20=20=20=20(save-excursion=0A=20=20= =20=20=20=20=20=20(if=20(eq=20point=20(point-max))=0A=20=20=20=20=20=20=20= =20=20=20=20=20(throw=20'early-termination=20(cons=20point=20point)))=0A=20= =20=20=20=20=20=20=20(let*=20((end=20(line-end-position))=0A=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(prev-break=20(if=20(sfill-at-break=20= point)=20point=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=20=20=20=20=20(sfill-prev-break=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=20=20=20=20=20=20point=20= (line-beginning-position))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(prev-break=20(sfill-prev-break=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=20=20=20=20prev-break=20= (line-beginning-position)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= next-existing-break=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(beg=20= prev-break)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(match-count=20= 0))=0A=20=20=20=20=20=20=20=20=20=20(goto-char=20beg)=0A=20=20=20=20=20=20= =20=20=20=20(while=20(<=20(point)=20end)=0A=20=20=20=20=20=20=20=20=20=20= =20=20(setq=20next-existing-break=20(sfill-next-break=20(point)=20end))=0A= =20=20=20=20=20=20=20=20=20=20=20=20(sfill-delete-overlay-at=20= next-existing-break)=0A=20=20=20=20=20=20=20=20=20=20=20=20= (sfill-go-to-break-point=20(point)=20end)=0A=20=20=20=20=20=20=20=20=20=20= =20=20(unless=20(>=3D=20(point)=20end)=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(sfill-insert-newline))=0A=20=20=20=20=20=20=20=20=20=20=20=20= (if=20(eq=20next-existing-break=20(point))=0A=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(setq=20match-count=20(1+=20match-count)))=0A=20=20=20=20= =20=20=20=20=20=20=20=20(if=20(and=20(not=20force)=20(>=3D=20match-count=20= 2))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(throw=20= 'early-termination=20(cons=20beg=20end))))=0A=20=20=20=20=20=20=20=20=20=20= (cons=20beg=20end))))))=0A=0A;;=20Slightly=20faster=20but=20not=20= completely=20correct=0A;;=0A;;=20(defun=20sfill-line=20(point=20= &optional=20force)=0A;;=20=20=20"Fill=20the=20line=20in=20where=20POINT=20= is.=0A;;=20Return=20(BEG=20END)=20where=20the=20text=20is=20filled.=20= BEG=20is=20the=20visual=0A;;=20beginning=20of=20current=20live.=20END=20= is=20the=20actual=20end=20of=20line.=20If=0A;;=20FORCE=20is=20non-nil,=20= update=20the=20whole=20line."=0A;;=20=20=20(catch=20'early-termination=0A= ;;=20=20=20=20=20(save-window-excursion=0A;;=20=20=20=20=20=20=20= (save-excursion=0A;;=20=20=20=20=20=20=20=20=20(if=20(eq=20point=20= (point-max))=0A;;=20=20=20=20=20=20=20=20=20=20=20=20=20(throw=20= 'early-termination=20(cons=20point=20point)))=0A;;=20=20=20=20=20=20=20=20= =20(let*=20((end=20(line-end-position))=0A;;=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(prev-break=20(if=20(sfill-at-break=20point)=20point=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= =20=20=20=20=20=20(sfill-prev-break=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=20=20=20=20=20=20=20point=20= (line-beginning-position))))=0A;;=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20next-existing-break=0A;;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(beg=20prev-break))=0A;;=20=20=20=20=20=20=20=20=20=20=20(goto-char=20= beg)=0A;;=20=20=20=20=20=20=20=20=20=20=20(while=20(<=20(point)=20end)=0A= ;;=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20next-existing-break=20= (sfill-next-break=20(point)=20end))=0A;;=20=20=20=20=20=20=20=20=20=20=20= =20=20(sfill-delete-overlay-at=20next-existing-break)=0A;;=20=20=20=20=20= =20=20=20=20=20=20=20=20(sfill-go-to-break-point=20(point)=20end)=0A;;=20= =20=20=20=20=20=20=20=20=20=20=20=20(unless=20(>=3D=20(point)=20end)=0A= ;;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(sfill-insert-newline))=0A= ;;=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(and=20(not=20force)=20= (eq=20next-existing-break=20(point)))=0A;;=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(throw=20'early-termination=20(cons=20beg=20end))))=0A= ;;=20=20=20=20=20=20=20=20=20=20=20(cons=20beg=20end))))))=0A=0A(defun=20= sfill-region=20(&optional=20beg=20end=20force)=0A=20=20"Fill=20each=20= line=20in=20the=20region=20from=20BEG=20to=20END.=0A=0AIf=20FORCE=20is=20= non-nil,=20update=20the=20whole=20line.=20BEG=20and=20END=20default=0Ato=20= beginning=20and=20end=20of=20the=20buffer."=0A=20=20(save-excursion=0A=20= =20=20=20(goto-char=20(or=20beg=20(point-min)))=0A=20=20=20=20= (sfill-line=20(point)=20force)=0A=20=20=20=20(while=20(re-search-forward=20= "\n"=20(or=20end=20(point-max))=20t)=0A=20=20=20=20=20=20(sfill-line=20= (point)=20force))=0A=20=20=20=20(cons=20(or=20beg=20(point-min))=20(or=20= end=20(point-max)))))=0A=0A;;=20(defun=20sfill-paragraph=20()=0A;;=20=20=20= "Fill=20current=20paragraph."=0A;;=20=20=20(interactive)=0A;;=20=20=20= (let=20(beg=20end)=0A;;=20=20=20=20=20(save-excursion=0A;;=20=20=20=20=20= =20=20(backward-paragraph)=0A;;=20=20=20=20=20=20=20(skip-chars-forward=20= "\n")=0A;;=20=20=20=20=20=20=20(setq=20beg=20(point))=0A;;=20=20=20=20=20= =20=20(forward-paragraph)=0A;;=20=20=20=20=20=20=20(skip-chars-backward=20= "\n")=0A;;=20=20=20=20=20=20=20(setq=20end=20(point))=0A;;=20=20=20=20=20= =20=20(sfill-region-destructive=20beg=20end))))=0A=0A(defun=20= sfill-unfill=20(&optional=20beg=20end)=0A=20=20"Un-fill=20region=20from=20= BEG=20to=20END,=20default=20to=20whole=20buffer."=0A=20=20= (sfill-clear-overlay=20(or=20beg=20(point-min))=20(or=20end=20= (point-max))))=0A=0A(defun=20sfill-jit-lock-fn=20(beg=20end)=0A=20=20= "Fill=20line=20in=20region=20between=20BEG=20and=20END."=0A=20=20(cons=20= 'jit-lock-bounds=20(sfill-region=20beg=20end)))=0A=0A(defvar=20= sfill-mode-map=20(let=20((map=20(make-sparse-keymap)))=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=20;;=20= (define-key=20map=20(kbd=20"C-a")=20#'backward-sentence)=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=20;;=20= (define-key=20map=20(kbd=20"C-e")=20#'forward-sentence)=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=20map)=0A=20=20= "The=20keymap=20for=20minor=20mode=20=E2=80=98sfill-mode=E2=80=99.")=0A=0A= (define-minor-mode=20sfill-mode=0A=20=20"Automatically=20wrap=20lines."=0A= =20=20:lighter=20""=0A=20=20:keymap=20'sfill-mode-map=0A=20=20(if=20= sfill-mode=0A=20=20=20=20=20=20(progn=0A=20=20=20=20=20=20=20=20= (jit-lock-register=20#'sfill-jit-lock-fn)=0A=20=20=20=20=20=20=20=20= (jit-lock-refontify))=0A=20=20=20=20(jit-lock-unregister=20= #'sfill-jit-lock-fn)=0A=20=20=20=20(sfill-unfill)))=0A=0A(provide=20= 'sfill)=0A=0A;;;=20sfill.el=20ends=20here=0A= --Apple-Mail=_433FF1E4-46CE-4266-86B6-8E41E007BB73--