From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Wolfgang Scherer Newsgroups: gmane.emacs.bugs Subject: bug#37189: 25.4.1: vc-hg-ignore implementation is missing Date: Tue, 11 Feb 2020 02:45:41 +0100 Message-ID: References: <1ba53ae2-42a4-3ab3-d4f2-2ceae565d198@gmx.de> <52917e6f-2f00-25cf-4353-dfb40287d0ea@gmx.de> <83pnkrdpb3.fsf@gnu.org> <679942e8-abe9-b0fc-720d-75a54d8d0b5a@gmx.de> <95da41e8-7a55-a15c-cfa7-d70366f9ee6b@gmx.de> <412195c1-e196-12af-933b-0312f5075847@yandex.ru> <57825d73-27a4-d5f5-8198-a172796a558a@gmx.de> <1ebc6077-9175-65ba-4996-282bb2c8eca5@yandex.ru> <6145d6f6-37a8-7166-731b-57669086b145@gmx.de> <838slmk90j.fsf@gnu.org> <83h806gp2w.fsf@gnu.org> <8336bmg1o9.fsf@gnu.org> <2354821b-5c1e-f9e3-3a64-4ff978ded33b@gmx.de> <83sgjkdev5.fsf@gnu.org> <3fb73dbc-bf31-233b-4afc-2147c4ffd5b7@gmx.de> <5622487d-a21f-49cf-5420-21f87415af4f@gmx.de> <83wo8ubfbo.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="13660"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 Cc: 37189@debbugs.gnu.org, dgutov@yandex.ru To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Feb 11 02:46:43 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1j1KdP-0003Pn-DO for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 11 Feb 2020 02:46:43 +0100 Original-Received: from localhost ([::1]:42246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1KdN-00041e-Up for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 10 Feb 2020 20:46:42 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46130) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1Kcr-00041W-3x for bug-gnu-emacs@gnu.org; Mon, 10 Feb 2020 20:46:11 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j1Kcl-0007vy-JU for bug-gnu-emacs@gnu.org; Mon, 10 Feb 2020 20:46:08 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:49765) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j1Kck-0007uT-DQ for bug-gnu-emacs@gnu.org; Mon, 10 Feb 2020 20:46:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1j1Kck-0004FG-BQ for bug-gnu-emacs@gnu.org; Mon, 10 Feb 2020 20:46:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Wolfgang Scherer Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 11 Feb 2020 01:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37189 X-GNU-PR-Package: emacs Original-Received: via spool by 37189-submit@debbugs.gnu.org id=B37189.158138555116300 (code B ref 37189); Tue, 11 Feb 2020 01:46:02 +0000 Original-Received: (at 37189) by debbugs.gnu.org; 11 Feb 2020 01:45:51 +0000 Original-Received: from localhost ([127.0.0.1]:55738 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j1KcZ-0004Ep-0P for submit@debbugs.gnu.org; Mon, 10 Feb 2020 20:45:51 -0500 Original-Received: from mout.gmx.net ([212.227.17.22]:59277) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j1KcX-0004Ec-A9 for 37189@debbugs.gnu.org; Mon, 10 Feb 2020 20:45:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1581385542; bh=SPEaVKpAuwSpnUi86YCVGlx3mNlDkfVuwGrRFymr1mo=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=G9DPzexJnjj10s+HXweyTb0GT0V6uoRezCQp/o6BSvGWqmYVBNkEVk0m+Cj86z0j4 wURBaHi/XsYM+tXt8k87D38h88ZJxCeYP8dPiOxWtCqtJmtR9QIKT8WTU9JEYjcRJI eTYgzXJmS2eWg9zaP15rJisxg6b3aX4F3OZU6i2c= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from sheckley.simul.de ([87.160.210.52]) by mail.gmx.com (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MpUYu-1jrDqc2zBk-00ptYm; Tue, 11 Feb 2020 02:45:42 +0100 Original-Received: from [127.0.0.1] (sheckley.simul.de [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sheckley.simul.de (Postfix) with ESMTPSA id B956B1943190; Tue, 11 Feb 2020 02:45:41 +0100 (CET) Openpgp: preference=signencrypt Autocrypt: addr=Wolfgang.Scherer@gmx.de; prefer-encrypt=mutual; keydata= xsDiBEb46IgRBACMHOAb1KNo1Ylk+ebri+4R+bG4tyKlqBlrpv8D9/ZwRdXSGt+0DyCHoaAd 7KW7noHapLe87DunABOjKG4nqTGv+dRiWuUBlp3I4aYRFDVa3Da+XnIYkMHKqhK59VEHQCdp Km42nuLS7TS+n99at9YwzTG6VBdOlBKTlRFngOjVLwCg1RGXJ6X3EjS1FKCQeXziURVpWlkD /2zY6Ayhxi62TS84VjikXrrmjXykAAaAmMVEyKKYb9L5pGlqiZz9g/K9xw1EUoZTYuaufquD v4rAGR58K/3V4CYfJLEeshMWiaXHvMmlxMznlG16/um4MvmR8B3r+cx0nOPK1JBdD2qrkNnF Mw8FB+zouLFB4Gt2IUC5IlOmZ8OQA/4qdU53CItzWsCr9Nux4L0qUlRweSmCnV8xGQ2wP5XI MawIQxxREvSrsYDG8cNnYETMg4iQFfIktwAoxCJvuFAwIB6ZxHGF4FcEZm64CXc2u7CmFLqt rVhXhIfMz9oEYC+HhGczGamn9ofbGTFd2hJEtPcQgWNR4f7+aKknmi2+OM0fV29sZmdhbmcg U2NoZXJlciA8d3NAc3ctYW10LndzPsJhBBMRAgAhBQJYmz3YAhsjBQsJCAcCBhUICQoLAgQW AgMBAh4BAheAAAoJEIUCr3Gr112VZZoAoLTBSTp1qGuNhLdXY04iaWCMYmHCAJ4kHPtQ6nTw kEq9qCHgVgXDaY7wjs7ATQRG+OiIEAQAhi0wjcxvA4tychg2NQuwBIf9LX/46l+74+QbewCn a4a+mw/9s5KY In-Reply-To: <83wo8ubfbo.fsf@gnu.org> Content-Language: de-DE X-Provags-ID: V03:K1:Jqt2+B0quWdXvBInsYJ9d/Kp5x1SvPbaAAAqmaU0YBvLAOCpb3d 4xI1pAUhkItfWW4DOmH5kfsx6sTOjFGcY1n17YD8vnotcp1lr2twzV2m8wdC6/1e4HipymZ BWMeIWC00UgIbxH9fqailVgZhO7zqr9Yhl2bpZJNvBQmnLany4ssbEmyjCiwUWi0SkyPbtd NymDTd9LaW5RKHVFBAmgA== X-UI-Out-Filterresults: notjunk:1;V03:K0:RC/AIQ1amYQ=:LkuzTbOMSLmGFpgurZMs3g MvRA2xTZshpWiisPXnqFvLuh5NNgLLbDcqOdRbOoNchDhL7rdM9wuZtjF9DDQ7hXIRm0qs3nh fhZ0CMLa6whvGnD8q3FdrKwKKCazxHP7UH+D01rFHXTwtpsWJV662iV6qgRMJ+p1VlrAM9A6L QUcRzuoWZx6W0NSOtHHgPxlnI4pJwanFUwIGFNolwybnnq/kuKjI6Rfir14fb8owxEYawDNzl aDKeh16S1nzO1HkEZL7II4mximoqp5vIWTWuPSac+MMd3BmswW8u5WgeyOxLlHxmxJbOO8N8S YpRgpZthpaet3PRf3MppGTPVxuxt1D8qrxY/XK8fkTAMYehvYTUaUar5l2J2BM88Jv5a+wAaA 1V1SXXQV3wia+W1A1gP0ybEYMh3m+pO2xDYDmCmvGjQcoQkC6Eyl+TWo79wf7ovjAtrWef+6d yAzQBFcYGf5Uu8jlztZZ2YcAyZTsCqKyIQeG6oBKVSsl0eqyaI7Jha/MCcgfSi5UjPehpKFhj kT5MJlG/vWd6x8pI4SEJ7bB5adROeIb5U8OvB/xcusa+J5Kvc9iueajpNSOKhWJ3V7GyGjGcc IhBKBfO5RR4Zd7F37zMH+nMcuXZmnprJA9tL/v6tmRbeROPvHb4RKcv7ubp1dqcwCZOkatme9 FZ/hjQxypr6MHBsGbNwH2YCtf+a1FCdDOJVkm8uSFGed7SBHn+qob4bAPcT9YjGqbVCarhpwE xEb0ln0LjLK6HQ7Dfr2iG1j3JeMTMi2kt1Ox6jsxcS/XqXhTbq/vxdAl+vlGLCg3vbJUodJ8 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-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:175918 Archived-At: Hi Eli, I suggest, we stop talking about the use case, where `vc-ignore` is called interactively, I will let you have your opinion, although I strongly disagree and the unsolved problem of interactively locating the correct ignore file makes it ultimately hilarious: A command that locates an ignore file, but can only do so, if the default-directory is already the one containing the ignore file (always true for SRC, CVS, SVN) .Since the escaping must also be correct, I'm probably better off locating and editing the ignore file manually. Inserting the output of "ls -1" and editing away - as I sometimes do - is much more convenient than calling `vc-ignore` multiple times and repeating more complex editing of an absolute file path each time in the minibuffer. However, there is a use case that you keep avoiding to comment on, namely pressing "G" in `vc-dir-mode`, which calls `vc-dir-ignore`, which in turn calls `vc-ignore` **programmatically** with an absolute file path. It has been officially supported by Emacs since 2013. I did not invent it and I did not alter its API. Since there is no interactive prompt whatsoever for a user to 1. properly construct an escaped pattern and 2. specify the directory, where the search for the ignore file =C2=A0=C2=A0 should start, the function called to ignore the file must consequently escape and anchor it properly, just like any command that uses `shell-quote-args` because the use case requires it and the purpose of the argument is well-known. How do you plan to support this use case? (For a humorous suggestion, see below). According to your opinion `vc-ignore` can only be used **interactively** by a learned expert user, who wants to make ignore file administration even more complicated by editing random ignore files without any feedback. So it is the wrong candidate for a noob user of `vc-dir-mode` who just wants to ignore the selected files literally without worrying about ignore files and escaping. They also expect a visual feedback, that the operation had the desired effect, as they have come to expect from all the other commands in `vc-dir-mode`. So, if you do not plan to drop this feature from `vc-dir-mode` altogether, then a new function must be implemented, which does exactly what my implementation does. Therefore, it only fixes the broken behavior in `vc-dir-mode`. If you are just worried, that somebody will use `vc-ignore` and expect the old broken behavior, I suggest to accept my implementaton and add a custom variable `vc-ignore-posixly-correct` with a default value of `t` to prefer the same behavior as before (see below for a draft implementation). I don't think it is really necessary, since I removed interactive from `vc-ignore` and `C-x v G` calls `vc-ignore-pattern` which essentially behaves like the old `vc-ignore` minus the real bugs. So a user would only realize the API change when executing `M-x vc-ignore`. Am 10.02.20 um 17:02 schrieb Eli Zaretskii: >> From: Wolfgang Scherer >> Cc: dgutov@yandex.ru, 37189@debbugs.gnu.org >> Date: Sun, 9 Feb 2020 14:57:12 +0100 >> >> =C2=A0=C2=A0=C2=A0 +-------------+-----------------+---------------+---= --------------+--------------------+ >> =C2=A0=C2=A0=C2=A0 | `file path` | glob(7)=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 | anchored glob | Hg `regex`=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 | Bzr `regex`=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | >> =C2=A0=C2=A0=C2=A0 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ >> =C2=A0=C2=A0=C2=A0 | test[56].xx |=C2=A0=C2=A0 test\[56].xx=C2=A0 | /te= st\[56].xx | ^test\[56]\.xx$ | RE:^test\[56]\.xx$ | >> =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 test[[]56].xx |=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | >> =C2=A0=C2=A0=C2=A0 +-------------+-----------------+---------------+---= --------------+--------------------+ >> =C2=A0=C2=A0=C2=A0 | simple.txt=C2=A0 |=C2=A0=C2=A0 simple.txt=C2=A0=C2= =A0=C2=A0 | /simple.txt=C2=A0=C2=A0 | ^simple\.txt$=C2=A0=C2=A0 | RE:^simp= le\.txt$=C2=A0=C2=A0 | >> =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 simple[.]txt=C2=A0 |=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | >> =C2=A0=C2=A0=C2=A0 +-------------+-----------------+---------------+---= --------------+--------------------+ > Just a note: this table might be interpreted to mean that hg and bzr > only support regexes in their ignore files, but that is of course > false: they also support glob-style widlcards. This is not an exhaustive table of ignore specification syntaxes. It is meant to illustrate that the case =C2=A0 file path =3D=3D=3D ignore specification is really the exception. >> =C2=A0=C2=A0=C2=A0 The correct escaping of FILE can only be determined = by the >> =C2=A0=C2=A0=C2=A0 backend. Therefore neither vc-dir-ignore nor lisp co= de calling >> =C2=A0=C2=A0=C2=A0 vc-ignore can escape the FILE parameter correctly wi= thout support >> =C2=A0=C2=A0=C2=A0 from the backend. This makes pattern input for FILE = only useful >> =C2=A0=C2=A0=C2=A0 during interactive calls. >> >> Even, if it was magically possible to determine the correct >> pattern in the frontend, submitting an anchored >> glob "/some-sub/file.txt" to `vc-ignore` would be interpreted as >> an absolute path. >> >> In other words, the API specificaton >> >> =C2=A0 [...] FILE is a wildcard specification, either relative to >> =C2=A0 DIRECTORY or absolute. >> >> which asks for implementing the pattern use case inextricably >> mixed with the file path use case, is nonsense. >> >> It also means, that all of the backend functions which currently >> demand a pattern are absolutely useless. > I don't think I agree. While the direction in which you propose to > move -- which AFAIU is to offer 2 different commands, one to ignore a > file name, the other to ignore a file pattern -- is definitely > possible, (Sorry, I did not have time to clean the ReStructured Text source, it is r= endered in HTML at http://sw-amt.ws/emacs/doc/_build/html/emacs-vc-ignore-= feature.html#implementation-of-vc-ignore-parameter-extension) The actual implementation is in a single function :defun:`vc-ignore`. The use cases "pattern" and "file path" are selected with the flag AS-IS. For interactive use, there are 2 separate commands :defun:`vc-ignore-file` and :defun:`vc-ignore-pattern`, both of which just call :defun:`vc-ignore` with a different value for the flag AS-IS. This decision was made, because the prefix argument as usual choice to specify a flag parameter interactively is already appropriated for the flag REMOVE. Instead of an interactive y/n question for each invocation - which is pretty annoying - 2 separate functions also facilitate keymap definitions. It also has the advantage that only the relevant information for each use case can be presented in the doc string. Granted that typing :kbd:`C-x v F` instead of :kbd:`C-x v G` or :kbd:`F` instead of :kbd:`G` is also a decision, but it does not necessarily have to be made each time, especially if a user only cares about a single use case. That concludes the argument for 2 separate interactive commands as user interface. The implementation consists of a linear call chain with two short code path variations. Besides backend specific implementations for some functions, there are **never** 2 separate functions in the entire chain. .. uml:: =C2=A0=C2=A0 :caption: :defun:`vc-ignore` call chain =C2=A0=C2=A0=C2=A0 @startuml =C2=A0=C2=A0=C2=A0 participant "vc-default-\nignore" as VCDI =C2=A0=C2=A0=C2=A0 participant "vc-default-\nget-ignore-file-\nand-pattern= " as VCDIAP =C2=A0=C2=A0=C2=A0 participant "vc-backend-\nignore-param" as VCBIP =C2=A0=C2=A0=C2=A0 participant "vc-backend-\nfind-ignore-file" as VCBFIF =C2=A0=C2=A0=C2=A0 participant "vc-default-\nmod-ignores" as VCDMI =C2=A0=C2=A0=C2=A0 VCDI=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 VCDIAP : (vc-call= -backend FILE-OR-PATTERN\n DIRECTORY AS-IS REMOVE) =C2=A0=C2=A0=C2=A0 alt AS-IS non-nil =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 VCDIAP ->=C2=A0 VCDIAP : absolute FILE-PATH= \nnormalize DIRECTORY =C2=A0=C2=A0=C2=A0 end =C2=A0=C2=A0=C2=A0 VCDIAP=C2=A0=C2=A0 ->=C2=A0 VCBFIF : (vcb DIRECTORY) =C2=A0=C2=A0=C2=A0 VCDIAP=C2=A0=C2=A0 <-- VCBFIF :IGNORE-FILE =C2=A0=C2=A0=C2=A0 alt AS-IS nil =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 VCDIAP ->=C2=A0 VCDIAP : null ignore spec p= rocessing parameters =C2=A0=C2=A0=C2=A0 else AS-IS non-nil =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 VCDIAP ->=C2=A0 VCDIAP : relative FILE-PATH =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 VCDIAP ->=C2=A0 VCBIP : (vcb IGNORE-FILE) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 VCDIAP <-- VCBIP : ignore spec processing p= arameters =C2=A0=C2=A0=C2=A0 end =C2=A0=C2=A0=C2=A0 VCDIAP=C2=A0=C2=A0 ->=C2=A0 VCDIAP : escape/anchor patt= ern =C2=A0=C2=A0=C2=A0 VCDI=C2=A0=C2=A0=C2=A0=C2=A0 <-- VCDIAP : '(IGNORE-FILE= PATTERN REMOVE) =C2=A0=C2=A0=C2=A0 VCDI=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 VCDMI : (vcb IGNO= RE-FILE PATTERN REMOVE) =C2=A0=C2=A0=C2=A0 VCDI=C2=A0=C2=A0=C2=A0=C2=A0 <-- VCDMI =C2=A0=C2=A0=C2=A0 @enduml The code path variations based on the AS-IS flag are confined to :defun:`vc-default-get-ignore-file-and-pattern`. First, if AS-IS is nil, the FILE-OR-PATTERN argument is expanded to an absolute FILE-PATH. DIRECTORY is set to the immediate parent directory of :elisp:`(vc-no-final-slash FILE-PATH)`: This normalization is necessary, because the search for an ignore file starts at DIRECTORY. .. code-block:: elisp =C2=A0=C2=A0 (when (not as-is) =C2=A0=C2=A0=C2=A0=C2=A0 (setq file-or-pattern (expand-file-name file-or-p= attern directory)) =C2=A0=C2=A0=C2=A0=C2=A0 (setq directory (file-name-directory (vc-no-final= -slash file-or-pattern)))) Second, if AS-IS is non-nil, the parameters for escaping and anchoring an ignore pattern are set to an identity function. If AS-IS is nil, FILE-PATH is made relative to the path of the directory where the pattern will be stored.=C2=A0 Parameters for escaping and anchoring an ignore pattern are obtained from the VC backend. .. code-block:: elisp =C2=A0=C2=A0 (if as-is =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (setq ignore-param vc-ignore-param-no= ne) =C2=A0=C2=A0=C2=A0=C2=A0 (when (not (string=3D (substring file-or-pattern = 0 (length ignore-dir)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 i= gnore-dir)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (error "Ignore spec %s is not below p= roject root %s" =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 file-or-pattern ignore-dir)) =C2=A0=C2=A0=C2=A0=C2=A0 (setq is-dir (or (file-directory-p file-or-patter= n) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (vc-has-final-slash= file-or-pattern))) =C2=A0=C2=A0=C2=A0=C2=A0 (setq file-or-pattern (vc-no-final-slash =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 (substring file-or-pattern (length ignore-dir)))) =C2=A0=C2=A0=C2=A0=C2=A0 (setq ignore-param (vc-call-backend backend 'igno= re-param ignore-file))) E.g. an invocation of :elisp:`(vc-ignore "some/rel/path/" "/re/po")` translates to: .. code-block:: elisp =C2=A0=C2=A0 ;; normalize FILE-PATH and DIRECTORY =C2=A0=C2=A0 (setq file-or-pattern "/re/po/some/rel/path/" ) =C2=A0=C2=A0 (setq directory "/re/po/some/rel/" ) =C2=A0=C2=A0 ;; determine, whether file path is a directory =C2=A0=C2=A0 (setq is-dir t) =C2=A0=C2=A0 ;; prepare pattern as relative file path to directory of igno= re file =C2=A0=C2=A0 (setq file-or-pattern "path" ) =C2=A0=C2=A0 ;; obtain parameters for escaping and anchoring an ignore pat= tern from VC backend All further processing is identical for verbatim patterns and for file pat= hs. If you insist on calling a code path difference of 3 lines versus 13 lines two independent functions, then technically you are correct and we should just remove the extra 13 lines of code (and also the two separate interactive commands) to get a **properly working** implementation of the pattern use case for **all** VC backends, which is still needed, because right now, the vc ignore feature is incomplete and very buggy. > I question its necessity. > In the use cases I have in mind, > the ignore file-or-pattern always comes from the user, because only > the users can decide which files they want to ignore. These are my major use cases. I do not have a real use case involving Lisp= code, but it is always worth considering. > And the users > always know both which backend they are working with, and whether the > file-or-pattern is a filename or a pattern. Yes, I do. 99.9% of the time I want to ignore one or more files in `vc-dir= -mode` or `dired-mode` > It follows that we can > ask the users to escape and anchor the file-or-pattern argument they > type, Are you aware, that the current implementation of `vc-dir-ignore` calls `vc-ignore` with a plain absolute file path obtained from (vc-dir-current-file)?=C2=A0 There is no prompting whatsoever that would let the user escape and anchor anything. How would you propose to handle this officially supported use case (since 2013)? =C2=A0=C2=A0 (defun vc-dir-ignore (&optional arg) =C2=A0=C2=A0=C2=A0=C2=A0 "Ignore the current file." =C2=A0=C2=A0=C2=A0=C2=A0 (interactive "P") =C2=A0=C2=A0=C2=A0=C2=A0 (vc-ignore =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (if (called-interactively-p 'any) =C2=A0=C2=A0=C2=A0 =C2=A0 (read-string "Make the path relative to the igno= re file, =C2=A0=C2=A0=C2=A0 which may or may not be at the location you expect. The= n guess =C2=A0=C2=A0=C2=A0 the currently active pattern escape syntax, apply it to= the file =C2=A0=C2=A0=C2=A0 path and anchor it: " (vc-dir-current-file)) =C2=A0=C2=A0=C2=A0 (error "This will fail, when called from lisp code.")))= ) > and that is not an unreasonable expectation. If you analyze the above humorous prompt, you will see, that it is entirely unreasonable, since it is no longer possible to determine the correct ignore file for a given pattern, unless the DIRECTORY parameter is also correct, which is always necessary for CVS, SVN, SRC. So before calling `vc-ignore` I have to change into the correct directory? =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 1. Locating the correct ignore file is no simple task for Git or =C2=A0=C2=A0 Hg, which support sub-tree ignore files. The current =C2=A0=C2=A0 implementation via =C2=A0=C2=A0 : (expand-file-name ".hgignore" (vc-root-dir)) =C2=A0=C2=A0 is extremely simplistic and should be augmented in a separate =C2=A0=C2=A0 effort. 2. The current syntax in an Hg ignore file may be either regex =C2=A0=C2=A0 or glob. Since we are in a collaborative environment, after =C2=A0=C2=A0 all, anybody may have changed the default syntax since we las= t =C2=A0=C2=A0 checked. 3. Nobody knows all ignore spec syntaxes all the time (memory is =C2=A0=C2=A0 always fading). 4. If I have to contribute to a project that uses an unfamiliar =C2=A0=C2=A0 VC, it would be extremely reasonable, if my development =C2=A0=C2=A0 environment (Emacs) would spare me the trouble of totally =C2=A0=C2=A0 avoidable "ignore file" mistakes. It would be so extremely =C2=A0=C2=A0 reasonable, that it would be actually unreasonable not to hav= e =C2=A0=C2=A0 it implemented. 5. I have users, which are only just learning how to program. I =C2=A0=C2=A0 do not wish for them to delve into just another distraction =C2=A0=C2=A0 from the task at hand. It would be very reasonable, if Emacs =C2=A0=C2=A0 helped me keep them on point. =C2=A0=C2=A0 ("Don't worry, Emacs will handle that for you!") > In fact, your > approach expects the same from the users, because you are asking the > users to decide which of the two commands to invoke in each case. I handled that above. If you only ever add files from `vc-dir-mode` or `dired-mode` you only have to make that decision once in your lifetime. > If there are no flaws in my way of reasoning, then I think the > resulting changes will be much less extensive, because the same > vc-ignore command can then be used for both ignoring a specific file > and for ignoring a pattern of any kind. I can give you that with my implementation as a bonus added interactive co= mmand: =C2=A0=C2=A0 (defun vc-ignore-posixly-correct (file &optional directory re= move as-is) =C2=A0=C2=A0=C2=A0=C2=A0 (interactive =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (let ((remove current-prefix-arg) file as-i= s) =C2=A0=C2=A0=C2=A0 (if (not (y-or-n-p "Ignore a file?")) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (setq file (read-string "Pattern: ")= ) =C2=A0=C2=A0=C2=A0 =C2=A0 (setq as-is (not (y-or-n-p "Escape manually?"))) =C2=A0=C2=A0=C2=A0 =C2=A0 (setq file (read-file-name "File: "))) =C2=A0=C2=A0=C2=A0 (list file nil remove as-is))) =C2=A0=C2=A0=C2=A0=C2=A0 (vcignore file directory remove as-is)) > We just need to document that > if the argument is a pattern of any kind, the user will have to make > sure it is escaped and anchored for the backend to DTRT. > > A further advantage of my proposal is that we don't need to write any > backend-specific code to escape special characters in patterns, > because we expect the users to do that. Since we have to check for the active syntax anyway, it may be better to abandon the entire ignore feature and just open the appropriate ignore file for editing. It is a lot simpler and much more convenient than the minibuffer for editing multiple files. It would also help the user to determine what the correct relative file name should be. > > This concept is similar to what we do in commands such as "M-x grep", > where we expect the users to escape special characters in the > command-line arguments to be passed to Grep the program via the shell. That is not at all comparable, since there is no use case "search for file path in a bunch of files". If such a command `grep-for-file-name` were derived from `grep`, a user could reasonably expect that the file argument is properly quoted as a grep pattern. The correct comparison would be with various employments of `shell-quote-argument`, when passing a string to the shell, which is known to be interpreted verbatim. Or as just recently reported in bug #35492, where file arguments for Git commands must be properly quoted to work correctly (this is not because of the shell but because of Git!). If this quoting is omitted, `vc-dir-mode` becomes entirely unreliable for Git. If it is done quick and dirty instead of properly, it causes other problems. > Am I missing something?