From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#36372: 27.0.50; replace-regexp-in-string skips START first chars in return value [PATCH] Date: Wed, 26 Jun 2019 19:03:19 +0200 Message-ID: <4BBC2AEF-642C-40C8-9E28-570C4BA21F18@acm.org> References: <83tvcdlm8x.fsf@gnu.org> <8336jwl7sa.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_4ED47032-99C6-4DB4-80F2-AB922129398F" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="84032"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Lars Ingebrigtsen , 36372@debbugs.gnu.org To: =?UTF-8?Q?Cl=C3=A9ment?= Pit-Claudel Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jun 26 19:04:46 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hgBLh-000Ljk-Tq for geb-bug-gnu-emacs@m.gmane.org; Wed, 26 Jun 2019 19:04:46 +0200 Original-Received: from localhost ([::1]:42102 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgBLg-0003w8-Ds for geb-bug-gnu-emacs@m.gmane.org; Wed, 26 Jun 2019 13:04:44 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43611) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgBLE-0003fV-Mg for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 13:04:23 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgBLC-0003cR-98 for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 13:04:16 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:51636) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hgBL0-0003N9-Ro for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 13:04:07 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hgBL0-00032g-Bg for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 13:04:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 17:04:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36372 X-GNU-PR-Package: emacs Original-Received: via spool by 36372-submit@debbugs.gnu.org id=B36372.156156860811650 (code B ref 36372); Wed, 26 Jun 2019 17:04:02 +0000 Original-Received: (at 36372) by debbugs.gnu.org; 26 Jun 2019 17:03:28 +0000 Original-Received: from localhost ([127.0.0.1]:36947 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgBKR-00031p-Lt for submit@debbugs.gnu.org; Wed, 26 Jun 2019 13:03:28 -0400 Original-Received: from mail175c50.megamailservers.eu ([91.136.10.185]:45368 helo=mail50c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgBKO-00031e-D0 for 36372@debbugs.gnu.org; Wed, 26 Jun 2019 13:03:25 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1561568602; bh=dDgVpYS+BW6pEUHBAyOG01c6KLIpsb2AJPm/R3Wrmxg=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=aSyitmkljg6d1FjGZTJdX46l8R01vTXV43OgLCnGuzS1QOPUmU0hkVi5umFCU0Cix tPEmc6qtrqFjafDyupN/OD/9nsZHGZnHaOwsU3BN6uhSNLACNij8Gppc3S/Ov0fH9p kqFQqb2s4wamfbt/SlYnoK8EE3w3eTW/YIc5+YNs= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail50c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5QH3JC9014502; Wed, 26 Jun 2019 17:03:21 +0000 In-Reply-To: X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0204.5D13A55A.0016, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=U/y889ju c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=pGLkceISAAAA:8 a=mDV3o1hIAAAA:8 a=3Y6RloVvkZW40JNhmQ4A:9 a=QEXdDO2ut3YA:10 a=h5Ve0Ubz_8bRSecn0PcA:9 a=B2y7HmGcmWMA:10 a=VDk6hhGL7EvPjjgMrysA:9 a=1OfwrDeanrQA:10 a=_FVE-zBwftR9WsbkzFJk:22 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:161531 Archived-At: --Apple-Mail=_4ED47032-99C6-4DB4-80F2-AB922129398F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 26 juni 2019 kl. 17.59 skrev Cl=C3=A9ment Pit-Claudel = : >=20 >> (1) Does this code, in company-coq--loc-fully-qualified-name, = actually work the way you intended? (Looks like it.) >=20 > Yes, I think it does. It's a bit inscrutable, so here's an annotated = copy: Thanks, so at least it wasn't written blindly from the docs --- good to = know. > This code would probably be clearer if I just used a substring to trim = out the beginning of the string ^^ Well I thought so, but who am I to judge? If it works... >> (2) Did you learn how the START parameter affects the return value by = reading the doc string, the manual, the source code, or by testing? >=20 > Almost certainly the docstring, confirmed by testing. I haven't = looked at this section of the manual.=20 >=20 >> (3) Are you aware of other code using the START parameter to = replace-regexp-in-string? >=20 > Nothing off the top of my head, but I probably wouldn't have thought = of the instance in company-coq either. A quick grep through my local = sources doesn't turn up anything else, but a quick visual check isn't a = very reliable method (did you use a plain grep to find the instance in = company-coq, or do you have a more sophisticated trick?). Definitely not sophisticated, just re-purposed my old regexp trawler = (attached in case you want to try). Cl=C3=A9ment, thank you very much for humouring me. We are in the = unenviable position to decide whether to fix an old, unsatisfactory, = apparently very rarely used interface, or to document the behaviour. The = stakes are low, but it looks like the semantics will be kept after all. 26 juni 2019 kl. 17.17 skrev Eli Zaretskii : >=20 > For the manual, I'd expand a bit on this, and explained how to get the > result you thought you will when using non-nil START (by concatenating > with the initial substring). All right, I added a sentence to that effect. --Apple-Mail=_4ED47032-99C6-4DB4-80F2-AB922129398F Content-Disposition: attachment; filename=0001-Document-bug-in-replace-regexp-in-string.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Document-bug-in-replace-regexp-in-string.patch" Content-Transfer-Encoding: quoted-printable =46rom=2095b5c2f463edfe617f16a238081639ac58f6e7fb=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Wed,=2026=20Jun=202019=2011:23:32=20+0200=0A= Subject:=20[PATCH]=20Document=20bug=20in=20`replace-regexp-in-string'=0A=0A= `replace-regexp-in-string'=20omits=20the=20first=20START=20characters=20= of=20the=0Ainput=20string=20in=20its=20return=20value.=20=20This=20is=20= a=20clear=20bug,=20but=20fixing=20it=0Aprobably=20causes=20more=20= trouble;=20document=20the=20behaviour=20instead=20(bug#36372).=0A=0A*=20= doc/lispref/searching.texi=20(Search=20and=20Replace)=0A*=20lisp/subr.el=20= (replace-regexp-in-string):=0ADocument=20current=20behaviour.=0A---=0A=20= doc/lispref/searching.texi=20|=206=20++++--=0A=20lisp/subr.el=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20|=203=20++-=0A=202=20files=20changed,=20= 6=20insertions(+),=203=20deletions(-)=0A=0Adiff=20--git=20= a/doc/lispref/searching.texi=20b/doc/lispref/searching.texi=0Aindex=20= 33455114da..ef1cffc446=20100644=0A---=20a/doc/lispref/searching.texi=0A= +++=20b/doc/lispref/searching.texi=0A@@=20-1790,8=20+1790,10=20@@=20= Search=20and=20Replace=0A=20This=20function=20copies=20@var{string}=20= and=20searches=20it=20for=20matches=20for=0A=20@var{regexp},=20and=20= replaces=20them=20with=20@var{rep}.=20=20It=20returns=20the=0A=20= modified=20copy.=20=20If=20@var{start}=20is=20non-@code{nil},=20the=20= search=20for=0A-matches=20starts=20at=20that=20index=20in=20= @var{string},=20so=20matches=20starting=0A-before=20that=20index=20are=20= not=20changed.=0A+matches=20starts=20at=20that=20index=20in=20= @var{string},=20and=20the=20returned=20value=0A+does=20not=20include=20= the=20first=20@var{start}=20characters=20of=20@var{string}.=0A+To=20get=20= the=20whole=20transformed=20string,=20concatenate=20the=20first=0A= +@var{start}=20characters=20of=20@var{string}=20with=20the=20return=20= value.=0A=20=0A=20This=20function=20uses=20@code{replace-match}=20to=20= do=20the=20replacement,=20and=20it=0A=20passes=20the=20optional=20= arguments=20@var{fixedcase},=20@var{literal}=20and=0Adiff=20--git=20= a/lisp/subr.el=20b/lisp/subr.el=0Aindex=20baff1e909a..b981af6afe=20= 100644=0A---=20a/lisp/subr.el=0A+++=20b/lisp/subr.el=0A@@=20-4208,7=20= +4208,8=20@@=20replace-regexp-in-string=0A=20=0A=20Optional=20arguments=20= FIXEDCASE,=20LITERAL=20and=20SUBEXP=20are=20like=20the=0A=20arguments=20= with=20the=20same=20names=20of=20function=20`replace-match'.=20=20If=20= START=0A-is=20non-nil,=20start=20replacements=20at=20that=20index=20in=20= STRING.=0A+is=20non-nil,=20start=20replacements=20at=20that=20index=20in=20= STRING,=20and=20omit=0A+the=20first=20START=20characters=20of=20STRING=20= from=20the=20return=20value.=0A=20=0A=20REP=20is=20either=20a=20string=20= used=20as=20the=20NEWTEXT=20arg=20of=20`replace-match'=20or=20a=0A=20= function.=20=20If=20it=20is=20a=20function,=20it=20is=20called=20with=20= the=20actual=20text=20of=20each=0A--=20=0A2.20.1=20(Apple=20Git-117)=0A=0A= --Apple-Mail=_4ED47032-99C6-4DB4-80F2-AB922129398F Content-Disposition: attachment; filename=trawl.el Content-Type: application/octet-stream; x-unix-mode=0644; name="trawl.el" Content-Transfer-Encoding: quoted-printable ;;;=20trawl.el=20--=20scan=20elisp=20code=20for=20various=20things=20=20=20= -*-=20lexical-binding:=20t=20-*-=0A=0A(require=20'compile)=0A(require=20= 'cl-lib)=0A=0A(defconst=20trawl--error-buffer-name=20"*trawl*")=0A=0A= (defun=20trawl--error-buffer=20()=0A=20=20(let=20((buf=20(get-buffer=20= trawl--error-buffer-name)))=0A=20=20=20=20(or=20buf=0A=20=20=20=20=20=20=20= =20(let=20((buf=20(get-buffer-create=20trawl--error-buffer-name)))=0A=20=20= =20=20=20=20=20=20=20=20(with-current-buffer=20buf=0A=20=20=20=20=20=20=20= =20=20=20=20=20(trawl-mode))=0A=20=20=20=20=20=20=20=20=20=20buf))))=0A=0A= (defvar=20trawl--error-count)=0A=0A(defun=20trawl--add-to-error-buffer=20= (string)=0A=20=20(with-current-buffer=20(trawl--error-buffer)=0A=20=20=20= =20(goto-char=20(point-max))=0A=20=20=20=20(let=20((inhibit-read-only=20= t))=0A=20=20=20=20=20=20(insert=20string))))=0A=0A(defun=20= trawl--line-col-from-pos-path=20(pos=20path)=0A=20=20"Compute=20(LINE=20= .=20COLUMN)=20from=20POS=20(toplevel=20position)=0Aand=20PATH=20= (reversed=20list=20of=20list=20indices=20to=20follow=20to=20target)."=0A=20= =20(save-excursion=0A=20=20=20=20(goto-char=20pos)=0A=20=20=20=20(let=20= ((p=20(reverse=20path)))=0A=20=20=20=20=20=20(while=20p=0A=20=20=20=20=20= =20=20=20(when=20(looking-at=20(rx=20(1+=20(or=20blank=20"\n"=20"\f"=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(seq=20";"=20(0+=20nonl))))))=0A=20=20= =20=20=20=20=20=20=20=20(goto-char=20(match-end=200)))=0A=20=20=20=20=20=20= =20=20(let=20((skip=20(car=20p)))=0A=20=20=20=20=20=20=20=20=20=20(cond=0A= =20=20=20=20=20=20=20=20=20=20=20((looking-at=20(rx=20(or=20"'"=20"#'"=20= "`"=20","=20",@")))=0A=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20= (match-end=200))=0A=20=20=20=20=20=20=20=20=20=20=20=20(setq=20skip=20= (1-=20skip)))=0A=20=20=20=20=20=20=20=20=20=20=20((looking-at=20(rx=20= "("))=0A=20=20=20=20=20=20=20=20=20=20=20=20(forward-char=201)))=0A=20=20= =20=20=20=20=20=20=20=20(forward-sexp=20skip)=0A=20=20=20=20=20=20=20=20=20= =20(setq=20p=20(cdr=20p))))=0A=20=20=20=20=20=20(when=20(looking-at=20= (rx=20(1+=20(or=20blank=20"\n"=20"\f"=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= (seq=20";"=20(0+=20nonl))))))=0A=20=20=20=20=20=20=20=20(goto-char=20= (match-end=200)))=0A=20=20=20=20=20=20(cons=20(line-number-at-pos=20= (point)=20t)=0A=20=20=20=20=20=20=20=20=20=20=20=20(1+=20= (current-column))))))=0A=0A(defun=20trawl--output-error=20(string)=0A=20=20= (if=20noninteractive=0A=20=20=20=20=20=20(message=20"%s"=20string)=0A=20=20= =20=20(trawl--add-to-error-buffer=20(concat=20string=20"\n"))))=0A=0A= (defun=20trawl--report=20(file=20pos=20path=20message)=0A=20=20(let=20= ((line-col=20(trawl--line-col-from-pos-path=20pos=20path)))=0A=20=20=20=20= (trawl--output-error=0A=20=20=20=20=20(format=20"%s:%d:%d:=20%s"=20file=20= (car=20line-col)=20(cdr=20line-col)=20message)))=0A=20=20(setq=20= trawl--error-count=20(1+=20trawl--error-count)))=0A=0A(defun=20= trawl--quote-string=20(str)=0A=20=20(concat=20"\""=0A=20=20=20=20=20=20=20= =20=20=20(replace-regexp-in-string=0A=20=20=20=20=20=20=20=20=20=20=20= (rx=20(any=20cntrl=20"\177-\377"=20?\\=20?\"))=0A=20=20=20=20=20=20=20=20= =20=20=20(lambda=20(s)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20= ((c=20(logand=20(string-to-char=20s)=20#xff)))=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(or=20(cdr=20(assq=20c=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"\\\"")=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"\\\\")=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(?\b=20.=20"\\b")=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(?\t=20.=20"\\t")=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(?\n=20.=20"\\n")=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(?\v=20.=20"\\v")=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(?\f=20.=20"\\f")=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(?\r=20.=20= "\\r")=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(?\e=20.=20"\\e"))))=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(format=20"\\%03o"=20c))))=0A=20=20=20= =20=20=20=20=20=20=20=20str=20t=20t)=0A=20=20=20=20=20=20=20=20=20=20= "\""))=0A=0A(defun=20trawl--caret-string=20(string=20pos)=0A=20=20(let=20= ((quoted-pos=0A=20=20=20=20=20=20=20=20=20(-=20(length=20= (trawl--quote-string=20(substring=20string=200=20pos)))=0A=20=20=20=20=20= =20=20=20=20=20=20=202)))=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20;=20Lop=20off=20quotes=0A=20=20=20=20(concat=20= (make-string=20quoted-pos=20?.)=20"^")))=0A=0A=0A(defconst=20= trawl--report-could-be=20nil)=0A(defconst=20trawl--report-pcase=20nil)=0A= (defconst=20trawl--report-cl-case=20nil)=0A=0A(defun=20= trawl--check-form-recursively=20(form=20file=20pos=20path)=0A=20=20= (pcase=20form=0A=20=20=20=20(`(replace-regexp-in-string=20.=20,_)=0A=20=20= =20=20=20(when=20(>=20(length=20form)=207)=0A=20=20=20=20=20=20=20= (trawl--report=20file=20pos=20path=20"replace-regexp-in-string=20with=20= start")))=0A=0A;;;=20=20=20=20(`(apply=20,(or=20'nconc=20'(quote=20= nconc)=20'(function=20nconc))=20(mapcar=20.=20,_))=0A;;;=20=20=20=20=20= (trawl--report=20file=20pos=20path=0A;;;=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"use=20mapcan=20instead=20of=20(apply=20nconc=20= (mapcar...))"))=0A;;;=20=20=20=20(`(lambda=20(,var1)=20(,_=20,var2))=0A= ;;;=20=20=20=20=20(when=20(eq=20var1=20var2)=0A;;;=20=20=20=20=20=20=20= (trawl--report=20file=20pos=20path=0A;;;=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20"lambda=20expression=20can=20be=20= =CE=B7-reduced")))=0A;;;=20=20=20=20(`(lambda=20(,var1)=20,var2)=0A;;;=20= =20=20=20=20(when=20(eq=20var1=20var2)=0A;;;=20=20=20=20=20=20=20= (trawl--report=20file=20pos=20path=0A;;;=09=09=20=20=20=20=20=20"lambda=20= expression=20is=20#'identity")))=0A;;;=20=20=20=20(`(,(or=20'defun=20= 'defsubst)=20,name=20,_=20.=20,body)=0A;;;=20=20=20=20=20(let=20((f=20= body))=0A;;;=20=20=20=20=20=20=20(while=20(and=20f=20(consp=20(car=20f))=20= (eq=20(caar=20f)=20'declare))=0A;;;=20=20=20=20=20=20=20=20=20(setq=20f=20= (cdr=20f)))=0A;;;=20=20=20=20=20=20=20(when=20(and=20f=20(consp=20(car=20= f)))=0A;;;=20=20=20=20=20=20=20=20=20(setq=20f=20(cdr=20f))=0A;;;=20=20=20= =20=20=20=20=20=20(while=20(cdr=20f)=0A;;;=20=20=20=20=20=20=20=20=20=20=20= (when=20(stringp=20(car=20f))=0A;;;=20=20=20=20=20=20=20=20=20=20=20=20=20= (trawl--report=20file=20pos=20path=0A;;;=09=09=09=20=20=20=20(format=20= "defun=20%s:=20misplaced=20doc=20string"=20name)))=0A;;;=20=20=20=20=20=20= =20=20=20=20=20(setq=20f=20(cdr=20f))))))=0A=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20)=0A=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(let=20((index=200))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(while=20(consp=20form)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(when=20(consp=20(car=20form))=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(trawl--check-form-recursively=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (car=20form)=20file=20pos=20(cons=20index=20path)))=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20form=20(cdr=20form))=0A=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20index=20= (1+=20index)))))=0A=0A(defun=20trawl--show-errors=20()=0A=20=20(unless=20= noninteractive=0A=20=20=20=20(let=20((pop-up-windows=20t))=0A=20=20=20=20= =20=20(display-buffer=20(trawl--error-buffer))=0A=20=20=20=20=20=20= (sit-for=200))))=0A=0A(defun=20trawl--read-buffer=20(file)=0A=20=20"Read=20= top-level=20forms=20from=20the=20current=20buffer.=0AReturn=20a=20list=20= of=20(FORM=20.=20STARTING-POSITION)."=0A=20=20(goto-char=20(point-min))=0A= =20=20(let=20((pos=20nil)=0A=20=20=20=20=20=20=20=20(keep-going=20t)=0A=20= =20=20=20=20=20=20=20(read-circle=20nil)=0A=20=20=20=20=20=20=20=20= (forms=20nil))=0A=20=20=20=20(while=20keep-going=0A=20=20=20=20=20=20= (setq=20pos=20(point))=0A=20=20=20=20=20=20(let=20((form=20nil))=0A=20=20= =20=20=20=20=20=20(condition-case=20err=0A=20=20=20=20=20=20=20=20=20=20=20= =20(setq=20form=20(read=20(current-buffer)))=0A=20=20=20=20=20=20=20=20=20= =20(end-of-file=0A=20=20=20=20=20=20=20=20=20=20=20(setq=20keep-going=20= nil))=0A=20=20=20=20=20=20=20=20=20=20(invalid-read-syntax=0A=20=20=20=20= =20=20=20=20=20=20=20(cond=0A=20=20=20=20=20=20=20=20=20=20=20=20((equal=20= (cadr=20err)=20"#")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20= pos)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(forward-sexp=201))=0A=20=20= =20=20=20=20=20=20=20=20=20=20(t=0A=20=20=20=20=20=20=20=20=20=20=20=20=20= (trawl--report=20file=20(point)=20nil=20(prin1-to-string=20err))=0A=20=20= =20=20=20=20=20=20=20=20=20=20=20(setq=20keep-going=20nil))))=0A=20=20=20= =20=20=20=20=20=20=20(error=0A=20=20=20=20=20=20=20=20=20=20=20= (trawl--report=20file=20(point)=20nil=20(prin1-to-string=20err))=0A=20=20= =20=20=20=20=20=20=20=20=20(setq=20keep-going=20nil)))=0A=20=20=20=20=20=20= =20=20(when=20(consp=20form)=0A=20=20=20=20=20=20=20=20=20=20(push=20= (cons=20form=20pos)=20forms))))=0A=20=20=20=20(nreverse=20forms)))=0A=0A= (defun=20trawl--scan-current-buffer=20(file)=0A=20=20(let=20= ((errors-before=20trawl--error-count))=0A=20=20=20=20(let=20((forms=20= (trawl--read-buffer=20file))=0A=20=20=20=20=20=20=20=20=20=20= (case-fold-search=20nil))=0A=20=20=20=20=20=20(dolist=20(form=20forms)=0A= =20=20=20=20=20=20=20=20(trawl--check-form-recursively=20(car=20form)=20= file=20(cdr=20form)=20nil)))=0A=20=20=20=20(when=20(>=20= trawl--error-count=20errors-before)=0A=20=20=20=20=20=20= (trawl--show-errors))))=0A=0A(defun=20trawl--scan-file=20(file=20= base-dir)=0A=20=20(with-temp-buffer=0A=20=20=20=20(emacs-lisp-mode)=0A=20= =20=20=20(insert-file-contents=20file)=0A=20=20=20=20= (trawl--scan-current-buffer=20(file-relative-name=20file=20base-dir))))=0A= =0A(defvar=20trawl-last-target=20nil=0A=20=20"The=20last=20file,=20= directory=20or=20buffer=20on=20which=20trawl=20was=20run.")=0A=0A(defun=20= trawl--init=20(target=20base-dir)=0A=20=20(if=20noninteractive=0A=20=20=20= =20=20=20(setq=20trawl--error-count=200)=0A=20=20=20=20= (with-current-buffer=20(trawl--error-buffer)=0A=20=20=20=20=20=20(let=20= ((inhibit-read-only=20t))=0A=20=20=20=20=20=20=20=20= (compilation-forget-errors)=0A=20=20=20=20=20=20=20=20(erase-buffer)=0A=20= =20=20=20=20=20=20=20(insert=20(format=20"Trawl=20results=20for=20%s\n"=20= target))=0A=20=20=20=20=20=20=20=20(trawl--show-errors))=0A=20=20=20=20=20= =20(setq=20trawl-last-target=20target)=0A=20=20=20=20=20=20(setq=20= default-directory=20base-dir)=0A=20=20=20=20=20=20(setq=20= trawl--error-count=200))))=0A=0A(defun=20trawl--finish=20()=0A=20=20= (let*=20((errors=20trawl--error-count)=0A=20=20=20=20=20=20=20=20=20(msg=20= (format=20"%d=20error%s"=20errors=20(if=20(=3D=20errors=201)=20""=20= "s"))))=0A=20=20=20=20(unless=20noninteractive=0A=20=20=20=20=20=20= (trawl--add-to-error-buffer=20(format=20"\nFinished=20--=20%s=20= found.\n"=20msg)))=0A=20=20=20=20(message=20"trawl:=20%s=20found."=20= msg)))=0A=0A(defun=20trawl-again=20()=0A=20=20"Re-run=20trawl=20on=20the=20= same=20file,=20directory=20or=20buffer=20as=20last=20time."=0A=20=20= (interactive)=0A=20=20(cond=20((bufferp=20trawl-last-target)=0A=20=20=20=20= =20=20=20=20=20(with-current-buffer=20trawl-last-target=0A=20=20=20=20=20= =20=20=20=20=20=20(trawl-current-buffer)))=0A=20=20=20=20=20=20=20=20= ((file-directory-p=20trawl-last-target)=0A=20=20=20=20=20=20=20=20=20= (trawl-directory=20trawl-last-target))=0A=20=20=20=20=20=20=20=20= ((file-readable-p=20trawl-last-target)=0A=20=20=20=20=20=20=20=20=20= (trawl-file=20trawl-last-target))=0A=20=20=20=20=20=20=20=20(t=20(error=20= "No=20target"))))=0A=0A(defvar=20trawl-mode-map=0A=20=20(let=20((map=20= (make-sparse-keymap)))=0A=20=20=20=20(set-keymap-parent=20map=20= compilation-minor-mode-map)=0A=20=20=20=20(define-key=20map=20"n"=20= 'next-error-no-select)=0A=20=20=20=20(define-key=20map=20"p"=20= 'previous-error-no-select)=0A=20=20=20=20(define-key=20map=20"g"=20= 'trawl-again)=0A=20=20=20=20map)=0A=20=20"Keymap=20for=20trawl=20= buffers.")=0A=0A(define-compilation-mode=20trawl-mode=20"Trawl"=0A=20=20= "Mode=20for=20trawl=20output."=0A=20=20(setq-local=20trawl-last-target=20= nil))=0A=0A(defun=20trawl--scan-files=20(files=20target=20base-dir)=0A=20= =20(trawl--init=20target=20base-dir)=0A=20=20(dolist=20(file=20files)=0A=20= =20=20=20;;(trawl--add-to-error-buffer=20(format=20"Scanning=20%s\n"=20= file))=0A=20=20=20=20(trawl--scan-file=20file=20base-dir))=0A=20=20= (trawl--finish))=0A=0A(defun=20trawl--tree-files=20(dir)=0A=20=20= (directory-files-recursively=0A=20=20=20dir=20(rx=20bos=20(not=20(any=20= "."))=20(*=20anything)=20".el"=20eos)))=0A=0A=0A;;;###autoload=0A(defun=20= trawl-file=20(file)=0A=20=20"Scan=20FILE,=20an=20elisp=20file."=0A=20=20= (interactive=20"fTrawl=20elisp=20file:=20")=0A=20=20(trawl--scan-files=20= (list=20file)=20file=20(file-name-directory=20file)))=0A=0A= ;;;###autoload=0A(defun=20trawl-directory=20(dir)=0A=20=20"Scan=20all=20= *.el=20files=20in=20DIR."=0A=20=20(interactive=20"DTrawl=20directory:=20= ")=0A=20=20(message=20"Finding=20.el=20files=20in=20%s..."=20dir)=0A=20=20= (let=20((files=20(trawl--tree-files=20dir)))=0A=20=20=20=20(message=20= "Scanning=20files...")=0A=20=20=20=20(trawl--scan-files=20files=20dir=20= dir)))=0A=0A;;;###autoload=0A(defun=20trawl-current-buffer=20()=0A=20=20= "Scan=20the=20current=20buffer.=0AThe=20buffer=20must=20be=20in=20= emacs-lisp-mode."=0A=20=20(interactive)=0A=20=20(unless=20(eq=20= major-mode=20'emacs-lisp-mode)=0A=20=20=20=20(error=20"Trawl:=20can=20= only=20scan=20elisp=20code=20(use=20emacs-lisp-mode)"))=0A=20=20= (trawl--init=20(current-buffer)=20default-directory)=0A=20=20= (save-excursion=0A=20=20=20=20(trawl--scan-current-buffer=20= (buffer-name)))=0A=20=20(trawl--finish))=0A=0A=0A(defun=20trawl-batch=20= ()=0A=20=20"Scan=20elisp=20source=20files.=0ACall=20this=20function=20in=20= batch=20mode=20with=20files=20and=20directories=20as=0Acommand-line=20= arguments.=20=20Files=20are=20scanned;=20directories=20are=0Asearched=20= recursively=20for=20*.el=20files=20to=20scan."=0A=20=20(unless=20= noninteractive=0A=20=20=20=20(error=20"`trawl-batch'=20is=20only=20for=20= use=20with=20-batch"))=0A=20=20(trawl--scan-files=20(mapcan=20(lambda=20= (arg)=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(if=20(file-directory-p=20arg)=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(trawl--tree-files=20arg)=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= (list=20arg)))=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=20command-line-args-left)=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20nil=20default-directory)=0A=20= =20(setq=20command-line-args-left=20nil))=0A=0A(provide=20'trawl)=0A=0A= ;;;=20trawl.el=20ends=20here=0A= --Apple-Mail=_4ED47032-99C6-4DB4-80F2-AB922129398F--